node-network-devtools
Version:
Inspecting Node.js's Network with Chrome DevTools
1,034 lines (1,033 loc) • 31.3 kB
JavaScript
import ie from "http";
import W from "https";
import { R as Q, g as ne, _ as O, w as oe, a as ae, b as he, P as le, S as fe } from "./common-BUk9ORDJ.mjs";
import { Writable as ce } from "stream";
import y from "node:zlib";
import { isUtf8 as U } from "node:buffer";
import C from "ws";
import { fork as _e } from "child_process";
import { resolve as F } from "path";
import T from "fs";
import de from "net";
import v from "undici";
function ee(i) {
const e = {};
return i.forEach((t, r) => {
e[r] = t;
}), e;
}
const ue = typeof Blob < "u", A = [
"nodebuffer",
"arraybuffer",
"fragments",
ue ? "blob" : null
].filter(Boolean), I = Buffer.alloc(0), pe = Symbol("status-code"), me = Symbol("websocket"), ge = Buffer[Symbol.species];
function E(i, e) {
if (i.length === 0) return I;
if (i.length === 1) return i[0];
const t = Buffer.allocUnsafe(e);
let r = 0;
for (let s = 0; s < i.length; s++) {
const n = i[s];
t.set(n, r), r += n.length;
}
return r < e ? new ge(t.buffer, t.byteOffset, r) : t;
}
function we(i, e) {
for (let t = 0; t < i.length; t++)
i[t] ^= e[t & 3];
}
function ye(i) {
return i.length === i.buffer.byteLength ? i.buffer : i.buffer.slice(i.byteOffset, i.byteOffset + i.length);
}
const D = Symbol("kDone"), k = Symbol("kRun");
class Ee {
/**
* Creates a new `Limiter`.
*
* @param {Number} [concurrency=Infinity] The maximum number of jobs allowed
* to run concurrently
*/
constructor(e = 1 / 0) {
this[D] = () => {
this.pending--, this[k]();
}, 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[k]();
}
/**
* Removes a job from the queue and runs it if possible.
*
* @private
*/
[k]() {
if (this.pending !== this.concurrency && this.jobs.length) {
const e = this.jobs.shift();
this.pending++, e(this[D]);
}
}
}
const Re = Buffer.from([0, 0, 255, 255]), M = Symbol("permessage-deflate"), g = Symbol("total-length"), R = Symbol("callback"), w = Symbol("buffers"), Se = Symbol("error");
let b;
class q {
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, !b) {
const s = this._options.concurrencyLimit !== void 0 ? this._options.concurrencyLimit : 10;
b = new Ee(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[R];
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 n = +s;
if (!Number.isInteger(n) || n < 8 || n > 15)
throw new TypeError(`Invalid value for parameter "${r}": ${s}`);
s = n;
} else if (!this._isServer)
throw new TypeError(`Invalid value for parameter "${r}": ${s}`);
} else if (r === "server_max_window_bits") {
const n = +s;
if (!Number.isInteger(n) || n < 8 || n > 15)
throw new TypeError(`Invalid value for parameter "${r}": ${s}`);
s = n;
} 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) {
b?.add((s) => {
this._decompress(e, t, (n, o) => {
s(), r(n, o);
});
});
}
compress(e, t, r) {
b?.add((s) => {
this._compress(e, t, (n, o) => {
s(), r(n, o);
});
});
}
_decompress(e, t, r) {
const s = this._isServer ? "client" : "server";
if (!this._inflate) {
const n = `${s}_max_window_bits`, o = typeof this.params[n] != "number" ? y.constants.Z_DEFAULT_WINDOWBITS : this.params[n];
this._inflate = y.createInflateRaw({
...this._options.zlibInflateOptions,
windowBits: o
}), this._inflate[M] = this, this._inflate[g] = 0, this._inflate[w] = [], this._inflate.on("error", ve), this._inflate.on("data", be);
}
this._inflate[R] = r, this._inflate.write(e), t && this._inflate.write(Re), this._inflate.flush(() => {
const n = this._inflate[Se];
if (n) {
this._inflate.close(), this._inflate = null, r(n);
return;
}
const o = E(
this._inflate[w],
this._inflate[g]
);
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 n = `${s}_max_window_bits`, o = typeof this.params[n] != "number" ? y.constants.Z_DEFAULT_WINDOWBITS : this.params[n];
this._deflate = y.createDeflateRaw({
...this._options.zlibDeflateOptions,
windowBits: o
}), this._deflate[g] = 0, this._deflate[w] = [], this._deflate.on("error", xe), this._deflate.on("data", Le);
}
this._deflate[R] = r, this._deflate.write(e), t && this._deflate.flush(y.Z_SYNC_FLUSH, () => {
const n = E(
this._deflate[w],
this._deflate[g]
);
if (this._maxPayload < 1 || n.length <= this._maxPayload) {
r(null, n);
return;
}
r(new RangeError("Max payload size exceeded"), null);
});
}
}
function ve(i) {
this[M][R](i);
}
function be(i) {
this[g] += i.length, this[w].push(i);
}
function xe(i) {
this[M][R](i);
}
function Le(i) {
this[g] += i.length, this[w].push(i);
}
function Te(i) {
return i >= 1e3 && i <= 1014 && i !== 1004 && i !== 1005 && i !== 1006 || i >= 3e3 && i <= 4999;
}
function H(i) {
const e = i.length;
let t = 0;
for (; t < e; )
if (!(i[t] & 128))
t++;
else if ((i[t] & 224) === 192) {
if (t + 1 === e || (i[t + 1] & 192) !== 128 || (i[t] & 254) === 192)
return !1;
t += 2;
} else if ((i[t] & 240) === 224) {
if (t + 2 >= e || (i[t + 1] & 192) !== 128 || (i[t + 2] & 192) !== 128 || i[t] === 224 && (i[t + 1] & 224) === 128 || // Overlong
i[t] === 237 && (i[t + 1] & 224) === 160)
return !1;
t += 3;
} else if ((i[t] & 248) === 240) {
if (t + 3 >= e || (i[t + 1] & 192) !== 128 || (i[t + 2] & 192) !== 128 || (i[t + 3] & 192) !== 128 || i[t] === 240 && (i[t + 1] & 240) === 128 || // Overlong
i[t] === 244 && i[t + 1] > 143 || i[t] > 244)
return !1;
t += 4;
} else
return !1;
return !0;
}
const V = U ? function(i) {
return i.length < 24 ? H(i) : U(i);
} : H;
var $;
const x = Buffer[Symbol.species], _ = 0, G = 1, z = 2, j = 3, P = 4, N = 5, L = 6;
class Y extends ($ = ce, $) {
constructor(e = {}) {
super(), this._allowSynchronousEvents = e.allowSynchronousEvents !== void 0 ? e.allowSynchronousEvents : !0, this._binaryType = e.binaryType || A[0], this._extensions = e.extensions || {}, this._isServer = !!e.isServer, this._maxPayload = e.maxPayload || 0, this._skipUTF8Validation = !!e.skipUTF8Validation, this[me] = 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 = _;
}
/**
* 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 === _) 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 x(r.buffer, r.byteOffset + e, r.length - e), new x(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 x(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 _:
this.getInfo(e);
break;
case G:
this.getPayloadLength16(e);
break;
case z:
this.getPayloadLength64(e);
break;
case j:
this.getMask();
break;
case P:
this.getData(e);
break;
case N:
case L:
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[q.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 = G : this._payloadLength === 127 ? this._state = z : 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 = j : this._state = P;
}
/**
* Reads the mask bytes.
*
* @private
*/
getMask() {
if (this._bufferedBytes < 4) {
this._loop = !1;
return;
}
this._mask = this.consume(4), this._state = P;
}
/**
* Reads data bytes.
*
* @param {Function} cb Callback
* @private
*/
getData(e) {
let t = I;
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] && we(t, this._mask);
}
if (this._opcode > 7) {
this.controlMessage(t, e);
return;
}
if (this._compressed) {
this._state = N, 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[q.extensionName].decompress(e, this._fin, (s, n) => {
if (s) return t(s);
if (n && n.length) {
if (this._messageLength += n.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(n);
}
this.dataMessage(t), this._state === _ && this.startLoop(t);
});
}
/**
* Handles a data message.
*
* @param {Function} cb Callback
* @private
*/
dataMessage(e) {
if (!this._fin) {
this._state = _;
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 = E(r, t) : this._binaryType === "arraybuffer" ? s = ye(E(r, t)) : this._binaryType === "blob" ? s = new Blob(r) : s = r, this._allowSynchronousEvents ? (this.emit("message", s, !0), this._state = _) : (this._state = L, setImmediate(() => {
this.emit("message", s, !0), this._state = _, this.startLoop(e);
}));
} else {
const s = E(r, t);
if (!this._skipUTF8Validation && !V(s)) {
const n = this.createError(
Error,
"invalid UTF-8 sequence",
!0,
1007,
"WS_ERR_INVALID_UTF8"
);
e(n);
return;
}
this._state === N || this._allowSynchronousEvents ? (this.emit("message", s, !1), this._state = _) : (this._state = L, setImmediate(() => {
this.emit("message", s, !1), this._state = _, 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, I), this.end();
else {
const r = e.readUInt16BE(0);
if (!Te(r)) {
const n = this.createError(
RangeError,
`invalid status code ${r}`,
!0,
1002,
"WS_ERR_INVALID_CLOSE_CODE"
);
t(n);
return;
}
const s = new x(e.buffer, e.byteOffset + 2, e.length - 2);
if (!this._skipUTF8Validation && !V(s)) {
const n = this.createError(
Error,
"invalid UTF-8 sequence",
!0,
1007,
"WS_ERR_INVALID_UTF8"
);
t(n);
return;
}
this._loop = !1, this.emit("conclude", r, s), this.end();
}
this._state = _;
return;
}
this._allowSynchronousEvents ? (this.emit(this._opcode === 9 ? "ping" : "pong", e), this._state = _) : (this._state = L, setImmediate(() => {
this.emit(this._opcode === 9 ? "ping" : "pong", e), this._state = _, this.startLoop(t);
}));
}
createError(e, t, r, s, n) {
this._loop = !1, this._errored = !0;
const o = new e(r ? `Invalid WebSocket frame: ${t}` : t);
return Error.captureStackTrace(o, this.createError), o.code = n, o[pe] = s, o;
}
}
function X(i, e, t) {
const r = i.write;
return i.write = (s) => {
try {
e.requestData = JSON.parse(s.toString());
} catch {
e.requestData = s;
}
return r.bind(i)(s);
}, i.on("error", () => {
e.responseStatusCode = 0, e.requestEndTime = (/* @__PURE__ */ new Date()).getTime(), t.sendRequest("endRequest", e);
}), e.isWebSocket() ? i.on("upgrade", async (s, n, o) => {
const f = n.write;
if (e.isHiden())
return;
await t.send({
type: "Network.webSocketCreated",
data: {
requestId: e.id,
url: e.url,
initiator: e.initiator,
response: s
}
});
const a = new Y({
allowSynchronousEvents: !0,
binaryType: A[0],
isServer: !1
}), c = new Y({
allowSynchronousEvents: !0,
binaryType: A[0],
isServer: !0
}), h = (d) => {
const p = d.toString();
t.send({
type: "Network.webSocketFrameReceived",
data: {
requestId: e.id,
response: {
payloadData: p,
opcode: 1,
mask: !1
}
}
});
}, m = (d) => {
const p = d.toString();
t.send({
type: "Network.webSocketFrameSent",
data: {
requestId: e.id,
response: {
payloadData: p,
opcode: 1,
mask: !0
}
}
});
};
a.on("message", h), c.on("message", m);
let l;
n.write = (d, ...p) => {
const u = Buffer.from(d);
return c.write(u), f.call(n, d, ...p);
}, n.addListener("data", (d) => {
const p = Buffer.from(d);
a.write(p);
}), n.addListener("close", () => {
l = n.read(), l !== null && (a.write(l), c.write(l)), a.end(), c.end(), a.removeAllListeners(), c.removeAllListeners(), t.send({
method: "Network.webSocketClosed",
params: {
requestId: e.id,
timestamp: ne()
}
});
}), n.addListener("end", () => {
a.end(), c.end(), a.removeAllListeners(), c.removeAllListeners();
});
}) : t.sendRequest("registerRequest", e), i;
}
function ke(i, e, t) {
return (r) => {
e.responseHeaders = r.headers, typeof i == "function" && i(r), t.responseRequest(e.id, r);
};
}
function J(i, e) {
let t = i.setHeader;
i.setHeader = function(r, s) {
return Array.isArray(s) ? s.forEach((n) => {
e.requestHeaders[r] = n;
}) : e.requestHeaders[r] = s, t.call(i, r, s);
};
}
function Pe(i, e, t) {
return (s, n, o) => {
let f, a, c;
typeof s == "string" || s instanceof URL ? (f = s, a = n, c = o) : (a = s, c = n);
const h = new Q();
if (typeof f == "string")
h.url = f, h.method = "GET";
else if (f instanceof URL)
h.url = f.toString(), h.method = "GET";
else if (a && typeof a != "string" && !(a instanceof URL)) {
const l = e ? "https" : "http";
h.url = `${l}://${a.hostname || a.host}${a.path}`;
}
a && typeof a != "string" && !(a instanceof URL) && (h.method = a.method, h.requestHeaders = a.headers), h.loadCallFrames(), h.isWebSocket() && (h.url = h.url.replace("http://", "ws://").replace("https://", "wss://")), t.sendRequest("initRequest", h);
const m = ke(c, h, t);
if (typeof s == "string" || s instanceof URL) {
const l = i(
f,
a,
m
);
return J(l, h), X(l, h, t);
} else {
const l = i(a, m);
return J(l, h), X(l, h, t);
}
};
}
const Ne = (i) => new Promise((e) => setTimeout(e, i)), Be = (i, e) => {
try {
return Number(i) === process.pid ? Promise.resolve(!0) : (process.kill(Number(i), 0), new Promise((t) => {
const r = de.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);
}
}, B = (i) => {
try {
T.unlinkSync(i);
} catch {
}
};
let te = null;
function S() {
return te;
}
function K(i) {
te = i;
}
class Z extends Error {
constructor(e) {
super(e);
}
}
class Ae {
constructor(e) {
this.options = e, this.ws = new Promise(async (t, r) => {
const s = F(O, `./${e.key}`);
if (T.existsSync(s)) {
const o = T.readFileSync(s, "utf-8");
if (await Ne(1), await Be(o, e.port)) {
oe("The main process with same options is already running, skip it.");
return;
}
B(s);
}
T.writeFileSync(s, `${process.pid}`);
const n = new C(`ws://localhost:${e.port}`);
n.on("open", () => {
B(s), t(n);
}), n.on("error", () => {
this.openProcess(() => {
B(s);
const o = new C(`ws://localhost:${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 Z))
throw t;
});
}
openProcess(e) {
(() => {
const r = _e(F(O, "./fork"), {
env: {
...process.env,
NETWORK_OPTIONS: JSON.stringify(this.options)
}
}), s = (n) => {
n === ae && (e && e(r), r.off("message", s));
};
r.on("message", s), this.cp = r;
})();
}
async send(e) {
if (S()?.isAborted)
return;
const r = await this.ws.catch((s) => {
if (s instanceof Z)
return null;
throw s;
});
r && r.send(JSON.stringify(e));
}
sendRequest(e, t) {
const r = S();
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: "health",
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((n) => {
n.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 Ie(i) {
if (!globalThis.fetch)
return;
const e = globalThis.fetch;
return globalThis.fetch = se(e, i), () => {
globalThis.fetch = e;
};
}
function se(i, e) {
return function(t, r) {
const s = new Q();
s.requestStartTime = Date.now(), K({ request: s, pipes: [], isAborted: !1 }), typeof t == "string" ? s.url = t : t instanceof URL && (s.url = t.toString()), s.method = r?.method ?? "GET";
const n = r?.headers;
if (n instanceof Headers) {
const f = ee(n);
s.requestHeaders = f;
} else
s.requestHeaders = n ?? {};
s.requestData = r?.body;
const o = i(t, r).then(Me(s, e)).catch(We(s, e)).finally(() => {
K(null);
});
return e.sendRequest("initRequest", s).sendRequest("registerRequest", s), o;
};
}
function Me(i, e) {
return (t) => (i.requestEndTime = (/* @__PURE__ */ new Date()).getTime(), i.responseHeaders = ee(t.headers), i.responseStatusCode = t.status || 0, t.clone().arrayBuffer().then((r) => {
const s = Buffer.from(r);
i.responseData = s, i.responseInfo.dataLength = s.length, i.responseInfo.encodedDataLength = s.length;
}).finally(() => {
e.sendRequest("updateRequest", i).sendRequest("endRequest", i);
}), t);
}
function We(i, e) {
return (t) => {
throw i.requestEndTime = Date.now(), i.responseStatusCode = 0, e.sendRequest("updateRequest", i).sendRequest("endRequest", i), t;
};
}
const Oe = (i) => {
if (!v.fetch)
return;
const e = v.fetch;
return v.fetch = se(
e,
i
), () => {
v.fetch = e;
};
}, Xe = (i) => {
const e = S();
if (!e)
throw new Error("useRegisterRequest must be used in request handler");
e.pipes.push({
pipe: i,
type: "registerRequest"
});
}, Je = (i, e) => {
const t = S();
if (!t)
throw new Error("useRequestPipe must be used in request handler");
t.pipes.push({
pipe: e,
type: i
});
}, Ke = () => {
const i = S();
if (!i)
throw new Error("useRegisterRequest must be used in request handler");
i.isAborted = !0;
};
function Ze(i) {
const {
port: e = le,
serverPort: t = fe,
autoOpenDevtool: r = !0,
intercept: s = {}
} = i || {}, {
fetch: n = !0,
normal: o = !0,
undici: f = !1
} = s, a = f && f.fetch, c = he(JSON.stringify({ port: e, serverPort: t, autoOpenDevtool: r })), h = new Ae({
port: e,
serverPort: t,
autoOpenDevtool: r,
key: c
}), m = n ? Ie(h) : void 0, l = /* @__PURE__ */ new WeakMap(), d = [ie, W];
o && d.forEach((u) => {
l.set(u, u.request);
const re = u.request;
u.request = Pe(re, u === W, h);
});
const p = a ? Oe(h) : void 0;
return () => {
m && m(), o && d.forEach((u) => {
u.request = l.get(u), l.delete(u);
}), p && p(), h.dispose();
};
}
export {
S as getCurrentCell,
Ze as register,
K as setCurrentCell,
Ke as useAbortRequest,
Xe as useRegisterRequest,
Je as useRequestPipe
};