@scelar/nodepod 1.0.2 → 1.0.4

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.
Files changed (94) hide show
  1. package/dist/__sw__.js +642 -642
  2. package/dist/__tests__/bench/integration.bench.d.ts +1 -0
  3. package/dist/__tests__/bench/memory-volume.bench.d.ts +1 -0
  4. package/dist/__tests__/bench/polyfills.bench.d.ts +1 -0
  5. package/dist/__tests__/bench/script-engine.bench.d.ts +1 -0
  6. package/dist/__tests__/bench/shell.bench.d.ts +1 -0
  7. package/dist/__tests__/bench/syntax-transforms.bench.d.ts +1 -0
  8. package/dist/__tests__/bench/version-resolver.bench.d.ts +1 -0
  9. package/dist/__tests__/buffer.test.d.ts +1 -0
  10. package/dist/__tests__/byte-encoding.test.d.ts +1 -0
  11. package/dist/__tests__/digest.test.d.ts +1 -0
  12. package/dist/__tests__/events.test.d.ts +1 -0
  13. package/dist/__tests__/memory-volume.test.d.ts +1 -0
  14. package/dist/__tests__/path.test.d.ts +1 -0
  15. package/dist/__tests__/process.test.d.ts +1 -0
  16. package/dist/__tests__/script-engine.test.d.ts +1 -0
  17. package/dist/__tests__/shell-builtins.test.d.ts +1 -0
  18. package/dist/__tests__/shell-interpreter.test.d.ts +1 -0
  19. package/dist/__tests__/shell-parser.test.d.ts +1 -0
  20. package/dist/__tests__/stream.test.d.ts +1 -0
  21. package/dist/__tests__/syntax-transforms.test.d.ts +1 -0
  22. package/dist/__tests__/version-resolver.test.d.ts +1 -0
  23. package/dist/{child_process-Dopvyd-E.js → child_process-53fMkug_.js} +4 -4
  24. package/dist/child_process-53fMkug_.js.map +1 -0
  25. package/dist/{child_process-B38qoN6R.cjs → child_process-lxSKECHq.cjs} +5 -5
  26. package/dist/child_process-lxSKECHq.cjs.map +1 -0
  27. package/dist/{index--Qr8LVpQ.js → index-B8lyh_ti.js} +1316 -559
  28. package/dist/index-B8lyh_ti.js.map +1 -0
  29. package/dist/{index-cnitc68U.cjs → index-C-TQIrdG.cjs} +1422 -612
  30. package/dist/index-C-TQIrdG.cjs.map +1 -0
  31. package/dist/index.cjs +1 -1
  32. package/dist/index.mjs +1 -1
  33. package/dist/memory-volume.d.ts +1 -1
  34. package/dist/polyfills/wasi.d.ts +45 -4
  35. package/dist/script-engine.d.ts +2 -0
  36. package/dist/sdk/nodepod.d.ts +4 -3
  37. package/dist/sdk/types.d.ts +6 -0
  38. package/dist/syntax-transforms.d.ts +1 -0
  39. package/dist/threading/process-manager.d.ts +1 -1
  40. package/dist/threading/worker-protocol.d.ts +1 -1
  41. package/package.json +5 -3
  42. package/src/__tests__/bench/integration.bench.ts +117 -0
  43. package/src/__tests__/bench/memory-volume.bench.ts +115 -0
  44. package/src/__tests__/bench/polyfills.bench.ts +147 -0
  45. package/src/__tests__/bench/script-engine.bench.ts +104 -0
  46. package/src/__tests__/bench/shell.bench.ts +101 -0
  47. package/src/__tests__/bench/syntax-transforms.bench.ts +82 -0
  48. package/src/__tests__/bench/version-resolver.bench.ts +95 -0
  49. package/src/__tests__/buffer.test.ts +273 -0
  50. package/src/__tests__/byte-encoding.test.ts +98 -0
  51. package/src/__tests__/digest.test.ts +44 -0
  52. package/src/__tests__/events.test.ts +245 -0
  53. package/src/__tests__/memory-volume.test.ts +443 -0
  54. package/src/__tests__/path.test.ts +181 -0
  55. package/src/__tests__/process.test.ts +129 -0
  56. package/src/__tests__/script-engine.test.ts +229 -0
  57. package/src/__tests__/shell-builtins.test.ts +357 -0
  58. package/src/__tests__/shell-interpreter.test.ts +157 -0
  59. package/src/__tests__/shell-parser.test.ts +204 -0
  60. package/src/__tests__/stream.test.ts +142 -0
  61. package/src/__tests__/syntax-transforms.test.ts +158 -0
  62. package/src/__tests__/version-resolver.test.ts +184 -0
  63. package/src/constants/cdn-urls.ts +18 -18
  64. package/src/helpers/byte-encoding.ts +51 -39
  65. package/src/index.ts +192 -192
  66. package/src/memory-volume.ts +968 -941
  67. package/src/module-transformer.ts +368 -368
  68. package/src/packages/installer.ts +396 -396
  69. package/src/packages/version-resolver.ts +12 -2
  70. package/src/polyfills/buffer.ts +633 -628
  71. package/src/polyfills/child_process.ts +2288 -2288
  72. package/src/polyfills/esbuild.ts +854 -854
  73. package/src/polyfills/events.ts +282 -276
  74. package/src/polyfills/fs.ts +2888 -2888
  75. package/src/polyfills/http.ts +1450 -1449
  76. package/src/polyfills/process.ts +721 -690
  77. package/src/polyfills/readline.ts +692 -692
  78. package/src/polyfills/stream.ts +1620 -1620
  79. package/src/polyfills/tty.ts +71 -71
  80. package/src/polyfills/wasi.ts +1284 -22
  81. package/src/request-proxy.ts +716 -716
  82. package/src/script-engine.ts +465 -146
  83. package/src/sdk/nodepod.ts +525 -509
  84. package/src/sdk/types.ts +7 -0
  85. package/src/syntax-transforms.ts +543 -561
  86. package/src/threading/offload-worker.ts +383 -383
  87. package/src/threading/offload.ts +271 -271
  88. package/src/threading/process-manager.ts +956 -956
  89. package/src/threading/process-worker-entry.ts +858 -854
  90. package/src/threading/worker-protocol.ts +1 -1
  91. package/dist/child_process-B38qoN6R.cjs.map +0 -1
  92. package/dist/child_process-Dopvyd-E.js.map +0 -1
  93. package/dist/index--Qr8LVpQ.js.map +0 -1
  94. package/dist/index-cnitc68U.cjs.map +0 -1
@@ -1,690 +1,721 @@
1
- // Process polyfill -- buildProcessEnv() constructs a full process object
2
-
3
- import { EventEmitter, EventHandler } from "./events";
4
- import {
5
- VERSIONS,
6
- NODE_SUB_VERSIONS,
7
- MOCK_OS,
8
- MOCK_PROCESS,
9
- MOCK_MEMORY,
10
- DEFAULT_ENV,
11
- DEFAULT_TERMINAL,
12
- } from "../constants/config";
13
-
14
- // capture before engine wrapper overrides globalThis.console
15
- const _nativeConsole = console;
16
-
17
- export interface ProcessEnvVars {
18
- [key: string]: string | undefined;
19
- }
20
-
21
- interface OutputStreamBridge {
22
- isTTY: boolean;
23
- columns: number;
24
- rows: number;
25
- write: (data: string | Buffer, encoding?: string, cb?: () => void) => boolean;
26
- end?: (data?: string, cb?: () => void) => void;
27
- on: (evt: string, fn: EventHandler) => OutputStreamBridge;
28
- once: (evt: string, fn: EventHandler) => OutputStreamBridge;
29
- off: (evt: string, fn: EventHandler) => OutputStreamBridge;
30
- emit: (evt: string, ...args: unknown[]) => boolean;
31
- addListener: (evt: string, fn: EventHandler) => OutputStreamBridge;
32
- removeListener: (evt: string, fn: EventHandler) => OutputStreamBridge;
33
- removeAllListeners: (evt?: string) => OutputStreamBridge;
34
- setMaxListeners: (n: number) => OutputStreamBridge;
35
- getMaxListeners: () => number;
36
- listenerCount: (evt: string) => number;
37
- listeners: (evt: string) => EventHandler[];
38
- rawListeners: (evt: string) => EventHandler[];
39
- prependListener: (evt: string, fn: EventHandler) => OutputStreamBridge;
40
- prependOnceListener: (evt: string, fn: EventHandler) => OutputStreamBridge;
41
- eventNames: () => string[];
42
- pause?: () => OutputStreamBridge;
43
- resume?: () => OutputStreamBridge;
44
- setEncoding?: (enc: string) => OutputStreamBridge;
45
- clearLine?: (dir: number, cb?: () => void) => boolean;
46
- cursorTo?: (x: number, y?: number, cb?: () => void) => boolean;
47
- moveCursor?: (dx: number, dy: number, cb?: () => void) => boolean;
48
- getWindowSize?: () => [number, number];
49
- getColorDepth?: (env?: Record<string, string>) => number;
50
- hasColors?: (
51
- countOrEnv?: number | Record<string, string>,
52
- env?: Record<string, string>,
53
- ) => boolean;
54
- }
55
-
56
- interface InputStreamBridge extends OutputStreamBridge {
57
- read?: (size?: number) => string | Buffer | null;
58
- setRawMode?: (flag: boolean) => InputStreamBridge;
59
- isRaw?: boolean;
60
- destroy?: () => InputStreamBridge;
61
- pipe?: (dest: any) => any;
62
- unpipe?: () => InputStreamBridge;
63
- unshift?: (...args: unknown[]) => void;
64
- wrap?: (stream: any) => InputStreamBridge;
65
- readable?: boolean;
66
- writable?: boolean;
67
- destroyed?: boolean;
68
- [Symbol.asyncIterator]?: () => AsyncIterator<any>;
69
- }
70
-
71
- export interface ProcessObject {
72
- env: ProcessEnvVars;
73
- cwd: () => string;
74
- chdir: (dir: string) => void;
75
- _chdirHook?: (dir: string) => void;
76
- platform: string;
77
- version: string;
78
- versions: {
79
- node: string;
80
- v8: string;
81
- uv: string;
82
- modules: string;
83
- openssl: string;
84
- napi: string;
85
- webcontainer: string;
86
- };
87
- argv: string[];
88
- argv0: string;
89
- execPath: string;
90
- execArgv: string[];
91
- pid: number;
92
- ppid: number;
93
- exit: (code?: number) => never;
94
- nextTick: (fn: (...args: unknown[]) => void, ...args: unknown[]) => void;
95
- stdout: OutputStreamBridge;
96
- stderr: OutputStreamBridge;
97
- stdin: InputStreamBridge;
98
- arch: string;
99
- title: string;
100
- hrtime: {
101
- (prev?: [number, number]): [number, number];
102
- bigint: () => bigint;
103
- };
104
- memoryUsage: () => {
105
- rss: number;
106
- heapTotal: number;
107
- heapUsed: number;
108
- external: number;
109
- arrayBuffers: number;
110
- };
111
- uptime: () => number;
112
- cpuUsage: () => { user: number; system: number };
113
- resourceUsage: () => {
114
- userCPUTime: number; systemCPUTime: number;
115
- maxRSS: number; sharedMemorySize: number;
116
- unsharedDataSize: number; unsharedStackSize: number;
117
- minorPageFault: number; majorPageFault: number;
118
- swappedOut: number; fsRead: number; fsWrite: number;
119
- ipcSent: number; ipcReceived: number;
120
- signalsCount: number; voluntaryContextSwitches: number;
121
- involuntaryContextSwitches: number;
122
- };
123
- abort: () => never;
124
- kill: (pid: number, signal?: string | number) => boolean;
125
- umask: (mask?: number) => number;
126
- config: {
127
- variables: Record<string, unknown>;
128
- target_defaults: Record<string, unknown>;
129
- };
130
- release: { name: string; sourceUrl: string; headersUrl: string };
131
- features: {
132
- inspector: boolean;
133
- debug: boolean;
134
- uv: boolean;
135
- ipv6: boolean;
136
- tls_alpn: boolean;
137
- tls_sni: boolean;
138
- tls_ocsp: boolean;
139
- tls: boolean;
140
- };
141
- debugPort: number;
142
- allowedNodeEnvironmentFlags: Set<string>;
143
- on: (evt: string, fn: EventHandler) => ProcessObject;
144
- once: (evt: string, fn: EventHandler) => ProcessObject;
145
- off: (evt: string, fn: EventHandler) => ProcessObject;
146
- emit: (evt: string, ...args: unknown[]) => boolean;
147
- addListener: (evt: string, fn: EventHandler) => ProcessObject;
148
- removeListener: (evt: string, fn: EventHandler) => ProcessObject;
149
- removeAllListeners: (evt?: string) => ProcessObject;
150
- listeners: (evt: string) => EventHandler[];
151
- listenerCount: (evt: string) => number;
152
- prependListener: (evt: string, fn: EventHandler) => ProcessObject;
153
- prependOnceListener: (evt: string, fn: EventHandler) => ProcessObject;
154
- eventNames: () => string[];
155
- setMaxListeners: (n: number) => ProcessObject;
156
- getMaxListeners: () => number;
157
- send?: (msg: unknown, cb?: (err: Error | null) => void) => boolean;
158
- disconnect?: () => void;
159
- connected?: boolean;
160
- _debugCwdCalls?: number;
161
- mainModule?: unknown;
162
- channel?: unknown;
163
- noDeprecation?: boolean;
164
- throwDeprecation?: boolean;
165
- traceDeprecation?: boolean;
166
- traceProcessWarnings?: boolean;
167
- report?: Record<string, unknown>;
168
- binding?: (name: string) => Record<string, unknown>;
169
- _linkedBinding?: (name: string) => Record<string, unknown>;
170
- dlopen?: (module: unknown, filename: string, flags?: number) => void;
171
- reallyExit?: (code?: number) => void;
172
- _getActiveRequests?: () => unknown[];
173
- _getActiveHandles?: () => unknown[];
174
- emitWarning?: (
175
- warning: string | Error,
176
- typeOrOptions?: string | { type?: string; code?: string; detail?: string },
177
- code?: string,
178
- ) => void;
179
- hasUncaughtExceptionCaptureCallback?: () => boolean;
180
- setUncaughtExceptionCaptureCallback?: (
181
- fn: ((err: Error) => void) | null,
182
- ) => void;
183
- sourceMapsEnabled?: boolean;
184
- setSourceMapsEnabled?: (val: boolean) => void;
185
- constrainedMemory?: () => number;
186
- availableMemory?: () => number;
187
- }
188
-
189
- function fabricateStream(
190
- isOutput: boolean,
191
- writeFn?: (text: string) => boolean,
192
- ): OutputStreamBridge & InputStreamBridge {
193
- const bus = new EventEmitter();
194
-
195
- // raw ANSI writes bypass the stream's write() method
196
- const rawWrite = (text: string) => {
197
- if (writeFn) writeFn(text);
198
- };
199
-
200
- const stream: OutputStreamBridge & InputStreamBridge = {
201
- isTTY: false,
202
- columns: DEFAULT_TERMINAL.COLUMNS,
203
- rows: DEFAULT_TERMINAL.ROWS,
204
- isRaw: false,
205
- on(evt, fn) {
206
- bus.on(evt, fn);
207
- return stream;
208
- },
209
- once(evt, fn) {
210
- bus.once(evt, fn);
211
- return stream;
212
- },
213
- off(evt, fn) {
214
- bus.off(evt, fn);
215
- return stream;
216
- },
217
- emit(evt, ...args) {
218
- return bus.emit(evt, ...args);
219
- },
220
- addListener(evt, fn) {
221
- bus.addListener(evt, fn);
222
- return stream;
223
- },
224
- removeListener(evt, fn) {
225
- bus.removeListener(evt, fn);
226
- return stream;
227
- },
228
- removeAllListeners(evt) {
229
- bus.removeAllListeners(evt);
230
- return stream;
231
- },
232
- setMaxListeners(n) {
233
- bus.setMaxListeners(n);
234
- return stream;
235
- },
236
- getMaxListeners() {
237
- return bus.getMaxListeners();
238
- },
239
- listenerCount(evt) {
240
- return bus.listenerCount(evt);
241
- },
242
- listeners(evt) {
243
- return bus.listeners(evt);
244
- },
245
- rawListeners(evt) {
246
- return bus.rawListeners(evt);
247
- },
248
- prependListener(evt, fn) {
249
- bus.prependListener(evt, fn);
250
- return stream;
251
- },
252
- prependOnceListener(evt, fn) {
253
- bus.prependOnceListener(evt, fn);
254
- return stream;
255
- },
256
- eventNames() {
257
- return bus.eventNames();
258
- },
259
- pause() {
260
- return stream;
261
- },
262
- resume() {
263
- return stream;
264
- },
265
- setEncoding(_enc) {
266
- return stream;
267
- },
268
- write(data, _enc?, cb?) {
269
- if (isOutput && writeFn && data != null) {
270
- const text = typeof data === "string" ? data : String(data);
271
- writeFn(text);
272
- }
273
- if (cb) queueMicrotask(cb);
274
- return true;
275
- },
276
- end(data?, cb?) {
277
- if (isOutput && writeFn && data != null) {
278
- const text = typeof data === "string" ? data : String(data);
279
- writeFn(text);
280
- }
281
- if (cb) queueMicrotask(cb);
282
- },
283
- read() {
284
- return null;
285
- },
286
- destroy() {
287
- return stream;
288
- },
289
- pipe(dest: any) {
290
- const onData = (chunk: any) => {
291
- if (dest.write) dest.write(chunk);
292
- };
293
- bus.on("data", onData);
294
- if (!(stream as any)._pipeDests) (stream as any)._pipeDests = [];
295
- (stream as any)._pipeDests.push({ dest, onData });
296
- return dest;
297
- },
298
- unpipe(dest?: any) {
299
- const dests: Array<{ dest: any; onData: Function }> =
300
- (stream as any)._pipeDests || [];
301
- if (dest) {
302
- const idx = dests.findIndex((d) => d.dest === dest);
303
- if (idx >= 0) {
304
- bus.off("data", dests[idx].onData as any);
305
- dests.splice(idx, 1);
306
- }
307
- } else {
308
- for (const d of dests) bus.off("data", d.onData as any);
309
- dests.length = 0;
310
- }
311
- return stream;
312
- },
313
- unshift() {},
314
- wrap() {
315
- return stream;
316
- },
317
- [Symbol.asyncIterator]() {
318
- return { next: async () => ({ done: true, value: undefined }) };
319
- },
320
- readable: true,
321
- writable: true,
322
- destroyed: false,
323
- setRawMode(flag) {
324
- stream.isRaw = flag;
325
- return stream;
326
- },
327
- clearLine(dir: number, cb?) {
328
- if (isOutput) {
329
- if (dir === -1)
330
- rawWrite("\x1b[1K"); // clear left of cursor
331
- else if (dir === 1)
332
- rawWrite("\x1b[0K"); // clear right of cursor
333
- else rawWrite("\x1b[2K"); // clear entire line
334
- }
335
- if (cb) cb();
336
- return true;
337
- },
338
- cursorTo(x: number, y?: number | (() => void), cb?: () => void) {
339
- if (typeof y === "function") {
340
- cb = y;
341
- y = undefined;
342
- }
343
- if (isOutput) {
344
- if (typeof y === "number") {
345
- rawWrite(`\x1b[${y + 1};${x + 1}H`); // move to row;col
346
- } else {
347
- rawWrite(`\x1b[${x + 1}G`); // move to column
348
- }
349
- }
350
- if (typeof cb === "function") cb();
351
- return true;
352
- },
353
- moveCursor(dx: number, dy: number, cb?) {
354
- if (isOutput) {
355
- if (dx > 0)
356
- rawWrite(`\x1b[${dx}C`); // move right
357
- else if (dx < 0) rawWrite(`\x1b[${-dx}D`); // move left
358
- if (dy > 0)
359
- rawWrite(`\x1b[${dy}B`); // move down
360
- else if (dy < 0) rawWrite(`\x1b[${-dy}A`); // move up
361
- }
362
- if (cb) cb();
363
- return true;
364
- },
365
- getWindowSize() {
366
- return [stream.columns, stream.rows];
367
- },
368
- getColorDepth(_env?: Record<string, string>): number {
369
- return 8;
370
- },
371
- hasColors(
372
- countOrEnv?: number | Record<string, string>,
373
- _env?: Record<string, string>,
374
- ): boolean {
375
- const count = typeof countOrEnv === "number" ? countOrEnv : 256;
376
- return 256 >= count;
377
- },
378
- };
379
-
380
- if (isOutput && writeFn) {
381
- stream.write = (data: string | Buffer, _enc?: string, cb?: () => void) => {
382
- const text = typeof data === "string" ? data : data.toString();
383
- const ok = writeFn(text);
384
- if (cb) queueMicrotask(cb);
385
- return ok;
386
- };
387
- }
388
-
389
- return stream;
390
- }
391
-
392
- export function buildProcessEnv(config?: {
393
- cwd?: string;
394
- env?: ProcessEnvVars;
395
- onExit?: (code: number) => void;
396
- onStdout?: (text: string) => void;
397
- onStderr?: (text: string) => void;
398
- pid?: number;
399
- ppid?: number;
400
- }): ProcessObject {
401
- let workingDir = config?.cwd || "/";
402
- let currentUmask = 0o022;
403
- const bootTime = Date.now();
404
- const bus = new EventEmitter();
405
-
406
- const envVars: ProcessEnvVars = {
407
- NODE_ENV: DEFAULT_ENV.NODE_ENV,
408
- PATH: DEFAULT_ENV.PATH,
409
- HOME: DEFAULT_ENV.HOME,
410
- SHELL: DEFAULT_ENV.SHELL,
411
- TERM: DEFAULT_ENV.TERM,
412
- COLORTERM: DEFAULT_ENV.COLORTERM,
413
- REQUIRES_WASM: DEFAULT_ENV.REQUIRES_WASM,
414
- npm_config_user_agent: DEFAULT_ENV.npm_config_user_agent,
415
- npm_execpath: DEFAULT_ENV.npm_execpath,
416
- npm_node_execpath: DEFAULT_ENV.npm_node_execpath,
417
- NEXT_TELEMETRY_DISABLED: "1",
418
- DO_NOT_TRACK: "1",
419
- ...config?.env,
420
- };
421
-
422
- const stdoutStream = fabricateStream(true, (text) => {
423
- if (config?.onStdout) {
424
- config.onStdout(text);
425
- } else {
426
- _nativeConsole.log(text);
427
- }
428
- return true;
429
- });
430
-
431
- const stderrStream = fabricateStream(true, (text) => {
432
- if (config?.onStderr) {
433
- config.onStderr(text);
434
- } else {
435
- _nativeConsole.error(text);
436
- }
437
- return true;
438
- });
439
-
440
- const stdinStream = fabricateStream(false);
441
-
442
- const hrtimeFn = function hrtime(prev?: [number, number]): [number, number] {
443
- const now = performance.now();
444
- const secs = Math.floor(now / 1000);
445
- const nanos = Math.floor((now % 1000) * 1e6);
446
- if (prev) {
447
- return [secs - prev[0], nanos - prev[1]];
448
- }
449
- return [secs, nanos];
450
- };
451
- hrtimeFn.bigint = (): bigint => BigInt(Math.floor(performance.now() * 1e6));
452
-
453
- const proc: ProcessObject = {
454
- env: envVars,
455
-
456
- cwd() {
457
- if (!proc._debugCwdCalls) proc._debugCwdCalls = 0;
458
- proc._debugCwdCalls++;
459
- return workingDir;
460
- },
461
-
462
- chdir(dir: string) {
463
- if (!dir.startsWith("/")) {
464
- dir = workingDir + "/" + dir;
465
- }
466
- workingDir = dir;
467
- if (proc._chdirHook) proc._chdirHook(dir);
468
- },
469
-
470
- platform: MOCK_OS.PLATFORM,
471
- arch: MOCK_OS.ARCH,
472
- title: MOCK_PROCESS.TITLE,
473
- version: VERSIONS.NODE,
474
- versions: { ...NODE_SUB_VERSIONS },
475
-
476
- argv: ["node", "/index.js"],
477
- argv0: "node",
478
- execPath: MOCK_PROCESS.EXEC_PATH,
479
- execArgv: [],
480
-
481
- pid: config?.pid ?? MOCK_PROCESS.PID,
482
- ppid: config?.ppid ?? MOCK_PROCESS.PPID,
483
-
484
- exit(code = 0) {
485
- bus.emit("exit", code);
486
- if (config?.onExit) config.onExit(code);
487
- throw new Error(`Process exited with code ${code}`);
488
- },
489
-
490
- nextTick(fn, ...args) {
491
- queueMicrotask(() => fn(...args));
492
- },
493
-
494
- stdout: stdoutStream,
495
- stderr: stderrStream,
496
- stdin: stdinStream,
497
-
498
- hrtime: hrtimeFn as ProcessObject["hrtime"],
499
-
500
- memoryUsage: Object.assign(
501
- function memoryUsage() {
502
- return {
503
- rss: MOCK_MEMORY.RSS,
504
- heapTotal: MOCK_MEMORY.HEAP_TOTAL,
505
- heapUsed: MOCK_MEMORY.HEAP_USED,
506
- external: MOCK_MEMORY.EXTERNAL,
507
- arrayBuffers: 0,
508
- };
509
- },
510
- { rss: () => MOCK_MEMORY.RSS },
511
- ),
512
-
513
- uptime() {
514
- return (Date.now() - bootTime) / 1000;
515
- },
516
-
517
- cpuUsage() {
518
- return { user: 0, system: 0 };
519
- },
520
-
521
- resourceUsage() {
522
- return {
523
- userCPUTime: 0, systemCPUTime: 0,
524
- maxRSS: MOCK_MEMORY.RSS / 1024,
525
- sharedMemorySize: 0, unsharedDataSize: 0, unsharedStackSize: 0,
526
- minorPageFault: 0, majorPageFault: 0,
527
- swappedOut: 0, fsRead: 0, fsWrite: 0,
528
- ipcSent: 0, ipcReceived: 0,
529
- signalsCount: 0, voluntaryContextSwitches: 0, involuntaryContextSwitches: 0,
530
- };
531
- },
532
-
533
- abort() {
534
- throw new Error("process.abort() called");
535
- },
536
-
537
- kill(_pid: number, _signal?: string | number) {
538
- return true;
539
- },
540
-
541
- umask(mask?: number) {
542
- const old = currentUmask;
543
- if (mask !== undefined) currentUmask = mask;
544
- return old;
545
- },
546
-
547
- config: { variables: {}, target_defaults: {} },
548
- release: { name: "node", sourceUrl: "", headersUrl: "" },
549
- features: {
550
- inspector: false,
551
- debug: false,
552
- uv: true,
553
- ipv6: true,
554
- tls_alpn: true,
555
- tls_sni: true,
556
- tls_ocsp: true,
557
- tls: true,
558
- },
559
- debugPort: 9229,
560
- allowedNodeEnvironmentFlags: new Set<string>(),
561
- mainModule: undefined as any,
562
- channel: undefined,
563
- noDeprecation: false,
564
- throwDeprecation: false,
565
- traceDeprecation: false,
566
- traceProcessWarnings: false,
567
- report: {
568
- directory: "",
569
- filename: "",
570
- getReport: () => ({}),
571
- reportOnFatalError: false,
572
- reportOnSignal: false,
573
- reportOnUncaughtException: false,
574
- signal: "SIGUSR2",
575
- writeReport: () => "",
576
- },
577
- binding(name: string): Record<string, unknown> {
578
- if (name === "natives") return {};
579
- if (name === "config") return { exposeInternals: false };
580
- if (name === "constants") return {};
581
- if (name === "util") return {};
582
- if (name === "fs") return {};
583
- if (name === "buffer") return {};
584
- if (name === "stream_wrap") return {};
585
- if (name === "tcp_wrap") return {};
586
- if (name === "pipe_wrap") return {};
587
- // throw for unknown bindings so callers fall back gracefully
588
- throw new Error(`No such module: ${name}`);
589
- },
590
- _linkedBinding(_name: string): Record<string, unknown> {
591
- return {};
592
- },
593
- dlopen(_module: unknown, _filename: string, _flags?: number): void {
594
- throw new Error("process.dlopen is not supported in browser environment");
595
- },
596
- reallyExit(_code?: number): void {},
597
- _getActiveRequests(): unknown[] {
598
- return [];
599
- },
600
- _getActiveHandles(): unknown[] {
601
- return [];
602
- },
603
- emitWarning(
604
- warning: string | Error,
605
- typeOrOptions?:
606
- | string
607
- | { type?: string; code?: string; detail?: string },
608
- code?: string,
609
- ): void {
610
- const msg = typeof warning === "string" ? warning : warning.message;
611
- const type =
612
- typeof typeOrOptions === "string"
613
- ? typeOrOptions
614
- : (typeOrOptions?.type ?? "Warning");
615
- bus.emit("warning", { name: type, message: msg, code });
616
- },
617
- hasUncaughtExceptionCaptureCallback(): boolean {
618
- return false;
619
- },
620
- setUncaughtExceptionCaptureCallback(
621
- _fn: ((err: Error) => void) | null,
622
- ): void {},
623
- sourceMapsEnabled: false,
624
- setSourceMapsEnabled(_val: boolean): void {},
625
- constrainedMemory(): number {
626
- return 0;
627
- },
628
- availableMemory(): number {
629
- return 512 * 1024 * 1024; // 512MB
630
- },
631
-
632
- on(evt, fn) {
633
- bus.on(evt, fn);
634
- return proc;
635
- },
636
- once(evt, fn) {
637
- bus.once(evt, fn);
638
- return proc;
639
- },
640
- off(evt, fn) {
641
- bus.off(evt, fn);
642
- return proc;
643
- },
644
- emit(evt, ...args) {
645
- return bus.emit(evt, ...args);
646
- },
647
- addListener(evt, fn) {
648
- bus.addListener(evt, fn);
649
- return proc;
650
- },
651
- removeListener(evt, fn) {
652
- bus.removeListener(evt, fn);
653
- return proc;
654
- },
655
- removeAllListeners(evt) {
656
- bus.removeAllListeners(evt);
657
- return proc;
658
- },
659
- listeners(evt) {
660
- return bus.listeners(evt);
661
- },
662
- listenerCount(evt) {
663
- return bus.listenerCount(evt);
664
- },
665
- prependListener(evt, fn) {
666
- bus.prependListener(evt, fn);
667
- return proc;
668
- },
669
- prependOnceListener(evt, fn) {
670
- bus.prependOnceListener(evt, fn);
671
- return proc;
672
- },
673
- eventNames() {
674
- return bus.eventNames();
675
- },
676
- setMaxListeners(n) {
677
- bus.setMaxListeners(n);
678
- return proc;
679
- },
680
- getMaxListeners() {
681
- return bus.getMaxListeners();
682
- },
683
- };
684
-
685
- return proc;
686
- }
687
-
688
- export const process = buildProcessEnv();
689
-
690
- export default process;
1
+ // Process polyfill -- buildProcessEnv() constructs a full process object
2
+
3
+ import { EventEmitter, EventHandler } from "./events";
4
+ import {
5
+ VERSIONS,
6
+ NODE_SUB_VERSIONS,
7
+ MOCK_OS,
8
+ MOCK_PROCESS,
9
+ MOCK_MEMORY,
10
+ DEFAULT_ENV,
11
+ DEFAULT_TERMINAL,
12
+ } from "../constants/config";
13
+
14
+ // capture before engine wrapper overrides globalThis.console
15
+ const _nativeConsole = console;
16
+
17
+ export interface ProcessEnvVars {
18
+ [key: string]: string | undefined;
19
+ }
20
+
21
+ interface OutputStreamBridge {
22
+ isTTY: boolean;
23
+ columns: number;
24
+ rows: number;
25
+ write: (data: string | Buffer, encoding?: string, cb?: () => void) => boolean;
26
+ end?: (data?: string, cb?: () => void) => void;
27
+ on: (evt: string, fn: EventHandler) => OutputStreamBridge;
28
+ once: (evt: string, fn: EventHandler) => OutputStreamBridge;
29
+ off: (evt: string, fn: EventHandler) => OutputStreamBridge;
30
+ emit: (evt: string, ...args: unknown[]) => boolean;
31
+ addListener: (evt: string, fn: EventHandler) => OutputStreamBridge;
32
+ removeListener: (evt: string, fn: EventHandler) => OutputStreamBridge;
33
+ removeAllListeners: (evt?: string) => OutputStreamBridge;
34
+ setMaxListeners: (n: number) => OutputStreamBridge;
35
+ getMaxListeners: () => number;
36
+ listenerCount: (evt: string) => number;
37
+ listeners: (evt: string) => EventHandler[];
38
+ rawListeners: (evt: string) => EventHandler[];
39
+ prependListener: (evt: string, fn: EventHandler) => OutputStreamBridge;
40
+ prependOnceListener: (evt: string, fn: EventHandler) => OutputStreamBridge;
41
+ eventNames: () => string[];
42
+ pause?: () => OutputStreamBridge;
43
+ resume?: () => OutputStreamBridge;
44
+ setEncoding?: (enc: string) => OutputStreamBridge;
45
+ clearLine?: (dir: number, cb?: () => void) => boolean;
46
+ cursorTo?: (x: number, y?: number, cb?: () => void) => boolean;
47
+ moveCursor?: (dx: number, dy: number, cb?: () => void) => boolean;
48
+ getWindowSize?: () => [number, number];
49
+ getColorDepth?: (env?: Record<string, string>) => number;
50
+ hasColors?: (
51
+ countOrEnv?: number | Record<string, string>,
52
+ env?: Record<string, string>,
53
+ ) => boolean;
54
+ }
55
+
56
+ interface InputStreamBridge extends OutputStreamBridge {
57
+ read?: (size?: number) => string | Buffer | null;
58
+ setRawMode?: (flag: boolean) => InputStreamBridge;
59
+ isRaw?: boolean;
60
+ destroy?: () => InputStreamBridge;
61
+ pipe?: (dest: any) => any;
62
+ unpipe?: () => InputStreamBridge;
63
+ unshift?: (...args: unknown[]) => void;
64
+ wrap?: (stream: any) => InputStreamBridge;
65
+ readable?: boolean;
66
+ writable?: boolean;
67
+ destroyed?: boolean;
68
+ [Symbol.asyncIterator]?: () => AsyncIterator<any>;
69
+ }
70
+
71
+ export interface ProcessObject {
72
+ env: ProcessEnvVars;
73
+ cwd: () => string;
74
+ chdir: (dir: string) => void;
75
+ _chdirHook?: (dir: string) => void;
76
+ platform: string;
77
+ version: string;
78
+ versions: {
79
+ node: string;
80
+ v8: string;
81
+ uv: string;
82
+ modules: string;
83
+ openssl: string;
84
+ napi: string;
85
+ webcontainer: string;
86
+ };
87
+ argv: string[];
88
+ argv0: string;
89
+ execPath: string;
90
+ execArgv: string[];
91
+ pid: number;
92
+ ppid: number;
93
+ exit: (code?: number) => never;
94
+ nextTick: (fn: (...args: unknown[]) => void, ...args: unknown[]) => void;
95
+ stdout: OutputStreamBridge;
96
+ stderr: OutputStreamBridge;
97
+ stdin: InputStreamBridge;
98
+ arch: string;
99
+ title: string;
100
+ hrtime: {
101
+ (prev?: [number, number]): [number, number];
102
+ bigint: () => bigint;
103
+ };
104
+ memoryUsage: () => {
105
+ rss: number;
106
+ heapTotal: number;
107
+ heapUsed: number;
108
+ external: number;
109
+ arrayBuffers: number;
110
+ };
111
+ uptime: () => number;
112
+ cpuUsage: () => { user: number; system: number };
113
+ resourceUsage: () => {
114
+ userCPUTime: number; systemCPUTime: number;
115
+ maxRSS: number; sharedMemorySize: number;
116
+ unsharedDataSize: number; unsharedStackSize: number;
117
+ minorPageFault: number; majorPageFault: number;
118
+ swappedOut: number; fsRead: number; fsWrite: number;
119
+ ipcSent: number; ipcReceived: number;
120
+ signalsCount: number; voluntaryContextSwitches: number;
121
+ involuntaryContextSwitches: number;
122
+ };
123
+ abort: () => never;
124
+ kill: (pid: number, signal?: string | number) => boolean;
125
+ umask: (mask?: number) => number;
126
+ config: {
127
+ variables: Record<string, unknown>;
128
+ target_defaults: Record<string, unknown>;
129
+ };
130
+ release: { name: string; sourceUrl: string; headersUrl: string };
131
+ features: {
132
+ inspector: boolean;
133
+ debug: boolean;
134
+ uv: boolean;
135
+ ipv6: boolean;
136
+ tls_alpn: boolean;
137
+ tls_sni: boolean;
138
+ tls_ocsp: boolean;
139
+ tls: boolean;
140
+ };
141
+ debugPort: number;
142
+ allowedNodeEnvironmentFlags: Set<string>;
143
+ on: (evt: string, fn: EventHandler) => ProcessObject;
144
+ once: (evt: string, fn: EventHandler) => ProcessObject;
145
+ off: (evt: string, fn: EventHandler) => ProcessObject;
146
+ emit: (evt: string, ...args: unknown[]) => boolean;
147
+ addListener: (evt: string, fn: EventHandler) => ProcessObject;
148
+ removeListener: (evt: string, fn: EventHandler) => ProcessObject;
149
+ removeAllListeners: (evt?: string) => ProcessObject;
150
+ listeners: (evt: string) => EventHandler[];
151
+ listenerCount: (evt: string) => number;
152
+ prependListener: (evt: string, fn: EventHandler) => ProcessObject;
153
+ prependOnceListener: (evt: string, fn: EventHandler) => ProcessObject;
154
+ eventNames: () => string[];
155
+ setMaxListeners: (n: number) => ProcessObject;
156
+ getMaxListeners: () => number;
157
+ send?: (msg: unknown, cb?: (err: Error | null) => void) => boolean;
158
+ disconnect?: () => void;
159
+ connected?: boolean;
160
+ _debugCwdCalls?: number;
161
+ mainModule?: unknown;
162
+ channel?: unknown;
163
+ noDeprecation?: boolean;
164
+ throwDeprecation?: boolean;
165
+ traceDeprecation?: boolean;
166
+ traceProcessWarnings?: boolean;
167
+ report?: Record<string, unknown>;
168
+ binding?: (name: string) => Record<string, unknown>;
169
+ _linkedBinding?: (name: string) => Record<string, unknown>;
170
+ dlopen?: (module: unknown, filename: string, flags?: number) => void;
171
+ reallyExit?: (code?: number) => void;
172
+ _getActiveRequests?: () => unknown[];
173
+ _getActiveHandles?: () => unknown[];
174
+ emitWarning?: (
175
+ warning: string | Error,
176
+ typeOrOptions?: string | { type?: string; code?: string; detail?: string },
177
+ code?: string,
178
+ ) => void;
179
+ hasUncaughtExceptionCaptureCallback?: () => boolean;
180
+ setUncaughtExceptionCaptureCallback?: (
181
+ fn: ((err: Error) => void) | null,
182
+ ) => void;
183
+ sourceMapsEnabled?: boolean;
184
+ setSourceMapsEnabled?: (val: boolean) => void;
185
+ constrainedMemory?: () => number;
186
+ availableMemory?: () => number;
187
+ }
188
+
189
+ function fabricateStream(
190
+ isOutput: boolean,
191
+ writeFn?: (text: string) => boolean,
192
+ ): OutputStreamBridge & InputStreamBridge {
193
+ const bus = new EventEmitter();
194
+
195
+ // raw ANSI writes bypass the stream's write() method
196
+ const rawWrite = (text: string) => {
197
+ if (writeFn) writeFn(text);
198
+ };
199
+
200
+ const stream: OutputStreamBridge & InputStreamBridge = {
201
+ isTTY: false,
202
+ columns: DEFAULT_TERMINAL.COLUMNS,
203
+ rows: DEFAULT_TERMINAL.ROWS,
204
+ isRaw: false,
205
+ on(evt, fn) {
206
+ bus.on(evt, fn);
207
+ return stream;
208
+ },
209
+ once(evt, fn) {
210
+ bus.once(evt, fn);
211
+ return stream;
212
+ },
213
+ off(evt, fn) {
214
+ bus.off(evt, fn);
215
+ return stream;
216
+ },
217
+ emit(evt, ...args) {
218
+ return bus.emit(evt, ...args);
219
+ },
220
+ addListener(evt, fn) {
221
+ bus.addListener(evt, fn);
222
+ return stream;
223
+ },
224
+ removeListener(evt, fn) {
225
+ bus.removeListener(evt, fn);
226
+ return stream;
227
+ },
228
+ removeAllListeners(evt) {
229
+ bus.removeAllListeners(evt);
230
+ return stream;
231
+ },
232
+ setMaxListeners(n) {
233
+ bus.setMaxListeners(n);
234
+ return stream;
235
+ },
236
+ getMaxListeners() {
237
+ return bus.getMaxListeners();
238
+ },
239
+ listenerCount(evt) {
240
+ return bus.listenerCount(evt);
241
+ },
242
+ listeners(evt) {
243
+ return bus.listeners(evt);
244
+ },
245
+ rawListeners(evt) {
246
+ return bus.rawListeners(evt);
247
+ },
248
+ prependListener(evt, fn) {
249
+ bus.prependListener(evt, fn);
250
+ return stream;
251
+ },
252
+ prependOnceListener(evt, fn) {
253
+ bus.prependOnceListener(evt, fn);
254
+ return stream;
255
+ },
256
+ eventNames() {
257
+ return bus.eventNames();
258
+ },
259
+ pause() {
260
+ return stream;
261
+ },
262
+ resume() {
263
+ return stream;
264
+ },
265
+ setEncoding(_enc) {
266
+ return stream;
267
+ },
268
+ write(data, _enc?, cb?) {
269
+ if (isOutput && writeFn && data != null) {
270
+ const text = typeof data === "string" ? data : String(data);
271
+ writeFn(text);
272
+ }
273
+ if (cb) queueMicrotask(cb);
274
+ return true;
275
+ },
276
+ end(data?, cb?) {
277
+ if (isOutput && writeFn && data != null) {
278
+ const text = typeof data === "string" ? data : String(data);
279
+ writeFn(text);
280
+ }
281
+ if (cb) queueMicrotask(cb);
282
+ },
283
+ read() {
284
+ return null;
285
+ },
286
+ destroy() {
287
+ return stream;
288
+ },
289
+ pipe(dest: any) {
290
+ const onData = (chunk: any) => {
291
+ if (dest.write) dest.write(chunk);
292
+ };
293
+ bus.on("data", onData);
294
+ if (!(stream as any)._pipeDests) (stream as any)._pipeDests = [];
295
+ (stream as any)._pipeDests.push({ dest, onData });
296
+ return dest;
297
+ },
298
+ unpipe(dest?: any) {
299
+ const dests: Array<{ dest: any; onData: Function }> =
300
+ (stream as any)._pipeDests || [];
301
+ if (dest) {
302
+ const idx = dests.findIndex((d) => d.dest === dest);
303
+ if (idx >= 0) {
304
+ bus.off("data", dests[idx].onData as any);
305
+ dests.splice(idx, 1);
306
+ }
307
+ } else {
308
+ for (const d of dests) bus.off("data", d.onData as any);
309
+ dests.length = 0;
310
+ }
311
+ return stream;
312
+ },
313
+ unshift() {},
314
+ wrap() {
315
+ return stream;
316
+ },
317
+ [Symbol.asyncIterator]() {
318
+ return { next: async () => ({ done: true, value: undefined }) };
319
+ },
320
+ readable: true,
321
+ writable: true,
322
+ destroyed: false,
323
+ setRawMode(flag) {
324
+ stream.isRaw = flag;
325
+ return stream;
326
+ },
327
+ clearLine(dir: number, cb?) {
328
+ if (isOutput) {
329
+ if (dir === -1)
330
+ rawWrite("\x1b[1K"); // clear left of cursor
331
+ else if (dir === 1)
332
+ rawWrite("\x1b[0K"); // clear right of cursor
333
+ else rawWrite("\x1b[2K"); // clear entire line
334
+ }
335
+ if (cb) cb();
336
+ return true;
337
+ },
338
+ cursorTo(x: number, y?: number | (() => void), cb?: () => void) {
339
+ if (typeof y === "function") {
340
+ cb = y;
341
+ y = undefined;
342
+ }
343
+ if (isOutput) {
344
+ if (typeof y === "number") {
345
+ rawWrite(`\x1b[${y + 1};${x + 1}H`); // move to row;col
346
+ } else {
347
+ rawWrite(`\x1b[${x + 1}G`); // move to column
348
+ }
349
+ }
350
+ if (typeof cb === "function") cb();
351
+ return true;
352
+ },
353
+ moveCursor(dx: number, dy: number, cb?) {
354
+ if (isOutput) {
355
+ if (dx > 0)
356
+ rawWrite(`\x1b[${dx}C`); // move right
357
+ else if (dx < 0) rawWrite(`\x1b[${-dx}D`); // move left
358
+ if (dy > 0)
359
+ rawWrite(`\x1b[${dy}B`); // move down
360
+ else if (dy < 0) rawWrite(`\x1b[${-dy}A`); // move up
361
+ }
362
+ if (cb) cb();
363
+ return true;
364
+ },
365
+ getWindowSize() {
366
+ return [stream.columns, stream.rows];
367
+ },
368
+ getColorDepth(_env?: Record<string, string>): number {
369
+ return 8;
370
+ },
371
+ hasColors(
372
+ countOrEnv?: number | Record<string, string>,
373
+ _env?: Record<string, string>,
374
+ ): boolean {
375
+ const count = typeof countOrEnv === "number" ? countOrEnv : 256;
376
+ return 256 >= count;
377
+ },
378
+ };
379
+
380
+ if (isOutput && writeFn) {
381
+ stream.write = (data: string | Buffer, _enc?: string, cb?: () => void) => {
382
+ const text = typeof data === "string" ? data : data.toString();
383
+ const ok = writeFn(text);
384
+ if (cb) queueMicrotask(cb);
385
+ return ok;
386
+ };
387
+ }
388
+
389
+ return stream;
390
+ }
391
+
392
+ export function buildProcessEnv(config?: {
393
+ cwd?: string;
394
+ env?: ProcessEnvVars;
395
+ onExit?: (code: number) => void;
396
+ onStdout?: (text: string) => void;
397
+ onStderr?: (text: string) => void;
398
+ pid?: number;
399
+ ppid?: number;
400
+ }): ProcessObject {
401
+ let workingDir = config?.cwd || "/";
402
+ let currentUmask = 0o022;
403
+ const bootTime = Date.now();
404
+ const bus = new EventEmitter();
405
+
406
+ const envVars: ProcessEnvVars = {
407
+ NODE_ENV: DEFAULT_ENV.NODE_ENV,
408
+ PATH: DEFAULT_ENV.PATH,
409
+ HOME: DEFAULT_ENV.HOME,
410
+ SHELL: DEFAULT_ENV.SHELL,
411
+ TERM: DEFAULT_ENV.TERM,
412
+ COLORTERM: DEFAULT_ENV.COLORTERM,
413
+ REQUIRES_WASM: DEFAULT_ENV.REQUIRES_WASM,
414
+ npm_config_user_agent: DEFAULT_ENV.npm_config_user_agent,
415
+ npm_execpath: DEFAULT_ENV.npm_execpath,
416
+ npm_node_execpath: DEFAULT_ENV.npm_node_execpath,
417
+ NAPI_RS_FORCE_WASM: "1",
418
+ NEXT_TELEMETRY_DISABLED: "1",
419
+ DO_NOT_TRACK: "1",
420
+ ...config?.env,
421
+ };
422
+
423
+ const stdoutStream = fabricateStream(true, (text) => {
424
+ if (config?.onStdout) {
425
+ config.onStdout(text);
426
+ } else {
427
+ _nativeConsole.log(text);
428
+ }
429
+ return true;
430
+ });
431
+
432
+ const stderrStream = fabricateStream(true, (text) => {
433
+ if (config?.onStderr) {
434
+ config.onStderr(text);
435
+ } else {
436
+ _nativeConsole.error(text);
437
+ }
438
+ return true;
439
+ });
440
+
441
+ const stdinStream = fabricateStream(false);
442
+
443
+ const hrtimeFn = function hrtime(prev?: [number, number]): [number, number] {
444
+ const now = performance.now();
445
+ const secs = Math.floor(now / 1000);
446
+ const nanos = Math.floor((now % 1000) * 1e6);
447
+ if (prev) {
448
+ return [secs - prev[0], nanos - prev[1]];
449
+ }
450
+ return [secs, nanos];
451
+ };
452
+ hrtimeFn.bigint = (): bigint => BigInt(Math.floor(performance.now() * 1e6));
453
+
454
+ const proc: ProcessObject = {
455
+ env: envVars,
456
+
457
+ cwd() {
458
+ if (!proc._debugCwdCalls) proc._debugCwdCalls = 0;
459
+ proc._debugCwdCalls++;
460
+ return workingDir;
461
+ },
462
+
463
+ chdir(dir: string) {
464
+ if (!dir.startsWith("/")) {
465
+ dir = workingDir + "/" + dir;
466
+ }
467
+ workingDir = dir;
468
+ if (proc._chdirHook) proc._chdirHook(dir);
469
+ },
470
+
471
+ platform: MOCK_OS.PLATFORM,
472
+ arch: MOCK_OS.ARCH,
473
+ title: MOCK_PROCESS.TITLE,
474
+ version: VERSIONS.NODE,
475
+ versions: { ...NODE_SUB_VERSIONS },
476
+
477
+ argv: ["node", "/index.js"],
478
+ argv0: "node",
479
+ execPath: MOCK_PROCESS.EXEC_PATH,
480
+ execArgv: [],
481
+
482
+ pid: config?.pid ?? MOCK_PROCESS.PID,
483
+ ppid: config?.ppid ?? MOCK_PROCESS.PPID,
484
+
485
+ exit(code = 0) {
486
+ bus.emit("exit", code);
487
+ if (config?.onExit) config.onExit(code);
488
+ throw new Error(`Process exited with code ${code}`);
489
+ },
490
+
491
+ nextTick(fn, ...args) {
492
+ queueMicrotask(() => fn(...args));
493
+ },
494
+
495
+ stdout: stdoutStream,
496
+ stderr: stderrStream,
497
+ stdin: stdinStream,
498
+
499
+ hrtime: hrtimeFn as ProcessObject["hrtime"],
500
+
501
+ memoryUsage: Object.assign(
502
+ function memoryUsage() {
503
+ return {
504
+ rss: MOCK_MEMORY.RSS,
505
+ heapTotal: MOCK_MEMORY.HEAP_TOTAL,
506
+ heapUsed: MOCK_MEMORY.HEAP_USED,
507
+ external: MOCK_MEMORY.EXTERNAL,
508
+ arrayBuffers: 0,
509
+ };
510
+ },
511
+ { rss: () => MOCK_MEMORY.RSS },
512
+ ),
513
+
514
+ uptime() {
515
+ return (Date.now() - bootTime) / 1000;
516
+ },
517
+
518
+ cpuUsage() {
519
+ return { user: 0, system: 0 };
520
+ },
521
+
522
+ resourceUsage() {
523
+ return {
524
+ userCPUTime: 0, systemCPUTime: 0,
525
+ maxRSS: MOCK_MEMORY.RSS / 1024,
526
+ sharedMemorySize: 0, unsharedDataSize: 0, unsharedStackSize: 0,
527
+ minorPageFault: 0, majorPageFault: 0,
528
+ swappedOut: 0, fsRead: 0, fsWrite: 0,
529
+ ipcSent: 0, ipcReceived: 0,
530
+ signalsCount: 0, voluntaryContextSwitches: 0, involuntaryContextSwitches: 0,
531
+ };
532
+ },
533
+
534
+ abort() {
535
+ throw new Error("process.abort() called");
536
+ },
537
+
538
+ kill(_pid: number, _signal?: string | number) {
539
+ // Emit the signal on this process so listeners (e.g. nodemon) can
540
+ // react to SIGINT / SIGUSR2 etc. just like real Node.js.
541
+ const sig = typeof _signal === "string" ? _signal : "SIGTERM";
542
+ bus.emit(sig);
543
+ return true;
544
+ },
545
+
546
+ umask(mask?: number) {
547
+ const old = currentUmask;
548
+ if (mask !== undefined) currentUmask = mask;
549
+ return old;
550
+ },
551
+
552
+ config: { variables: {}, target_defaults: {} },
553
+ release: { name: "node", sourceUrl: "", headersUrl: "" },
554
+ features: {
555
+ inspector: false,
556
+ debug: false,
557
+ uv: true,
558
+ ipv6: true,
559
+ tls_alpn: true,
560
+ tls_sni: true,
561
+ tls_ocsp: true,
562
+ tls: true,
563
+ },
564
+ debugPort: 9229,
565
+ allowedNodeEnvironmentFlags: new Set<string>(),
566
+ mainModule: undefined as any,
567
+ channel: undefined,
568
+ noDeprecation: false,
569
+ throwDeprecation: false,
570
+ traceDeprecation: false,
571
+ traceProcessWarnings: false,
572
+ report: {
573
+ directory: "",
574
+ filename: "",
575
+ getReport: () => ({}),
576
+ reportOnFatalError: false,
577
+ reportOnSignal: false,
578
+ reportOnUncaughtException: false,
579
+ signal: "SIGUSR2",
580
+ writeReport: () => "",
581
+ },
582
+ binding(name: string): Record<string, unknown> {
583
+ if (name === "natives") return {};
584
+ if (name === "config") return { exposeInternals: false };
585
+ if (name === "constants")
586
+ return {
587
+ os: {
588
+ UV_UDP_REUSEADDR: 4,
589
+ signals: {
590
+ SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGILL: 4, SIGTRAP: 5,
591
+ SIGABRT: 6, SIGBUS: 7, SIGFPE: 8, SIGKILL: 9, SIGUSR1: 10,
592
+ SIGSEGV: 11, SIGUSR2: 12, SIGPIPE: 13, SIGALRM: 14, SIGTERM: 15,
593
+ SIGCHLD: 17, SIGCONT: 18, SIGSTOP: 19, SIGTSTP: 20, SIGTTIN: 21,
594
+ SIGTTOU: 22, SIGURG: 23, SIGXCPU: 24, SIGXFSZ: 25, SIGVTALRM: 26,
595
+ SIGPROF: 27, SIGWINCH: 28, SIGIO: 29, SIGPWR: 30, SIGSYS: 31,
596
+ },
597
+ errno: {},
598
+ },
599
+ fs: {
600
+ O_RDONLY: 0, O_WRONLY: 1, O_RDWR: 2, O_CREAT: 64, O_EXCL: 128,
601
+ O_NOCTTY: 256, O_TRUNC: 512, O_APPEND: 1024, O_NONBLOCK: 2048,
602
+ O_DSYNC: 4096, O_SYNC: 1052672, O_DIRECT: 16384, O_DIRECTORY: 65536,
603
+ O_NOATIME: 262144, O_NOFOLLOW: 131072, O_CLOEXEC: 524288,
604
+ UV_FS_O_FILEMAP: 0,
605
+ S_IFMT: 61440, S_IFREG: 32768, S_IFDIR: 16384, S_IFCHR: 8192,
606
+ S_IFBLK: 24576, S_IFIFO: 4096, S_IFLNK: 40960, S_IFSOCK: 49152,
607
+ F_OK: 0, R_OK: 4, W_OK: 2, X_OK: 1,
608
+ },
609
+ crypto: {},
610
+ zlib: {},
611
+ };
612
+ if (name === "util") return {};
613
+ if (name === "fs") return {};
614
+ if (name === "buffer") return {};
615
+ if (name === "stream_wrap") return {};
616
+ if (name === "tcp_wrap") return {};
617
+ if (name === "pipe_wrap") return {};
618
+ // throw for unknown bindings so callers fall back gracefully
619
+ throw new Error(`No such module: ${name}`);
620
+ },
621
+ _linkedBinding(_name: string): Record<string, unknown> {
622
+ return {};
623
+ },
624
+ dlopen(_module: unknown, _filename: string, _flags?: number): void {
625
+ throw new Error("process.dlopen is not supported in browser environment");
626
+ },
627
+ reallyExit(_code?: number): void {},
628
+ _getActiveRequests(): unknown[] {
629
+ return [];
630
+ },
631
+ _getActiveHandles(): unknown[] {
632
+ return [];
633
+ },
634
+ emitWarning(
635
+ warning: string | Error,
636
+ typeOrOptions?:
637
+ | string
638
+ | { type?: string; code?: string; detail?: string },
639
+ code?: string,
640
+ ): void {
641
+ const msg = typeof warning === "string" ? warning : warning.message;
642
+ const type =
643
+ typeof typeOrOptions === "string"
644
+ ? typeOrOptions
645
+ : (typeOrOptions?.type ?? "Warning");
646
+ bus.emit("warning", { name: type, message: msg, code });
647
+ },
648
+ hasUncaughtExceptionCaptureCallback(): boolean {
649
+ return false;
650
+ },
651
+ setUncaughtExceptionCaptureCallback(
652
+ _fn: ((err: Error) => void) | null,
653
+ ): void {},
654
+ sourceMapsEnabled: false,
655
+ setSourceMapsEnabled(_val: boolean): void {},
656
+ constrainedMemory(): number {
657
+ return 0;
658
+ },
659
+ availableMemory(): number {
660
+ return 512 * 1024 * 1024; // 512MB
661
+ },
662
+
663
+ on(evt, fn) {
664
+ bus.on(evt, fn);
665
+ return proc;
666
+ },
667
+ once(evt, fn) {
668
+ bus.once(evt, fn);
669
+ return proc;
670
+ },
671
+ off(evt, fn) {
672
+ bus.off(evt, fn);
673
+ return proc;
674
+ },
675
+ emit(evt, ...args) {
676
+ return bus.emit(evt, ...args);
677
+ },
678
+ addListener(evt, fn) {
679
+ bus.addListener(evt, fn);
680
+ return proc;
681
+ },
682
+ removeListener(evt, fn) {
683
+ bus.removeListener(evt, fn);
684
+ return proc;
685
+ },
686
+ removeAllListeners(evt) {
687
+ bus.removeAllListeners(evt);
688
+ return proc;
689
+ },
690
+ listeners(evt) {
691
+ return bus.listeners(evt);
692
+ },
693
+ listenerCount(evt) {
694
+ return bus.listenerCount(evt);
695
+ },
696
+ prependListener(evt, fn) {
697
+ bus.prependListener(evt, fn);
698
+ return proc;
699
+ },
700
+ prependOnceListener(evt, fn) {
701
+ bus.prependOnceListener(evt, fn);
702
+ return proc;
703
+ },
704
+ eventNames() {
705
+ return bus.eventNames();
706
+ },
707
+ setMaxListeners(n) {
708
+ bus.setMaxListeners(n);
709
+ return proc;
710
+ },
711
+ getMaxListeners() {
712
+ return bus.getMaxListeners();
713
+ },
714
+ };
715
+
716
+ return proc;
717
+ }
718
+
719
+ export const process = buildProcessEnv();
720
+
721
+ export default process;