@run0/jiki 0.1.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.
Files changed (152) hide show
  1. package/dist/browser-bundle.d.ts +40 -0
  2. package/dist/builtins.d.ts +22 -0
  3. package/dist/code-transform.d.ts +7 -0
  4. package/dist/config/cdn.d.ts +13 -0
  5. package/dist/container.d.ts +101 -0
  6. package/dist/dev-server.d.ts +69 -0
  7. package/dist/errors.d.ts +19 -0
  8. package/dist/frameworks/code-transforms.d.ts +32 -0
  9. package/dist/frameworks/next-api-handler.d.ts +72 -0
  10. package/dist/frameworks/next-dev-server.d.ts +141 -0
  11. package/dist/frameworks/next-html-generator.d.ts +36 -0
  12. package/dist/frameworks/next-route-resolver.d.ts +19 -0
  13. package/dist/frameworks/next-shims.d.ts +78 -0
  14. package/dist/frameworks/remix-dev-server.d.ts +47 -0
  15. package/dist/frameworks/sveltekit-dev-server.d.ts +43 -0
  16. package/dist/frameworks/vite-dev-server.d.ts +50 -0
  17. package/dist/fs-errors.d.ts +36 -0
  18. package/dist/index.cjs +14916 -0
  19. package/dist/index.cjs.map +1 -0
  20. package/dist/index.d.ts +61 -0
  21. package/dist/index.mjs +14898 -0
  22. package/dist/index.mjs.map +1 -0
  23. package/dist/kernel.d.ts +48 -0
  24. package/dist/memfs.d.ts +144 -0
  25. package/dist/metrics.d.ts +78 -0
  26. package/dist/module-resolver.d.ts +60 -0
  27. package/dist/network-interceptor.d.ts +71 -0
  28. package/dist/npm/cache.d.ts +76 -0
  29. package/dist/npm/index.d.ts +60 -0
  30. package/dist/npm/lockfile-reader.d.ts +32 -0
  31. package/dist/npm/pnpm.d.ts +18 -0
  32. package/dist/npm/registry.d.ts +45 -0
  33. package/dist/npm/resolver.d.ts +39 -0
  34. package/dist/npm/sync-installer.d.ts +18 -0
  35. package/dist/npm/tarball.d.ts +4 -0
  36. package/dist/npm/workspaces.d.ts +46 -0
  37. package/dist/persistence.d.ts +94 -0
  38. package/dist/plugin.d.ts +156 -0
  39. package/dist/polyfills/assert.d.ts +30 -0
  40. package/dist/polyfills/child_process.d.ts +116 -0
  41. package/dist/polyfills/chokidar.d.ts +18 -0
  42. package/dist/polyfills/crypto.d.ts +49 -0
  43. package/dist/polyfills/events.d.ts +28 -0
  44. package/dist/polyfills/fs.d.ts +82 -0
  45. package/dist/polyfills/http.d.ts +147 -0
  46. package/dist/polyfills/module.d.ts +29 -0
  47. package/dist/polyfills/net.d.ts +53 -0
  48. package/dist/polyfills/os.d.ts +91 -0
  49. package/dist/polyfills/path.d.ts +96 -0
  50. package/dist/polyfills/perf_hooks.d.ts +21 -0
  51. package/dist/polyfills/process.d.ts +99 -0
  52. package/dist/polyfills/querystring.d.ts +15 -0
  53. package/dist/polyfills/readdirp.d.ts +18 -0
  54. package/dist/polyfills/readline.d.ts +32 -0
  55. package/dist/polyfills/stream.d.ts +106 -0
  56. package/dist/polyfills/stubs.d.ts +737 -0
  57. package/dist/polyfills/tty.d.ts +25 -0
  58. package/dist/polyfills/url.d.ts +41 -0
  59. package/dist/polyfills/util.d.ts +61 -0
  60. package/dist/polyfills/v8.d.ts +43 -0
  61. package/dist/polyfills/vm.d.ts +76 -0
  62. package/dist/polyfills/worker-threads.d.ts +77 -0
  63. package/dist/polyfills/ws.d.ts +32 -0
  64. package/dist/polyfills/zlib.d.ts +87 -0
  65. package/dist/runtime-helpers.d.ts +4 -0
  66. package/dist/runtime-interface.d.ts +39 -0
  67. package/dist/sandbox.d.ts +69 -0
  68. package/dist/server-bridge.d.ts +55 -0
  69. package/dist/shell-commands.d.ts +2 -0
  70. package/dist/shell.d.ts +101 -0
  71. package/dist/transpiler.d.ts +47 -0
  72. package/dist/type-checker.d.ts +57 -0
  73. package/dist/types/package-json.d.ts +17 -0
  74. package/dist/utils/binary-encoding.d.ts +4 -0
  75. package/dist/utils/hash.d.ts +6 -0
  76. package/dist/utils/safe-path.d.ts +6 -0
  77. package/dist/worker-runtime.d.ts +34 -0
  78. package/package.json +59 -0
  79. package/src/browser-bundle.ts +498 -0
  80. package/src/builtins.ts +222 -0
  81. package/src/code-transform.ts +183 -0
  82. package/src/config/cdn.ts +17 -0
  83. package/src/container.ts +343 -0
  84. package/src/dev-server.ts +322 -0
  85. package/src/errors.ts +604 -0
  86. package/src/frameworks/code-transforms.ts +667 -0
  87. package/src/frameworks/next-api-handler.ts +366 -0
  88. package/src/frameworks/next-dev-server.ts +1252 -0
  89. package/src/frameworks/next-html-generator.ts +585 -0
  90. package/src/frameworks/next-route-resolver.ts +521 -0
  91. package/src/frameworks/next-shims.ts +1084 -0
  92. package/src/frameworks/remix-dev-server.ts +163 -0
  93. package/src/frameworks/sveltekit-dev-server.ts +197 -0
  94. package/src/frameworks/vite-dev-server.ts +370 -0
  95. package/src/fs-errors.ts +118 -0
  96. package/src/index.ts +188 -0
  97. package/src/kernel.ts +381 -0
  98. package/src/memfs.ts +1006 -0
  99. package/src/metrics.ts +140 -0
  100. package/src/module-resolver.ts +511 -0
  101. package/src/network-interceptor.ts +143 -0
  102. package/src/npm/cache.ts +172 -0
  103. package/src/npm/index.ts +377 -0
  104. package/src/npm/lockfile-reader.ts +105 -0
  105. package/src/npm/pnpm.ts +108 -0
  106. package/src/npm/registry.ts +120 -0
  107. package/src/npm/resolver.ts +339 -0
  108. package/src/npm/sync-installer.ts +217 -0
  109. package/src/npm/tarball.ts +136 -0
  110. package/src/npm/workspaces.ts +255 -0
  111. package/src/persistence.ts +235 -0
  112. package/src/plugin.ts +293 -0
  113. package/src/polyfills/assert.ts +164 -0
  114. package/src/polyfills/child_process.ts +535 -0
  115. package/src/polyfills/chokidar.ts +52 -0
  116. package/src/polyfills/crypto.ts +433 -0
  117. package/src/polyfills/events.ts +178 -0
  118. package/src/polyfills/fs.ts +297 -0
  119. package/src/polyfills/http.ts +478 -0
  120. package/src/polyfills/module.ts +97 -0
  121. package/src/polyfills/net.ts +123 -0
  122. package/src/polyfills/os.ts +108 -0
  123. package/src/polyfills/path.ts +169 -0
  124. package/src/polyfills/perf_hooks.ts +30 -0
  125. package/src/polyfills/process.ts +349 -0
  126. package/src/polyfills/querystring.ts +66 -0
  127. package/src/polyfills/readdirp.ts +72 -0
  128. package/src/polyfills/readline.ts +80 -0
  129. package/src/polyfills/stream.ts +610 -0
  130. package/src/polyfills/stubs.ts +600 -0
  131. package/src/polyfills/tty.ts +43 -0
  132. package/src/polyfills/url.ts +97 -0
  133. package/src/polyfills/util.ts +173 -0
  134. package/src/polyfills/v8.ts +62 -0
  135. package/src/polyfills/vm.ts +111 -0
  136. package/src/polyfills/worker-threads.ts +189 -0
  137. package/src/polyfills/ws.ts +73 -0
  138. package/src/polyfills/zlib.ts +244 -0
  139. package/src/runtime-helpers.ts +83 -0
  140. package/src/runtime-interface.ts +46 -0
  141. package/src/sandbox.ts +178 -0
  142. package/src/server-bridge.ts +473 -0
  143. package/src/service-worker.ts +153 -0
  144. package/src/shell-commands.ts +708 -0
  145. package/src/shell.ts +795 -0
  146. package/src/transpiler.ts +282 -0
  147. package/src/type-checker.ts +241 -0
  148. package/src/types/package-json.ts +17 -0
  149. package/src/utils/binary-encoding.ts +38 -0
  150. package/src/utils/hash.ts +24 -0
  151. package/src/utils/safe-path.ts +38 -0
  152. package/src/worker-runtime.ts +42 -0
@@ -0,0 +1,108 @@
1
+ export function hostname(): string {
2
+ return "localhost";
3
+ }
4
+ export function type(): string {
5
+ return "Linux";
6
+ }
7
+ export function platform(): string {
8
+ return "linux";
9
+ }
10
+ export function arch(): string {
11
+ return "x64";
12
+ }
13
+ export function release(): string {
14
+ return "5.15.0";
15
+ }
16
+ export function tmpdir(): string {
17
+ return "/tmp";
18
+ }
19
+ export function homedir(): string {
20
+ return "/";
21
+ }
22
+ export function userInfo(): {
23
+ username: string;
24
+ uid: number;
25
+ gid: number;
26
+ shell: string;
27
+ homedir: string;
28
+ } {
29
+ return {
30
+ username: "user",
31
+ uid: 1000,
32
+ gid: 1000,
33
+ shell: "/bin/sh",
34
+ homedir: "/",
35
+ };
36
+ }
37
+ export function cpus(): {
38
+ model: string;
39
+ speed: number;
40
+ times: { user: number; nice: number; sys: number; idle: number; irq: number };
41
+ }[] {
42
+ const count =
43
+ typeof navigator !== "undefined" ? navigator.hardwareConcurrency || 4 : 4;
44
+ return Array.from({ length: count }, () => ({
45
+ model: "Browser CPU",
46
+ speed: 2400,
47
+ times: { user: 0, nice: 0, sys: 0, idle: 0, irq: 0 },
48
+ }));
49
+ }
50
+ export function totalmem(): number {
51
+ return 8 * 1024 * 1024 * 1024;
52
+ }
53
+ export function freemem(): number {
54
+ return 4 * 1024 * 1024 * 1024;
55
+ }
56
+ export function uptime(): number {
57
+ return performance.now() / 1000;
58
+ }
59
+ export function loadavg(): [number, number, number] {
60
+ return [0, 0, 0];
61
+ }
62
+ export function networkInterfaces(): Record<string, unknown[]> {
63
+ return {};
64
+ }
65
+ export function endianness(): "BE" | "LE" {
66
+ return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1 ? "LE" : "BE";
67
+ }
68
+ export const EOL = "\n";
69
+ export const constants = {
70
+ signals: { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGTERM: 15, SIGKILL: 9 },
71
+ errno: {},
72
+ priority: {
73
+ PRIORITY_LOW: 19,
74
+ PRIORITY_BELOW_NORMAL: 10,
75
+ PRIORITY_NORMAL: 0,
76
+ PRIORITY_ABOVE_NORMAL: -7,
77
+ PRIORITY_HIGH: -14,
78
+ PRIORITY_HIGHEST: -20,
79
+ },
80
+ };
81
+ export function version(): string {
82
+ return "v20.0.0";
83
+ }
84
+ export function machine(): string {
85
+ return "x86_64";
86
+ }
87
+
88
+ export default {
89
+ hostname,
90
+ type,
91
+ platform,
92
+ arch,
93
+ release,
94
+ tmpdir,
95
+ homedir,
96
+ userInfo,
97
+ cpus,
98
+ totalmem,
99
+ freemem,
100
+ uptime,
101
+ loadavg,
102
+ networkInterfaces,
103
+ endianness,
104
+ EOL,
105
+ constants,
106
+ version,
107
+ machine,
108
+ };
@@ -0,0 +1,169 @@
1
+ export const sep = "/";
2
+ export const delimiter = ":";
3
+
4
+ export function normalize(path: string): string {
5
+ if (!path) return ".";
6
+ const isAbs = path.startsWith("/");
7
+ const parts = path.split("/").filter(Boolean);
8
+ const resolved: string[] = [];
9
+ for (const part of parts) {
10
+ if (part === "..") {
11
+ if (resolved.length > 0 && resolved[resolved.length - 1] !== "..")
12
+ resolved.pop();
13
+ else if (!isAbs) resolved.push("..");
14
+ } else if (part !== ".") {
15
+ resolved.push(part);
16
+ }
17
+ }
18
+ let result = resolved.join("/");
19
+ if (isAbs) result = "/" + result;
20
+ return result || ".";
21
+ }
22
+
23
+ export function join(...paths: string[]): string {
24
+ if (paths.length === 0) return ".";
25
+ return normalize(paths.filter(Boolean).join("/"));
26
+ }
27
+
28
+ export function resolve(...paths: string[]): string {
29
+ let resolvedPath = "";
30
+ for (let i = paths.length - 1; i >= 0 && !resolvedPath.startsWith("/"); i--) {
31
+ const p = paths[i];
32
+ if (!p) continue;
33
+ resolvedPath = p + (resolvedPath ? "/" + resolvedPath : "");
34
+ }
35
+ if (!resolvedPath.startsWith("/")) {
36
+ const cwd =
37
+ (typeof globalThis !== "undefined" && globalThis.process?.cwd?.()) || "/";
38
+ resolvedPath = cwd + (resolvedPath ? "/" + resolvedPath : "");
39
+ }
40
+ return normalize(resolvedPath);
41
+ }
42
+
43
+ export function isAbsolute(path: string): boolean {
44
+ return path.startsWith("/");
45
+ }
46
+
47
+ export function dirname(path: string): string {
48
+ if (!path) return ".";
49
+ const n = normalize(path);
50
+ const last = n.lastIndexOf("/");
51
+ if (last === -1) return ".";
52
+ if (last === 0) return "/";
53
+ return n.slice(0, last);
54
+ }
55
+
56
+ export function basename(path: string, ext?: string): string {
57
+ if (!path) return "";
58
+ const n = normalize(path);
59
+ let base = n.slice(n.lastIndexOf("/") + 1);
60
+ if (ext && base.endsWith(ext)) base = base.slice(0, -ext.length);
61
+ return base;
62
+ }
63
+
64
+ export function extname(path: string): string {
65
+ const base = basename(path);
66
+ const dotIndex = base.lastIndexOf(".");
67
+ if (dotIndex <= 0) return "";
68
+ return base.slice(dotIndex);
69
+ }
70
+
71
+ export function relative(from: string, to: string): string {
72
+ from = resolve(from);
73
+ to = resolve(to);
74
+ if (from === to) return "";
75
+ const fromParts = from.split("/").filter(Boolean);
76
+ const toParts = to.split("/").filter(Boolean);
77
+ let common = 0;
78
+ for (let i = 0; i < Math.min(fromParts.length, toParts.length); i++) {
79
+ if (fromParts[i] !== toParts[i]) break;
80
+ common++;
81
+ }
82
+ return (
83
+ [
84
+ ...Array(fromParts.length - common).fill(".."),
85
+ ...toParts.slice(common),
86
+ ].join("/") || "."
87
+ );
88
+ }
89
+
90
+ export function parse(path: string): {
91
+ root: string;
92
+ dir: string;
93
+ base: string;
94
+ ext: string;
95
+ name: string;
96
+ } {
97
+ const n = normalize(path);
98
+ const dir = dirname(n);
99
+ const base = basename(n);
100
+ const ext = extname(n);
101
+ return {
102
+ root: isAbsolute(n) ? "/" : "",
103
+ dir,
104
+ base,
105
+ ext,
106
+ name: base.slice(0, base.length - ext.length),
107
+ };
108
+ }
109
+
110
+ export function format(obj: {
111
+ root?: string;
112
+ dir?: string;
113
+ base?: string;
114
+ ext?: string;
115
+ name?: string;
116
+ }): string {
117
+ const dir = obj.dir || obj.root || "";
118
+ const base = obj.base || (obj.name || "") + (obj.ext || "");
119
+ if (!dir) return base;
120
+ if (dir === obj.root) return dir + base;
121
+ return dir + "/" + base;
122
+ }
123
+
124
+ export const posix = {
125
+ sep,
126
+ delimiter,
127
+ normalize,
128
+ join,
129
+ resolve,
130
+ isAbsolute,
131
+ dirname,
132
+ basename,
133
+ extname,
134
+ relative,
135
+ parse,
136
+ format,
137
+ };
138
+ /** @note win32 uses posix implementation — Windows paths not supported in browser */
139
+ export const win32 = {
140
+ sep: "\\",
141
+ delimiter: ";",
142
+ normalize,
143
+ join,
144
+ resolve,
145
+ isAbsolute,
146
+ dirname,
147
+ basename,
148
+ extname,
149
+ relative,
150
+ parse,
151
+ format,
152
+ };
153
+
154
+ export default {
155
+ sep,
156
+ delimiter,
157
+ normalize,
158
+ join,
159
+ resolve,
160
+ isAbsolute,
161
+ dirname,
162
+ basename,
163
+ extname,
164
+ relative,
165
+ parse,
166
+ format,
167
+ posix,
168
+ win32,
169
+ };
@@ -0,0 +1,30 @@
1
+ export const performance = globalThis.performance;
2
+
3
+ export class PerformanceObserver {
4
+ private callback: (list: unknown) => void;
5
+ constructor(callback: (list: unknown) => void) {
6
+ this.callback = callback;
7
+ }
8
+ observe(_options?: unknown): void {}
9
+ disconnect(): void {}
10
+ }
11
+
12
+ export function monitorEventLoopDelay(_options?: unknown): {
13
+ enable(): void;
14
+ disable(): void;
15
+ min: number;
16
+ max: number;
17
+ mean: number;
18
+ percentile(p: number): number;
19
+ } {
20
+ return {
21
+ enable() {},
22
+ disable() {},
23
+ min: 0,
24
+ max: 0,
25
+ mean: 0,
26
+ percentile: () => 0,
27
+ };
28
+ }
29
+
30
+ export default { performance, PerformanceObserver, monitorEventLoopDelay };
@@ -0,0 +1,349 @@
1
+ import { EventEmitter, EventListener } from "./events";
2
+
3
+ export interface ProcessEnv {
4
+ [key: string]: string | undefined;
5
+ }
6
+
7
+ interface ProcessStream {
8
+ isTTY: boolean;
9
+ on: (event: string, listener: EventListener) => ProcessStream;
10
+ once: (event: string, listener: EventListener) => ProcessStream;
11
+ off: (event: string, listener: EventListener) => ProcessStream;
12
+ emit: (event: string, ...args: unknown[]) => boolean;
13
+ addListener: (event: string, listener: EventListener) => ProcessStream;
14
+ removeListener: (event: string, listener: EventListener) => ProcessStream;
15
+ removeAllListeners: (event?: string) => ProcessStream;
16
+ setMaxListeners: (n: number) => ProcessStream;
17
+ getMaxListeners: () => number;
18
+ listenerCount: (event: string) => number;
19
+ listeners: (event: string) => EventListener[];
20
+ rawListeners: (event: string) => EventListener[];
21
+ prependListener: (event: string, listener: EventListener) => ProcessStream;
22
+ prependOnceListener: (
23
+ event: string,
24
+ listener: EventListener,
25
+ ) => ProcessStream;
26
+ eventNames: () => string[];
27
+ pause?: () => ProcessStream;
28
+ resume?: () => ProcessStream;
29
+ setEncoding?: (encoding: string) => ProcessStream;
30
+ }
31
+
32
+ interface ProcessWritableStream extends ProcessStream {
33
+ write: (
34
+ data: string | Buffer,
35
+ encoding?: string,
36
+ callback?: () => void,
37
+ ) => boolean;
38
+ end?: (data?: string, callback?: () => void) => void;
39
+ }
40
+
41
+ interface ProcessReadableStream extends ProcessStream {
42
+ read?: (size?: number) => string | Buffer | null;
43
+ setRawMode?: (mode: boolean) => ProcessReadableStream;
44
+ }
45
+
46
+ export interface Process {
47
+ env: ProcessEnv;
48
+ cwd: () => string;
49
+ chdir: (directory: string) => void;
50
+ platform: string;
51
+ arch: string;
52
+ version: string;
53
+ versions: { node: string; v8: string; uv: string };
54
+ argv: string[];
55
+ argv0: string;
56
+ execPath: string;
57
+ execArgv: string[];
58
+ pid: number;
59
+ ppid: number;
60
+ exit: (code?: number) => never;
61
+ nextTick: (
62
+ callback: (...args: unknown[]) => void,
63
+ ...args: unknown[]
64
+ ) => void;
65
+ stdout: ProcessWritableStream;
66
+ stderr: ProcessWritableStream;
67
+ stdin: ProcessReadableStream;
68
+ hrtime: { (time?: [number, number]): [number, number]; bigint: () => bigint };
69
+ memoryUsage: () => {
70
+ rss: number;
71
+ heapTotal: number;
72
+ heapUsed: number;
73
+ external: number;
74
+ arrayBuffers: number;
75
+ };
76
+ uptime: () => number;
77
+ cpuUsage: () => { user: number; system: number };
78
+ on: (event: string, listener: EventListener) => Process;
79
+ once: (event: string, listener: EventListener) => Process;
80
+ off: (event: string, listener: EventListener) => Process;
81
+ emit: (event: string, ...args: unknown[]) => boolean;
82
+ addListener: (event: string, listener: EventListener) => Process;
83
+ removeListener: (event: string, listener: EventListener) => Process;
84
+ removeAllListeners: (event?: string) => Process;
85
+ listeners: (event: string) => EventListener[];
86
+ listenerCount: (event: string) => number;
87
+ prependListener: (event: string, listener: EventListener) => Process;
88
+ prependOnceListener: (event: string, listener: EventListener) => Process;
89
+ eventNames: () => string[];
90
+ setMaxListeners: (n: number) => Process;
91
+ getMaxListeners: () => number;
92
+ send?: (
93
+ message: unknown,
94
+ callback?: (error: Error | null) => void,
95
+ ) => boolean;
96
+ connected?: boolean;
97
+ _cwdCallCount?: number;
98
+ }
99
+
100
+ function createProcessStream(
101
+ isWritable: boolean,
102
+ writeImpl?: (data: string) => boolean,
103
+ ): ProcessWritableStream & ProcessReadableStream {
104
+ const emitter = new EventEmitter();
105
+ const stream: ProcessWritableStream & ProcessReadableStream = {
106
+ isTTY: false,
107
+ on(event, listener) {
108
+ emitter.on(event, listener);
109
+ return stream;
110
+ },
111
+ once(event, listener) {
112
+ emitter.once(event, listener);
113
+ return stream;
114
+ },
115
+ off(event, listener) {
116
+ emitter.off(event, listener);
117
+ return stream;
118
+ },
119
+ emit(event, ...args) {
120
+ return emitter.emit(event, ...args);
121
+ },
122
+ addListener(event, listener) {
123
+ emitter.addListener(event, listener);
124
+ return stream;
125
+ },
126
+ removeListener(event, listener) {
127
+ emitter.removeListener(event, listener);
128
+ return stream;
129
+ },
130
+ removeAllListeners(event?) {
131
+ emitter.removeAllListeners(event);
132
+ return stream;
133
+ },
134
+ setMaxListeners(n) {
135
+ emitter.setMaxListeners(n);
136
+ return stream;
137
+ },
138
+ getMaxListeners() {
139
+ return emitter.getMaxListeners();
140
+ },
141
+ listenerCount(event) {
142
+ return emitter.listenerCount(event);
143
+ },
144
+ listeners(event) {
145
+ return emitter.listeners(event);
146
+ },
147
+ rawListeners(event) {
148
+ return emitter.rawListeners(event);
149
+ },
150
+ prependListener(event, listener) {
151
+ emitter.prependListener(event, listener);
152
+ return stream;
153
+ },
154
+ prependOnceListener(event, listener) {
155
+ emitter.prependOnceListener(event, listener);
156
+ return stream;
157
+ },
158
+ eventNames() {
159
+ return emitter.eventNames();
160
+ },
161
+ pause() {
162
+ return stream;
163
+ },
164
+ resume() {
165
+ return stream;
166
+ },
167
+ setEncoding() {
168
+ return stream;
169
+ },
170
+ write(data, _encoding?, callback?) {
171
+ if (callback) queueMicrotask(callback);
172
+ return true;
173
+ },
174
+ end(_data?, callback?) {
175
+ if (callback) queueMicrotask(callback);
176
+ },
177
+ read() {
178
+ return null;
179
+ },
180
+ setRawMode() {
181
+ return stream;
182
+ },
183
+ };
184
+ if (isWritable && writeImpl) {
185
+ stream.write = (data, _encoding?, callback?) => {
186
+ const result = writeImpl(
187
+ typeof data === "string" ? data : data.toString(),
188
+ );
189
+ if (callback) queueMicrotask(callback);
190
+ return result;
191
+ };
192
+ }
193
+ return stream;
194
+ }
195
+
196
+ export function createProcess(options?: {
197
+ cwd?: string;
198
+ env?: ProcessEnv;
199
+ onExit?: (code: number) => void;
200
+ onStdout?: (data: string) => void;
201
+ onStderr?: (data: string) => void;
202
+ }): Process {
203
+ let currentDir = options?.cwd || "/";
204
+ const env: ProcessEnv = {
205
+ NODE_ENV: "development",
206
+ PATH: "/usr/local/bin:/usr/bin:/bin:/node_modules/.bin",
207
+ HOME: "/",
208
+ ...options?.env,
209
+ };
210
+ const emitter = new EventEmitter();
211
+ const startTime = Date.now();
212
+
213
+ const proc: Process = {
214
+ env,
215
+ cwd() {
216
+ return currentDir;
217
+ },
218
+ chdir(dir) {
219
+ currentDir = dir.startsWith("/") ? dir : currentDir + "/" + dir;
220
+ },
221
+ platform: "linux",
222
+ /** Set to 'wasm32' to indicate browser-based WebAssembly runtime */
223
+ arch: "wasm32",
224
+ version: "v20.0.0",
225
+ versions: { node: "20.0.0", v8: "11.3.244.8", uv: "1.44.2" },
226
+ argv: ["node", "/index.js"],
227
+ argv0: "node",
228
+ execPath: "/usr/local/bin/node",
229
+ execArgv: [],
230
+ pid: 1,
231
+ ppid: 0,
232
+ // process.exit() emits 'beforeExit' and 'exit' events before throwing
233
+ // to halt execution. In a real Node.js process, 'beforeExit' fires when
234
+ // the event loop drains. In the browser runtime, we emit it synchronously
235
+ // before 'exit' as a best-effort approximation. The throw after events
236
+ // is intentional — it stops execution in the browser environment where
237
+ // we cannot actually terminate the process.
238
+ exit(code = 0) {
239
+ if (!(proc as any)._exiting) {
240
+ (proc as any)._exiting = true;
241
+ emitter.emit("beforeExit", code);
242
+ emitter.emit("exit", code);
243
+ options?.onExit?.(code);
244
+ }
245
+ throw new Error(`Process exited with code ${code}`);
246
+ },
247
+ nextTick(cb, ...args) {
248
+ queueMicrotask(() => cb(...args));
249
+ },
250
+ stdout: createProcessStream(true, d => {
251
+ options?.onStdout?.(d) ?? console.log(d);
252
+ return true;
253
+ }) as ProcessWritableStream,
254
+ stderr: createProcessStream(true, d => {
255
+ options?.onStderr?.(d) ?? console.error(d);
256
+ return true;
257
+ }) as ProcessWritableStream,
258
+ stdin: Object.assign(createProcessStream(false), {
259
+ /** Buffer for pending input data. */
260
+ _buffer: [] as string[],
261
+ /** Push data into stdin (called by Container.sendInput). */
262
+ _push(data: string): void {
263
+ (proc.stdin as any)._buffer.push(data);
264
+ proc.stdin.emit("data", data);
265
+ },
266
+ read(): string | null {
267
+ const buf = (proc.stdin as any)._buffer;
268
+ return buf.length > 0 ? buf.shift() : null;
269
+ },
270
+ }) as ProcessReadableStream,
271
+ hrtime: Object.assign(
272
+ function hrtime(time?: [number, number]): [number, number] {
273
+ const now = performance.now();
274
+ const s = Math.floor(now / 1000);
275
+ const ns = Math.floor((now % 1000) * 1e6);
276
+ if (time) return [s - time[0], ns - time[1]];
277
+ return [s, ns];
278
+ },
279
+ { bigint: (): bigint => BigInt(Math.floor(performance.now() * 1e6)) },
280
+ ),
281
+ connected: false,
282
+ send: (_message: unknown, _callback?: (error: Error | null) => void) =>
283
+ false,
284
+ memoryUsage: () => ({
285
+ rss: 50 * 1024 * 1024,
286
+ heapTotal: 30 * 1024 * 1024,
287
+ heapUsed: 20 * 1024 * 1024,
288
+ external: 1024 * 1024,
289
+ arrayBuffers: 0,
290
+ }),
291
+ uptime: () => (Date.now() - startTime) / 1000,
292
+ cpuUsage: () => ({ user: 0, system: 0 }),
293
+ on(event, listener) {
294
+ emitter.on(event, listener);
295
+ return proc;
296
+ },
297
+ once(event, listener) {
298
+ emitter.once(event, listener);
299
+ return proc;
300
+ },
301
+ off(event, listener) {
302
+ emitter.off(event, listener);
303
+ return proc;
304
+ },
305
+ emit(event, ...args) {
306
+ return emitter.emit(event, ...args);
307
+ },
308
+ addListener(event, listener) {
309
+ emitter.addListener(event, listener);
310
+ return proc;
311
+ },
312
+ removeListener(event, listener) {
313
+ emitter.removeListener(event, listener);
314
+ return proc;
315
+ },
316
+ removeAllListeners(event?) {
317
+ emitter.removeAllListeners(event);
318
+ return proc;
319
+ },
320
+ listeners(event) {
321
+ return emitter.listeners(event);
322
+ },
323
+ listenerCount(event) {
324
+ return emitter.listenerCount(event);
325
+ },
326
+ prependListener(event, listener) {
327
+ emitter.prependListener(event, listener);
328
+ return proc;
329
+ },
330
+ prependOnceListener(event, listener) {
331
+ emitter.prependOnceListener(event, listener);
332
+ return proc;
333
+ },
334
+ eventNames() {
335
+ return emitter.eventNames();
336
+ },
337
+ setMaxListeners(n) {
338
+ emitter.setMaxListeners(n);
339
+ return proc;
340
+ },
341
+ getMaxListeners() {
342
+ return emitter.getMaxListeners();
343
+ },
344
+ };
345
+ return proc;
346
+ }
347
+
348
+ export const process = createProcess();
349
+ export default process;
@@ -0,0 +1,66 @@
1
+ export function stringify(
2
+ obj: Record<string, unknown>,
3
+ sep = "&",
4
+ eq = "=",
5
+ ): string {
6
+ if (!obj) return "";
7
+ return Object.entries(obj)
8
+ .filter(([, v]) => v !== undefined)
9
+ .map(([k, v]) => {
10
+ if (Array.isArray(v))
11
+ return v
12
+ .map(
13
+ item =>
14
+ encodeURIComponent(k) + eq + encodeURIComponent(String(item)),
15
+ )
16
+ .join(sep);
17
+ return encodeURIComponent(k) + eq + encodeURIComponent(String(v));
18
+ })
19
+ .join(sep);
20
+ }
21
+
22
+ export function parse(
23
+ str: string,
24
+ sep = "&",
25
+ eq = "=",
26
+ ): Record<string, string | string[]> {
27
+ const result: Record<string, string | string[]> = {};
28
+ if (!str) return result;
29
+ for (const part of str.split(sep)) {
30
+ const idx = part.indexOf(eq);
31
+ const key = decodeURIComponent(idx >= 0 ? part.slice(0, idx) : part);
32
+ const value =
33
+ idx >= 0 ? decodeURIComponent(part.slice(idx + eq.length)) : "";
34
+ if (key in result) {
35
+ const existing = result[key];
36
+ if (Array.isArray(existing)) existing.push(value);
37
+ else result[key] = [existing, value];
38
+ } else {
39
+ result[key] = value;
40
+ }
41
+ }
42
+ return result;
43
+ }
44
+
45
+ export function escape(str: string): string {
46
+ return encodeURIComponent(str);
47
+ }
48
+ export function unescape(str: string): string {
49
+ return decodeURIComponent(str.replace(/\+/g, " "));
50
+ }
51
+ export function encode(
52
+ obj: Record<string, unknown>,
53
+ sep?: string,
54
+ eq?: string,
55
+ ): string {
56
+ return stringify(obj, sep, eq);
57
+ }
58
+ export function decode(
59
+ str: string,
60
+ sep?: string,
61
+ eq?: string,
62
+ ): Record<string, string | string[]> {
63
+ return parse(str, sep, eq);
64
+ }
65
+
66
+ export default { stringify, parse, escape, unescape, encode, decode };