@ricsam/isolate-client 0.1.14 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +238 -6
- package/dist/cjs/connection.cjs +377 -165
- package/dist/cjs/connection.cjs.map +3 -3
- package/dist/cjs/index.cjs +2 -1
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/connection.mjs +383 -163
- package/dist/mjs/connection.mjs.map +3 -3
- package/dist/mjs/index.mjs +3 -2
- package/dist/mjs/index.mjs.map +2 -2
- package/dist/mjs/package.json +1 -1
- package/dist/types/connection.d.ts +1 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/types.d.ts +17 -10
- package/package.json +1 -1
package/dist/mjs/connection.mjs
CHANGED
|
@@ -8,11 +8,21 @@ import {
|
|
|
8
8
|
STREAM_THRESHOLD,
|
|
9
9
|
STREAM_CHUNK_SIZE,
|
|
10
10
|
STREAM_DEFAULT_CREDIT,
|
|
11
|
-
|
|
11
|
+
IsolateEvents,
|
|
12
|
+
ClientEvents,
|
|
13
|
+
marshalValue,
|
|
14
|
+
isPromiseRef,
|
|
15
|
+
isAsyncIteratorRef,
|
|
16
|
+
serializeResponse,
|
|
17
|
+
deserializeResponse
|
|
12
18
|
} from "@ricsam/isolate-protocol";
|
|
13
|
-
import {
|
|
14
|
-
|
|
19
|
+
import {
|
|
20
|
+
getDefaultPlaywrightHandlerMetadata
|
|
21
|
+
} from "@ricsam/isolate-playwright/client";
|
|
15
22
|
var isolateWsCallbacks = new Map;
|
|
23
|
+
var isolateClientWebSockets = new Map;
|
|
24
|
+
var isolateWebSocketCallbacks = new Map;
|
|
25
|
+
var isolateEventListeners = new Map;
|
|
16
26
|
async function connect(options = {}) {
|
|
17
27
|
const socket = await createSocket(options);
|
|
18
28
|
const state = {
|
|
@@ -42,9 +52,6 @@ async function connect(options = {}) {
|
|
|
42
52
|
socket.on("close", () => {
|
|
43
53
|
state.connected = false;
|
|
44
54
|
for (const [, pending] of state.pendingRequests) {
|
|
45
|
-
if (pending.timeoutId) {
|
|
46
|
-
clearTimeout(pending.timeoutId);
|
|
47
|
-
}
|
|
48
55
|
pending.reject(new Error("Connection closed"));
|
|
49
56
|
}
|
|
50
57
|
state.pendingRequests.clear();
|
|
@@ -83,7 +90,7 @@ async function connect(options = {}) {
|
|
|
83
90
|
}
|
|
84
91
|
function createSocket(options) {
|
|
85
92
|
return new Promise((resolve, reject) => {
|
|
86
|
-
const timeout = options.timeout
|
|
93
|
+
const timeout = options.timeout;
|
|
87
94
|
let socket;
|
|
88
95
|
const onError = (err) => {
|
|
89
96
|
reject(err);
|
|
@@ -98,13 +105,15 @@ function createSocket(options) {
|
|
|
98
105
|
socket = netConnect(options.port ?? 47891, options.host ?? "127.0.0.1", onConnect);
|
|
99
106
|
}
|
|
100
107
|
socket.on("error", onError);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
if (timeout && timeout > 0) {
|
|
109
|
+
const timeoutId = setTimeout(() => {
|
|
110
|
+
socket.destroy();
|
|
111
|
+
reject(new Error("Connection timeout"));
|
|
112
|
+
}, timeout);
|
|
113
|
+
socket.once("connect", () => {
|
|
114
|
+
clearTimeout(timeoutId);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
108
117
|
});
|
|
109
118
|
}
|
|
110
119
|
function handleMessage(message, state) {
|
|
@@ -114,8 +123,6 @@ function handleMessage(message, state) {
|
|
|
114
123
|
const pending = state.pendingRequests.get(response.requestId);
|
|
115
124
|
if (pending) {
|
|
116
125
|
state.pendingRequests.delete(response.requestId);
|
|
117
|
-
if (pending.timeoutId)
|
|
118
|
-
clearTimeout(pending.timeoutId);
|
|
119
126
|
pending.resolve(response.data);
|
|
120
127
|
}
|
|
121
128
|
break;
|
|
@@ -125,8 +132,6 @@ function handleMessage(message, state) {
|
|
|
125
132
|
const pending = state.pendingRequests.get(response.requestId);
|
|
126
133
|
if (pending) {
|
|
127
134
|
state.pendingRequests.delete(response.requestId);
|
|
128
|
-
if (pending.timeoutId)
|
|
129
|
-
clearTimeout(pending.timeoutId);
|
|
130
135
|
const error = new Error(response.message);
|
|
131
136
|
if (response.details) {
|
|
132
137
|
error.name = response.details.name;
|
|
@@ -153,27 +158,9 @@ function handleMessage(message, state) {
|
|
|
153
158
|
}
|
|
154
159
|
break;
|
|
155
160
|
}
|
|
156
|
-
case MessageType.
|
|
161
|
+
case MessageType.ISOLATE_EVENT: {
|
|
157
162
|
const msg = message;
|
|
158
|
-
|
|
159
|
-
if (callbacks) {
|
|
160
|
-
let data;
|
|
161
|
-
if (msg.command.data instanceof Uint8Array) {
|
|
162
|
-
data = msg.command.data.buffer.slice(msg.command.data.byteOffset, msg.command.data.byteOffset + msg.command.data.byteLength);
|
|
163
|
-
} else {
|
|
164
|
-
data = msg.command.data;
|
|
165
|
-
}
|
|
166
|
-
const cmd = {
|
|
167
|
-
type: msg.command.type,
|
|
168
|
-
connectionId: msg.command.connectionId,
|
|
169
|
-
data,
|
|
170
|
-
code: msg.command.code,
|
|
171
|
-
reason: msg.command.reason
|
|
172
|
-
};
|
|
173
|
-
for (const cb of callbacks) {
|
|
174
|
-
cb(cmd);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
163
|
+
handleIsolateEvent(msg, state);
|
|
177
164
|
break;
|
|
178
165
|
}
|
|
179
166
|
case MessageType.RESPONSE_STREAM_START: {
|
|
@@ -243,8 +230,6 @@ function handleMessage(message, state) {
|
|
|
243
230
|
const pending = state.pendingRequests.get(msg.requestId);
|
|
244
231
|
if (pending) {
|
|
245
232
|
state.pendingRequests.delete(msg.requestId);
|
|
246
|
-
if (pending.timeoutId)
|
|
247
|
-
clearTimeout(pending.timeoutId);
|
|
248
233
|
const response = new Response(readableStream, {
|
|
249
234
|
status: msg.metadata?.status ?? 200,
|
|
250
235
|
statusText: msg.metadata?.statusText ?? "OK",
|
|
@@ -369,25 +354,24 @@ function sendMessage(socket, message) {
|
|
|
369
354
|
const frame = buildFrame(message);
|
|
370
355
|
socket.write(frame);
|
|
371
356
|
}
|
|
372
|
-
function sendRequest(state, message
|
|
357
|
+
function sendRequest(state, message) {
|
|
373
358
|
return new Promise((resolve, reject) => {
|
|
374
359
|
if (!state.connected) {
|
|
375
360
|
reject(new Error("Not connected"));
|
|
376
361
|
return;
|
|
377
362
|
}
|
|
378
363
|
const requestId = message.requestId;
|
|
379
|
-
const timeoutId = setTimeout(() => {
|
|
380
|
-
state.pendingRequests.delete(requestId);
|
|
381
|
-
reject(new Error("Request timeout"));
|
|
382
|
-
}, timeout);
|
|
383
364
|
state.pendingRequests.set(requestId, {
|
|
384
365
|
resolve,
|
|
385
|
-
reject
|
|
386
|
-
timeoutId
|
|
366
|
+
reject
|
|
387
367
|
});
|
|
388
368
|
sendMessage(state.socket, message);
|
|
389
369
|
});
|
|
390
370
|
}
|
|
371
|
+
function isBenignDisposeError(error) {
|
|
372
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
373
|
+
return /isolate not owned by this connection|isolate not found|not connected|connection closed/i.test(message);
|
|
374
|
+
}
|
|
391
375
|
async function createRuntime(state, options = {}, namespaceId) {
|
|
392
376
|
const callbacks = {};
|
|
393
377
|
if (options.console) {
|
|
@@ -411,73 +395,76 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
411
395
|
const networkResponses = [];
|
|
412
396
|
const pageListenerCleanups = [];
|
|
413
397
|
if (options.playwright) {
|
|
414
|
-
playwrightHandler =
|
|
415
|
-
|
|
416
|
-
|
|
398
|
+
playwrightHandler = options.playwright.handler;
|
|
399
|
+
if (!playwrightHandler) {
|
|
400
|
+
throw new Error("playwright.handler is required when using playwright options");
|
|
401
|
+
}
|
|
402
|
+
const page = getDefaultPlaywrightHandlerMetadata(playwrightHandler)?.page;
|
|
417
403
|
const handlerCallbackId = state.nextCallbackId++;
|
|
418
404
|
state.callbacks.set(handlerCallbackId, async (opJson) => {
|
|
419
405
|
const op = JSON.parse(opJson);
|
|
420
406
|
const result2 = await playwrightHandler(op);
|
|
421
407
|
return JSON.stringify(result2);
|
|
422
408
|
});
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
409
|
+
if (page) {
|
|
410
|
+
const onConsole = (msg) => {
|
|
411
|
+
const entry = {
|
|
412
|
+
level: msg.type(),
|
|
413
|
+
stdout: msg.text(),
|
|
414
|
+
timestamp: Date.now()
|
|
415
|
+
};
|
|
416
|
+
browserConsoleLogs.push(entry);
|
|
417
|
+
if (options.playwright.onEvent) {
|
|
418
|
+
options.playwright.onEvent({
|
|
419
|
+
type: "browserConsoleLog",
|
|
420
|
+
...entry
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
if (options.playwright.console && options.console?.onEntry) {
|
|
424
|
+
options.console.onEntry({
|
|
425
|
+
type: "browserOutput",
|
|
426
|
+
...entry
|
|
427
|
+
});
|
|
428
|
+
} else if (options.playwright.console) {
|
|
429
|
+
const prefix = entry.level === "error" ? "[browser:error]" : "[browser]";
|
|
430
|
+
console.log(prefix, entry.stdout);
|
|
431
|
+
}
|
|
429
432
|
};
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
options.
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
console.log(prefix, entry.stdout);
|
|
445
|
-
}
|
|
446
|
-
};
|
|
447
|
-
const onRequest = (request2) => {
|
|
448
|
-
const info = {
|
|
449
|
-
url: request2.url(),
|
|
450
|
-
method: request2.method(),
|
|
451
|
-
headers: request2.headers(),
|
|
452
|
-
timestamp: Date.now()
|
|
433
|
+
const onRequest = (request2) => {
|
|
434
|
+
const info = {
|
|
435
|
+
url: request2.url(),
|
|
436
|
+
method: request2.method(),
|
|
437
|
+
headers: request2.headers(),
|
|
438
|
+
timestamp: Date.now()
|
|
439
|
+
};
|
|
440
|
+
networkRequests.push(info);
|
|
441
|
+
if (options.playwright.onEvent) {
|
|
442
|
+
options.playwright.onEvent({
|
|
443
|
+
type: "networkRequest",
|
|
444
|
+
...info
|
|
445
|
+
});
|
|
446
|
+
}
|
|
453
447
|
};
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
448
|
+
const onResponse = (response) => {
|
|
449
|
+
const info = {
|
|
450
|
+
url: response.url(),
|
|
451
|
+
status: response.status(),
|
|
452
|
+
headers: response.headers(),
|
|
453
|
+
timestamp: Date.now()
|
|
454
|
+
};
|
|
455
|
+
networkResponses.push(info);
|
|
456
|
+
if (options.playwright.onEvent) {
|
|
457
|
+
options.playwright.onEvent({
|
|
458
|
+
type: "networkResponse",
|
|
459
|
+
...info
|
|
460
|
+
});
|
|
461
|
+
}
|
|
468
462
|
};
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
};
|
|
477
|
-
page.on("console", onConsole);
|
|
478
|
-
page.on("request", onRequest);
|
|
479
|
-
page.on("response", onResponse);
|
|
480
|
-
pageListenerCleanups.push(() => page.removeListener("console", onConsole), () => page.removeListener("request", onRequest), () => page.removeListener("response", onResponse));
|
|
463
|
+
page.on("console", onConsole);
|
|
464
|
+
page.on("request", onRequest);
|
|
465
|
+
page.on("response", onResponse);
|
|
466
|
+
pageListenerCleanups.push(() => page.removeListener("console", onConsole), () => page.removeListener("request", onRequest), () => page.removeListener("response", onResponse));
|
|
467
|
+
}
|
|
481
468
|
callbacks.playwright = {
|
|
482
469
|
handlerCallbackId,
|
|
483
470
|
console: options.playwright.console && !options.console?.onEntry
|
|
@@ -525,8 +512,18 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
525
512
|
const reused = result.reused ?? false;
|
|
526
513
|
const wsCommandCallbacks = new Set;
|
|
527
514
|
isolateWsCallbacks.set(isolateId, wsCommandCallbacks);
|
|
515
|
+
if (options.onWebSocketCommand) {
|
|
516
|
+
wsCommandCallbacks.add(options.onWebSocketCommand);
|
|
517
|
+
}
|
|
518
|
+
if (options.webSocket) {
|
|
519
|
+
isolateWebSocketCallbacks.set(isolateId, options.webSocket);
|
|
520
|
+
}
|
|
528
521
|
const fetchHandle = {
|
|
529
522
|
async dispatchRequest(req, opts) {
|
|
523
|
+
const signal = opts?.signal;
|
|
524
|
+
if (signal?.aborted) {
|
|
525
|
+
throw new DOMException("The operation was aborted", "AbortError");
|
|
526
|
+
}
|
|
530
527
|
const reqId = state.nextRequestId++;
|
|
531
528
|
const serialized = await serializeRequestWithStreaming(state, req);
|
|
532
529
|
const { bodyStream, ...serializableRequest } = serialized;
|
|
@@ -534,8 +531,7 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
534
531
|
type: MessageType.DISPATCH_REQUEST,
|
|
535
532
|
requestId: reqId,
|
|
536
533
|
isolateId,
|
|
537
|
-
request: serializableRequest
|
|
538
|
-
options: opts
|
|
534
|
+
request: serializableRequest
|
|
539
535
|
};
|
|
540
536
|
const handleResponse = (res) => {
|
|
541
537
|
if (res.__streaming && res.response instanceof Response) {
|
|
@@ -543,15 +539,32 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
543
539
|
}
|
|
544
540
|
return deserializeResponse(res.response);
|
|
545
541
|
};
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
542
|
+
let onAbort;
|
|
543
|
+
if (signal) {
|
|
544
|
+
onAbort = () => {
|
|
545
|
+
const pending = state.pendingRequests.get(reqId);
|
|
546
|
+
if (pending) {
|
|
547
|
+
state.pendingRequests.delete(reqId);
|
|
548
|
+
pending.reject(new DOMException("The operation was aborted", "AbortError"));
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
552
|
+
}
|
|
553
|
+
try {
|
|
554
|
+
if (serialized.bodyStreamId !== undefined && bodyStream) {
|
|
555
|
+
const streamId = serialized.bodyStreamId;
|
|
556
|
+
const responsePromise = sendRequest(state, request2);
|
|
557
|
+
await sendBodyStream(state, streamId, bodyStream);
|
|
558
|
+
const res = await responsePromise;
|
|
559
|
+
return handleResponse(res);
|
|
560
|
+
} else {
|
|
561
|
+
const res = await sendRequest(state, request2);
|
|
562
|
+
return handleResponse(res);
|
|
563
|
+
}
|
|
564
|
+
} finally {
|
|
565
|
+
if (signal && onAbort) {
|
|
566
|
+
signal.removeEventListener("abort", onAbort);
|
|
567
|
+
}
|
|
555
568
|
}
|
|
556
569
|
},
|
|
557
570
|
async getUpgradeRequest() {
|
|
@@ -698,7 +711,7 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
698
711
|
isolateId,
|
|
699
712
|
timeout
|
|
700
713
|
};
|
|
701
|
-
return sendRequest(state, req
|
|
714
|
+
return sendRequest(state, req);
|
|
702
715
|
},
|
|
703
716
|
async hasTests() {
|
|
704
717
|
if (!testEnvironmentEnabled) {
|
|
@@ -740,7 +753,7 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
740
753
|
const playwrightHandle = {
|
|
741
754
|
getCollectedData() {
|
|
742
755
|
if (!playwrightEnabled) {
|
|
743
|
-
throw new Error("Playwright not configured. Provide playwright.
|
|
756
|
+
throw new Error("Playwright not configured. Provide playwright.handler in createRuntime options.");
|
|
744
757
|
}
|
|
745
758
|
return {
|
|
746
759
|
browserConsoleLogs: [...browserConsoleLogs],
|
|
@@ -750,7 +763,7 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
750
763
|
},
|
|
751
764
|
clearCollectedData() {
|
|
752
765
|
if (!playwrightEnabled) {
|
|
753
|
-
throw new Error("Playwright not configured. Provide playwright.
|
|
766
|
+
throw new Error("Playwright not configured. Provide playwright.handler in createRuntime options.");
|
|
754
767
|
}
|
|
755
768
|
browserConsoleLogs.length = 0;
|
|
756
769
|
networkRequests.length = 0;
|
|
@@ -759,7 +772,6 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
759
772
|
};
|
|
760
773
|
return {
|
|
761
774
|
id: isolateId,
|
|
762
|
-
isolateId,
|
|
763
775
|
reused,
|
|
764
776
|
fetch: fetchHandle,
|
|
765
777
|
timers: timersHandle,
|
|
@@ -774,24 +786,69 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
774
786
|
requestId: reqId,
|
|
775
787
|
isolateId,
|
|
776
788
|
code,
|
|
777
|
-
filename: options2?.filename
|
|
778
|
-
maxExecutionMs: options2?.maxExecutionMs,
|
|
779
|
-
module: true
|
|
789
|
+
filename: options2?.filename
|
|
780
790
|
};
|
|
781
791
|
await sendRequest(state, req);
|
|
782
792
|
},
|
|
793
|
+
on(event, callback) {
|
|
794
|
+
let listeners = isolateEventListeners.get(isolateId);
|
|
795
|
+
if (!listeners) {
|
|
796
|
+
listeners = new Map;
|
|
797
|
+
isolateEventListeners.set(isolateId, listeners);
|
|
798
|
+
}
|
|
799
|
+
let eventListeners = listeners.get(event);
|
|
800
|
+
if (!eventListeners) {
|
|
801
|
+
eventListeners = new Set;
|
|
802
|
+
listeners.set(event, eventListeners);
|
|
803
|
+
}
|
|
804
|
+
eventListeners.add(callback);
|
|
805
|
+
return () => {
|
|
806
|
+
eventListeners.delete(callback);
|
|
807
|
+
if (eventListeners.size === 0) {
|
|
808
|
+
listeners.delete(event);
|
|
809
|
+
if (listeners.size === 0) {
|
|
810
|
+
isolateEventListeners.delete(isolateId);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
};
|
|
814
|
+
},
|
|
815
|
+
emit(event, payload) {
|
|
816
|
+
sendMessage(state.socket, {
|
|
817
|
+
type: MessageType.CLIENT_EVENT,
|
|
818
|
+
isolateId,
|
|
819
|
+
event,
|
|
820
|
+
payload
|
|
821
|
+
});
|
|
822
|
+
},
|
|
783
823
|
dispose: async () => {
|
|
784
824
|
for (const cleanup of pageListenerCleanups) {
|
|
785
825
|
cleanup();
|
|
786
826
|
}
|
|
787
827
|
isolateWsCallbacks.delete(isolateId);
|
|
828
|
+
isolateWebSocketCallbacks.delete(isolateId);
|
|
829
|
+
isolateEventListeners.delete(isolateId);
|
|
830
|
+
const clientSockets = isolateClientWebSockets.get(isolateId);
|
|
831
|
+
if (clientSockets) {
|
|
832
|
+
for (const ws of clientSockets.values()) {
|
|
833
|
+
if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
|
|
834
|
+
ws.close(1000, "Isolate disposed");
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
isolateClientWebSockets.delete(isolateId);
|
|
838
|
+
}
|
|
788
839
|
const reqId = state.nextRequestId++;
|
|
789
840
|
const req = {
|
|
790
841
|
type: MessageType.DISPOSE_RUNTIME,
|
|
791
842
|
requestId: reqId,
|
|
792
843
|
isolateId
|
|
793
844
|
};
|
|
794
|
-
|
|
845
|
+
try {
|
|
846
|
+
await sendRequest(state, req);
|
|
847
|
+
} catch (error) {
|
|
848
|
+
if (!isBenignDisposeError(error)) {
|
|
849
|
+
throw error;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
795
852
|
}
|
|
796
853
|
};
|
|
797
854
|
}
|
|
@@ -819,8 +876,15 @@ function registerFetchCallback(state, callback) {
|
|
|
819
876
|
const callbackId = state.nextCallbackId++;
|
|
820
877
|
state.callbacksNeedingRequestId.add(callbackId);
|
|
821
878
|
state.callbacks.set(callbackId, async (serialized, requestId) => {
|
|
822
|
-
const
|
|
823
|
-
const
|
|
879
|
+
const data = serialized;
|
|
880
|
+
const init = {
|
|
881
|
+
method: data.method,
|
|
882
|
+
headers: data.headers,
|
|
883
|
+
rawBody: data.body ?? null,
|
|
884
|
+
body: data.body ?? null,
|
|
885
|
+
signal: new AbortController().signal
|
|
886
|
+
};
|
|
887
|
+
const response = await callback(data.url, init);
|
|
824
888
|
const contentLength = response.headers.get("content-length");
|
|
825
889
|
const knownSize = contentLength ? parseInt(contentLength, 10) : null;
|
|
826
890
|
const isNetworkResponse = response.url && (response.url.startsWith("http://") || response.url.startsWith("https://"));
|
|
@@ -973,12 +1037,6 @@ var clientIteratorSessions = new Map;
|
|
|
973
1037
|
var nextClientIteratorId = 1;
|
|
974
1038
|
var returnedPromiseRegistry = new Map;
|
|
975
1039
|
var returnedIteratorRegistry = new Map;
|
|
976
|
-
function isPromiseRef(value) {
|
|
977
|
-
return typeof value === "object" && value !== null && value.__type === "PromiseRef";
|
|
978
|
-
}
|
|
979
|
-
function isAsyncIteratorRef(value) {
|
|
980
|
-
return typeof value === "object" && value !== null && value.__type === "AsyncIteratorRef";
|
|
981
|
-
}
|
|
982
1040
|
function registerCustomFunctions(state, customFunctions) {
|
|
983
1041
|
const registrations = {};
|
|
984
1042
|
for (const [name, def] of Object.entries(customFunctions)) {
|
|
@@ -1162,36 +1220,6 @@ function registerCustomFunctions(state, customFunctions) {
|
|
|
1162
1220
|
}
|
|
1163
1221
|
return registrations;
|
|
1164
1222
|
}
|
|
1165
|
-
async function serializeResponse(response) {
|
|
1166
|
-
const headers = [];
|
|
1167
|
-
response.headers.forEach((value, key) => {
|
|
1168
|
-
headers.push([key, value]);
|
|
1169
|
-
});
|
|
1170
|
-
let body = null;
|
|
1171
|
-
if (response.body) {
|
|
1172
|
-
body = new Uint8Array(await response.arrayBuffer());
|
|
1173
|
-
}
|
|
1174
|
-
return {
|
|
1175
|
-
status: response.status,
|
|
1176
|
-
statusText: response.statusText,
|
|
1177
|
-
headers,
|
|
1178
|
-
body
|
|
1179
|
-
};
|
|
1180
|
-
}
|
|
1181
|
-
function deserializeRequest(data) {
|
|
1182
|
-
return new Request(data.url, {
|
|
1183
|
-
method: data.method,
|
|
1184
|
-
headers: data.headers,
|
|
1185
|
-
body: data.body
|
|
1186
|
-
});
|
|
1187
|
-
}
|
|
1188
|
-
function deserializeResponse(data) {
|
|
1189
|
-
return new Response(data.body, {
|
|
1190
|
-
status: data.status,
|
|
1191
|
-
statusText: data.statusText,
|
|
1192
|
-
headers: data.headers
|
|
1193
|
-
});
|
|
1194
|
-
}
|
|
1195
1223
|
async function serializeRequestWithStreaming(state, request) {
|
|
1196
1224
|
const headers = [];
|
|
1197
1225
|
request.headers.forEach((value, key) => {
|
|
@@ -1290,8 +1318,200 @@ async function sendBodyStream(state, streamId, body) {
|
|
|
1290
1318
|
state.uploadStreams.delete(streamId);
|
|
1291
1319
|
}
|
|
1292
1320
|
}
|
|
1321
|
+
function handleIsolateEvent(message, state) {
|
|
1322
|
+
switch (message.event) {
|
|
1323
|
+
case IsolateEvents.WS_COMMAND: {
|
|
1324
|
+
const payload = message.payload;
|
|
1325
|
+
const callbacks = isolateWsCallbacks.get(message.isolateId);
|
|
1326
|
+
if (callbacks) {
|
|
1327
|
+
let data;
|
|
1328
|
+
if (payload.data instanceof Uint8Array) {
|
|
1329
|
+
data = payload.data.buffer.slice(payload.data.byteOffset, payload.data.byteOffset + payload.data.byteLength);
|
|
1330
|
+
} else {
|
|
1331
|
+
data = payload.data;
|
|
1332
|
+
}
|
|
1333
|
+
const cmd = {
|
|
1334
|
+
type: payload.type,
|
|
1335
|
+
connectionId: payload.connectionId,
|
|
1336
|
+
data,
|
|
1337
|
+
code: payload.code,
|
|
1338
|
+
reason: payload.reason
|
|
1339
|
+
};
|
|
1340
|
+
for (const cb of callbacks) {
|
|
1341
|
+
cb(cmd);
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
break;
|
|
1345
|
+
}
|
|
1346
|
+
case IsolateEvents.WS_CLIENT_CONNECT: {
|
|
1347
|
+
const payload = message.payload;
|
|
1348
|
+
handleClientWsConnect(message.isolateId, payload, state);
|
|
1349
|
+
break;
|
|
1350
|
+
}
|
|
1351
|
+
case IsolateEvents.WS_CLIENT_SEND: {
|
|
1352
|
+
const payload = message.payload;
|
|
1353
|
+
handleClientWsSend(message.isolateId, payload, state);
|
|
1354
|
+
break;
|
|
1355
|
+
}
|
|
1356
|
+
case IsolateEvents.WS_CLIENT_CLOSE: {
|
|
1357
|
+
const payload = message.payload;
|
|
1358
|
+
handleClientWsClose(message.isolateId, payload, state);
|
|
1359
|
+
break;
|
|
1360
|
+
}
|
|
1361
|
+
default: {
|
|
1362
|
+
const listeners = isolateEventListeners.get(message.isolateId);
|
|
1363
|
+
if (listeners) {
|
|
1364
|
+
const eventListeners = listeners.get(message.event);
|
|
1365
|
+
if (eventListeners) {
|
|
1366
|
+
for (const cb of eventListeners) {
|
|
1367
|
+
cb(message.payload);
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
break;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
function handleClientWsConnect(isolateId, payload, state) {
|
|
1376
|
+
const { socketId, url, protocols } = payload;
|
|
1377
|
+
let sockets = isolateClientWebSockets.get(isolateId);
|
|
1378
|
+
if (!sockets) {
|
|
1379
|
+
sockets = new Map;
|
|
1380
|
+
isolateClientWebSockets.set(isolateId, sockets);
|
|
1381
|
+
}
|
|
1382
|
+
const setupWebSocket = (ws) => {
|
|
1383
|
+
sockets.set(socketId, ws);
|
|
1384
|
+
ws.onopen = () => {
|
|
1385
|
+
sendMessage(state.socket, {
|
|
1386
|
+
type: MessageType.CLIENT_EVENT,
|
|
1387
|
+
isolateId,
|
|
1388
|
+
event: ClientEvents.WS_CLIENT_OPENED,
|
|
1389
|
+
payload: { socketId, protocol: ws.protocol || "", extensions: ws.extensions || "" }
|
|
1390
|
+
});
|
|
1391
|
+
};
|
|
1392
|
+
ws.onmessage = (event) => {
|
|
1393
|
+
let data;
|
|
1394
|
+
if (typeof event.data === "string") {
|
|
1395
|
+
data = event.data;
|
|
1396
|
+
} else if (event.data instanceof ArrayBuffer) {
|
|
1397
|
+
data = new Uint8Array(event.data);
|
|
1398
|
+
} else if (event.data instanceof Blob) {
|
|
1399
|
+
event.data.arrayBuffer().then((buffer) => {
|
|
1400
|
+
sendMessage(state.socket, {
|
|
1401
|
+
type: MessageType.CLIENT_EVENT,
|
|
1402
|
+
isolateId,
|
|
1403
|
+
event: ClientEvents.WS_CLIENT_MESSAGE,
|
|
1404
|
+
payload: { socketId, data: new Uint8Array(buffer) }
|
|
1405
|
+
});
|
|
1406
|
+
});
|
|
1407
|
+
return;
|
|
1408
|
+
} else {
|
|
1409
|
+
data = String(event.data);
|
|
1410
|
+
}
|
|
1411
|
+
sendMessage(state.socket, {
|
|
1412
|
+
type: MessageType.CLIENT_EVENT,
|
|
1413
|
+
isolateId,
|
|
1414
|
+
event: ClientEvents.WS_CLIENT_MESSAGE,
|
|
1415
|
+
payload: { socketId, data }
|
|
1416
|
+
});
|
|
1417
|
+
};
|
|
1418
|
+
ws.onerror = () => {
|
|
1419
|
+
sendMessage(state.socket, {
|
|
1420
|
+
type: MessageType.CLIENT_EVENT,
|
|
1421
|
+
isolateId,
|
|
1422
|
+
event: ClientEvents.WS_CLIENT_ERROR,
|
|
1423
|
+
payload: { socketId }
|
|
1424
|
+
});
|
|
1425
|
+
};
|
|
1426
|
+
ws.onclose = (event) => {
|
|
1427
|
+
sendMessage(state.socket, {
|
|
1428
|
+
type: MessageType.CLIENT_EVENT,
|
|
1429
|
+
isolateId,
|
|
1430
|
+
event: ClientEvents.WS_CLIENT_CLOSED,
|
|
1431
|
+
payload: { socketId, code: event.code, reason: event.reason, wasClean: event.wasClean }
|
|
1432
|
+
});
|
|
1433
|
+
sockets?.delete(socketId);
|
|
1434
|
+
if (sockets?.size === 0) {
|
|
1435
|
+
isolateClientWebSockets.delete(isolateId);
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
};
|
|
1439
|
+
const sendConnectionFailed = (reason) => {
|
|
1440
|
+
sendMessage(state.socket, {
|
|
1441
|
+
type: MessageType.CLIENT_EVENT,
|
|
1442
|
+
isolateId,
|
|
1443
|
+
event: ClientEvents.WS_CLIENT_ERROR,
|
|
1444
|
+
payload: { socketId }
|
|
1445
|
+
});
|
|
1446
|
+
sendMessage(state.socket, {
|
|
1447
|
+
type: MessageType.CLIENT_EVENT,
|
|
1448
|
+
isolateId,
|
|
1449
|
+
event: ClientEvents.WS_CLIENT_CLOSED,
|
|
1450
|
+
payload: { socketId, code: 1006, reason, wasClean: false }
|
|
1451
|
+
});
|
|
1452
|
+
};
|
|
1453
|
+
const callback = isolateWebSocketCallbacks.get(isolateId);
|
|
1454
|
+
if (callback) {
|
|
1455
|
+
try {
|
|
1456
|
+
const result = callback(url, protocols || []);
|
|
1457
|
+
if (result instanceof Promise) {
|
|
1458
|
+
result.then((ws) => {
|
|
1459
|
+
if (ws === null) {
|
|
1460
|
+
sendConnectionFailed("Connection blocked");
|
|
1461
|
+
} else {
|
|
1462
|
+
setupWebSocket(ws);
|
|
1463
|
+
}
|
|
1464
|
+
}).catch(() => {
|
|
1465
|
+
sendConnectionFailed("Callback error");
|
|
1466
|
+
});
|
|
1467
|
+
} else if (result === null) {
|
|
1468
|
+
sendConnectionFailed("Connection blocked");
|
|
1469
|
+
} else {
|
|
1470
|
+
setupWebSocket(result);
|
|
1471
|
+
}
|
|
1472
|
+
} catch {
|
|
1473
|
+
sendConnectionFailed("Callback error");
|
|
1474
|
+
}
|
|
1475
|
+
} else {
|
|
1476
|
+
try {
|
|
1477
|
+
const ws = protocols && protocols.length > 0 ? new WebSocket(url, protocols) : new WebSocket(url);
|
|
1478
|
+
setupWebSocket(ws);
|
|
1479
|
+
} catch {
|
|
1480
|
+
sendConnectionFailed("Connection failed");
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
function handleClientWsSend(isolateId, payload, state) {
|
|
1485
|
+
const { socketId, data } = payload;
|
|
1486
|
+
const sockets = isolateClientWebSockets.get(isolateId);
|
|
1487
|
+
const ws = sockets?.get(socketId);
|
|
1488
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
if (typeof data === "string" && data.startsWith("__BINARY__")) {
|
|
1492
|
+
const base64 = data.slice(10);
|
|
1493
|
+
const binary = Buffer.from(base64, "base64");
|
|
1494
|
+
ws.send(binary);
|
|
1495
|
+
} else if (data instanceof Uint8Array) {
|
|
1496
|
+
ws.send(data);
|
|
1497
|
+
} else {
|
|
1498
|
+
ws.send(data);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
function handleClientWsClose(isolateId, payload, state) {
|
|
1502
|
+
const { socketId, code, reason } = payload;
|
|
1503
|
+
const sockets = isolateClientWebSockets.get(isolateId);
|
|
1504
|
+
const ws = sockets?.get(socketId);
|
|
1505
|
+
if (!ws) {
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
|
|
1509
|
+
ws.close(code ?? 1000, reason ?? "");
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1293
1512
|
export {
|
|
1513
|
+
isBenignDisposeError,
|
|
1294
1514
|
connect
|
|
1295
1515
|
};
|
|
1296
1516
|
|
|
1297
|
-
//# debugId=
|
|
1517
|
+
//# debugId=A84790A2E8D5115464756E2164756E21
|