@ricsam/isolate-client 0.1.16 → 0.1.17
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/dist/cjs/connection.cjs +161 -38
- package/dist/cjs/connection.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/connection.mjs +161 -38
- package/dist/mjs/connection.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/package.json +1 -1
package/dist/cjs/connection.cjs
CHANGED
|
@@ -68,44 +68,142 @@ async function connect(options = {}) {
|
|
|
68
68
|
streamResponses: new Map,
|
|
69
69
|
uploadStreams: new Map,
|
|
70
70
|
moduleSourceCache: new Map,
|
|
71
|
-
callbackStreamReaders: new Map
|
|
71
|
+
callbackStreamReaders: new Map,
|
|
72
|
+
closing: false,
|
|
73
|
+
namespacedRuntimes: new Map
|
|
72
74
|
};
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
function setupSocket(sock) {
|
|
76
|
+
const parser = import_isolate_protocol.createFrameParser();
|
|
77
|
+
sock.on("data", (data) => {
|
|
78
|
+
try {
|
|
79
|
+
for (const frame of parser.feed(new Uint8Array(data))) {
|
|
80
|
+
handleMessage(frame.message, state);
|
|
81
|
+
}
|
|
82
|
+
} catch (err) {
|
|
83
|
+
console.error("Error parsing frame:", err);
|
|
78
84
|
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
state.connected = false;
|
|
85
|
-
for (const [, pending] of state.pendingRequests) {
|
|
86
|
-
pending.reject(new Error("Connection closed"));
|
|
87
|
-
}
|
|
88
|
-
state.pendingRequests.clear();
|
|
89
|
-
for (const [, receiver] of state.streamResponses) {
|
|
90
|
-
receiver.state = "errored";
|
|
91
|
-
receiver.error = new Error("Connection closed");
|
|
92
|
-
const resolvers = receiver.pullResolvers.splice(0);
|
|
93
|
-
for (const resolver of resolvers) {
|
|
94
|
-
resolver();
|
|
85
|
+
});
|
|
86
|
+
sock.on("close", () => {
|
|
87
|
+
state.connected = false;
|
|
88
|
+
for (const [, pending] of state.pendingRequests) {
|
|
89
|
+
pending.reject(new Error("Connection closed"));
|
|
95
90
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
91
|
+
state.pendingRequests.clear();
|
|
92
|
+
for (const [, receiver] of state.streamResponses) {
|
|
93
|
+
receiver.state = "errored";
|
|
94
|
+
receiver.error = new Error("Connection closed");
|
|
95
|
+
const resolvers = receiver.pullResolvers.splice(0);
|
|
96
|
+
for (const resolver of resolvers) {
|
|
97
|
+
resolver();
|
|
98
|
+
}
|
|
102
99
|
}
|
|
100
|
+
state.streamResponses.clear();
|
|
101
|
+
for (const [, session] of state.uploadStreams) {
|
|
102
|
+
session.state = "closed";
|
|
103
|
+
if (session.creditResolver) {
|
|
104
|
+
session.creditResolver();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
state.uploadStreams.clear();
|
|
108
|
+
if (!state.closing && state.namespacedRuntimes.size > 0) {
|
|
109
|
+
state.reconnecting = reconnect(state, options).catch(() => {
|
|
110
|
+
state.namespacedRuntimes.clear();
|
|
111
|
+
state.reconnecting = undefined;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
sock.on("error", (err) => {
|
|
116
|
+
if (!state.closing && state.namespacedRuntimes.size > 0)
|
|
117
|
+
return;
|
|
118
|
+
console.error("Socket error:", err);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
setupSocket(socket);
|
|
122
|
+
async function reconnect(st, opts) {
|
|
123
|
+
try {
|
|
124
|
+
const newSocket = await createSocket(opts);
|
|
125
|
+
st.socket = newSocket;
|
|
126
|
+
st.connected = true;
|
|
127
|
+
setupSocket(newSocket);
|
|
128
|
+
for (const [namespaceId, descriptor] of st.namespacedRuntimes) {
|
|
129
|
+
const runtimeOptions = descriptor.runtimeOptions;
|
|
130
|
+
const callbacks = {};
|
|
131
|
+
if (runtimeOptions.console) {
|
|
132
|
+
callbacks.console = registerConsoleCallbacks(st, runtimeOptions.console);
|
|
133
|
+
}
|
|
134
|
+
if (runtimeOptions.fetch) {
|
|
135
|
+
callbacks.fetch = registerFetchCallback(st, runtimeOptions.fetch);
|
|
136
|
+
}
|
|
137
|
+
if (runtimeOptions.fs) {
|
|
138
|
+
callbacks.fs = registerFsCallbacks(st, runtimeOptions.fs);
|
|
139
|
+
}
|
|
140
|
+
if (runtimeOptions.moduleLoader) {
|
|
141
|
+
callbacks.moduleLoader = registerModuleLoaderCallback(st, runtimeOptions.moduleLoader);
|
|
142
|
+
}
|
|
143
|
+
if (runtimeOptions.customFunctions) {
|
|
144
|
+
callbacks.custom = registerCustomFunctions(st, runtimeOptions.customFunctions);
|
|
145
|
+
}
|
|
146
|
+
if (runtimeOptions.playwright) {
|
|
147
|
+
const playwrightHandler = runtimeOptions.playwright.handler;
|
|
148
|
+
if (playwrightHandler) {
|
|
149
|
+
const handlerCallbackId = st.nextCallbackId++;
|
|
150
|
+
st.callbacks.set(handlerCallbackId, async (opJson) => {
|
|
151
|
+
const op = JSON.parse(opJson);
|
|
152
|
+
const result2 = await playwrightHandler(op);
|
|
153
|
+
return JSON.stringify(result2);
|
|
154
|
+
});
|
|
155
|
+
callbacks.playwright = {
|
|
156
|
+
handlerCallbackId,
|
|
157
|
+
console: runtimeOptions.playwright.console && !runtimeOptions.console?.onEntry
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
let testEnvironmentOption;
|
|
162
|
+
if (runtimeOptions.testEnvironment) {
|
|
163
|
+
if (typeof runtimeOptions.testEnvironment === "object") {
|
|
164
|
+
const testEnvOptions = runtimeOptions.testEnvironment;
|
|
165
|
+
const testEnvCallbacks = {};
|
|
166
|
+
if (testEnvOptions.onEvent) {
|
|
167
|
+
const userOnEvent = testEnvOptions.onEvent;
|
|
168
|
+
const onEventCallbackId = registerEventCallback(st, (eventJson) => {
|
|
169
|
+
const event = JSON.parse(eventJson);
|
|
170
|
+
userOnEvent(event);
|
|
171
|
+
});
|
|
172
|
+
testEnvCallbacks.onEvent = {
|
|
173
|
+
callbackId: onEventCallbackId,
|
|
174
|
+
name: "testEnvironment.onEvent",
|
|
175
|
+
type: "sync"
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
testEnvironmentOption = {
|
|
179
|
+
callbacks: testEnvCallbacks,
|
|
180
|
+
testTimeout: testEnvOptions.testTimeout
|
|
181
|
+
};
|
|
182
|
+
} else {
|
|
183
|
+
testEnvironmentOption = true;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const requestId = st.nextRequestId++;
|
|
187
|
+
const request = {
|
|
188
|
+
type: import_isolate_protocol.MessageType.CREATE_RUNTIME,
|
|
189
|
+
requestId,
|
|
190
|
+
options: {
|
|
191
|
+
memoryLimitMB: runtimeOptions.memoryLimitMB,
|
|
192
|
+
cwd: runtimeOptions.cwd,
|
|
193
|
+
callbacks,
|
|
194
|
+
testEnvironment: testEnvironmentOption,
|
|
195
|
+
namespaceId
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
const result = await sendRequest(st, request);
|
|
199
|
+
descriptor.isolateId = result.isolateId;
|
|
200
|
+
}
|
|
201
|
+
st.reconnecting = undefined;
|
|
202
|
+
} catch {
|
|
203
|
+
st.reconnecting = undefined;
|
|
204
|
+
throw new Error("Failed to reconnect to daemon");
|
|
103
205
|
}
|
|
104
|
-
|
|
105
|
-
});
|
|
106
|
-
socket.on("error", (err) => {
|
|
107
|
-
console.error("Socket error:", err);
|
|
108
|
-
});
|
|
206
|
+
}
|
|
109
207
|
return {
|
|
110
208
|
createRuntime: (runtimeOptions) => createRuntime(state, runtimeOptions),
|
|
111
209
|
createNamespace: (id) => ({
|
|
@@ -113,8 +211,9 @@ async function connect(options = {}) {
|
|
|
113
211
|
createRuntime: (runtimeOptions) => createRuntime(state, runtimeOptions, id)
|
|
114
212
|
}),
|
|
115
213
|
close: async () => {
|
|
214
|
+
state.closing = true;
|
|
116
215
|
state.connected = false;
|
|
117
|
-
socket.destroy();
|
|
216
|
+
state.socket.destroy();
|
|
118
217
|
},
|
|
119
218
|
isConnected: () => state.connected
|
|
120
219
|
};
|
|
@@ -541,6 +640,12 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
541
640
|
const result = await sendRequest(state, request);
|
|
542
641
|
const isolateId = result.isolateId;
|
|
543
642
|
const reused = result.reused ?? false;
|
|
643
|
+
if (namespaceId != null) {
|
|
644
|
+
state.namespacedRuntimes.set(namespaceId, {
|
|
645
|
+
isolateId,
|
|
646
|
+
runtimeOptions: options
|
|
647
|
+
});
|
|
648
|
+
}
|
|
544
649
|
const wsCommandCallbacks = new Set;
|
|
545
650
|
isolateWsCallbacks.set(isolateId, wsCommandCallbacks);
|
|
546
651
|
if (options.onWebSocketCommand) {
|
|
@@ -742,7 +847,22 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
742
847
|
isolateId,
|
|
743
848
|
timeout
|
|
744
849
|
};
|
|
745
|
-
|
|
850
|
+
try {
|
|
851
|
+
return await sendRequest(state, req);
|
|
852
|
+
} catch (err) {
|
|
853
|
+
if (err instanceof Error && /connection closed|not connected/i.test(err.message) && state.reconnecting) {
|
|
854
|
+
await state.reconnecting;
|
|
855
|
+
const retryReqId = state.nextRequestId++;
|
|
856
|
+
const retryReq = {
|
|
857
|
+
type: import_isolate_protocol.MessageType.RUN_TESTS,
|
|
858
|
+
requestId: retryReqId,
|
|
859
|
+
isolateId,
|
|
860
|
+
timeout
|
|
861
|
+
};
|
|
862
|
+
return sendRequest(state, retryReq);
|
|
863
|
+
}
|
|
864
|
+
throw err;
|
|
865
|
+
}
|
|
746
866
|
},
|
|
747
867
|
async hasTests() {
|
|
748
868
|
if (!testEnvironmentEnabled) {
|
|
@@ -867,6 +987,9 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
867
987
|
}
|
|
868
988
|
isolateClientWebSockets.delete(isolateId);
|
|
869
989
|
}
|
|
990
|
+
if (namespaceId != null) {
|
|
991
|
+
state.namespacedRuntimes.delete(namespaceId);
|
|
992
|
+
}
|
|
870
993
|
const reqId = state.nextRequestId++;
|
|
871
994
|
const req = {
|
|
872
995
|
type: import_isolate_protocol.MessageType.DISPOSE_RUNTIME,
|
|
@@ -1058,7 +1181,7 @@ function registerModuleLoaderCallback(state, callback) {
|
|
|
1058
1181
|
const specifier = moduleName;
|
|
1059
1182
|
const importerInfo = importer;
|
|
1060
1183
|
const result = await callback(specifier, importerInfo);
|
|
1061
|
-
const resolvedPath = import_node_path.default.posix.join(result.resolveDir,
|
|
1184
|
+
const resolvedPath = import_node_path.default.posix.join(result.resolveDir, result.filename);
|
|
1062
1185
|
state.moduleSourceCache.set(resolvedPath, result.code);
|
|
1063
1186
|
return result;
|
|
1064
1187
|
});
|
|
@@ -1524,7 +1647,7 @@ function handleClientWsSend(isolateId, payload, state) {
|
|
|
1524
1647
|
const binary = Buffer.from(base64, "base64");
|
|
1525
1648
|
ws.send(binary);
|
|
1526
1649
|
} else if (data instanceof Uint8Array) {
|
|
1527
|
-
ws.send(data);
|
|
1650
|
+
ws.send(Buffer.from(data));
|
|
1528
1651
|
} else {
|
|
1529
1652
|
ws.send(data);
|
|
1530
1653
|
}
|
|
@@ -1541,4 +1664,4 @@ function handleClientWsClose(isolateId, payload, state) {
|
|
|
1541
1664
|
}
|
|
1542
1665
|
}
|
|
1543
1666
|
|
|
1544
|
-
//# debugId=
|
|
1667
|
+
//# debugId=BB5A27475A32C8E264756E2164756E21
|