@scelar/nodepod 1.0.0
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/LICENSE +43 -0
- package/README.md +240 -0
- package/dist/child_process-BJOMsZje.js +8233 -0
- package/dist/child_process-BJOMsZje.js.map +1 -0
- package/dist/child_process-Cj8vOcuc.cjs +7434 -0
- package/dist/child_process-Cj8vOcuc.cjs.map +1 -0
- package/dist/index-Cb1Cgdnd.js +35308 -0
- package/dist/index-Cb1Cgdnd.js.map +1 -0
- package/dist/index-DsMGS-xc.cjs +37195 -0
- package/dist/index-DsMGS-xc.cjs.map +1 -0
- package/dist/index.cjs +65 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +59 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +95 -0
- package/src/__tests__/smoke.test.ts +11 -0
- package/src/constants/cdn-urls.ts +18 -0
- package/src/constants/config.ts +236 -0
- package/src/cross-origin.ts +26 -0
- package/src/engine-factory.ts +176 -0
- package/src/engine-types.ts +56 -0
- package/src/helpers/byte-encoding.ts +39 -0
- package/src/helpers/digest.ts +9 -0
- package/src/helpers/event-loop.ts +96 -0
- package/src/helpers/wasm-cache.ts +133 -0
- package/src/iframe-sandbox.ts +141 -0
- package/src/index.ts +192 -0
- package/src/isolation-helpers.ts +148 -0
- package/src/memory-volume.ts +941 -0
- package/src/module-transformer.ts +368 -0
- package/src/packages/archive-extractor.ts +248 -0
- package/src/packages/browser-bundler.ts +284 -0
- package/src/packages/installer.ts +396 -0
- package/src/packages/registry-client.ts +131 -0
- package/src/packages/version-resolver.ts +411 -0
- package/src/polyfills/assert.ts +384 -0
- package/src/polyfills/async_hooks.ts +144 -0
- package/src/polyfills/buffer.ts +628 -0
- package/src/polyfills/child_process.ts +2288 -0
- package/src/polyfills/chokidar.ts +336 -0
- package/src/polyfills/cluster.ts +106 -0
- package/src/polyfills/console.ts +136 -0
- package/src/polyfills/constants.ts +123 -0
- package/src/polyfills/crypto.ts +885 -0
- package/src/polyfills/dgram.ts +87 -0
- package/src/polyfills/diagnostics_channel.ts +76 -0
- package/src/polyfills/dns.ts +134 -0
- package/src/polyfills/domain.ts +68 -0
- package/src/polyfills/esbuild.ts +854 -0
- package/src/polyfills/events.ts +276 -0
- package/src/polyfills/fs.ts +2888 -0
- package/src/polyfills/fsevents.ts +79 -0
- package/src/polyfills/http.ts +1449 -0
- package/src/polyfills/http2.ts +199 -0
- package/src/polyfills/https.ts +76 -0
- package/src/polyfills/inspector.ts +62 -0
- package/src/polyfills/lightningcss.ts +105 -0
- package/src/polyfills/module.ts +191 -0
- package/src/polyfills/net.ts +353 -0
- package/src/polyfills/os.ts +238 -0
- package/src/polyfills/path.ts +206 -0
- package/src/polyfills/perf_hooks.ts +102 -0
- package/src/polyfills/process.ts +690 -0
- package/src/polyfills/punycode.ts +159 -0
- package/src/polyfills/querystring.ts +93 -0
- package/src/polyfills/quic.ts +118 -0
- package/src/polyfills/readdirp.ts +229 -0
- package/src/polyfills/readline.ts +692 -0
- package/src/polyfills/repl.ts +134 -0
- package/src/polyfills/rollup.ts +119 -0
- package/src/polyfills/sea.ts +33 -0
- package/src/polyfills/sqlite.ts +78 -0
- package/src/polyfills/stream.ts +1620 -0
- package/src/polyfills/string_decoder.ts +25 -0
- package/src/polyfills/tailwindcss-oxide.ts +309 -0
- package/src/polyfills/test.ts +197 -0
- package/src/polyfills/timers.ts +32 -0
- package/src/polyfills/tls.ts +105 -0
- package/src/polyfills/trace_events.ts +50 -0
- package/src/polyfills/tty.ts +71 -0
- package/src/polyfills/url.ts +174 -0
- package/src/polyfills/util.ts +559 -0
- package/src/polyfills/v8.ts +126 -0
- package/src/polyfills/vm.ts +132 -0
- package/src/polyfills/volume-registry.ts +15 -0
- package/src/polyfills/wasi.ts +44 -0
- package/src/polyfills/worker_threads.ts +326 -0
- package/src/polyfills/ws.ts +595 -0
- package/src/polyfills/zlib.ts +881 -0
- package/src/request-proxy.ts +716 -0
- package/src/script-engine.ts +3375 -0
- package/src/sdk/nodepod-fs.ts +93 -0
- package/src/sdk/nodepod-process.ts +86 -0
- package/src/sdk/nodepod-terminal.ts +350 -0
- package/src/sdk/nodepod.ts +509 -0
- package/src/sdk/types.ts +70 -0
- package/src/shell/commands/bun.ts +121 -0
- package/src/shell/commands/directory.ts +297 -0
- package/src/shell/commands/file-ops.ts +525 -0
- package/src/shell/commands/git.ts +2142 -0
- package/src/shell/commands/node.ts +80 -0
- package/src/shell/commands/npm.ts +198 -0
- package/src/shell/commands/pm-types.ts +45 -0
- package/src/shell/commands/pnpm.ts +82 -0
- package/src/shell/commands/search.ts +264 -0
- package/src/shell/commands/shell-env.ts +352 -0
- package/src/shell/commands/text-processing.ts +1152 -0
- package/src/shell/commands/yarn.ts +84 -0
- package/src/shell/shell-builtins.ts +19 -0
- package/src/shell/shell-helpers.ts +250 -0
- package/src/shell/shell-interpreter.ts +514 -0
- package/src/shell/shell-parser.ts +429 -0
- package/src/shell/shell-types.ts +85 -0
- package/src/syntax-transforms.ts +561 -0
- package/src/threading/engine-worker.ts +64 -0
- package/src/threading/inline-worker.ts +372 -0
- package/src/threading/offload-types.ts +112 -0
- package/src/threading/offload-worker.ts +383 -0
- package/src/threading/offload.ts +271 -0
- package/src/threading/process-context.ts +92 -0
- package/src/threading/process-handle.ts +275 -0
- package/src/threading/process-manager.ts +956 -0
- package/src/threading/process-worker-entry.ts +854 -0
- package/src/threading/shared-vfs.ts +352 -0
- package/src/threading/sync-channel.ts +135 -0
- package/src/threading/task-queue.ts +177 -0
- package/src/threading/vfs-bridge.ts +231 -0
- package/src/threading/worker-pool.ts +233 -0
- package/src/threading/worker-protocol.ts +358 -0
- package/src/threading/worker-vfs.ts +218 -0
- package/src/types/externals.d.ts +38 -0
- package/src/types/fs-streams.ts +142 -0
- package/src/types/manifest.ts +17 -0
- package/src/worker-sandbox.ts +90 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// VM polyfill using eval/Function since no V8 isolate API in browser
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/* ------------------------------------------------------------------ */
|
|
5
|
+
/* Script */
|
|
6
|
+
/* ------------------------------------------------------------------ */
|
|
7
|
+
|
|
8
|
+
export interface Script {
|
|
9
|
+
runInThisContext(_opts?: object): unknown;
|
|
10
|
+
runInNewContext(ctx?: object, _opts?: object): unknown;
|
|
11
|
+
runInContext(ctx: object, _opts?: object): unknown;
|
|
12
|
+
createCachedData(): Uint8Array;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const Script = function Script(this: any, src: string, _opts?: object) {
|
|
16
|
+
if (!this) return;
|
|
17
|
+
this._src = src;
|
|
18
|
+
} as unknown as { new(src: string, _opts?: object): Script; prototype: any };
|
|
19
|
+
|
|
20
|
+
Script.prototype.runInThisContext = function runInThisContext(_opts?: object): unknown {
|
|
21
|
+
return (0, eval)(this._src);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
Script.prototype.runInNewContext = function runInNewContext(ctx?: object, _opts?: object): unknown {
|
|
25
|
+
const names = ctx ? Object.keys(ctx) : [];
|
|
26
|
+
const vals = ctx ? Object.values(ctx) : [];
|
|
27
|
+
const wrapper = new Function(...names, `return eval(${JSON.stringify(this._src)})`);
|
|
28
|
+
return wrapper(...vals);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
Script.prototype.runInContext = function runInContext(ctx: object, _opts?: object): unknown {
|
|
32
|
+
return this.runInNewContext(ctx, _opts);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
Script.prototype.createCachedData = function createCachedData(): Uint8Array {
|
|
36
|
+
return new Uint8Array(0);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/* ------------------------------------------------------------------ */
|
|
40
|
+
/* Standalone helpers */
|
|
41
|
+
/* ------------------------------------------------------------------ */
|
|
42
|
+
|
|
43
|
+
export function createContext(sandbox?: object, _opts?: object): object {
|
|
44
|
+
return sandbox ?? {};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function isContext(_box: object): boolean {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function runInThisContext(code: string, _opts?: object): unknown {
|
|
52
|
+
return (0, eval)(code);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function runInNewContext(code: string, ctx?: object, _opts?: object): unknown {
|
|
56
|
+
return new Script(code).runInNewContext(ctx);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function runInContext(code: string, ctx: object, _opts?: object): unknown {
|
|
60
|
+
return runInNewContext(code, ctx);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function compileFunction(
|
|
64
|
+
body: string,
|
|
65
|
+
params?: string[],
|
|
66
|
+
_opts?: object
|
|
67
|
+
): Function {
|
|
68
|
+
return new Function(...(params ?? []), body);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* ------------------------------------------------------------------ */
|
|
72
|
+
/* ESM Module stubs */
|
|
73
|
+
/* ------------------------------------------------------------------ */
|
|
74
|
+
|
|
75
|
+
export interface Module {
|
|
76
|
+
link(_linker: unknown): Promise<void>;
|
|
77
|
+
evaluate(_opts?: object): Promise<unknown>;
|
|
78
|
+
readonly status: string;
|
|
79
|
+
readonly identifier: string;
|
|
80
|
+
readonly context: object;
|
|
81
|
+
readonly namespace: object;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const Module = function Module(this: any, _code: string, _opts?: object) {
|
|
85
|
+
if (!this) return;
|
|
86
|
+
} as unknown as { new(_code: string, _opts?: object): Module; prototype: any };
|
|
87
|
+
|
|
88
|
+
Module.prototype.link = function link(_linker: unknown): Promise<void> { return Promise.resolve(); };
|
|
89
|
+
Module.prototype.evaluate = function evaluate(_opts?: object): Promise<unknown> { return Promise.resolve(); };
|
|
90
|
+
Object.defineProperty(Module.prototype, 'status', { get() { return 'unlinked'; }, configurable: true });
|
|
91
|
+
Object.defineProperty(Module.prototype, 'identifier', { get() { return ''; }, configurable: true });
|
|
92
|
+
Object.defineProperty(Module.prototype, 'context', { get() { return {}; }, configurable: true });
|
|
93
|
+
Object.defineProperty(Module.prototype, 'namespace', { get() { return {}; }, configurable: true });
|
|
94
|
+
|
|
95
|
+
export interface SourceTextModule extends Module {}
|
|
96
|
+
|
|
97
|
+
export const SourceTextModule = function SourceTextModule(this: any, _code: string, _opts?: object) {
|
|
98
|
+
if (!this) return;
|
|
99
|
+
(Module as any).call(this, _code, _opts);
|
|
100
|
+
} as unknown as { new(_code: string, _opts?: object): SourceTextModule; prototype: any };
|
|
101
|
+
|
|
102
|
+
Object.setPrototypeOf(SourceTextModule.prototype, Module.prototype);
|
|
103
|
+
|
|
104
|
+
export interface SyntheticModule extends Module {
|
|
105
|
+
setExport(_name: string, _value: unknown): void;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export const SyntheticModule = function SyntheticModule(this: any, _code: string, _opts?: object) {
|
|
109
|
+
if (!this) return;
|
|
110
|
+
(Module as any).call(this, _code, _opts);
|
|
111
|
+
} as unknown as { new(_code: string, _opts?: object): SyntheticModule; prototype: any };
|
|
112
|
+
|
|
113
|
+
Object.setPrototypeOf(SyntheticModule.prototype, Module.prototype);
|
|
114
|
+
|
|
115
|
+
SyntheticModule.prototype.setExport = function setExport(_name: string, _value: unknown): void {};
|
|
116
|
+
|
|
117
|
+
/* ------------------------------------------------------------------ */
|
|
118
|
+
/* Default export */
|
|
119
|
+
/* ------------------------------------------------------------------ */
|
|
120
|
+
|
|
121
|
+
export default {
|
|
122
|
+
Script,
|
|
123
|
+
createContext,
|
|
124
|
+
isContext,
|
|
125
|
+
runInThisContext,
|
|
126
|
+
runInNewContext,
|
|
127
|
+
runInContext,
|
|
128
|
+
compileFunction,
|
|
129
|
+
Module,
|
|
130
|
+
SourceTextModule,
|
|
131
|
+
SyntheticModule,
|
|
132
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Shared MemoryVolume reference for polyfills that need VFS access
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import type { MemoryVolume } from "../memory-volume";
|
|
5
|
+
|
|
6
|
+
let sharedVolume: MemoryVolume | null = null;
|
|
7
|
+
|
|
8
|
+
// must be called once during init before watchers/scanners are used
|
|
9
|
+
export function setSharedVolume(vol: MemoryVolume): void {
|
|
10
|
+
sharedVolume = vol;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getSharedVolume(): MemoryVolume | null {
|
|
14
|
+
return sharedVolume;
|
|
15
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// stub - not available in browser
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/* ------------------------------------------------------------------ */
|
|
5
|
+
/* WASI class */
|
|
6
|
+
/* ------------------------------------------------------------------ */
|
|
7
|
+
|
|
8
|
+
export interface WASI {
|
|
9
|
+
readonly wasiImport: Record<string, Function>;
|
|
10
|
+
start(_instance: object): number;
|
|
11
|
+
initialize(_instance: object): void;
|
|
12
|
+
getImportObject(): Record<string, Record<string, Function>>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface WASIConstructor {
|
|
16
|
+
new (_options?: object): WASI;
|
|
17
|
+
(this: any, _options?: object): void;
|
|
18
|
+
prototype: any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const WASI = function WASI(this: any, _options?: object) {
|
|
22
|
+
if (!this) return;
|
|
23
|
+
this.wasiImport = {};
|
|
24
|
+
} as unknown as WASIConstructor;
|
|
25
|
+
|
|
26
|
+
WASI.prototype.start = function start(_instance: object): number {
|
|
27
|
+
throw new Error("WASI is not supported in the browser environment");
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
WASI.prototype.initialize = function initialize(_instance: object): void {
|
|
31
|
+
throw new Error("WASI is not supported in the browser environment");
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
WASI.prototype.getImportObject = function getImportObject(this: any): Record<string, Record<string, Function>> {
|
|
35
|
+
return { wasi_snapshot_preview1: this.wasiImport };
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/* ------------------------------------------------------------------ */
|
|
39
|
+
/* Default export */
|
|
40
|
+
/* ------------------------------------------------------------------ */
|
|
41
|
+
|
|
42
|
+
export default {
|
|
43
|
+
WASI,
|
|
44
|
+
};
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
// worker_threads polyfill using fork infrastructure for real Web Workers
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import { EventEmitter } from "./events";
|
|
5
|
+
import { ref as eventLoopRef, unref as eventLoopUnref } from "../helpers/event-loop";
|
|
6
|
+
|
|
7
|
+
// shared defaults for main thread; child workers get per-engine overrides via buildResolver
|
|
8
|
+
export let isMainThread = true;
|
|
9
|
+
export let parentPort: MessagePort | null = null;
|
|
10
|
+
export let workerData: unknown = null;
|
|
11
|
+
export let threadId = 0;
|
|
12
|
+
|
|
13
|
+
// fork callback, set by process-worker-entry.ts
|
|
14
|
+
|
|
15
|
+
export type WorkerThreadForkFn = (
|
|
16
|
+
modulePath: string,
|
|
17
|
+
opts: {
|
|
18
|
+
workerData: unknown;
|
|
19
|
+
threadId: number;
|
|
20
|
+
isEval?: boolean;
|
|
21
|
+
cwd: string;
|
|
22
|
+
env: Record<string, string>;
|
|
23
|
+
onMessage: (data: unknown) => void;
|
|
24
|
+
onError: (err: Error) => void;
|
|
25
|
+
onExit: (code: number) => void;
|
|
26
|
+
onStdout?: (data: string) => void;
|
|
27
|
+
onStderr?: (data: string) => void;
|
|
28
|
+
},
|
|
29
|
+
) => {
|
|
30
|
+
postMessage: (data: unknown) => void;
|
|
31
|
+
terminate: () => void;
|
|
32
|
+
requestId: number;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
let _workerThreadForkFn: WorkerThreadForkFn | null = null;
|
|
36
|
+
|
|
37
|
+
export function setWorkerThreadForkCallback(fn: WorkerThreadForkFn): void {
|
|
38
|
+
_workerThreadForkFn = fn;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let _nextThreadId = 1;
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
export interface MessagePort extends EventEmitter {
|
|
45
|
+
postMessage(_val: unknown, _transfer?: unknown[]): void;
|
|
46
|
+
start(): void;
|
|
47
|
+
close(): void;
|
|
48
|
+
ref(): void;
|
|
49
|
+
unref(): void;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface MessagePortConstructor {
|
|
53
|
+
new (): MessagePort;
|
|
54
|
+
(this: any): void;
|
|
55
|
+
prototype: any;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const MessagePort = function MessagePort(this: any) {
|
|
59
|
+
if (!this) return;
|
|
60
|
+
EventEmitter.call(this);
|
|
61
|
+
} as unknown as MessagePortConstructor;
|
|
62
|
+
|
|
63
|
+
Object.setPrototypeOf(MessagePort.prototype, EventEmitter.prototype);
|
|
64
|
+
|
|
65
|
+
MessagePort.prototype.postMessage = function postMessage(_val: unknown, _transfer?: unknown[]): void {};
|
|
66
|
+
MessagePort.prototype.start = function start(): void {};
|
|
67
|
+
MessagePort.prototype.close = function close(): void {};
|
|
68
|
+
MessagePort.prototype.ref = function ref(): void {};
|
|
69
|
+
MessagePort.prototype.unref = function unref(): void {};
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
export interface MessageChannel {
|
|
73
|
+
port1: MessagePort;
|
|
74
|
+
port2: MessagePort;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface MessageChannelConstructor {
|
|
78
|
+
new (): MessageChannel;
|
|
79
|
+
(this: any): void;
|
|
80
|
+
prototype: any;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const MessageChannel = function MessageChannel(this: any) {
|
|
84
|
+
if (!this) return;
|
|
85
|
+
this.port1 = new MessagePort();
|
|
86
|
+
this.port2 = new MessagePort();
|
|
87
|
+
|
|
88
|
+
// wire the two ports together
|
|
89
|
+
const p1 = this.port1;
|
|
90
|
+
const p2 = this.port2;
|
|
91
|
+
p1.postMessage = (val: unknown) => {
|
|
92
|
+
queueMicrotask(() => p2.emit("message", val));
|
|
93
|
+
};
|
|
94
|
+
p2.postMessage = (val: unknown) => {
|
|
95
|
+
queueMicrotask(() => p1.emit("message", val));
|
|
96
|
+
};
|
|
97
|
+
} as unknown as MessageChannelConstructor;
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
export interface Worker extends EventEmitter {
|
|
101
|
+
threadId: number;
|
|
102
|
+
resourceLimits: object;
|
|
103
|
+
_handle: ReturnType<WorkerThreadForkFn> | null;
|
|
104
|
+
_terminated: boolean;
|
|
105
|
+
_isReffed: boolean;
|
|
106
|
+
postMessage(value: unknown, _transferListOrOptions?: unknown): void;
|
|
107
|
+
terminate(): Promise<number>;
|
|
108
|
+
ref(): this;
|
|
109
|
+
unref(): this;
|
|
110
|
+
getHeapSnapshot(): Promise<unknown>;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
interface WorkerConstructor {
|
|
114
|
+
new (
|
|
115
|
+
script: string | URL,
|
|
116
|
+
opts?: {
|
|
117
|
+
workerData?: unknown;
|
|
118
|
+
eval?: boolean;
|
|
119
|
+
env?: Record<string, string> | symbol;
|
|
120
|
+
argv?: string[];
|
|
121
|
+
execArgv?: string[];
|
|
122
|
+
resourceLimits?: Record<string, number>;
|
|
123
|
+
name?: string;
|
|
124
|
+
transferList?: unknown[];
|
|
125
|
+
},
|
|
126
|
+
): Worker;
|
|
127
|
+
(this: any, script: string | URL, opts?: any): void;
|
|
128
|
+
prototype: any;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export const Worker = function Worker(
|
|
132
|
+
this: any,
|
|
133
|
+
script: string | URL,
|
|
134
|
+
opts?: {
|
|
135
|
+
workerData?: unknown;
|
|
136
|
+
eval?: boolean;
|
|
137
|
+
env?: Record<string, string> | symbol;
|
|
138
|
+
argv?: string[];
|
|
139
|
+
execArgv?: string[];
|
|
140
|
+
resourceLimits?: Record<string, number>;
|
|
141
|
+
name?: string;
|
|
142
|
+
transferList?: unknown[];
|
|
143
|
+
},
|
|
144
|
+
) {
|
|
145
|
+
if (!this) return;
|
|
146
|
+
EventEmitter.call(this);
|
|
147
|
+
|
|
148
|
+
this.threadId = _nextThreadId++;
|
|
149
|
+
this.resourceLimits = {};
|
|
150
|
+
this._handle = null;
|
|
151
|
+
this._terminated = false;
|
|
152
|
+
this._isReffed = false;
|
|
153
|
+
|
|
154
|
+
const scriptStr = typeof script === "string" ? script : script.href;
|
|
155
|
+
const self = this;
|
|
156
|
+
|
|
157
|
+
if (!_workerThreadForkFn) {
|
|
158
|
+
// no fork callback wired
|
|
159
|
+
queueMicrotask(() => {
|
|
160
|
+
self.emit(
|
|
161
|
+
"error",
|
|
162
|
+
new Error(
|
|
163
|
+
"[Nodepod] worker_threads.Worker requires worker mode. " +
|
|
164
|
+
"Ensure the process is running in a worker context.",
|
|
165
|
+
),
|
|
166
|
+
);
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const workerDataVal = opts?.workerData ?? null;
|
|
172
|
+
const isEval = !!opts?.eval;
|
|
173
|
+
const env =
|
|
174
|
+
opts?.env && typeof opts.env !== "symbol"
|
|
175
|
+
? (opts.env as Record<string, string>)
|
|
176
|
+
: {};
|
|
177
|
+
|
|
178
|
+
const handle = _workerThreadForkFn(scriptStr, {
|
|
179
|
+
workerData: workerDataVal,
|
|
180
|
+
threadId: this.threadId,
|
|
181
|
+
isEval,
|
|
182
|
+
cwd: (globalThis as any).process?.cwd?.() ?? "/",
|
|
183
|
+
env,
|
|
184
|
+
onMessage: (data: unknown) => {
|
|
185
|
+
self.emit("message", data);
|
|
186
|
+
},
|
|
187
|
+
onError: (err: Error) => {
|
|
188
|
+
self.emit("error", err);
|
|
189
|
+
},
|
|
190
|
+
onExit: (code: number) => {
|
|
191
|
+
if (self._isReffed) {
|
|
192
|
+
self._isReffed = false;
|
|
193
|
+
eventLoopUnref();
|
|
194
|
+
}
|
|
195
|
+
self._terminated = true;
|
|
196
|
+
self.emit("exit", code);
|
|
197
|
+
},
|
|
198
|
+
onStdout: (data: string) => {
|
|
199
|
+
const sink = (globalThis as any).process?.stdout?.write;
|
|
200
|
+
if (typeof sink === "function") sink.call((globalThis as any).process.stdout, data);
|
|
201
|
+
},
|
|
202
|
+
onStderr: (data: string) => {
|
|
203
|
+
const sink = (globalThis as any).process?.stderr?.write;
|
|
204
|
+
if (typeof sink === "function") sink.call((globalThis as any).process.stderr, data);
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
this._handle = handle;
|
|
209
|
+
|
|
210
|
+
// keep parent alive while worker runs (Node.js default)
|
|
211
|
+
this._isReffed = true;
|
|
212
|
+
eventLoopRef();
|
|
213
|
+
|
|
214
|
+
queueMicrotask(() => {
|
|
215
|
+
if (!self._terminated) self.emit("online");
|
|
216
|
+
});
|
|
217
|
+
} as unknown as WorkerConstructor;
|
|
218
|
+
|
|
219
|
+
Object.setPrototypeOf(Worker.prototype, EventEmitter.prototype);
|
|
220
|
+
|
|
221
|
+
Worker.prototype.postMessage = function postMessage(this: any, value: unknown, _transferListOrOptions?: unknown): void {
|
|
222
|
+
if (this._handle && !this._terminated) {
|
|
223
|
+
this._handle.postMessage(value);
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
Worker.prototype.terminate = function terminate(this: any): Promise<number> {
|
|
228
|
+
if (this._handle && !this._terminated) {
|
|
229
|
+
if (this._isReffed) {
|
|
230
|
+
this._isReffed = false;
|
|
231
|
+
eventLoopUnref();
|
|
232
|
+
}
|
|
233
|
+
this._terminated = true;
|
|
234
|
+
this._handle.terminate();
|
|
235
|
+
}
|
|
236
|
+
return Promise.resolve(0);
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
Worker.prototype.ref = function ref(this: any): any {
|
|
240
|
+
if (!this._isReffed && !this._terminated) {
|
|
241
|
+
this._isReffed = true;
|
|
242
|
+
eventLoopRef();
|
|
243
|
+
}
|
|
244
|
+
return this;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
Worker.prototype.unref = function unref(this: any): any {
|
|
248
|
+
if (this._isReffed) {
|
|
249
|
+
this._isReffed = false;
|
|
250
|
+
eventLoopUnref();
|
|
251
|
+
}
|
|
252
|
+
return this;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
Worker.prototype.getHeapSnapshot = function getHeapSnapshot(): Promise<unknown> {
|
|
256
|
+
return Promise.resolve({});
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
export interface BroadcastChannel extends EventEmitter {
|
|
261
|
+
name: string;
|
|
262
|
+
postMessage(_msg: unknown): void;
|
|
263
|
+
close(): void;
|
|
264
|
+
ref(): void;
|
|
265
|
+
unref(): void;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
interface BroadcastChannelConstructor {
|
|
269
|
+
new (label: string): BroadcastChannel;
|
|
270
|
+
(this: any, label: string): void;
|
|
271
|
+
prototype: any;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export const BroadcastChannel = function BroadcastChannel(this: any, label: string) {
|
|
275
|
+
if (!this) return;
|
|
276
|
+
EventEmitter.call(this);
|
|
277
|
+
this.name = label;
|
|
278
|
+
} as unknown as BroadcastChannelConstructor;
|
|
279
|
+
|
|
280
|
+
Object.setPrototypeOf(BroadcastChannel.prototype, EventEmitter.prototype);
|
|
281
|
+
|
|
282
|
+
BroadcastChannel.prototype.postMessage = function postMessage(_msg: unknown): void {};
|
|
283
|
+
BroadcastChannel.prototype.close = function close(): void {};
|
|
284
|
+
BroadcastChannel.prototype.ref = function ref(): void {};
|
|
285
|
+
BroadcastChannel.prototype.unref = function unref(): void {};
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
export function moveMessagePortToContext(
|
|
289
|
+
port: MessagePort,
|
|
290
|
+
_ctx: unknown,
|
|
291
|
+
): MessagePort {
|
|
292
|
+
return port;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export function receiveMessageOnPort(
|
|
296
|
+
_port: MessagePort,
|
|
297
|
+
): { message: unknown } | undefined {
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export const SHARE_ENV = Symbol.for("nodejs.worker_threads.SHARE_ENV");
|
|
302
|
+
|
|
303
|
+
export function markAsUntransferable(_obj: unknown): void {}
|
|
304
|
+
export function getEnvironmentData(_key: unknown): unknown {
|
|
305
|
+
return undefined;
|
|
306
|
+
}
|
|
307
|
+
export function setEnvironmentData(_key: unknown, _val: unknown): void {}
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
export default {
|
|
311
|
+
isMainThread,
|
|
312
|
+
parentPort,
|
|
313
|
+
workerData,
|
|
314
|
+
threadId,
|
|
315
|
+
Worker,
|
|
316
|
+
MessageChannel,
|
|
317
|
+
MessagePort,
|
|
318
|
+
BroadcastChannel,
|
|
319
|
+
moveMessagePortToContext,
|
|
320
|
+
receiveMessageOnPort,
|
|
321
|
+
SHARE_ENV,
|
|
322
|
+
markAsUntransferable,
|
|
323
|
+
getEnvironmentData,
|
|
324
|
+
setEnvironmentData,
|
|
325
|
+
setWorkerThreadForkCallback,
|
|
326
|
+
};
|