node-network-devtools
Version:
Inspecting Node.js's Network with Chrome DevTools
1,099 lines (1,098 loc) • 33.6 kB
JavaScript
import ie from "http";
import U from "https";
import { R as te, g as oe, _ as C, w as ae, a as he, b as fe, P as le, S as ce } from "./common-D7uiq4bu.mjs";
import { Writable as de } from "stream";
import R from "node:zlib";
import { isUtf8 as F } from "node:buffer";
import D from "ws";
import { fork as _e } from "child_process";
import { resolve as q } from "path";
import I from "fs";
import ue from "net";
import x from "undici";
function se(n) {
const e = {};
return n.forEach((t, r) => {
e[r] = t;
}), e;
}
const pe = typeof Blob < "u", W = [
"nodebuffer",
"arraybuffer",
"fragments",
pe ? "blob" : null
].filter(Boolean), M = Buffer.alloc(0), me = Symbol("status-code"), ge = Symbol("websocket"), we = Buffer[Symbol.species];
function S(n, e) {
if (n.length === 0) return M;
if (n.length === 1) return n[0];
const t = Buffer.allocUnsafe(e);
let r = 0;
for (let s = 0; s < n.length; s++) {
const i = n[s];
t.set(i, r), r += i.length;
}
return r < e ? new we(t.buffer, t.byteOffset, r) : t;
}
function ye(n, e) {
for (let t = 0; t < n.length; t++)
n[t] ^= e[t & 3];
}
function Ee(n) {
return n.length === n.buffer.byteLength ? n.buffer : n.buffer.slice(n.byteOffset, n.byteOffset + n.length);
}
const H = Symbol("kDone"), N = Symbol("kRun");
class Re {
/**
* Creates a new `Limiter`.
*
* @param {Number} [concurrency=Infinity] The maximum number of jobs allowed
* to run concurrently
*/
constructor(e = 1 / 0) {
this[H] = () => {
this.pending--, this[N]();
}, this.concurrency = e, this.jobs = [], this.pending = 0;
}
/**
* Adds a job to the queue.
*
* @param {Function} job The job to run
* @public
*/
add(e) {
this.jobs.push(e), this[N]();
}
/**
* Removes a job from the queue and runs it if possible.
*
* @private
*/
[N]() {
if (this.pending !== this.concurrency && this.jobs.length) {
const e = this.jobs.shift();
this.pending++, e(this[H]);
}
}
}
const Se = Buffer.from([0, 0, 255, 255]), O = Symbol("permessage-deflate"), w = Symbol("total-length"), v = Symbol("callback"), y = Symbol("buffers"), ve = Symbol("error");
let L;
class V {
constructor(e = {}, t = !1, r = 0) {
if (this._maxPayload = r | 0, this._options = e, this._threshold = this._options.threshold !== void 0 ? this._options.threshold : 1024, this._isServer = !!t, this._deflate = null, this._inflate = null, this.params = null, !L) {
const s = this._options.concurrencyLimit !== void 0 ? this._options.concurrencyLimit : 10;
L = new Re(s);
}
}
static get extensionName() {
return "permessage-deflate";
}
offer() {
const e = {};
return this._options.serverNoContextTakeover && (e.server_no_context_takeover = !0), this._options.clientNoContextTakeover && (e.client_no_context_takeover = !0), this._options.serverMaxWindowBits && (e.server_max_window_bits = this._options.serverMaxWindowBits), this._options.clientMaxWindowBits ? e.client_max_window_bits = this._options.clientMaxWindowBits : this._options.clientMaxWindowBits == null && (e.client_max_window_bits = !0), e;
}
accept(e) {
return e = this.normalizeParams(e), this.params = this._isServer ? this.acceptAsServer(e) : this.acceptAsClient(e), this.params;
}
cleanup() {
if (this._inflate && (this._inflate.close(), this._inflate = null), this._deflate) {
const e = this._deflate[v];
this._deflate.close(), this._deflate = null, e && e(new Error("The deflate stream was closed while data was being processed"));
}
}
acceptAsServer(e) {
const t = this._options, r = e.find((s) => !(t.serverNoContextTakeover === !1 && s.server_no_context_takeover || s.server_max_window_bits && (t.serverMaxWindowBits === !1 || typeof t.serverMaxWindowBits == "number" && t.serverMaxWindowBits > s.server_max_window_bits) || typeof t.clientMaxWindowBits == "number" && !s.client_max_window_bits));
if (!r)
throw new Error("None of the extension offers can be accepted");
return t.serverNoContextTakeover && (r.server_no_context_takeover = !0), t.clientNoContextTakeover && (r.client_no_context_takeover = !0), typeof t.serverMaxWindowBits == "number" && (r.server_max_window_bits = t.serverMaxWindowBits), typeof t.clientMaxWindowBits == "number" ? r.client_max_window_bits = t.clientMaxWindowBits : (r.client_max_window_bits === !0 || t.clientMaxWindowBits === !1) && delete r.client_max_window_bits, r;
}
acceptAsClient(e) {
const t = e[0];
if (this._options.clientNoContextTakeover === !1 && t.client_no_context_takeover)
throw new Error('Unexpected parameter "client_no_context_takeover"');
if (!t.client_max_window_bits)
typeof this._options.clientMaxWindowBits == "number" && (t.client_max_window_bits = this._options.clientMaxWindowBits);
else if (this._options.clientMaxWindowBits === !1 || typeof this._options.clientMaxWindowBits == "number" && t.client_max_window_bits > this._options.clientMaxWindowBits)
throw new Error('Unexpected or invalid parameter "client_max_window_bits"');
return t;
}
normalizeParams(e) {
return e.forEach((t) => {
Object.keys(t).forEach((r) => {
let s = t[r];
if (s.length > 1)
throw new Error(`Parameter "${r}" must have only a single value`);
if (s = s[0], r === "client_max_window_bits") {
if (s !== !0) {
const i = +s;
if (!Number.isInteger(i) || i < 8 || i > 15)
throw new TypeError(`Invalid value for parameter "${r}": ${s}`);
s = i;
} else if (!this._isServer)
throw new TypeError(`Invalid value for parameter "${r}": ${s}`);
} else if (r === "server_max_window_bits") {
const i = +s;
if (!Number.isInteger(i) || i < 8 || i > 15)
throw new TypeError(`Invalid value for parameter "${r}": ${s}`);
s = i;
} else if (r === "client_no_context_takeover" || r === "server_no_context_takeover") {
if (s !== !0)
throw new TypeError(`Invalid value for parameter "${r}": ${s}`);
} else
throw new Error(`Unknown parameter "${r}"`);
t[r] = s;
});
}), e;
}
decompress(e, t, r) {
L?.add((s) => {
this._decompress(e, t, (i, o) => {
s(), r(i, o);
});
});
}
compress(e, t, r) {
L?.add((s) => {
this._compress(e, t, (i, o) => {
s(), r(i, o);
});
});
}
_decompress(e, t, r) {
const s = this._isServer ? "client" : "server";
if (!this._inflate) {
const i = `${s}_max_window_bits`, o = typeof this.params[i] != "number" ? R.constants.Z_DEFAULT_WINDOWBITS : this.params[i];
this._inflate = R.createInflateRaw({
...this._options.zlibInflateOptions,
windowBits: o
}), this._inflate[O] = this, this._inflate[w] = 0, this._inflate[y] = [], this._inflate.on("error", be), this._inflate.on("data", xe);
}
this._inflate[v] = r, this._inflate.write(e), t && this._inflate.write(Se), this._inflate.flush(() => {
const i = this._inflate[ve];
if (i) {
this._inflate.close(), this._inflate = null, r(i);
return;
}
const o = S(
this._inflate[y],
this._inflate[w]
);
if (this._maxPayload < 1 || o.length <= this._maxPayload) {
r(null, o);
return;
}
r(new RangeError("Max payload size exceeded"), null);
});
}
_compress(e, t, r) {
const s = this._isServer ? "server" : "client";
if (!this._deflate) {
const i = `${s}_max_window_bits`, o = typeof this.params[i] != "number" ? R.constants.Z_DEFAULT_WINDOWBITS : this.params[i];
this._deflate = R.createDeflateRaw({
...this._options.zlibDeflateOptions,
windowBits: o
}), this._deflate[w] = 0, this._deflate[y] = [], this._deflate.on("error", Le), this._deflate.on("data", Te);
}
this._deflate[v] = r, this._deflate.write(e), t && this._deflate.flush(R.Z_SYNC_FLUSH, () => {
const i = S(
this._deflate[y],
this._deflate[w]
);
if (this._maxPayload < 1 || i.length <= this._maxPayload) {
r(null, i);
return;
}
r(new RangeError("Max payload size exceeded"), null);
});
}
}
function be(n) {
this[O][v](n);
}
function xe(n) {
this[w] += n.length, this[y].push(n);
}
function Le(n) {
this[O][v](n);
}
function Te(n) {
this[w] += n.length, this[y].push(n);
}
function ke(n) {
return n >= 1e3 && n <= 1014 && n !== 1004 && n !== 1005 && n !== 1006 || n >= 3e3 && n <= 4999;
}
function $(n) {
const e = n.length;
let t = 0;
for (; t < e; )
if (!(n[t] & 128))
t++;
else if ((n[t] & 224) === 192) {
if (t + 1 === e || (n[t + 1] & 192) !== 128 || (n[t] & 254) === 192)
return !1;
t += 2;
} else if ((n[t] & 240) === 224) {
if (t + 2 >= e || (n[t + 1] & 192) !== 128 || (n[t + 2] & 192) !== 128 || n[t] === 224 && (n[t + 1] & 224) === 128 || // Overlong
n[t] === 237 && (n[t + 1] & 224) === 160)
return !1;
t += 3;
} else if ((n[t] & 248) === 240) {
if (t + 3 >= e || (n[t + 1] & 192) !== 128 || (n[t + 2] & 192) !== 128 || (n[t + 3] & 192) !== 128 || n[t] === 240 && (n[t + 1] & 240) === 128 || // Overlong
n[t] === 244 && n[t + 1] > 143 || n[t] > 244)
return !1;
t += 4;
} else
return !1;
return !0;
}
const G = F ? function(n) {
return n.length < 24 ? $(n) : F(n);
} : $;
var z;
const T = Buffer[Symbol.species], m = 0, j = 1, Y = 2, X = 3, B = 4, A = 5, k = 6;
class J extends (z = de, z) {
constructor(e = {}) {
super(), this._allowSynchronousEvents = e.allowSynchronousEvents !== void 0 ? e.allowSynchronousEvents : !0, this._binaryType = e.binaryType || W[0], this._extensions = e.extensions || {}, this._isServer = !!e.isServer, this._maxPayload = e.maxPayload || 0, this._skipUTF8Validation = !!e.skipUTF8Validation, this[ge] = void 0, this._bufferedBytes = 0, this._buffers = [], this._compressed = !1, this._payloadLength = 0, this._mask = void 0, this._fragmented = 0, this._masked = !1, this._fin = !1, this._opcode = 0, this._totalPayloadLength = 0, this._messageLength = 0, this._fragments = [], this._errored = !1, this._loop = !1, this._state = m;
}
/**
* Implements `Writable.prototype._write()`.
*
* @param {Buffer} chunk The chunk of data to write
* @param {string} encoding The character encoding of `chunk`
* @param {Function} cb Callback
* @private
*/
_write(e, t, r) {
if (this._opcode === 8 && this._state === m) return r();
this._bufferedBytes += e.length, this._buffers.push(e), this.startLoop(r);
}
/**
* Consumes `n` bytes from the buffered data.
*
* @param {number} n The number of bytes to consume
* @return {Buffer} The consumed bytes
* @private
*/
consume(e) {
if (this._bufferedBytes -= e, e === this._buffers[0].length) return this._buffers.shift();
if (e < this._buffers[0].length) {
const r = this._buffers[0];
return this._buffers[0] = new T(r.buffer, r.byteOffset + e, r.length - e), new T(r.buffer, r.byteOffset, e);
}
const t = Buffer.allocUnsafe(e);
do {
const r = this._buffers[0], s = t.length - e;
e >= r.length ? t.set(this._buffers.shift(), s) : (t.set(new Uint8Array(r.buffer, r.byteOffset, e), s), this._buffers[0] = new T(r.buffer, r.byteOffset + e, r.length - e)), e -= r.length;
} while (e > 0);
return t;
}
/**
* Starts the parsing loop.
*
* @param {Function} cb Callback
* @private
*/
startLoop(e) {
this._loop = !0;
do
switch (this._state) {
case m:
this.getInfo(e);
break;
case j:
this.getPayloadLength16(e);
break;
case Y:
this.getPayloadLength64(e);
break;
case X:
this.getMask();
break;
case B:
this.getData(e);
break;
case A:
case k:
this._loop = !1;
return;
}
while (this._loop);
this._errored || e();
}
/**
* Reads the first two bytes of a frame.
*
* @param {Function} cb Callback
* @private
*/
getInfo(e) {
if (this._bufferedBytes < 2) {
this._loop = !1;
return;
}
const t = this.consume(2);
if (t[0] & 48) {
const s = this.createError(
RangeError,
"RSV2 and RSV3 must be clear",
!0,
1002,
"WS_ERR_UNEXPECTED_RSV_2_3"
);
e(s);
return;
}
const r = (t[0] & 64) === 64;
if (r && !this._extensions[V.extensionName]) {
const s = this.createError(
RangeError,
"RSV1 must be clear",
!0,
1002,
"WS_ERR_UNEXPECTED_RSV_1"
);
e(s);
return;
}
if (this._fin = (t[0] & 128) === 128, this._opcode = t[0] & 15, this._payloadLength = t[1] & 127, this._opcode === 0) {
if (r) {
const s = this.createError(
RangeError,
"RSV1 must be clear",
!0,
1002,
"WS_ERR_UNEXPECTED_RSV_1"
);
e(s);
return;
}
if (!this._fragmented) {
const s = this.createError(
RangeError,
"invalid opcode 0",
!0,
1002,
"WS_ERR_INVALID_OPCODE"
);
e(s);
return;
}
this._opcode = this._fragmented;
} else if (this._opcode === 1 || this._opcode === 2) {
if (this._fragmented) {
const s = this.createError(
RangeError,
`invalid opcode ${this._opcode}`,
!0,
1002,
"WS_ERR_INVALID_OPCODE"
);
e(s);
return;
}
this._compressed = r;
} else if (this._opcode > 7 && this._opcode < 11) {
if (!this._fin) {
const s = this.createError(
RangeError,
"FIN must be set",
!0,
1002,
"WS_ERR_EXPECTED_FIN"
);
e(s);
return;
}
if (r) {
const s = this.createError(
RangeError,
"RSV1 must be clear",
!0,
1002,
"WS_ERR_UNEXPECTED_RSV_1"
);
e(s);
return;
}
if (this._payloadLength > 125 || this._opcode === 8 && this._payloadLength === 1) {
const s = this.createError(
RangeError,
`invalid payload length ${this._payloadLength}`,
!0,
1002,
"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH"
);
e(s);
return;
}
} else {
const s = this.createError(
RangeError,
`invalid opcode ${this._opcode}`,
!0,
1002,
"WS_ERR_INVALID_OPCODE"
);
e(s);
return;
}
if (!this._fin && !this._fragmented && (this._fragmented = this._opcode), this._masked = (t[1] & 128) === 128, this._isServer) {
if (!this._masked) {
const s = this.createError(
RangeError,
"MASK must be set",
!0,
1002,
"WS_ERR_EXPECTED_MASK"
);
e(s);
return;
}
} else if (this._masked) {
const s = this.createError(
RangeError,
"MASK must be clear",
!0,
1002,
"WS_ERR_UNEXPECTED_MASK"
);
e(s);
return;
}
this._payloadLength === 126 ? this._state = j : this._payloadLength === 127 ? this._state = Y : this.haveLength(e);
}
/**
* Reads the next two bytes and stores the message length.
*
* @param {Function} cb Callback
* @private
*/
getPayloadLength16(e) {
if (this._bufferedBytes < 2) {
this._loop = !1;
return;
}
this._payloadLength = this.consume(2).readUInt16BE(0), this.haveLength(e);
}
/**
* Reads the next eight bytes and stores the message length.
*
* @param {Function} cb Callback
* @private
*/
getPayloadLength64(e) {
if (this._bufferedBytes < 8) {
this._loop = !1;
return;
}
const t = this.consume(8), r = t.readUInt32BE(0);
if (r > Math.pow(2, 21) - 1) {
const s = this.createError(
RangeError,
"Unsupported WebSocket frame: payload length > 2^53 - 1",
!1,
1009,
"WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH"
);
e(s);
return;
}
this._payloadLength = r * Math.pow(2, 32) + t.readUInt32BE(4), this.haveLength(e);
}
/**
* Payload length has been read.
*
* @param {Function} cb Callback
* @private
*/
haveLength(e) {
if (this._payloadLength && this._opcode < 8 && (this._totalPayloadLength += this._payloadLength, this._totalPayloadLength > this._maxPayload && this._maxPayload > 0)) {
const t = this.createError(
RangeError,
"Max payload size exceeded",
!1,
1009,
"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"
);
e(t);
return;
}
this._masked ? this._state = X : this._state = B;
}
/**
* Reads the mask bytes.
*
* @private
*/
getMask() {
if (this._bufferedBytes < 4) {
this._loop = !1;
return;
}
this._mask = this.consume(4), this._state = B;
}
/**
* Reads data bytes.
*
* @param {Function} cb Callback
* @private
*/
getData(e) {
let t = M;
if (this._payloadLength) {
if (this._bufferedBytes < this._payloadLength) {
this._loop = !1;
return;
}
t = this.consume(this._payloadLength), this._masked && this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3] && ye(t, this._mask);
}
if (this._opcode > 7) {
this.controlMessage(t, e);
return;
}
if (this._compressed) {
this._state = A, this.decompress(t, e);
return;
}
t.length && (this._messageLength = this._totalPayloadLength, this._fragments.push(t)), this.dataMessage(e);
}
/**
* Decompresses data.
*
* @param {Buffer} data Compressed data
* @param {Function} cb Callback
* @private
*/
decompress(e, t) {
this._extensions[V.extensionName].decompress(e, this._fin, (s, i) => {
if (s) return t(s);
if (i && i.length) {
if (this._messageLength += i.length, this._messageLength > this._maxPayload && this._maxPayload > 0) {
const o = this.createError(
RangeError,
"Max payload size exceeded",
!1,
1009,
"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"
);
t(o);
return;
}
this._fragments.push(i);
}
this.dataMessage(t), this._state === m && this.startLoop(t);
});
}
/**
* Handles a data message.
*
* @param {Function} cb Callback
* @private
*/
dataMessage(e) {
if (!this._fin) {
this._state = m;
return;
}
const t = this._messageLength, r = this._fragments;
if (this._totalPayloadLength = 0, this._messageLength = 0, this._fragmented = 0, this._fragments = [], this._opcode === 2) {
let s;
this._binaryType === "nodebuffer" ? s = S(r, t) : this._binaryType === "arraybuffer" ? s = Ee(S(r, t)) : this._binaryType === "blob" ? s = new Blob(r) : s = r, this._allowSynchronousEvents ? (this.emit("message", s, !0), this._state = m) : (this._state = k, setImmediate(() => {
this.emit("message", s, !0), this._state = m, this.startLoop(e);
}));
} else {
const s = S(r, t);
if (!this._skipUTF8Validation && !G(s)) {
const i = this.createError(
Error,
"invalid UTF-8 sequence",
!0,
1007,
"WS_ERR_INVALID_UTF8"
);
e(i);
return;
}
this._state === A || this._allowSynchronousEvents ? (this.emit("message", s, !1), this._state = m) : (this._state = k, setImmediate(() => {
this.emit("message", s, !1), this._state = m, this.startLoop(e);
}));
}
}
/**
* Handles a control message.
*
* @param {Buffer} data Data to handle
* @return {(Error|RangeError|undefined)} A possible error
* @private
*/
controlMessage(e, t) {
if (this._opcode === 8) {
if (e.length === 0)
this._loop = !1, this.emit("conclude", 1005, M), this.end();
else {
const r = e.readUInt16BE(0);
if (!ke(r)) {
const i = this.createError(
RangeError,
`invalid status code ${r}`,
!0,
1002,
"WS_ERR_INVALID_CLOSE_CODE"
);
t(i);
return;
}
const s = new T(e.buffer, e.byteOffset + 2, e.length - 2);
if (!this._skipUTF8Validation && !G(s)) {
const i = this.createError(
Error,
"invalid UTF-8 sequence",
!0,
1007,
"WS_ERR_INVALID_UTF8"
);
t(i);
return;
}
this._loop = !1, this.emit("conclude", r, s), this.end();
}
this._state = m;
return;
}
this._allowSynchronousEvents ? (this.emit(this._opcode === 9 ? "ping" : "pong", e), this._state = m) : (this._state = k, setImmediate(() => {
this.emit(this._opcode === 9 ? "ping" : "pong", e), this._state = m, this.startLoop(t);
}));
}
createError(e, t, r, s, i) {
this._loop = !1, this._errored = !0;
const o = new e(r ? `Invalid WebSocket frame: ${t}` : t);
return Error.captureStackTrace(o, this.createError), o.code = i, o[me] = s, o;
}
}
function K(n, e, t) {
const r = n.write;
return n.write = (s) => {
let i;
return Buffer.isBuffer(s) ? i = s.toString("utf-8") : typeof s == "string" ? i = s : s != null ? i = JSON.stringify(s) : i = "", e.requestData ? e.requestData += i : e.requestData = i, r.bind(n)(s);
}, n.on("error", () => {
e.responseStatusCode = 0, e.requestEndTime = (/* @__PURE__ */ new Date()).getTime(), t.sendRequest("endRequest", e);
}), e.isWebSocket() ? n.on("upgrade", async (s, i, o) => {
const c = i.write;
if (e.isHiden())
return;
await t.send({
type: "Network.webSocketCreated",
data: {
requestId: e.id,
url: e.url,
initiator: e.initiator,
response: s
}
});
const h = new J({
allowSynchronousEvents: !0,
binaryType: W[0],
isServer: !1
}), _ = new J({
allowSynchronousEvents: !0,
binaryType: W[0],
isServer: !0
}), a = (d) => {
const p = d.toString();
t.send({
type: "Network.webSocketFrameReceived",
data: {
requestId: e.id,
response: {
payloadData: p,
opcode: 1,
mask: !1
}
}
});
}, u = (d) => {
const p = d.toString();
t.send({
type: "Network.webSocketFrameSent",
data: {
requestId: e.id,
response: {
payloadData: p,
opcode: 1,
mask: !0
}
}
});
};
h.on("message", a), _.on("message", u);
let f;
i.write = (d, ...p) => {
const l = Buffer.from(d);
return _.write(l), c.call(i, d, ...p);
}, i.addListener("data", (d) => {
const p = Buffer.from(d);
h.write(p);
}), i.addListener("close", () => {
f = i.read(), f !== null && (h.write(f), _.write(f)), h.end(), _.end(), h.removeAllListeners(), _.removeAllListeners(), t.send({
method: "Network.webSocketClosed",
params: {
requestId: e.id,
timestamp: oe()
}
});
}), i.addListener("end", () => {
h.end(), _.end(), h.removeAllListeners(), _.removeAllListeners();
});
}) : t.sendRequest("registerRequest", e), n;
}
function Ie(n, e, t) {
return (r) => {
e.responseHeaders = r.headers, typeof n == "function" && n(r), t.responseRequest(e.id, r);
};
}
function Z(n, e) {
let t = n.setHeader;
n.setHeader = function(r, s) {
return Array.isArray(s) ? s.forEach((i) => {
e.requestHeaders[r] = i;
}) : e.requestHeaders[r] = s, t.call(n, r, s);
};
}
function Ne(n, e, t) {
return (s, i, o) => {
let c, h, _;
typeof s == "string" || s instanceof URL ? (c = s, h = i, _ = o) : (h = s, _ = i);
const a = new te();
if (typeof c == "string")
a.url = c, a.method = "GET";
else if (c instanceof URL)
a.url = c.toString(), a.method = "GET";
else if (h && typeof h != "string" && !(h instanceof URL)) {
const f = e ? "https" : "http";
a.url = `${f}://${h.hostname || h.host}${h.path}`;
}
h && typeof h != "string" && !(h instanceof URL) && (a.method = h.method, a.requestHeaders = h.headers), a.loadCallFrames(), a.isWebSocket() && (a.url = a.url.replace("http://", "ws://").replace("https://", "wss://")), t.sendRequest("initRequest", a);
const u = Ie(_, a, t);
if (typeof s == "string" || s instanceof URL) {
const f = n(
c,
h,
u
);
return Z(f, a), K(f, a, t);
} else {
const f = n(h, u);
return Z(f, a), K(f, a, t);
}
};
}
const Be = (n) => new Promise((e) => setTimeout(e, n)), Ae = (n, e) => {
try {
return Number(n) === process.pid ? Promise.resolve(!0) : (process.kill(Number(n), 0), new Promise((t) => {
const r = ue.createServer();
r.once("error", (s) => {
s.code === "EADDRINUSE" && t(!1), t(!1);
}), r.once("listening", () => {
r.close(() => t(!0));
}), r.listen(e);
}));
} catch {
return Promise.resolve(!1);
}
}, P = (n) => {
try {
I.unlinkSync(n);
} catch {
}
};
let re = null;
function b() {
return re;
}
function Q(n) {
re = n;
}
class ee extends Error {
constructor(e) {
super(e);
}
}
class Pe {
constructor(e) {
this.options = e, this.ws = new Promise(async (t, r) => {
const s = q(C, `./${e.key}`);
if (I.existsSync(s)) {
const o = I.readFileSync(s, "utf-8");
if (await Be(1), await Ae(o, e.port)) {
ae("The main process with same options is already running, skip it.");
return;
}
P(s);
}
I.writeFileSync(s, `${process.pid}`);
const i = new D(`ws://127.0.0.1:${e.port}`);
i.on("open", () => {
P(s), t(i);
}), i.on("error", () => {
this.openProcess(() => {
P(s);
const o = new D(`ws://127.0.0.1:${e.port}`);
o.on("open", () => {
t(o);
}), o.on("error", r);
});
});
}), this.ws.then((t) => {
this.healthCheck(), t.on("error", (r) => {
console.error("MainProcess Socket Error: ", r);
});
}).catch((t) => {
if (!(t instanceof ee))
throw t;
});
}
openProcess(e) {
(() => {
const r = _e(q(C, "./fork"), {
env: {
...process.env,
NETWORK_OPTIONS: JSON.stringify(this.options)
}
}), s = (i) => {
i === he && (e && e(r), r.off("message", s));
};
r.on("message", s), this.cp = r;
})();
}
async send(e) {
if (b()?.isAborted)
return;
const r = await this.ws.catch((s) => {
if (s instanceof ee)
return null;
throw s;
});
r && r.send(JSON.stringify(e));
}
sendRequest(e, t) {
const r = b();
let s = t;
return r && (r.request = s, r.pipes.filter((o) => o.type === e).map((o) => o.pipe).forEach((o) => {
s = o(s);
}), r.request = s), this.send({
type: e,
data: t
}), this;
}
async healthCheck() {
const e = await this.ws, t = () => {
e.send(
JSON.stringify({
type: "healthcheck",
data: {}
})
);
};
t(), setInterval(t, 2e3);
}
responseRequest(e, t) {
const r = [];
t.on("data", (s) => {
r.push(s);
}), t.on("end", () => {
const s = Buffer.concat(r);
this.ws.then((i) => {
i.send(
JSON.stringify({
type: "responseData",
data: {
id: e,
rawData: s,
statusCode: t.statusCode,
headers: t.headers
}
}),
{ binary: !0 }
);
});
});
}
async dispose() {
const e = await this.ws;
e.removeAllListeners(), e.terminate(), this.cp && (this.cp.removeAllListeners(), this.cp.kill(), this.cp = void 0);
}
}
function We(n) {
if (!globalThis.fetch)
return;
const e = globalThis.fetch;
return globalThis.fetch = ne(e, n), () => {
globalThis.fetch = e;
};
}
function ne(n, e) {
return function(t, r) {
const s = new te();
s.requestStartTime = Date.now(), Q({ request: s, pipes: [], isAborted: !1 }), typeof t == "string" ? s.url = t : t instanceof URL && (s.url = t.toString()), s.method = r?.method ?? "GET";
const i = r?.headers;
if (i instanceof Headers) {
const c = se(i);
s.requestHeaders = c;
} else
s.requestHeaders = i ?? {};
s.requestData = r?.body;
const o = n(t, r).then(Ue(s, e)).catch(Ce(s, e)).finally(() => {
Q(null);
});
return e.sendRequest("initRequest", s).sendRequest("registerRequest", s), o;
};
}
function Me(n) {
return (n.headers.get("content-type") || "").includes("text/event-stream");
}
async function Oe(n, e, t) {
const r = n.clone().body;
if (!r)
return;
const s = r.getReader(), i = new TextDecoder();
let o = "";
const c = [];
t.sendRequest("updateRequest", e);
try {
for (; ; ) {
const { done: u, value: f } = await s.read();
if (u)
break;
if (f) {
c.push(f), o += i.decode(f, { stream: !0 });
const d = o.split(`
`);
o = d.pop() || "";
let p = "message", l = "", E = "";
for (const g of d)
g.startsWith("event:") ? p = g.slice(6).trim() : g.startsWith("data:") ? l += (l ? `
` : "") + g.slice(5).trim() : g.startsWith("id:") ? E = g.slice(3).trim() : g === "" && (l && t.send({
type: "eventSourceMessage",
data: {
requestId: e.id,
eventName: p,
eventId: E,
data: l
}
}), p = "message", l = "", E = "");
}
}
if (o.trim()) {
const u = o.split(`
`);
let f = "message", d = "", p = "";
for (const l of u)
l.startsWith("event:") ? f = l.slice(6).trim() : l.startsWith("data:") ? d += (d ? `
` : "") + l.slice(5).trim() : l.startsWith("id:") && (p = l.slice(3).trim());
d && t.send({
type: "eventSourceMessage",
data: {
requestId: e.id,
eventName: f,
eventId: p,
data: d
}
});
}
const h = c.reduce((u, f) => u + f.length, 0), _ = new Uint8Array(h);
let a = 0;
for (const u of c)
_.set(u, a), a += u.length;
e.responseData = Buffer.from(_), e.responseInfo.dataLength = h, e.responseInfo.encodedDataLength = h;
} catch {
if (c.length > 0) {
const _ = c.reduce((f, d) => f + d.length, 0), a = new Uint8Array(_);
let u = 0;
for (const f of c)
a.set(f, u), u += f.length;
e.responseData = Buffer.from(a), e.responseInfo.dataLength = _, e.responseInfo.encodedDataLength = _;
}
} finally {
e.requestEndTime = Date.now(), t.sendRequest("updateRequest", e).sendRequest("endRequest", e);
}
}
function Ue(n, e) {
return (t) => (n.requestEndTime = (/* @__PURE__ */ new Date()).getTime(), n.responseHeaders = se(t.headers), n.responseStatusCode = t.status || 0, Me(t) ? (Oe(t, n, e), t) : (t.clone().arrayBuffer().then((r) => {
const s = Buffer.from(r);
n.responseData = s, n.responseInfo.dataLength = s.length, n.responseInfo.encodedDataLength = s.length;
}).finally(() => {
e.sendRequest("updateRequest", n).sendRequest("endRequest", n);
}), t));
}
function Ce(n, e) {
return (t) => {
throw n.requestEndTime = Date.now(), n.responseStatusCode = 0, e.sendRequest("updateRequest", n).sendRequest("endRequest", n), t;
};
}
const Fe = (n) => {
if (!x.fetch)
return;
const e = x.fetch;
return x.fetch = ne(
e,
n
), () => {
x.fetch = e;
};
}, Ze = (n) => {
const e = b();
if (!e)
throw new Error("useRegisterRequest must be used in request handler");
e.pipes.push({
pipe: n,
type: "registerRequest"
});
}, Qe = (n, e) => {
const t = b();
if (!t)
throw new Error("useRequestPipe must be used in request handler");
t.pipes.push({
pipe: e,
type: n
});
}, et = () => {
const n = b();
if (!n)
throw new Error("useRegisterRequest must be used in request handler");
n.isAborted = !0;
};
function tt(n) {
const {
port: e = le,
serverPort: t = ce,
autoOpenDevtool: r = !0,
intercept: s = {}
} = n || {}, {
fetch: i = !0,
normal: o = !0,
undici: c = !1
} = s, h = c && c.fetch, _ = fe(JSON.stringify({ port: e, serverPort: t, autoOpenDevtool: r })), a = new Pe({
port: e,
serverPort: t,
autoOpenDevtool: r,
key: _
}), u = i ? We(a) : void 0, f = /* @__PURE__ */ new WeakMap(), d = [ie, U];
o && d.forEach((l) => {
f.set(l, l.request);
const E = l.request;
l.request = Ne(E, l === U, a);
});
const p = h ? Fe(a) : void 0;
return () => {
u && u(), o && d.forEach((l) => {
l.request = f.get(l), f.delete(l);
}), p && p(), a.dispose();
};
}
export {
b as getCurrentCell,
tt as register,
Q as setCurrentCell,
et as useAbortRequest,
Ze as useRegisterRequest,
Qe as useRequestPipe
};