@ricsam/isolate-client 0.1.9 → 0.1.11
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 +21 -10
- package/dist/cjs/connection.cjs +104 -89
- package/dist/cjs/connection.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/connection.mjs +91 -89
- package/dist/mjs/connection.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/types.d.ts +2 -3
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -85,7 +85,10 @@ const namespace = client.createNamespace("tenant-123");
|
|
|
85
85
|
// Create a runtime in this namespace
|
|
86
86
|
const runtime = await namespace.createRuntime({
|
|
87
87
|
memoryLimitMB: 128,
|
|
88
|
-
moduleLoader: async (name) =>
|
|
88
|
+
moduleLoader: async (name, importer) => {
|
|
89
|
+
const code = loadModule(name);
|
|
90
|
+
return { code, resolveDir: importer.resolveDir };
|
|
91
|
+
},
|
|
89
92
|
});
|
|
90
93
|
|
|
91
94
|
console.log(runtime.reused); // false - first time
|
|
@@ -145,21 +148,29 @@ interface Namespace {
|
|
|
145
148
|
|
|
146
149
|
## Module Loader
|
|
147
150
|
|
|
148
|
-
Register a custom module loader to handle dynamic `import()` calls:
|
|
151
|
+
Register a custom module loader to handle dynamic `import()` calls. The loader receives the module specifier and importer info, and returns an object with the source code and `resolveDir` (used to resolve nested relative imports):
|
|
149
152
|
|
|
150
153
|
```typescript
|
|
151
154
|
const runtime = await client.createRuntime({
|
|
152
|
-
moduleLoader: async (moduleName: string) => {
|
|
155
|
+
moduleLoader: async (moduleName: string, importer) => {
|
|
156
|
+
// importer.path = resolved path of importing module
|
|
157
|
+
// importer.resolveDir = directory for relative resolution
|
|
153
158
|
if (moduleName === "@/db") {
|
|
154
|
-
return
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
159
|
+
return {
|
|
160
|
+
code: `
|
|
161
|
+
export async function getUser(id) {
|
|
162
|
+
const response = await fetch("/api/users/" + id);
|
|
163
|
+
return response.json();
|
|
164
|
+
}
|
|
165
|
+
`,
|
|
166
|
+
resolveDir: "/modules",
|
|
167
|
+
};
|
|
160
168
|
}
|
|
161
169
|
if (moduleName === "@/config") {
|
|
162
|
-
return
|
|
170
|
+
return {
|
|
171
|
+
code: `export const API_KEY = "sk-xxx";`,
|
|
172
|
+
resolveDir: "/modules",
|
|
173
|
+
};
|
|
163
174
|
}
|
|
164
175
|
throw new Error(`Unknown module: ${moduleName}`);
|
|
165
176
|
},
|
package/dist/cjs/connection.cjs
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
1
3
|
var __defProp = Object.defineProperty;
|
|
2
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
5
18
|
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
6
19
|
var __toCommonJS = (from) => {
|
|
7
20
|
var entry = __moduleCache.get(from), desc;
|
|
@@ -33,6 +46,7 @@ __export(exports_connection, {
|
|
|
33
46
|
});
|
|
34
47
|
module.exports = __toCommonJS(exports_connection);
|
|
35
48
|
var import_node_net = require("node:net");
|
|
49
|
+
var import_node_path = __toESM(require("node:path"));
|
|
36
50
|
var import_isolate_protocol = require("@ricsam/isolate-protocol");
|
|
37
51
|
var import_client = require("@ricsam/isolate-playwright/client");
|
|
38
52
|
var DEFAULT_TIMEOUT = 30000;
|
|
@@ -421,6 +435,10 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
421
435
|
callbacks.custom = registerCustomFunctions(state, options.customFunctions);
|
|
422
436
|
}
|
|
423
437
|
let playwrightHandler;
|
|
438
|
+
const browserConsoleLogs = [];
|
|
439
|
+
const networkRequests = [];
|
|
440
|
+
const networkResponses = [];
|
|
441
|
+
const pageListenerCleanups = [];
|
|
424
442
|
if (options.playwright) {
|
|
425
443
|
playwrightHandler = import_client.createPlaywrightHandler(options.playwright.page, {
|
|
426
444
|
timeout: options.playwright.timeout,
|
|
@@ -432,65 +450,67 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
432
450
|
const result2 = await playwrightHandler(op);
|
|
433
451
|
return JSON.stringify(result2);
|
|
434
452
|
});
|
|
435
|
-
const
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
453
|
+
const page = options.playwright.page;
|
|
454
|
+
const onConsole = (msg) => {
|
|
455
|
+
const entry = {
|
|
456
|
+
level: msg.type(),
|
|
457
|
+
stdout: msg.text(),
|
|
458
|
+
timestamp: Date.now()
|
|
459
|
+
};
|
|
460
|
+
browserConsoleLogs.push(entry);
|
|
461
|
+
if (options.playwright.onEvent) {
|
|
462
|
+
options.playwright.onEvent({
|
|
463
|
+
type: "browserConsoleLog",
|
|
464
|
+
...entry
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
if (options.playwright.console && options.console?.onEntry) {
|
|
468
|
+
options.console.onEntry({
|
|
469
|
+
type: "browserOutput",
|
|
470
|
+
...entry
|
|
471
|
+
});
|
|
472
|
+
} else if (options.playwright.console) {
|
|
473
|
+
const prefix = entry.level === "error" ? "[browser:error]" : "[browser]";
|
|
474
|
+
console.log(prefix, entry.stdout);
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
const onRequest = (request2) => {
|
|
478
|
+
const info = {
|
|
479
|
+
url: request2.url(),
|
|
480
|
+
method: request2.method(),
|
|
481
|
+
headers: request2.headers(),
|
|
482
|
+
timestamp: Date.now()
|
|
483
|
+
};
|
|
484
|
+
networkRequests.push(info);
|
|
485
|
+
if (options.playwright.onEvent) {
|
|
463
486
|
options.playwright.onEvent({
|
|
464
487
|
type: "networkRequest",
|
|
465
|
-
|
|
466
|
-
method: reqInfo.method,
|
|
467
|
-
headers: reqInfo.headers,
|
|
468
|
-
postData: reqInfo.postData,
|
|
469
|
-
resourceType: reqInfo.resourceType,
|
|
470
|
-
timestamp: reqInfo.timestamp
|
|
488
|
+
...info
|
|
471
489
|
});
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
const onResponse = (response) => {
|
|
493
|
+
const info = {
|
|
494
|
+
url: response.url(),
|
|
495
|
+
status: response.status(),
|
|
496
|
+
headers: response.headers(),
|
|
497
|
+
timestamp: Date.now()
|
|
498
|
+
};
|
|
499
|
+
networkResponses.push(info);
|
|
500
|
+
if (options.playwright.onEvent) {
|
|
478
501
|
options.playwright.onEvent({
|
|
479
502
|
type: "networkResponse",
|
|
480
|
-
|
|
481
|
-
status: resInfo.status,
|
|
482
|
-
statusText: resInfo.statusText,
|
|
483
|
-
headers: resInfo.headers,
|
|
484
|
-
timestamp: resInfo.timestamp
|
|
503
|
+
...info
|
|
485
504
|
});
|
|
486
|
-
}
|
|
487
|
-
}
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
page.on("console", onConsole);
|
|
508
|
+
page.on("request", onRequest);
|
|
509
|
+
page.on("response", onResponse);
|
|
510
|
+
pageListenerCleanups.push(() => page.removeListener("console", onConsole), () => page.removeListener("request", onRequest), () => page.removeListener("response", onResponse));
|
|
488
511
|
callbacks.playwright = {
|
|
489
512
|
handlerCallbackId,
|
|
490
|
-
console: options.playwright.console && !options.console?.onEntry
|
|
491
|
-
onBrowserConsoleLogCallbackId: browserConsoleLogCallbackId,
|
|
492
|
-
onNetworkRequestCallbackId: networkRequestCallbackId,
|
|
493
|
-
onNetworkResponseCallbackId: networkResponseCallbackId
|
|
513
|
+
console: options.playwright.console && !options.console?.onEntry
|
|
494
514
|
};
|
|
495
515
|
}
|
|
496
516
|
let testEnvironmentOption;
|
|
@@ -748,29 +768,23 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
748
768
|
}
|
|
749
769
|
};
|
|
750
770
|
const playwrightHandle = {
|
|
751
|
-
|
|
771
|
+
getCollectedData() {
|
|
752
772
|
if (!playwrightEnabled) {
|
|
753
773
|
throw new Error("Playwright not configured. Provide playwright.page in createRuntime options.");
|
|
754
774
|
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
isolateId
|
|
775
|
+
return {
|
|
776
|
+
browserConsoleLogs: [...browserConsoleLogs],
|
|
777
|
+
networkRequests: [...networkRequests],
|
|
778
|
+
networkResponses: [...networkResponses]
|
|
760
779
|
};
|
|
761
|
-
return sendRequest(state, req);
|
|
762
780
|
},
|
|
763
|
-
|
|
781
|
+
clearCollectedData() {
|
|
764
782
|
if (!playwrightEnabled) {
|
|
765
783
|
throw new Error("Playwright not configured. Provide playwright.page in createRuntime options.");
|
|
766
784
|
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
requestId: reqId,
|
|
771
|
-
isolateId
|
|
772
|
-
};
|
|
773
|
-
await sendRequest(state, req);
|
|
785
|
+
browserConsoleLogs.length = 0;
|
|
786
|
+
networkRequests.length = 0;
|
|
787
|
+
networkResponses.length = 0;
|
|
774
788
|
}
|
|
775
789
|
};
|
|
776
790
|
return {
|
|
@@ -797,6 +811,9 @@ async function createRuntime(state, options = {}, namespaceId) {
|
|
|
797
811
|
await sendRequest(state, req);
|
|
798
812
|
},
|
|
799
813
|
dispose: async () => {
|
|
814
|
+
for (const cleanup of pageListenerCleanups) {
|
|
815
|
+
cleanup();
|
|
816
|
+
}
|
|
800
817
|
isolateWsCallbacks.delete(isolateId);
|
|
801
818
|
const reqId = state.nextRequestId++;
|
|
802
819
|
const req = {
|
|
@@ -899,15 +916,15 @@ function registerFsCallbacks(state, callbacks) {
|
|
|
899
916
|
const registrations = {};
|
|
900
917
|
if (callbacks.readFile) {
|
|
901
918
|
const callbackId = state.nextCallbackId++;
|
|
902
|
-
state.callbacks.set(callbackId, async (
|
|
903
|
-
const result = await callbacks.readFile(
|
|
919
|
+
state.callbacks.set(callbackId, async (path2) => {
|
|
920
|
+
const result = await callbacks.readFile(path2);
|
|
904
921
|
return new Uint8Array(result);
|
|
905
922
|
});
|
|
906
923
|
registrations.readFile = { callbackId, name: "readFile", type: "async" };
|
|
907
924
|
}
|
|
908
925
|
if (callbacks.writeFile) {
|
|
909
926
|
const callbackId = state.nextCallbackId++;
|
|
910
|
-
state.callbacks.set(callbackId, async (
|
|
927
|
+
state.callbacks.set(callbackId, async (path2, data) => {
|
|
911
928
|
let buffer;
|
|
912
929
|
if (data instanceof Uint8Array) {
|
|
913
930
|
buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
|
@@ -918,42 +935,42 @@ function registerFsCallbacks(state, callbacks) {
|
|
|
918
935
|
} else {
|
|
919
936
|
buffer = new ArrayBuffer(0);
|
|
920
937
|
}
|
|
921
|
-
await callbacks.writeFile(
|
|
938
|
+
await callbacks.writeFile(path2, buffer);
|
|
922
939
|
});
|
|
923
940
|
registrations.writeFile = { callbackId, name: "writeFile", type: "async" };
|
|
924
941
|
}
|
|
925
942
|
if (callbacks.unlink) {
|
|
926
943
|
const callbackId = state.nextCallbackId++;
|
|
927
|
-
state.callbacks.set(callbackId, async (
|
|
928
|
-
await callbacks.unlink(
|
|
944
|
+
state.callbacks.set(callbackId, async (path2) => {
|
|
945
|
+
await callbacks.unlink(path2);
|
|
929
946
|
});
|
|
930
947
|
registrations.unlink = { callbackId, name: "unlink", type: "async" };
|
|
931
948
|
}
|
|
932
949
|
if (callbacks.readdir) {
|
|
933
950
|
const callbackId = state.nextCallbackId++;
|
|
934
|
-
state.callbacks.set(callbackId, async (
|
|
935
|
-
return callbacks.readdir(
|
|
951
|
+
state.callbacks.set(callbackId, async (path2) => {
|
|
952
|
+
return callbacks.readdir(path2);
|
|
936
953
|
});
|
|
937
954
|
registrations.readdir = { callbackId, name: "readdir", type: "async" };
|
|
938
955
|
}
|
|
939
956
|
if (callbacks.mkdir) {
|
|
940
957
|
const callbackId = state.nextCallbackId++;
|
|
941
|
-
state.callbacks.set(callbackId, async (
|
|
942
|
-
await callbacks.mkdir(
|
|
958
|
+
state.callbacks.set(callbackId, async (path2, options) => {
|
|
959
|
+
await callbacks.mkdir(path2, options);
|
|
943
960
|
});
|
|
944
961
|
registrations.mkdir = { callbackId, name: "mkdir", type: "async" };
|
|
945
962
|
}
|
|
946
963
|
if (callbacks.rmdir) {
|
|
947
964
|
const callbackId = state.nextCallbackId++;
|
|
948
|
-
state.callbacks.set(callbackId, async (
|
|
949
|
-
await callbacks.rmdir(
|
|
965
|
+
state.callbacks.set(callbackId, async (path2) => {
|
|
966
|
+
await callbacks.rmdir(path2);
|
|
950
967
|
});
|
|
951
968
|
registrations.rmdir = { callbackId, name: "rmdir", type: "async" };
|
|
952
969
|
}
|
|
953
970
|
if (callbacks.stat) {
|
|
954
971
|
const callbackId = state.nextCallbackId++;
|
|
955
|
-
state.callbacks.set(callbackId, async (
|
|
956
|
-
return callbacks.stat(
|
|
972
|
+
state.callbacks.set(callbackId, async (path2) => {
|
|
973
|
+
return callbacks.stat(path2);
|
|
957
974
|
});
|
|
958
975
|
registrations.stat = { callbackId, name: "stat", type: "async" };
|
|
959
976
|
}
|
|
@@ -968,15 +985,13 @@ function registerFsCallbacks(state, callbacks) {
|
|
|
968
985
|
}
|
|
969
986
|
function registerModuleLoaderCallback(state, callback) {
|
|
970
987
|
const callbackId = state.nextCallbackId++;
|
|
971
|
-
state.callbacks.set(callbackId, async (moduleName) => {
|
|
988
|
+
state.callbacks.set(callbackId, async (moduleName, importer) => {
|
|
972
989
|
const specifier = moduleName;
|
|
973
|
-
const
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
state.moduleSourceCache.set(specifier, source);
|
|
979
|
-
return source;
|
|
990
|
+
const importerInfo = importer;
|
|
991
|
+
const result = await callback(specifier, importerInfo);
|
|
992
|
+
const resolvedPath = import_node_path.default.posix.join(result.resolveDir, import_node_path.default.posix.basename(specifier));
|
|
993
|
+
state.moduleSourceCache.set(resolvedPath, result.code);
|
|
994
|
+
return result;
|
|
980
995
|
});
|
|
981
996
|
return { callbackId, name: "moduleLoader", type: "async" };
|
|
982
997
|
}
|
|
@@ -1302,4 +1317,4 @@ async function sendBodyStream(state, streamId, body) {
|
|
|
1302
1317
|
}
|
|
1303
1318
|
}
|
|
1304
1319
|
|
|
1305
|
-
//# debugId=
|
|
1320
|
+
//# debugId=F22B720CD1D2496764756E2164756E21
|