@volter/tabnode 0.5.5 → 0.5.6
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.
|
@@ -74067,7 +74067,7 @@ function transformDynamicImportsRegex(code2) {
|
|
|
74067
74067
|
return code2.replace(new RegExp("(?<![.$\\w#])import\\s*\\(", "g"), "__dynamicImport(");
|
|
74068
74068
|
}
|
|
74069
74069
|
function __substrateRewriteDynamicImportsInScript(code2) {
|
|
74070
|
-
if (!new RegExp("(?<![.$\\w#])import\\s*\\(").test(code2)) return code2;
|
|
74070
|
+
if (!new RegExp("(?<![.$\\w#])(?:import|eval)\\s*\\(").test(code2)) return code2;
|
|
74071
74071
|
let ast;
|
|
74072
74072
|
try {
|
|
74073
74073
|
ast = parse3(code2, { ecmaVersion: "latest", sourceType: "script", allowReturnOutsideFunction: true, allowHashBang: true, allowAwaitOutsideFunction: true });
|
|
@@ -74076,14 +74076,30 @@ function __substrateRewriteDynamicImportsInScript(code2) {
|
|
|
74076
74076
|
}
|
|
74077
74077
|
const replacements = [];
|
|
74078
74078
|
walkAst(ast, (node) => {
|
|
74079
|
-
if (node.type === "ImportExpression") replacements.push([node.start, node.start + 6]);
|
|
74079
|
+
if (node.type === "ImportExpression") replacements.push([node.start, node.start + 6, "__dynamicImport"]);
|
|
74080
|
+
collectDirectEval(node, replacements);
|
|
74080
74081
|
});
|
|
74081
74082
|
if (replacements.length === 0) return code2;
|
|
74082
|
-
|
|
74083
|
+
return applyReplacements(code2, replacements);
|
|
74084
|
+
}
|
|
74085
|
+
function collectDirectEval(node, replacements) {
|
|
74086
|
+
var _a3, _b3;
|
|
74087
|
+
if (node.type !== "CallExpression" || node.optional || ((_a3 = node.callee) == null ? void 0 : _a3.type) !== "Identifier" || node.callee.name !== "eval") return;
|
|
74088
|
+
const source = (_b3 = node.arguments) == null ? void 0 : _b3[0];
|
|
74089
|
+
if (!source || source.type === "SpreadElement") return;
|
|
74090
|
+
replacements.push([source.start, source.start, "__substrateEvalSource("]);
|
|
74091
|
+
replacements.push([source.end, source.end, ")"]);
|
|
74092
|
+
}
|
|
74093
|
+
function applyReplacements(code2, replacements) {
|
|
74094
|
+
replacements.sort((a, b) => b[0] - a[0] || b[1] - a[1]);
|
|
74083
74095
|
let out = code2;
|
|
74084
|
-
for (const [start, end] of replacements) out = out.slice(0, start) +
|
|
74096
|
+
for (const [start, end, text] of replacements) out = out.slice(0, start) + text + out.slice(end);
|
|
74085
74097
|
return out;
|
|
74086
74098
|
}
|
|
74099
|
+
Object.defineProperty(globalThis, "__substrateEvalSource", {
|
|
74100
|
+
configurable: true,
|
|
74101
|
+
value: (source) => typeof source === "string" ? __substrateRewriteDynamicImportsInScript(source) : source
|
|
74102
|
+
});
|
|
74087
74103
|
function transformEsmToCjs(code2, filename) {
|
|
74088
74104
|
const maybeEsm = __substrateHasEsmSyntax(code2);
|
|
74089
74105
|
if (!maybeEsm) return __substrateRewriteDynamicImportsInScript(code2);
|
|
@@ -74107,17 +74123,14 @@ function transformEsmToCjsAst(code2, filename) {
|
|
|
74107
74123
|
if (node.type === "ImportExpression") {
|
|
74108
74124
|
deepReplacements.push([node.start, node.start + 6, "__dynamicImport"]);
|
|
74109
74125
|
}
|
|
74126
|
+
collectDirectEval(node, deepReplacements);
|
|
74110
74127
|
});
|
|
74111
74128
|
const hasImportDecl = ast.body.some((n8) => n8.type === "ImportDeclaration");
|
|
74112
74129
|
const hasExportDecl = ast.body.some((n8) => {
|
|
74113
74130
|
var _a3;
|
|
74114
74131
|
return (_a3 = n8.type) == null ? void 0 : _a3.startsWith("Export");
|
|
74115
74132
|
});
|
|
74116
|
-
let transformed = code2;
|
|
74117
|
-
deepReplacements.sort((a, b) => b[0] - a[0]);
|
|
74118
|
-
for (const [start, end, replacement] of deepReplacements) {
|
|
74119
|
-
transformed = transformed.slice(0, start) + replacement + transformed.slice(end);
|
|
74120
|
-
}
|
|
74133
|
+
let transformed = applyReplacements(code2, deepReplacements);
|
|
74121
74134
|
if (hasImportDecl || hasExportDecl) {
|
|
74122
74135
|
transformed = transformEsmToCjsSimple(transformed);
|
|
74123
74136
|
if (hasExportDecl) {
|
package/dist/index.mjs
CHANGED
|
@@ -33760,7 +33760,7 @@ function transformDynamicImportsRegex(code2) {
|
|
|
33760
33760
|
return code2.replace(new RegExp("(?<![.$\\w#])import\\s*\\(", "g"), "__dynamicImport(");
|
|
33761
33761
|
}
|
|
33762
33762
|
function __substrateRewriteDynamicImportsInScript(code2) {
|
|
33763
|
-
if (!new RegExp("(?<![.$\\w#])import\\s*\\(").test(code2)) return code2;
|
|
33763
|
+
if (!new RegExp("(?<![.$\\w#])(?:import|eval)\\s*\\(").test(code2)) return code2;
|
|
33764
33764
|
let ast;
|
|
33765
33765
|
try {
|
|
33766
33766
|
ast = parse3(code2, { ecmaVersion: "latest", sourceType: "script", allowReturnOutsideFunction: true, allowHashBang: true, allowAwaitOutsideFunction: true });
|
|
@@ -33769,14 +33769,30 @@ function __substrateRewriteDynamicImportsInScript(code2) {
|
|
|
33769
33769
|
}
|
|
33770
33770
|
const replacements = [];
|
|
33771
33771
|
walkAst(ast, (node) => {
|
|
33772
|
-
if (node.type === "ImportExpression") replacements.push([node.start, node.start + 6]);
|
|
33772
|
+
if (node.type === "ImportExpression") replacements.push([node.start, node.start + 6, "__dynamicImport"]);
|
|
33773
|
+
collectDirectEval(node, replacements);
|
|
33773
33774
|
});
|
|
33774
33775
|
if (replacements.length === 0) return code2;
|
|
33775
|
-
|
|
33776
|
+
return applyReplacements(code2, replacements);
|
|
33777
|
+
}
|
|
33778
|
+
function collectDirectEval(node, replacements) {
|
|
33779
|
+
var _a2, _b2;
|
|
33780
|
+
if (node.type !== "CallExpression" || node.optional || ((_a2 = node.callee) == null ? void 0 : _a2.type) !== "Identifier" || node.callee.name !== "eval") return;
|
|
33781
|
+
const source = (_b2 = node.arguments) == null ? void 0 : _b2[0];
|
|
33782
|
+
if (!source || source.type === "SpreadElement") return;
|
|
33783
|
+
replacements.push([source.start, source.start, "__substrateEvalSource("]);
|
|
33784
|
+
replacements.push([source.end, source.end, ")"]);
|
|
33785
|
+
}
|
|
33786
|
+
function applyReplacements(code2, replacements) {
|
|
33787
|
+
replacements.sort((a, b) => b[0] - a[0] || b[1] - a[1]);
|
|
33776
33788
|
let out = code2;
|
|
33777
|
-
for (const [start, end] of replacements) out = out.slice(0, start) +
|
|
33789
|
+
for (const [start, end, text] of replacements) out = out.slice(0, start) + text + out.slice(end);
|
|
33778
33790
|
return out;
|
|
33779
33791
|
}
|
|
33792
|
+
Object.defineProperty(globalThis, "__substrateEvalSource", {
|
|
33793
|
+
configurable: true,
|
|
33794
|
+
value: (source) => typeof source === "string" ? __substrateRewriteDynamicImportsInScript(source) : source
|
|
33795
|
+
});
|
|
33780
33796
|
function transformEsmToCjs(code2, filename) {
|
|
33781
33797
|
const maybeEsm = __substrateHasEsmSyntax(code2);
|
|
33782
33798
|
if (!maybeEsm) return __substrateRewriteDynamicImportsInScript(code2);
|
|
@@ -33800,17 +33816,14 @@ function transformEsmToCjsAst(code2, filename) {
|
|
|
33800
33816
|
if (node.type === "ImportExpression") {
|
|
33801
33817
|
deepReplacements.push([node.start, node.start + 6, "__dynamicImport"]);
|
|
33802
33818
|
}
|
|
33819
|
+
collectDirectEval(node, deepReplacements);
|
|
33803
33820
|
});
|
|
33804
33821
|
const hasImportDecl = ast.body.some((n) => n.type === "ImportDeclaration");
|
|
33805
33822
|
const hasExportDecl = ast.body.some((n) => {
|
|
33806
33823
|
var _a2;
|
|
33807
33824
|
return (_a2 = n.type) == null ? void 0 : _a2.startsWith("Export");
|
|
33808
33825
|
});
|
|
33809
|
-
let transformed = code2;
|
|
33810
|
-
deepReplacements.sort((a, b) => b[0] - a[0]);
|
|
33811
|
-
for (const [start, end, replacement] of deepReplacements) {
|
|
33812
|
-
transformed = transformed.slice(0, start) + replacement + transformed.slice(end);
|
|
33813
|
-
}
|
|
33826
|
+
let transformed = applyReplacements(code2, deepReplacements);
|
|
33814
33827
|
if (hasImportDecl || hasExportDecl) {
|
|
33815
33828
|
transformed = transformEsmToCjsSimple(transformed);
|
|
33816
33829
|
if (hasExportDecl) {
|
|
@@ -35655,7 +35668,7 @@ class WorkerRuntime {
|
|
|
35655
35668
|
this.worker = new Worker(
|
|
35656
35669
|
new URL(
|
|
35657
35670
|
/* @vite-ignore */
|
|
35658
|
-
"/assets/runtime-worker-
|
|
35671
|
+
"/assets/runtime-worker-Bt4uLPDa.js",
|
|
35659
35672
|
import.meta.url
|
|
35660
35673
|
),
|
|
35661
35674
|
{ type: "module" }
|
|
@@ -38023,7 +38036,11 @@ function resetServerBridge() {
|
|
|
38023
38036
|
}
|
|
38024
38037
|
const scopes = /* @__PURE__ */ new WeakMap();
|
|
38025
38038
|
class NativeStreamScope {
|
|
38026
|
-
|
|
38039
|
+
/**
|
|
38040
|
+
* `ownerPid` names the process whose worker this scope serves: a listener
|
|
38041
|
+
* it opens is that process's socket, as the container's /proc shows it.
|
|
38042
|
+
*/
|
|
38043
|
+
constructor(limits, emit2, ownerPid) {
|
|
38027
38044
|
__publicField(this, "entries", /* @__PURE__ */ new Map());
|
|
38028
38045
|
__publicField(this, "descriptors", /* @__PURE__ */ new Map());
|
|
38029
38046
|
__publicField(this, "writes", /* @__PURE__ */ new Map());
|
|
@@ -38033,6 +38050,7 @@ class NativeStreamScope {
|
|
|
38033
38050
|
__publicField(this, "disposed", false);
|
|
38034
38051
|
__publicField(this, "limits");
|
|
38035
38052
|
this.emit = emit2;
|
|
38053
|
+
this.ownerPid = ownerPid;
|
|
38036
38054
|
if ([limits.maxHandles, limits.maxReadChunkBytes, limits.maxQueuedBytes, limits.maxQueuedHandles, limits.maxPendingWriteBytes].some((value) => !Number.isSafeInteger(value) || value < 1) || limits.maxReadChunkBytes > 2147483647 || limits.maxReadChunkBytes > limits.maxQueuedBytes || limits.maxReadChunkBytes > limits.maxPendingWriteBytes) throw new Error("Invalid native stream resource limits.");
|
|
38037
38055
|
this.limits = Object.freeze({ ...limits });
|
|
38038
38056
|
}
|
|
@@ -38317,6 +38335,10 @@ class NativeStreamScope {
|
|
|
38317
38335
|
if (failures.length) throw new AggregateError(failures, "Native stream scope cleanup failed.");
|
|
38318
38336
|
}
|
|
38319
38337
|
}
|
|
38338
|
+
function nativeStreamOwnerPid(handle) {
|
|
38339
|
+
var _a2, _b2;
|
|
38340
|
+
return (_b2 = (_a2 = scopes.get(handle)) == null ? void 0 : _a2.ownerPid) == null ? void 0 : _b2.call(_a2);
|
|
38341
|
+
}
|
|
38320
38342
|
let __nextRunName = 1;
|
|
38321
38343
|
function createContainer(options) {
|
|
38322
38344
|
const vfs2 = options && options.vfs || new VirtualFS();
|
|
@@ -38374,7 +38396,8 @@ function createContainer(options) {
|
|
|
38374
38396
|
portPid: (port) => {
|
|
38375
38397
|
var _a2;
|
|
38376
38398
|
const listener = listenerOnPort(port);
|
|
38377
|
-
|
|
38399
|
+
if (!listener) return void 0;
|
|
38400
|
+
return ((_a2 = runPid(ownerOf(listener))) == null ? void 0 : _a2.pid) ?? nativeStreamOwnerPid(listener);
|
|
38378
38401
|
},
|
|
38379
38402
|
/**
|
|
38380
38403
|
* Deliver a signal to the named run as another process's `kill(pid)` does:
|
|
@@ -94,6 +94,7 @@ export interface NativeStreamTransport {
|
|
|
94
94
|
*/
|
|
95
95
|
export declare class NativeStreamScope {
|
|
96
96
|
private readonly emit;
|
|
97
|
+
readonly ownerPid?: (() => number | undefined) | undefined;
|
|
97
98
|
private readonly entries;
|
|
98
99
|
private readonly descriptors;
|
|
99
100
|
private readonly writes;
|
|
@@ -102,7 +103,11 @@ export declare class NativeStreamScope {
|
|
|
102
103
|
private pendingWriteBytes;
|
|
103
104
|
private disposed;
|
|
104
105
|
private readonly limits;
|
|
105
|
-
|
|
106
|
+
/**
|
|
107
|
+
* `ownerPid` names the process whose worker this scope serves: a listener
|
|
108
|
+
* it opens is that process's socket, as the container's /proc shows it.
|
|
109
|
+
*/
|
|
110
|
+
constructor(limits: NativeStreamLimits, emit: (event: NativeStreamEvent) => void, ownerPid?: (() => number | undefined) | undefined);
|
|
106
111
|
private entry;
|
|
107
112
|
private publish;
|
|
108
113
|
private claim;
|
|
@@ -119,3 +124,5 @@ export declare class NativeStreamScope {
|
|
|
119
124
|
private close;
|
|
120
125
|
dispose(): void;
|
|
121
126
|
}
|
|
127
|
+
/** The process a handle opened for another worker's process belongs to, where a scope holds it. */
|
|
128
|
+
export declare function nativeStreamOwnerPid(handle: object): number | undefined;
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -56,6 +56,7 @@ import { runCommand, registerRunStreams, releaseRunStreams, sendStdin } from './
|
|
|
56
56
|
import { Server as NetServer, __releaseOwnedHandles, type Socket as NetSocket } from './node-lib/net-module';
|
|
57
57
|
import { __adoptHandle, ownerOf, type OwnedHandle } from './node-lib/binding/handles';
|
|
58
58
|
import { listenerOnPort } from './node-lib/binding/tcp_wrap';
|
|
59
|
+
import { nativeStreamOwnerPid } from './native-stream-owner';
|
|
59
60
|
|
|
60
61
|
import { __currentProcessToken, __runFor, __signalOwnedProcess, __stopOwnedProcess, runPid, processByPid } from './process-tokens';
|
|
61
62
|
export { runPid, processByPid };
|
|
@@ -215,7 +216,9 @@ export function createContainer(options?: ContainerOptions): {
|
|
|
215
216
|
processPorts: (token: string): number[] => __ownedServerPorts(token),
|
|
216
217
|
portPid: (port: number): number | undefined => {
|
|
217
218
|
const listener = listenerOnPort(port);
|
|
218
|
-
|
|
219
|
+
if (!listener) return undefined;
|
|
220
|
+
// a guest's own listener, or one this engine holds for another worker's process
|
|
221
|
+
return runPid(ownerOf(listener as unknown as OwnedHandle))?.pid ?? nativeStreamOwnerPid(listener);
|
|
219
222
|
},
|
|
220
223
|
/**
|
|
221
224
|
* Deliver a signal to the named run as another process's `kill(pid)` does:
|
|
@@ -56,7 +56,11 @@ export class NativeStreamScope {
|
|
|
56
56
|
private disposed = false;
|
|
57
57
|
private readonly limits: Readonly<NativeStreamLimits>;
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
/**
|
|
60
|
+
* `ownerPid` names the process whose worker this scope serves: a listener
|
|
61
|
+
* it opens is that process's socket, as the container's /proc shows it.
|
|
62
|
+
*/
|
|
63
|
+
constructor(limits: NativeStreamLimits, private readonly emit: (event: NativeStreamEvent) => void, readonly ownerPid?: () => number | undefined) {
|
|
60
64
|
if ([limits.maxHandles, limits.maxReadChunkBytes, limits.maxQueuedBytes, limits.maxQueuedHandles, limits.maxPendingWriteBytes].some(value => !Number.isSafeInteger(value) || value < 1)
|
|
61
65
|
|| limits.maxReadChunkBytes > 0x7fffffff
|
|
62
66
|
|| limits.maxReadChunkBytes > limits.maxQueuedBytes
|
|
@@ -315,3 +319,8 @@ export class NativeStreamScope {
|
|
|
315
319
|
if (failures.length) throw new AggregateError(failures, 'Native stream scope cleanup failed.');
|
|
316
320
|
}
|
|
317
321
|
}
|
|
322
|
+
|
|
323
|
+
/** The process a handle opened for another worker's process belongs to, where a scope holds it. */
|
|
324
|
+
export function nativeStreamOwnerPid(handle: object): number | undefined {
|
|
325
|
+
return scopes.get(handle as NativeHandle)?.ownerPid?.();
|
|
326
|
+
}
|
package/src/runtime.ts
CHANGED
|
@@ -343,23 +343,49 @@ function transformDynamicImportsRegex(code: string): string {
|
|
|
343
343
|
* saw no import at all.
|
|
344
344
|
*/
|
|
345
345
|
function __substrateRewriteDynamicImportsInScript(code: string): string {
|
|
346
|
-
if (!/(?<![.$\w#])import\s*\(/.test(code)) return code;
|
|
346
|
+
if (!/(?<![.$\w#])(?:import|eval)\s*\(/.test(code)) return code;
|
|
347
347
|
let ast;
|
|
348
348
|
try {
|
|
349
349
|
ast = acorn.parse(code, { ecmaVersion: "latest", sourceType: "script", allowReturnOutsideFunction: true, allowHashBang: true, allowAwaitOutsideFunction: true });
|
|
350
350
|
} catch {
|
|
351
351
|
return code;
|
|
352
352
|
}
|
|
353
|
-
const replacements: Array<[number, number]> = [];
|
|
353
|
+
const replacements: Array<[number, number, string]> = [];
|
|
354
354
|
walkAst(ast, (node: any) => {
|
|
355
|
-
if (node.type === "ImportExpression") replacements.push([node.start, node.start + 6]);
|
|
355
|
+
if (node.type === "ImportExpression") replacements.push([node.start, node.start + 6, "__dynamicImport"]);
|
|
356
|
+
collectDirectEval(node, replacements);
|
|
356
357
|
});
|
|
357
358
|
if (replacements.length === 0) return code;
|
|
358
|
-
|
|
359
|
+
return applyReplacements(code, replacements);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* A direct `eval` runs source the module builds at run time, and Node runs an
|
|
364
|
+
* `import()` in it through the module's loader: Playwright loads an ES config
|
|
365
|
+
* with ``eval(`import(${url})`)``. The call stays a direct eval, so the
|
|
366
|
+
* source keeps the module's scope, `__dynamicImport` included; only the
|
|
367
|
+
* source it is given is rewritten the way the module's own was.
|
|
368
|
+
*/
|
|
369
|
+
function collectDirectEval(node: any, replacements: Array<[number, number, string]>): void {
|
|
370
|
+
if (node.type !== "CallExpression" || node.optional || node.callee?.type !== "Identifier" || node.callee.name !== "eval") return;
|
|
371
|
+
const source = node.arguments?.[0];
|
|
372
|
+
if (!source || source.type === "SpreadElement") return;
|
|
373
|
+
replacements.push([source.start, source.start, "__substrateEvalSource("]);
|
|
374
|
+
replacements.push([source.end, source.end, ")"]);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/** Applies insertions and replacements from the end, so earlier offsets hold. */
|
|
378
|
+
function applyReplacements(code: string, replacements: Array<[number, number, string]>): string {
|
|
379
|
+
replacements.sort((a, b) => b[0] - a[0] || b[1] - a[1]);
|
|
359
380
|
let out = code;
|
|
360
|
-
for (const [start, end] of replacements) out = out.slice(0, start) +
|
|
381
|
+
for (const [start, end, text] of replacements) out = out.slice(0, start) + text + out.slice(end);
|
|
361
382
|
return out;
|
|
362
383
|
}
|
|
384
|
+
|
|
385
|
+
Object.defineProperty(globalThis, "__substrateEvalSource", {
|
|
386
|
+
configurable: true,
|
|
387
|
+
value: (source: unknown): unknown => typeof source === "string" ? __substrateRewriteDynamicImportsInScript(source) : source,
|
|
388
|
+
});
|
|
363
389
|
function transformEsmToCjs(code: string, filename: string): string {
|
|
364
390
|
// Quick check: does the code have any ESM-like patterns?
|
|
365
391
|
const maybeEsm = __substrateHasEsmSyntax(code);
|
|
@@ -401,6 +427,7 @@ function transformEsmToCjsAst(code: string, filename: string): string {
|
|
|
401
427
|
// Replace just the 'import' keyword, preserving the (...) part
|
|
402
428
|
deepReplacements.push([node.start, node.start + 6, '__dynamicImport']);
|
|
403
429
|
}
|
|
430
|
+
collectDirectEval(node, deepReplacements);
|
|
404
431
|
});
|
|
405
432
|
|
|
406
433
|
// Check for actual import/export declarations
|
|
@@ -408,11 +435,7 @@ function transformEsmToCjsAst(code: string, filename: string): string {
|
|
|
408
435
|
const hasExportDecl = ast.body.some((n: any) => n.type?.startsWith('Export'));
|
|
409
436
|
|
|
410
437
|
// Apply deep replacements from end to start (preserves earlier positions)
|
|
411
|
-
let transformed = code;
|
|
412
|
-
deepReplacements.sort((a, b) => b[0] - a[0]);
|
|
413
|
-
for (const [start, end, replacement] of deepReplacements) {
|
|
414
|
-
transformed = transformed.slice(0, start) + replacement + transformed.slice(end);
|
|
415
|
-
}
|
|
438
|
+
let transformed = applyReplacements(code, deepReplacements);
|
|
416
439
|
|
|
417
440
|
// Transform import/export declarations (re-parses the modified code)
|
|
418
441
|
if (hasImportDecl || hasExportDecl) {
|