@ricsam/isolate-client 0.1.15 → 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 +1 -0
- package/dist/cjs/connection.cjs +196 -164
- 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 +199 -161
- 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 +15 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -145,6 +145,7 @@ interface Namespace {
|
|
|
145
145
|
- Namespaced runtimes are cached on dispose and evicted via LRU when `maxIsolates` limit is reached
|
|
146
146
|
- Cross-client reuse is allowed - any connection can reuse a namespace by ID
|
|
147
147
|
- A namespace can only have one active runtime at a time; creating a second runtime with the same namespace ID while one is active will fail
|
|
148
|
+
- Concurrent createRuntime calls for the same namespace are rejected with `Namespace "<id>" creation already in progress`
|
|
148
149
|
|
|
149
150
|
## Module Loader
|
|
150
151
|
|
package/dist/cjs/connection.cjs
CHANGED
|
@@ -42,6 +42,7 @@ var __export = (target, all) => {
|
|
|
42
42
|
// packages/isolate-client/src/connection.ts
|
|
43
43
|
var exports_connection = {};
|
|
44
44
|
__export(exports_connection, {
|
|
45
|
+
isBenignDisposeError: () => isBenignDisposeError,
|
|
45
46
|
connect: () => connect
|
|
46
47
|
});
|
|
47
48
|
module.exports = __toCommonJS(exports_connection);
|
|
@@ -49,11 +50,10 @@ var import_node_net = require("node:net");
|
|
|
49
50
|
var import_node_path = __toESM(require("node:path"));
|
|
50
51
|
var import_isolate_protocol = require("@ricsam/isolate-protocol");
|
|
51
52
|
var import_client = require("@ricsam/isolate-playwright/client");
|
|
52
|
-
var DEFAULT_TIMEOUT = 30000;
|
|
53
|
-
var TEST_REQUEST_TIMEOUT_BUFFER_MS = 1000;
|
|
54
53
|
var isolateWsCallbacks = new Map;
|
|
55
54
|
var isolateClientWebSockets = new Map;
|
|
56
55
|
var isolateWebSocketCallbacks = new Map;
|
|
56
|
+
var isolateEventListeners = new Map;
|
|
57
57
|
async function connect(options = {}) {
|
|
58
58
|
const socket = await createSocket(options);
|
|
59
59
|
const state = {
|
|
@@ -83,9 +83,6 @@ async function connect(options = {}) {
|
|
|
83
83
|
socket.on("close", () => {
|
|
84
84
|
state.connected = false;
|
|
85
85
|
for (const [, pending] of state.pendingRequests) {
|
|
86
|
-
if (pending.timeoutId) {
|
|
87
|
-
clearTimeout(pending.timeoutId);
|
|
88
|
-
}
|
|
89
86
|
pending.reject(new Error("Connection closed"));
|
|
90
87
|
}
|
|
91
88
|
state.pendingRequests.clear();
|
|
@@ -124,7 +121,7 @@ async function connect(options = {}) {
|
|
|
124
121
|
}
|
|
125
122
|
function createSocket(options) {
|
|
126
123
|
return new Promise((resolve, reject) => {
|
|
127
|
-
const timeout = options.timeout
|
|
124
|
+
const timeout = options.timeout;
|
|
128
125
|
let socket;
|
|
129
126
|
const onError = (err) => {
|
|
130
127
|
reject(err);
|
|
@@ -139,13 +136,15 @@ function createSocket(options) {
|
|
|
139
136
|
socket = import_node_net.connect(options.port ?? 47891, options.host ?? "127.0.0.1", onConnect);
|
|
140
137
|
}
|
|
141
138
|
socket.on("error", onError);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
139
|
+
if (timeout && timeout > 0) {
|
|
140
|
+
const timeoutId = setTimeout(() => {
|
|
141
|
+
socket.destroy();
|
|
142
|
+
reject(new Error("Connection timeout"));
|
|
143
|
+
}, timeout);
|
|
144
|
+
socket.once("connect", () => {
|
|
145
|
+
clearTimeout(timeoutId);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
149
148
|
});
|
|
150
149
|
}
|
|
151
150
|
function handleMessage(message, state) {
|
|
@@ -155,8 +154,6 @@ function handleMessage(message, state) {
|
|
|
155
154
|
const pending = state.pendingRequests.get(response.requestId);
|
|
156
155
|
if (pending) {
|
|
157
156
|
state.pendingRequests.delete(response.requestId);
|
|
158
|
-
if (pending.timeoutId)
|
|
159
|
-
clearTimeout(pending.timeoutId);
|
|
160
157
|
pending.resolve(response.data);
|
|
161
158
|
}
|
|
162
159
|
break;
|
|
@@ -166,8 +163,6 @@ function handleMessage(message, state) {
|
|
|
166
163
|
const pending = state.pendingRequests.get(response.requestId);
|
|
167
164
|
if (pending) {
|
|
168
165
|
state.pendingRequests.delete(response.requestId);
|
|
169
|
-
if (pending.timeoutId)
|
|
170
|
-
clearTimeout(pending.timeoutId);
|
|
171
166
|
const error = new Error(response.message);
|
|
172
167
|
if (response.details) {
|
|
173
168
|
error.name = response.details.name;
|
|
@@ -194,42 +189,9 @@ function handleMessage(message, state) {
|
|
|
194
189
|
}
|
|
195
190
|
break;
|
|
196
191
|
}
|
|
197
|
-
case import_isolate_protocol.MessageType.
|
|
192
|
+
case import_isolate_protocol.MessageType.ISOLATE_EVENT: {
|
|
198
193
|
const msg = message;
|
|
199
|
-
|
|
200
|
-
if (callbacks) {
|
|
201
|
-
let data;
|
|
202
|
-
if (msg.command.data instanceof Uint8Array) {
|
|
203
|
-
data = msg.command.data.buffer.slice(msg.command.data.byteOffset, msg.command.data.byteOffset + msg.command.data.byteLength);
|
|
204
|
-
} else {
|
|
205
|
-
data = msg.command.data;
|
|
206
|
-
}
|
|
207
|
-
const cmd = {
|
|
208
|
-
type: msg.command.type,
|
|
209
|
-
connectionId: msg.command.connectionId,
|
|
210
|
-
data,
|
|
211
|
-
code: msg.command.code,
|
|
212
|
-
reason: msg.command.reason
|
|
213
|
-
};
|
|
214
|
-
for (const cb of callbacks) {
|
|
215
|
-
cb(cmd);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
break;
|
|
219
|
-
}
|
|
220
|
-
case import_isolate_protocol.MessageType.CLIENT_WS_CONNECT: {
|
|
221
|
-
const msg = message;
|
|
222
|
-
handleClientWsConnect(msg, state);
|
|
223
|
-
break;
|
|
224
|
-
}
|
|
225
|
-
case import_isolate_protocol.MessageType.CLIENT_WS_SEND: {
|
|
226
|
-
const msg = message;
|
|
227
|
-
handleClientWsSend(msg, state);
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
case import_isolate_protocol.MessageType.CLIENT_WS_CLOSE: {
|
|
231
|
-
const msg = message;
|
|
232
|
-
handleClientWsClose(msg, state);
|
|
194
|
+
handleIsolateEvent(msg, state);
|
|
233
195
|
break;
|
|
234
196
|
}
|
|
235
197
|
case import_isolate_protocol.MessageType.RESPONSE_STREAM_START: {
|
|
@@ -299,8 +261,6 @@ function handleMessage(message, state) {
|
|
|
299
261
|
const pending = state.pendingRequests.get(msg.requestId);
|
|
300
262
|
if (pending) {
|
|
301
263
|
state.pendingRequests.delete(msg.requestId);
|
|
302
|
-
if (pending.timeoutId)
|
|
303
|
-
clearTimeout(pending.timeoutId);
|
|
304
264
|
const response = new Response(readableStream, {
|
|
305
265
|
status: msg.metadata?.status ?? 200,
|
|
306
266
|
statusText: msg.metadata?.statusText ?? "OK",
|
|
@@ -425,25 +385,24 @@ function sendMessage(socket, message) {
|
|
|
425
385
|
const frame = import_isolate_protocol.buildFrame(message);
|
|
426
386
|
socket.write(frame);
|
|
427
387
|
}
|
|
428
|
-
function sendRequest(state, message
|
|
388
|
+
function sendRequest(state, message) {
|
|
429
389
|
return new Promise((resolve, reject) => {
|
|
430
390
|
if (!state.connected) {
|
|
431
391
|
reject(new Error("Not connected"));
|
|
432
392
|
return;
|
|
433
393
|
}
|
|
434
394
|
const requestId = message.requestId;
|
|
435
|
-
const timeoutId = setTimeout(() => {
|
|
436
|
-
state.pendingRequests.delete(requestId);
|
|
437
|
-
reject(new Error("Request timeout"));
|
|
438
|
-
}, timeout);
|
|
439
395
|
state.pendingRequests.set(requestId, {
|
|
440
396
|
resolve,
|
|
441
|
-
reject
|
|
442
|
-
timeoutId
|
|
397
|
+
reject
|
|
443
398
|
});
|
|
444
399
|
sendMessage(state.socket, message);
|
|
445
400
|
});
|
|
446
401
|
}
|
|
402
|
+
function isBenignDisposeError(error) {
|
|
403
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
404
|
+
return /isolate not owned by this connection|isolate not found|not connected|connection closed/i.test(message);
|
|
405
|
+
}
|
|
447
406
|
async function createRuntime(state, options = {}, namespaceId) {
|
|
448
407
|
const callbacks = {};
|
|
449
408
|
if (options.console) {
|
|
@@ -584,11 +543,18 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
584
543
|
const reused = result.reused ?? false;
|
|
585
544
|
const wsCommandCallbacks = new Set;
|
|
586
545
|
isolateWsCallbacks.set(isolateId, wsCommandCallbacks);
|
|
546
|
+
if (options.onWebSocketCommand) {
|
|
547
|
+
wsCommandCallbacks.add(options.onWebSocketCommand);
|
|
548
|
+
}
|
|
587
549
|
if (options.webSocket) {
|
|
588
550
|
isolateWebSocketCallbacks.set(isolateId, options.webSocket);
|
|
589
551
|
}
|
|
590
552
|
const fetchHandle = {
|
|
591
553
|
async dispatchRequest(req, opts) {
|
|
554
|
+
const signal = opts?.signal;
|
|
555
|
+
if (signal?.aborted) {
|
|
556
|
+
throw new DOMException("The operation was aborted", "AbortError");
|
|
557
|
+
}
|
|
592
558
|
const reqId = state.nextRequestId++;
|
|
593
559
|
const serialized = await serializeRequestWithStreaming(state, req);
|
|
594
560
|
const { bodyStream, ...serializableRequest } = serialized;
|
|
@@ -596,24 +562,40 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
596
562
|
type: import_isolate_protocol.MessageType.DISPATCH_REQUEST,
|
|
597
563
|
requestId: reqId,
|
|
598
564
|
isolateId,
|
|
599
|
-
request: serializableRequest
|
|
600
|
-
options: opts
|
|
565
|
+
request: serializableRequest
|
|
601
566
|
};
|
|
602
567
|
const handleResponse = (res) => {
|
|
603
568
|
if (res.__streaming && res.response instanceof Response) {
|
|
604
569
|
return res.response;
|
|
605
570
|
}
|
|
606
|
-
return deserializeResponse(res.response);
|
|
571
|
+
return import_isolate_protocol.deserializeResponse(res.response);
|
|
607
572
|
};
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
573
|
+
let onAbort;
|
|
574
|
+
if (signal) {
|
|
575
|
+
onAbort = () => {
|
|
576
|
+
const pending = state.pendingRequests.get(reqId);
|
|
577
|
+
if (pending) {
|
|
578
|
+
state.pendingRequests.delete(reqId);
|
|
579
|
+
pending.reject(new DOMException("The operation was aborted", "AbortError"));
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
583
|
+
}
|
|
584
|
+
try {
|
|
585
|
+
if (serialized.bodyStreamId !== undefined && bodyStream) {
|
|
586
|
+
const streamId = serialized.bodyStreamId;
|
|
587
|
+
const responsePromise = sendRequest(state, request2);
|
|
588
|
+
await sendBodyStream(state, streamId, bodyStream);
|
|
589
|
+
const res = await responsePromise;
|
|
590
|
+
return handleResponse(res);
|
|
591
|
+
} else {
|
|
592
|
+
const res = await sendRequest(state, request2);
|
|
593
|
+
return handleResponse(res);
|
|
594
|
+
}
|
|
595
|
+
} finally {
|
|
596
|
+
if (signal && onAbort) {
|
|
597
|
+
signal.removeEventListener("abort", onAbort);
|
|
598
|
+
}
|
|
617
599
|
}
|
|
618
600
|
},
|
|
619
601
|
async getUpgradeRequest() {
|
|
@@ -760,8 +742,7 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
760
742
|
isolateId,
|
|
761
743
|
timeout
|
|
762
744
|
};
|
|
763
|
-
|
|
764
|
-
return sendRequest(state, req, requestTimeout);
|
|
745
|
+
return sendRequest(state, req);
|
|
765
746
|
},
|
|
766
747
|
async hasTests() {
|
|
767
748
|
if (!testEnvironmentEnabled) {
|
|
@@ -836,17 +817,47 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
836
817
|
requestId: reqId,
|
|
837
818
|
isolateId,
|
|
838
819
|
code,
|
|
839
|
-
filename: options2?.filename
|
|
840
|
-
maxExecutionMs: options2?.maxExecutionMs
|
|
820
|
+
filename: options2?.filename
|
|
841
821
|
};
|
|
842
822
|
await sendRequest(state, req);
|
|
843
823
|
},
|
|
824
|
+
on(event, callback) {
|
|
825
|
+
let listeners = isolateEventListeners.get(isolateId);
|
|
826
|
+
if (!listeners) {
|
|
827
|
+
listeners = new Map;
|
|
828
|
+
isolateEventListeners.set(isolateId, listeners);
|
|
829
|
+
}
|
|
830
|
+
let eventListeners = listeners.get(event);
|
|
831
|
+
if (!eventListeners) {
|
|
832
|
+
eventListeners = new Set;
|
|
833
|
+
listeners.set(event, eventListeners);
|
|
834
|
+
}
|
|
835
|
+
eventListeners.add(callback);
|
|
836
|
+
return () => {
|
|
837
|
+
eventListeners.delete(callback);
|
|
838
|
+
if (eventListeners.size === 0) {
|
|
839
|
+
listeners.delete(event);
|
|
840
|
+
if (listeners.size === 0) {
|
|
841
|
+
isolateEventListeners.delete(isolateId);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
};
|
|
845
|
+
},
|
|
846
|
+
emit(event, payload) {
|
|
847
|
+
sendMessage(state.socket, {
|
|
848
|
+
type: import_isolate_protocol.MessageType.CLIENT_EVENT,
|
|
849
|
+
isolateId,
|
|
850
|
+
event,
|
|
851
|
+
payload
|
|
852
|
+
});
|
|
853
|
+
},
|
|
844
854
|
dispose: async () => {
|
|
845
855
|
for (const cleanup of pageListenerCleanups) {
|
|
846
856
|
cleanup();
|
|
847
857
|
}
|
|
848
858
|
isolateWsCallbacks.delete(isolateId);
|
|
849
859
|
isolateWebSocketCallbacks.delete(isolateId);
|
|
860
|
+
isolateEventListeners.delete(isolateId);
|
|
850
861
|
const clientSockets = isolateClientWebSockets.get(isolateId);
|
|
851
862
|
if (clientSockets) {
|
|
852
863
|
for (const ws of clientSockets.values()) {
|
|
@@ -862,7 +873,13 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
862
873
|
requestId: reqId,
|
|
863
874
|
isolateId
|
|
864
875
|
};
|
|
865
|
-
|
|
876
|
+
try {
|
|
877
|
+
await sendRequest(state, req);
|
|
878
|
+
} catch (error) {
|
|
879
|
+
if (!isBenignDisposeError(error)) {
|
|
880
|
+
throw error;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
866
883
|
}
|
|
867
884
|
};
|
|
868
885
|
}
|
|
@@ -894,8 +911,8 @@ function registerFetchCallback(state, callback) {
|
|
|
894
911
|
const init = {
|
|
895
912
|
method: data.method,
|
|
896
913
|
headers: data.headers,
|
|
897
|
-
rawBody: data.body,
|
|
898
|
-
body: data.body,
|
|
914
|
+
rawBody: data.body ?? null,
|
|
915
|
+
body: data.body ?? null,
|
|
899
916
|
signal: new AbortController().signal
|
|
900
917
|
};
|
|
901
918
|
const response = await callback(data.url, init);
|
|
@@ -923,7 +940,7 @@ function registerFetchCallback(state, callback) {
|
|
|
923
940
|
streamCallbackResponseBody(state, streamId, requestId, response.body);
|
|
924
941
|
return { __callbackStreaming: true, streamId };
|
|
925
942
|
}
|
|
926
|
-
return serializeResponse(response);
|
|
943
|
+
return import_isolate_protocol.serializeResponse(response);
|
|
927
944
|
});
|
|
928
945
|
return { callbackId, name: "fetch", type: "async" };
|
|
929
946
|
}
|
|
@@ -1051,12 +1068,6 @@ var clientIteratorSessions = new Map;
|
|
|
1051
1068
|
var nextClientIteratorId = 1;
|
|
1052
1069
|
var returnedPromiseRegistry = new Map;
|
|
1053
1070
|
var returnedIteratorRegistry = new Map;
|
|
1054
|
-
function isPromiseRef(value) {
|
|
1055
|
-
return typeof value === "object" && value !== null && value.__type === "PromiseRef";
|
|
1056
|
-
}
|
|
1057
|
-
function isAsyncIteratorRef(value) {
|
|
1058
|
-
return typeof value === "object" && value !== null && value.__type === "AsyncIteratorRef";
|
|
1059
|
-
}
|
|
1060
1071
|
function registerCustomFunctions(state, customFunctions) {
|
|
1061
1072
|
const registrations = {};
|
|
1062
1073
|
for (const [name, def] of Object.entries(customFunctions)) {
|
|
@@ -1139,7 +1150,7 @@ function registerCustomFunctions(state, customFunctions) {
|
|
|
1139
1150
|
if (value === null || typeof value !== "object") {
|
|
1140
1151
|
return value;
|
|
1141
1152
|
}
|
|
1142
|
-
if (isPromiseRef(value)) {
|
|
1153
|
+
if (import_isolate_protocol.isPromiseRef(value)) {
|
|
1143
1154
|
const resolveCallbackId = state.nextCallbackId++;
|
|
1144
1155
|
state.callbacks.set(resolveCallbackId, async (...args2) => {
|
|
1145
1156
|
const promiseId = args2[0];
|
|
@@ -1157,7 +1168,7 @@ function registerCustomFunctions(state, customFunctions) {
|
|
|
1157
1168
|
__resolveCallbackId: resolveCallbackId
|
|
1158
1169
|
};
|
|
1159
1170
|
}
|
|
1160
|
-
if (isAsyncIteratorRef(value)) {
|
|
1171
|
+
if (import_isolate_protocol.isAsyncIteratorRef(value)) {
|
|
1161
1172
|
const nextCallbackId = state.nextCallbackId++;
|
|
1162
1173
|
state.callbacks.set(nextCallbackId, async (...args2) => {
|
|
1163
1174
|
const iteratorId = args2[0];
|
|
@@ -1240,29 +1251,6 @@ function registerCustomFunctions(state, customFunctions) {
|
|
|
1240
1251
|
}
|
|
1241
1252
|
return registrations;
|
|
1242
1253
|
}
|
|
1243
|
-
async function serializeResponse(response) {
|
|
1244
|
-
const headers = [];
|
|
1245
|
-
response.headers.forEach((value, key) => {
|
|
1246
|
-
headers.push([key, value]);
|
|
1247
|
-
});
|
|
1248
|
-
let body = null;
|
|
1249
|
-
if (response.body) {
|
|
1250
|
-
body = new Uint8Array(await response.arrayBuffer());
|
|
1251
|
-
}
|
|
1252
|
-
return {
|
|
1253
|
-
status: response.status,
|
|
1254
|
-
statusText: response.statusText,
|
|
1255
|
-
headers,
|
|
1256
|
-
body
|
|
1257
|
-
};
|
|
1258
|
-
}
|
|
1259
|
-
function deserializeResponse(data) {
|
|
1260
|
-
return new Response(data.body, {
|
|
1261
|
-
status: data.status,
|
|
1262
|
-
statusText: data.statusText,
|
|
1263
|
-
headers: data.headers
|
|
1264
|
-
});
|
|
1265
|
-
}
|
|
1266
1254
|
async function serializeRequestWithStreaming(state, request) {
|
|
1267
1255
|
const headers = [];
|
|
1268
1256
|
request.headers.forEach((value, key) => {
|
|
@@ -1361,8 +1349,62 @@ async function sendBodyStream(state, streamId, body) {
|
|
|
1361
1349
|
state.uploadStreams.delete(streamId);
|
|
1362
1350
|
}
|
|
1363
1351
|
}
|
|
1364
|
-
function
|
|
1365
|
-
|
|
1352
|
+
function handleIsolateEvent(message, state) {
|
|
1353
|
+
switch (message.event) {
|
|
1354
|
+
case import_isolate_protocol.IsolateEvents.WS_COMMAND: {
|
|
1355
|
+
const payload = message.payload;
|
|
1356
|
+
const callbacks = isolateWsCallbacks.get(message.isolateId);
|
|
1357
|
+
if (callbacks) {
|
|
1358
|
+
let data;
|
|
1359
|
+
if (payload.data instanceof Uint8Array) {
|
|
1360
|
+
data = payload.data.buffer.slice(payload.data.byteOffset, payload.data.byteOffset + payload.data.byteLength);
|
|
1361
|
+
} else {
|
|
1362
|
+
data = payload.data;
|
|
1363
|
+
}
|
|
1364
|
+
const cmd = {
|
|
1365
|
+
type: payload.type,
|
|
1366
|
+
connectionId: payload.connectionId,
|
|
1367
|
+
data,
|
|
1368
|
+
code: payload.code,
|
|
1369
|
+
reason: payload.reason
|
|
1370
|
+
};
|
|
1371
|
+
for (const cb of callbacks) {
|
|
1372
|
+
cb(cmd);
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
break;
|
|
1376
|
+
}
|
|
1377
|
+
case import_isolate_protocol.IsolateEvents.WS_CLIENT_CONNECT: {
|
|
1378
|
+
const payload = message.payload;
|
|
1379
|
+
handleClientWsConnect(message.isolateId, payload, state);
|
|
1380
|
+
break;
|
|
1381
|
+
}
|
|
1382
|
+
case import_isolate_protocol.IsolateEvents.WS_CLIENT_SEND: {
|
|
1383
|
+
const payload = message.payload;
|
|
1384
|
+
handleClientWsSend(message.isolateId, payload, state);
|
|
1385
|
+
break;
|
|
1386
|
+
}
|
|
1387
|
+
case import_isolate_protocol.IsolateEvents.WS_CLIENT_CLOSE: {
|
|
1388
|
+
const payload = message.payload;
|
|
1389
|
+
handleClientWsClose(message.isolateId, payload, state);
|
|
1390
|
+
break;
|
|
1391
|
+
}
|
|
1392
|
+
default: {
|
|
1393
|
+
const listeners = isolateEventListeners.get(message.isolateId);
|
|
1394
|
+
if (listeners) {
|
|
1395
|
+
const eventListeners = listeners.get(message.event);
|
|
1396
|
+
if (eventListeners) {
|
|
1397
|
+
for (const cb of eventListeners) {
|
|
1398
|
+
cb(message.payload);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
break;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
function handleClientWsConnect(isolateId, payload, state) {
|
|
1407
|
+
const { socketId, url, protocols } = payload;
|
|
1366
1408
|
let sockets = isolateClientWebSockets.get(isolateId);
|
|
1367
1409
|
if (!sockets) {
|
|
1368
1410
|
sockets = new Map;
|
|
@@ -1371,14 +1413,12 @@ function handleClientWsConnect(message, state) {
|
|
|
1371
1413
|
const setupWebSocket = (ws) => {
|
|
1372
1414
|
sockets.set(socketId, ws);
|
|
1373
1415
|
ws.onopen = () => {
|
|
1374
|
-
|
|
1375
|
-
type: import_isolate_protocol.MessageType.
|
|
1416
|
+
sendMessage(state.socket, {
|
|
1417
|
+
type: import_isolate_protocol.MessageType.CLIENT_EVENT,
|
|
1376
1418
|
isolateId,
|
|
1377
|
-
|
|
1378
|
-
protocol: ws.protocol || "",
|
|
1379
|
-
|
|
1380
|
-
};
|
|
1381
|
-
sendMessage(state.socket, msg);
|
|
1419
|
+
event: import_isolate_protocol.ClientEvents.WS_CLIENT_OPENED,
|
|
1420
|
+
payload: { socketId, protocol: ws.protocol || "", extensions: ws.extensions || "" }
|
|
1421
|
+
});
|
|
1382
1422
|
};
|
|
1383
1423
|
ws.onmessage = (event) => {
|
|
1384
1424
|
let data;
|
|
@@ -1388,44 +1428,39 @@ function handleClientWsConnect(message, state) {
|
|
|
1388
1428
|
data = new Uint8Array(event.data);
|
|
1389
1429
|
} else if (event.data instanceof Blob) {
|
|
1390
1430
|
event.data.arrayBuffer().then((buffer) => {
|
|
1391
|
-
|
|
1392
|
-
type: import_isolate_protocol.MessageType.
|
|
1431
|
+
sendMessage(state.socket, {
|
|
1432
|
+
type: import_isolate_protocol.MessageType.CLIENT_EVENT,
|
|
1393
1433
|
isolateId,
|
|
1394
|
-
|
|
1395
|
-
data: new Uint8Array(buffer)
|
|
1396
|
-
};
|
|
1397
|
-
sendMessage(state.socket, msg2);
|
|
1434
|
+
event: import_isolate_protocol.ClientEvents.WS_CLIENT_MESSAGE,
|
|
1435
|
+
payload: { socketId, data: new Uint8Array(buffer) }
|
|
1436
|
+
});
|
|
1398
1437
|
});
|
|
1399
1438
|
return;
|
|
1400
1439
|
} else {
|
|
1401
1440
|
data = String(event.data);
|
|
1402
1441
|
}
|
|
1403
|
-
|
|
1404
|
-
type: import_isolate_protocol.MessageType.
|
|
1442
|
+
sendMessage(state.socket, {
|
|
1443
|
+
type: import_isolate_protocol.MessageType.CLIENT_EVENT,
|
|
1405
1444
|
isolateId,
|
|
1406
|
-
|
|
1407
|
-
data
|
|
1408
|
-
};
|
|
1409
|
-
sendMessage(state.socket, msg);
|
|
1445
|
+
event: import_isolate_protocol.ClientEvents.WS_CLIENT_MESSAGE,
|
|
1446
|
+
payload: { socketId, data }
|
|
1447
|
+
});
|
|
1410
1448
|
};
|
|
1411
1449
|
ws.onerror = () => {
|
|
1412
|
-
|
|
1413
|
-
type: import_isolate_protocol.MessageType.
|
|
1450
|
+
sendMessage(state.socket, {
|
|
1451
|
+
type: import_isolate_protocol.MessageType.CLIENT_EVENT,
|
|
1414
1452
|
isolateId,
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1453
|
+
event: import_isolate_protocol.ClientEvents.WS_CLIENT_ERROR,
|
|
1454
|
+
payload: { socketId }
|
|
1455
|
+
});
|
|
1418
1456
|
};
|
|
1419
1457
|
ws.onclose = (event) => {
|
|
1420
|
-
|
|
1421
|
-
type: import_isolate_protocol.MessageType.
|
|
1458
|
+
sendMessage(state.socket, {
|
|
1459
|
+
type: import_isolate_protocol.MessageType.CLIENT_EVENT,
|
|
1422
1460
|
isolateId,
|
|
1423
|
-
|
|
1424
|
-
code: event.code,
|
|
1425
|
-
|
|
1426
|
-
wasClean: event.wasClean
|
|
1427
|
-
};
|
|
1428
|
-
sendMessage(state.socket, msg);
|
|
1461
|
+
event: import_isolate_protocol.ClientEvents.WS_CLIENT_CLOSED,
|
|
1462
|
+
payload: { socketId, code: event.code, reason: event.reason, wasClean: event.wasClean }
|
|
1463
|
+
});
|
|
1429
1464
|
sockets?.delete(socketId);
|
|
1430
1465
|
if (sockets?.size === 0) {
|
|
1431
1466
|
isolateClientWebSockets.delete(isolateId);
|
|
@@ -1433,21 +1468,18 @@ function handleClientWsConnect(message, state) {
|
|
|
1433
1468
|
};
|
|
1434
1469
|
};
|
|
1435
1470
|
const sendConnectionFailed = (reason) => {
|
|
1436
|
-
|
|
1437
|
-
type: import_isolate_protocol.MessageType.
|
|
1471
|
+
sendMessage(state.socket, {
|
|
1472
|
+
type: import_isolate_protocol.MessageType.CLIENT_EVENT,
|
|
1438
1473
|
isolateId,
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
type: import_isolate_protocol.MessageType.
|
|
1474
|
+
event: import_isolate_protocol.ClientEvents.WS_CLIENT_ERROR,
|
|
1475
|
+
payload: { socketId }
|
|
1476
|
+
});
|
|
1477
|
+
sendMessage(state.socket, {
|
|
1478
|
+
type: import_isolate_protocol.MessageType.CLIENT_EVENT,
|
|
1444
1479
|
isolateId,
|
|
1445
|
-
|
|
1446
|
-
code: 1006,
|
|
1447
|
-
|
|
1448
|
-
wasClean: false
|
|
1449
|
-
};
|
|
1450
|
-
sendMessage(state.socket, closeMsg);
|
|
1480
|
+
event: import_isolate_protocol.ClientEvents.WS_CLIENT_CLOSED,
|
|
1481
|
+
payload: { socketId, code: 1006, reason, wasClean: false }
|
|
1482
|
+
});
|
|
1451
1483
|
};
|
|
1452
1484
|
const callback = isolateWebSocketCallbacks.get(isolateId);
|
|
1453
1485
|
if (callback) {
|
|
@@ -1480,8 +1512,8 @@ function handleClientWsConnect(message, state) {
|
|
|
1480
1512
|
}
|
|
1481
1513
|
}
|
|
1482
1514
|
}
|
|
1483
|
-
function handleClientWsSend(
|
|
1484
|
-
const {
|
|
1515
|
+
function handleClientWsSend(isolateId, payload, state) {
|
|
1516
|
+
const { socketId, data } = payload;
|
|
1485
1517
|
const sockets = isolateClientWebSockets.get(isolateId);
|
|
1486
1518
|
const ws = sockets?.get(socketId);
|
|
1487
1519
|
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
@@ -1497,8 +1529,8 @@ function handleClientWsSend(message, state) {
|
|
|
1497
1529
|
ws.send(data);
|
|
1498
1530
|
}
|
|
1499
1531
|
}
|
|
1500
|
-
function handleClientWsClose(
|
|
1501
|
-
const {
|
|
1532
|
+
function handleClientWsClose(isolateId, payload, state) {
|
|
1533
|
+
const { socketId, code, reason } = payload;
|
|
1502
1534
|
const sockets = isolateClientWebSockets.get(isolateId);
|
|
1503
1535
|
const ws = sockets?.get(socketId);
|
|
1504
1536
|
if (!ws) {
|
|
@@ -1509,4 +1541,4 @@ function handleClientWsClose(message, state) {
|
|
|
1509
1541
|
}
|
|
1510
1542
|
}
|
|
1511
1543
|
|
|
1512
|
-
//# debugId=
|
|
1544
|
+
//# debugId=1DAE4D8C13C4D6B364756E2164756E21
|