mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
git-subtree-dir: turbopack git-subtree-mainline:344ddbf093git-subtree-split:fb033c4917
173 lines
5.6 KiB
JavaScript
173 lines
5.6 KiB
JavaScript
import { createConnection } from "node:net";
|
|
import { parse as parseStackTrace } from "../compiled/stacktrace-parser";
|
|
import { getProperError } from "./error";
|
|
export function structuredError(e) {
|
|
e = getProperError(e);
|
|
return {
|
|
name: e.name,
|
|
message: e.message,
|
|
stack: typeof e.stack === "string" ? parseStackTrace(e.stack) : []
|
|
};
|
|
}
|
|
function createIpc(port) {
|
|
const socket = createConnection(port, "127.0.0.1");
|
|
const packetQueue = [];
|
|
const recvPromiseResolveQueue = [];
|
|
function pushPacket(packet) {
|
|
const recvPromiseResolve = recvPromiseResolveQueue.shift();
|
|
if (recvPromiseResolve != null) {
|
|
recvPromiseResolve(JSON.parse(packet.toString("utf8")));
|
|
} else {
|
|
packetQueue.push(packet);
|
|
}
|
|
}
|
|
let state = {
|
|
type: "waiting"
|
|
};
|
|
let buffer = Buffer.alloc(0);
|
|
socket.once("connect", ()=>{
|
|
socket.on("data", (chunk)=>{
|
|
buffer = Buffer.concat([
|
|
buffer,
|
|
chunk
|
|
]);
|
|
loop: while(true){
|
|
switch(state.type){
|
|
case "waiting":
|
|
{
|
|
if (buffer.length >= 4) {
|
|
const length = buffer.readUInt32BE(0);
|
|
buffer = buffer.subarray(4);
|
|
state = {
|
|
type: "packet",
|
|
length
|
|
};
|
|
} else {
|
|
break loop;
|
|
}
|
|
break;
|
|
}
|
|
case "packet":
|
|
{
|
|
if (buffer.length >= state.length) {
|
|
const packet = buffer.subarray(0, state.length);
|
|
buffer = buffer.subarray(state.length);
|
|
state = {
|
|
type: "waiting"
|
|
};
|
|
pushPacket(packet);
|
|
} else {
|
|
break loop;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
socket.once("close", ()=>{
|
|
process.exit(0);
|
|
});
|
|
function send(message) {
|
|
const packet = Buffer.from(JSON.stringify(message), "utf8");
|
|
const length = Buffer.alloc(4);
|
|
length.writeUInt32BE(packet.length);
|
|
socket.write(length);
|
|
return new Promise((resolve, reject)=>{
|
|
socket.write(packet, (err)=>{
|
|
process.stderr.write(`TURBOPACK_OUTPUT_D\n`);
|
|
process.stdout.write(`TURBOPACK_OUTPUT_D\n`);
|
|
if (err != null) {
|
|
reject(err);
|
|
} else {
|
|
resolve();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
function sendReady() {
|
|
const length = Buffer.from([
|
|
0,
|
|
0,
|
|
0,
|
|
0
|
|
]);
|
|
return new Promise((resolve, reject)=>{
|
|
socket.write(length, (err)=>{
|
|
process.stderr.write(`TURBOPACK_OUTPUT_D\n`);
|
|
process.stdout.write(`TURBOPACK_OUTPUT_D\n`);
|
|
if (err != null) {
|
|
reject(err);
|
|
} else {
|
|
resolve();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
return {
|
|
async recv () {
|
|
const packet = packetQueue.shift();
|
|
if (packet != null) {
|
|
return JSON.parse(packet.toString("utf8"));
|
|
}
|
|
const result = await new Promise((resolve)=>{
|
|
recvPromiseResolveQueue.push((result)=>{
|
|
resolve(result);
|
|
});
|
|
});
|
|
return result;
|
|
},
|
|
send (message) {
|
|
return send(message);
|
|
},
|
|
sendReady,
|
|
async sendError (error) {
|
|
try {
|
|
await send({
|
|
type: "error",
|
|
...structuredError(error)
|
|
});
|
|
} catch (err) {
|
|
console.error("failed to send error back to rust:", err);
|
|
process.exit(1);
|
|
}
|
|
process.exit(0);
|
|
}
|
|
};
|
|
}
|
|
const PORT = process.argv[2];
|
|
export const IPC = createIpc(parseInt(PORT, 10));
|
|
process.on("uncaughtException", (err)=>{
|
|
IPC.sendError(err);
|
|
});
|
|
const improveConsole = (name, stream, addStack)=>{
|
|
const original = console[name];
|
|
const stdio = process[stream];
|
|
console[name] = (...args)=>{
|
|
stdio.write(`TURBOPACK_OUTPUT_B\n`);
|
|
original(...args);
|
|
if (addStack) {
|
|
const stack = new Error().stack?.replace(/^.+\n.+\n/, "") + "\n";
|
|
stdio.write("TURBOPACK_OUTPUT_S\n");
|
|
stdio.write(stack);
|
|
}
|
|
stdio.write("TURBOPACK_OUTPUT_E\n");
|
|
};
|
|
};
|
|
improveConsole("error", "stderr", true);
|
|
improveConsole("warn", "stderr", true);
|
|
improveConsole("count", "stdout", true);
|
|
improveConsole("trace", "stderr", false);
|
|
improveConsole("log", "stdout", true);
|
|
improveConsole("group", "stdout", true);
|
|
improveConsole("groupCollapsed", "stdout", true);
|
|
improveConsole("table", "stdout", true);
|
|
improveConsole("debug", "stdout", true);
|
|
improveConsole("info", "stdout", true);
|
|
improveConsole("dir", "stdout", true);
|
|
improveConsole("dirxml", "stdout", true);
|
|
improveConsole("timeEnd", "stdout", true);
|
|
improveConsole("timeLog", "stdout", true);
|
|
improveConsole("timeStamp", "stdout", true);
|
|
improveConsole("assert", "stderr", true);
|