almostnode 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 (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +731 -0
  3. package/dist/__sw__.js +394 -0
  4. package/dist/ai-chatbot-demo-entry.d.ts +6 -0
  5. package/dist/ai-chatbot-demo-entry.d.ts.map +1 -0
  6. package/dist/ai-chatbot-demo.d.ts +42 -0
  7. package/dist/ai-chatbot-demo.d.ts.map +1 -0
  8. package/dist/assets/runtime-worker-D9x_Ddwz.js +60543 -0
  9. package/dist/assets/runtime-worker-D9x_Ddwz.js.map +1 -0
  10. package/dist/convex-app-demo-entry.d.ts +6 -0
  11. package/dist/convex-app-demo-entry.d.ts.map +1 -0
  12. package/dist/convex-app-demo.d.ts +68 -0
  13. package/dist/convex-app-demo.d.ts.map +1 -0
  14. package/dist/cors-proxy.d.ts +46 -0
  15. package/dist/cors-proxy.d.ts.map +1 -0
  16. package/dist/create-runtime.d.ts +42 -0
  17. package/dist/create-runtime.d.ts.map +1 -0
  18. package/dist/demo.d.ts +6 -0
  19. package/dist/demo.d.ts.map +1 -0
  20. package/dist/dev-server.d.ts +97 -0
  21. package/dist/dev-server.d.ts.map +1 -0
  22. package/dist/frameworks/next-dev-server.d.ts +202 -0
  23. package/dist/frameworks/next-dev-server.d.ts.map +1 -0
  24. package/dist/frameworks/vite-dev-server.d.ts +85 -0
  25. package/dist/frameworks/vite-dev-server.d.ts.map +1 -0
  26. package/dist/index.cjs +14965 -0
  27. package/dist/index.cjs.map +1 -0
  28. package/dist/index.d.ts +71 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.mjs +14867 -0
  31. package/dist/index.mjs.map +1 -0
  32. package/dist/next-demo.d.ts +49 -0
  33. package/dist/next-demo.d.ts.map +1 -0
  34. package/dist/npm/index.d.ts +71 -0
  35. package/dist/npm/index.d.ts.map +1 -0
  36. package/dist/npm/registry.d.ts +66 -0
  37. package/dist/npm/registry.d.ts.map +1 -0
  38. package/dist/npm/resolver.d.ts +52 -0
  39. package/dist/npm/resolver.d.ts.map +1 -0
  40. package/dist/npm/tarball.d.ts +29 -0
  41. package/dist/npm/tarball.d.ts.map +1 -0
  42. package/dist/runtime-interface.d.ts +90 -0
  43. package/dist/runtime-interface.d.ts.map +1 -0
  44. package/dist/runtime.d.ts +103 -0
  45. package/dist/runtime.d.ts.map +1 -0
  46. package/dist/sandbox-helpers.d.ts +43 -0
  47. package/dist/sandbox-helpers.d.ts.map +1 -0
  48. package/dist/sandbox-runtime.d.ts +65 -0
  49. package/dist/sandbox-runtime.d.ts.map +1 -0
  50. package/dist/server-bridge.d.ts +89 -0
  51. package/dist/server-bridge.d.ts.map +1 -0
  52. package/dist/shims/assert.d.ts +51 -0
  53. package/dist/shims/assert.d.ts.map +1 -0
  54. package/dist/shims/async_hooks.d.ts +37 -0
  55. package/dist/shims/async_hooks.d.ts.map +1 -0
  56. package/dist/shims/buffer.d.ts +20 -0
  57. package/dist/shims/buffer.d.ts.map +1 -0
  58. package/dist/shims/child_process-browser.d.ts +92 -0
  59. package/dist/shims/child_process-browser.d.ts.map +1 -0
  60. package/dist/shims/child_process.d.ts +93 -0
  61. package/dist/shims/child_process.d.ts.map +1 -0
  62. package/dist/shims/chokidar.d.ts +55 -0
  63. package/dist/shims/chokidar.d.ts.map +1 -0
  64. package/dist/shims/cluster.d.ts +52 -0
  65. package/dist/shims/cluster.d.ts.map +1 -0
  66. package/dist/shims/crypto.d.ts +122 -0
  67. package/dist/shims/crypto.d.ts.map +1 -0
  68. package/dist/shims/dgram.d.ts +34 -0
  69. package/dist/shims/dgram.d.ts.map +1 -0
  70. package/dist/shims/diagnostics_channel.d.ts +80 -0
  71. package/dist/shims/diagnostics_channel.d.ts.map +1 -0
  72. package/dist/shims/dns.d.ts +87 -0
  73. package/dist/shims/dns.d.ts.map +1 -0
  74. package/dist/shims/domain.d.ts +25 -0
  75. package/dist/shims/domain.d.ts.map +1 -0
  76. package/dist/shims/esbuild.d.ts +105 -0
  77. package/dist/shims/esbuild.d.ts.map +1 -0
  78. package/dist/shims/events.d.ts +37 -0
  79. package/dist/shims/events.d.ts.map +1 -0
  80. package/dist/shims/fs.d.ts +115 -0
  81. package/dist/shims/fs.d.ts.map +1 -0
  82. package/dist/shims/fsevents.d.ts +67 -0
  83. package/dist/shims/fsevents.d.ts.map +1 -0
  84. package/dist/shims/http.d.ts +217 -0
  85. package/dist/shims/http.d.ts.map +1 -0
  86. package/dist/shims/http2.d.ts +81 -0
  87. package/dist/shims/http2.d.ts.map +1 -0
  88. package/dist/shims/https.d.ts +36 -0
  89. package/dist/shims/https.d.ts.map +1 -0
  90. package/dist/shims/inspector.d.ts +25 -0
  91. package/dist/shims/inspector.d.ts.map +1 -0
  92. package/dist/shims/module.d.ts +22 -0
  93. package/dist/shims/module.d.ts.map +1 -0
  94. package/dist/shims/net.d.ts +100 -0
  95. package/dist/shims/net.d.ts.map +1 -0
  96. package/dist/shims/os.d.ts +159 -0
  97. package/dist/shims/os.d.ts.map +1 -0
  98. package/dist/shims/path.d.ts +72 -0
  99. package/dist/shims/path.d.ts.map +1 -0
  100. package/dist/shims/perf_hooks.d.ts +50 -0
  101. package/dist/shims/perf_hooks.d.ts.map +1 -0
  102. package/dist/shims/process.d.ts +93 -0
  103. package/dist/shims/process.d.ts.map +1 -0
  104. package/dist/shims/querystring.d.ts +23 -0
  105. package/dist/shims/querystring.d.ts.map +1 -0
  106. package/dist/shims/readdirp.d.ts +52 -0
  107. package/dist/shims/readdirp.d.ts.map +1 -0
  108. package/dist/shims/readline.d.ts +62 -0
  109. package/dist/shims/readline.d.ts.map +1 -0
  110. package/dist/shims/rollup.d.ts +34 -0
  111. package/dist/shims/rollup.d.ts.map +1 -0
  112. package/dist/shims/sentry.d.ts +163 -0
  113. package/dist/shims/sentry.d.ts.map +1 -0
  114. package/dist/shims/stream.d.ts +181 -0
  115. package/dist/shims/stream.d.ts.map +1 -0
  116. package/dist/shims/tls.d.ts +53 -0
  117. package/dist/shims/tls.d.ts.map +1 -0
  118. package/dist/shims/tty.d.ts +30 -0
  119. package/dist/shims/tty.d.ts.map +1 -0
  120. package/dist/shims/url.d.ts +64 -0
  121. package/dist/shims/url.d.ts.map +1 -0
  122. package/dist/shims/util.d.ts +106 -0
  123. package/dist/shims/util.d.ts.map +1 -0
  124. package/dist/shims/v8.d.ts +73 -0
  125. package/dist/shims/v8.d.ts.map +1 -0
  126. package/dist/shims/vfs-adapter.d.ts +126 -0
  127. package/dist/shims/vfs-adapter.d.ts.map +1 -0
  128. package/dist/shims/vm.d.ts +45 -0
  129. package/dist/shims/vm.d.ts.map +1 -0
  130. package/dist/shims/worker_threads.d.ts +66 -0
  131. package/dist/shims/worker_threads.d.ts.map +1 -0
  132. package/dist/shims/ws.d.ts +66 -0
  133. package/dist/shims/ws.d.ts.map +1 -0
  134. package/dist/shims/zlib.d.ts +161 -0
  135. package/dist/shims/zlib.d.ts.map +1 -0
  136. package/dist/transform.d.ts +24 -0
  137. package/dist/transform.d.ts.map +1 -0
  138. package/dist/virtual-fs.d.ts +226 -0
  139. package/dist/virtual-fs.d.ts.map +1 -0
  140. package/dist/vite-demo.d.ts +35 -0
  141. package/dist/vite-demo.d.ts.map +1 -0
  142. package/dist/vite-sw.js +132 -0
  143. package/dist/worker/runtime-worker.d.ts +8 -0
  144. package/dist/worker/runtime-worker.d.ts.map +1 -0
  145. package/dist/worker-runtime.d.ts +50 -0
  146. package/dist/worker-runtime.d.ts.map +1 -0
  147. package/package.json +85 -0
  148. package/src/ai-chatbot-demo-entry.ts +244 -0
  149. package/src/ai-chatbot-demo.ts +509 -0
  150. package/src/convex-app-demo-entry.ts +1107 -0
  151. package/src/convex-app-demo.ts +1316 -0
  152. package/src/cors-proxy.ts +81 -0
  153. package/src/create-runtime.ts +147 -0
  154. package/src/demo.ts +304 -0
  155. package/src/dev-server.ts +274 -0
  156. package/src/frameworks/next-dev-server.ts +2224 -0
  157. package/src/frameworks/vite-dev-server.ts +702 -0
  158. package/src/index.ts +101 -0
  159. package/src/next-demo.ts +1784 -0
  160. package/src/npm/index.ts +347 -0
  161. package/src/npm/registry.ts +152 -0
  162. package/src/npm/resolver.ts +385 -0
  163. package/src/npm/tarball.ts +209 -0
  164. package/src/runtime-interface.ts +103 -0
  165. package/src/runtime.ts +1046 -0
  166. package/src/sandbox-helpers.ts +173 -0
  167. package/src/sandbox-runtime.ts +252 -0
  168. package/src/server-bridge.ts +426 -0
  169. package/src/shims/assert.ts +664 -0
  170. package/src/shims/async_hooks.ts +86 -0
  171. package/src/shims/buffer.ts +75 -0
  172. package/src/shims/child_process-browser.ts +217 -0
  173. package/src/shims/child_process.ts +463 -0
  174. package/src/shims/chokidar.ts +313 -0
  175. package/src/shims/cluster.ts +67 -0
  176. package/src/shims/crypto.ts +830 -0
  177. package/src/shims/dgram.ts +47 -0
  178. package/src/shims/diagnostics_channel.ts +196 -0
  179. package/src/shims/dns.ts +172 -0
  180. package/src/shims/domain.ts +58 -0
  181. package/src/shims/esbuild.ts +805 -0
  182. package/src/shims/events.ts +195 -0
  183. package/src/shims/fs.ts +803 -0
  184. package/src/shims/fsevents.ts +63 -0
  185. package/src/shims/http.ts +904 -0
  186. package/src/shims/http2.ts +96 -0
  187. package/src/shims/https.ts +86 -0
  188. package/src/shims/inspector.ts +30 -0
  189. package/src/shims/module.ts +82 -0
  190. package/src/shims/net.ts +359 -0
  191. package/src/shims/os.ts +195 -0
  192. package/src/shims/path.ts +199 -0
  193. package/src/shims/perf_hooks.ts +92 -0
  194. package/src/shims/process.ts +346 -0
  195. package/src/shims/querystring.ts +97 -0
  196. package/src/shims/readdirp.ts +228 -0
  197. package/src/shims/readline.ts +110 -0
  198. package/src/shims/rollup.ts +80 -0
  199. package/src/shims/sentry.ts +133 -0
  200. package/src/shims/stream.ts +1126 -0
  201. package/src/shims/tls.ts +95 -0
  202. package/src/shims/tty.ts +64 -0
  203. package/src/shims/url.ts +171 -0
  204. package/src/shims/util.ts +312 -0
  205. package/src/shims/v8.ts +113 -0
  206. package/src/shims/vfs-adapter.ts +402 -0
  207. package/src/shims/vm.ts +83 -0
  208. package/src/shims/worker_threads.ts +111 -0
  209. package/src/shims/ws.ts +382 -0
  210. package/src/shims/zlib.ts +289 -0
  211. package/src/transform.ts +313 -0
  212. package/src/types/external.d.ts +67 -0
  213. package/src/virtual-fs.ts +903 -0
  214. package/src/vite-demo.ts +577 -0
  215. package/src/worker/runtime-worker.ts +128 -0
  216. package/src/worker-runtime.ts +145 -0
@@ -0,0 +1,463 @@
1
+ /**
2
+ * Node.js child_process module shim
3
+ * Uses just-bash for command execution in browser with VirtualFS adapter
4
+ */
5
+
6
+ // Polyfill process for just-bash (it expects Node.js environment)
7
+ if (typeof globalThis.process === 'undefined') {
8
+ (globalThis as any).process = {
9
+ env: {
10
+ HOME: '/home/user',
11
+ USER: 'user',
12
+ PATH: '/usr/local/bin:/usr/bin:/bin',
13
+ NODE_ENV: 'development',
14
+ },
15
+ cwd: () => '/',
16
+ platform: 'linux',
17
+ version: 'v18.0.0',
18
+ versions: { node: '18.0.0' },
19
+ stdout: { write: () => {} },
20
+ stderr: { write: () => {} },
21
+ };
22
+ }
23
+
24
+ import { Bash, defineCommand } from 'just-bash';
25
+ import { EventEmitter } from './events';
26
+ import { Readable, Writable, Buffer } from './stream';
27
+ import type { VirtualFS } from '../virtual-fs';
28
+ import { VirtualFSAdapter } from './vfs-adapter';
29
+ import { Runtime } from '../runtime';
30
+
31
+ // Singleton bash instance - uses VFS adapter for two-way file sync
32
+ let bashInstance: Bash | null = null;
33
+ let vfsAdapter: VirtualFSAdapter | null = null;
34
+ let currentVfs: VirtualFS | null = null;
35
+
36
+ /**
37
+ * Initialize the child_process shim with a VirtualFS instance
38
+ * Creates a single Bash instance with VirtualFSAdapter for efficient file access
39
+ */
40
+ export function initChildProcess(vfs: VirtualFS): void {
41
+ currentVfs = vfs;
42
+ vfsAdapter = new VirtualFSAdapter(vfs);
43
+
44
+ // Create custom 'node' command that runs JS files using the Runtime
45
+ const nodeCommand = defineCommand('node', async (args, ctx) => {
46
+ if (!currentVfs) {
47
+ return { stdout: '', stderr: 'VFS not initialized\n', exitCode: 1 };
48
+ }
49
+
50
+ const scriptPath = args[0];
51
+ if (!scriptPath) {
52
+ return { stdout: '', stderr: 'Usage: node <script.js> [args...]\n', exitCode: 1 };
53
+ }
54
+
55
+ // Resolve the script path
56
+ const resolvedPath = scriptPath.startsWith('/')
57
+ ? scriptPath
58
+ : `${ctx.cwd}/${scriptPath}`.replace(/\/+/g, '/');
59
+
60
+ try {
61
+ // Check if file exists
62
+ if (!currentVfs.existsSync(resolvedPath)) {
63
+ return { stdout: '', stderr: `Error: Cannot find module '${resolvedPath}'\n`, exitCode: 1 };
64
+ }
65
+
66
+ let stdout = '';
67
+ let stderr = '';
68
+
69
+ // Create a runtime with the current environment
70
+ const runtime = new Runtime(currentVfs, {
71
+ cwd: ctx.cwd,
72
+ env: ctx.env,
73
+ onConsole: (method, consoleArgs) => {
74
+ const msg = consoleArgs.map(a => String(a)).join(' ') + '\n';
75
+ if (method === 'error') {
76
+ stderr += msg;
77
+ } else {
78
+ stdout += msg;
79
+ }
80
+ },
81
+ });
82
+
83
+ // Set up process.argv for the script
84
+ const processShim = (globalThis as any).process || {};
85
+ const originalArgv = processShim.argv;
86
+ processShim.argv = ['node', resolvedPath, ...args.slice(1)];
87
+ (globalThis as any).process = processShim;
88
+
89
+ try {
90
+ // Run the script
91
+ runtime.runFile(resolvedPath);
92
+ return { stdout, stderr, exitCode: 0 };
93
+ } finally {
94
+ // Restore original argv
95
+ processShim.argv = originalArgv;
96
+ }
97
+ } catch (error) {
98
+ const errorMsg = error instanceof Error ? error.message : String(error);
99
+ return { stdout: '', stderr: `Error: ${errorMsg}\n`, exitCode: 1 };
100
+ }
101
+ });
102
+
103
+ // Create custom 'convex' command that runs the Convex CLI
104
+ const convexCommand = defineCommand('convex', async (args, ctx) => {
105
+ if (!currentVfs) {
106
+ return { stdout: '', stderr: 'VFS not initialized\n', exitCode: 1 };
107
+ }
108
+
109
+ // Find the Convex CLI bundle
110
+ const cliBundlePath = '/node_modules/convex/dist/cli.bundle.cjs';
111
+ if (!currentVfs.existsSync(cliBundlePath)) {
112
+ return { stdout: '', stderr: 'Convex CLI not found. Run: npm install convex\n', exitCode: 1 };
113
+ }
114
+
115
+ let stdout = '';
116
+ let stderr = '';
117
+
118
+ try {
119
+ // Create a runtime with the current environment
120
+ const runtime = new Runtime(currentVfs, {
121
+ cwd: ctx.cwd,
122
+ env: ctx.env,
123
+ onConsole: (method, consoleArgs) => {
124
+ const msg = consoleArgs.map(a => String(a)).join(' ') + '\n';
125
+ if (method === 'error') {
126
+ stderr += msg;
127
+ } else {
128
+ stdout += msg;
129
+ }
130
+ },
131
+ });
132
+
133
+ // Set up process.argv for the CLI
134
+ const processShim = (globalThis as any).process || {};
135
+ const originalArgv = processShim.argv;
136
+ const originalEnv = { ...processShim.env };
137
+
138
+ processShim.argv = ['node', 'convex', ...args];
139
+ processShim.env = { ...processShim.env, ...ctx.env };
140
+ (globalThis as any).process = processShim;
141
+
142
+ try {
143
+ // Run the CLI bundle
144
+ runtime.runFile(cliBundlePath);
145
+ return { stdout, stderr, exitCode: 0 };
146
+ } finally {
147
+ // Restore original state
148
+ processShim.argv = originalArgv;
149
+ processShim.env = originalEnv;
150
+ }
151
+ } catch (error) {
152
+ const errorMsg = error instanceof Error ? error.message : String(error);
153
+ return { stdout, stderr: stderr + `Error: ${errorMsg}\n`, exitCode: 1 };
154
+ }
155
+ });
156
+
157
+ bashInstance = new Bash({
158
+ fs: vfsAdapter,
159
+ cwd: '/',
160
+ env: {
161
+ HOME: '/home/user',
162
+ USER: 'user',
163
+ PATH: '/usr/local/bin:/usr/bin:/bin:/node_modules/.bin',
164
+ NODE_ENV: 'development',
165
+ },
166
+ customCommands: [nodeCommand, convexCommand],
167
+ });
168
+ }
169
+
170
+ export interface ExecOptions {
171
+ cwd?: string;
172
+ env?: Record<string, string>;
173
+ encoding?: BufferEncoding | 'buffer';
174
+ timeout?: number;
175
+ maxBuffer?: number;
176
+ shell?: string | boolean;
177
+ }
178
+
179
+ export interface ExecResult {
180
+ stdout: string | Buffer;
181
+ stderr: string | Buffer;
182
+ }
183
+
184
+ export type ExecCallback = (
185
+ error: Error | null,
186
+ stdout: string | Buffer,
187
+ stderr: string | Buffer
188
+ ) => void;
189
+
190
+ /**
191
+ * Execute a command in a shell
192
+ */
193
+ export function exec(
194
+ command: string,
195
+ optionsOrCallback?: ExecOptions | ExecCallback,
196
+ callback?: ExecCallback
197
+ ): ChildProcess {
198
+ let options: ExecOptions = {};
199
+ let cb: ExecCallback | undefined;
200
+
201
+ if (typeof optionsOrCallback === 'function') {
202
+ cb = optionsOrCallback;
203
+ } else if (optionsOrCallback) {
204
+ options = optionsOrCallback;
205
+ cb = callback;
206
+ }
207
+
208
+ const child = new ChildProcess();
209
+
210
+ // Execute asynchronously
211
+ (async () => {
212
+ if (!bashInstance) {
213
+ const error = new Error('child_process not initialized');
214
+ child.emit('error', error);
215
+ if (cb) cb(error, '', '');
216
+ return;
217
+ }
218
+
219
+ try {
220
+ const result = await bashInstance!.exec(command, {
221
+ cwd: options.cwd,
222
+ env: options.env,
223
+ });
224
+
225
+ const stdout = result.stdout || '';
226
+ const stderr = result.stderr || '';
227
+
228
+ // Emit data events
229
+ if (stdout) {
230
+ child.stdout?.push(Buffer.from(stdout));
231
+ }
232
+ child.stdout?.push(null);
233
+
234
+ if (stderr) {
235
+ child.stderr?.push(Buffer.from(stderr));
236
+ }
237
+ child.stderr?.push(null);
238
+
239
+ // Emit close/exit
240
+ child.emit('close', result.exitCode, null);
241
+ child.emit('exit', result.exitCode, null);
242
+
243
+ if (cb) {
244
+ if (result.exitCode !== 0) {
245
+ const error = new Error(`Command failed: ${command}`);
246
+ (error as any).code = result.exitCode;
247
+ cb(error, stdout, stderr);
248
+ } else {
249
+ cb(null, stdout, stderr);
250
+ }
251
+ }
252
+ } catch (error) {
253
+ child.emit('error', error);
254
+ if (cb) cb(error as Error, '', '');
255
+ }
256
+ })();
257
+
258
+ return child;
259
+ }
260
+
261
+ /**
262
+ * Execute a command synchronously
263
+ */
264
+ export function execSync(
265
+ command: string,
266
+ options?: ExecOptions
267
+ ): string | Buffer {
268
+ if (!bashInstance) {
269
+ throw new Error('child_process not initialized');
270
+ }
271
+
272
+ // Note: just-bash exec is async, so we can't truly do sync execution
273
+ // This is a limitation of the browser environment
274
+ // For now, throw an error suggesting to use exec() instead
275
+ throw new Error(
276
+ 'execSync is not supported in browser environment. Use exec() with async/await or callbacks instead.'
277
+ );
278
+ }
279
+
280
+ export interface SpawnOptions {
281
+ cwd?: string;
282
+ env?: Record<string, string>;
283
+ shell?: boolean | string;
284
+ stdio?: 'pipe' | 'inherit' | 'ignore' | Array<'pipe' | 'inherit' | 'ignore'>;
285
+ }
286
+
287
+ /**
288
+ * Spawn a new process
289
+ */
290
+ export function spawn(
291
+ command: string,
292
+ args?: string[] | SpawnOptions,
293
+ options?: SpawnOptions
294
+ ): ChildProcess {
295
+ let spawnArgs: string[] = [];
296
+ let spawnOptions: SpawnOptions = {};
297
+
298
+ if (Array.isArray(args)) {
299
+ spawnArgs = args;
300
+ spawnOptions = options || {};
301
+ } else if (args) {
302
+ spawnOptions = args;
303
+ }
304
+
305
+ const child = new ChildProcess();
306
+
307
+ // Build the full command
308
+ const fullCommand = spawnArgs.length > 0
309
+ ? `${command} ${spawnArgs.map(arg =>
310
+ arg.includes(' ') ? `"${arg}"` : arg
311
+ ).join(' ')}`
312
+ : command;
313
+
314
+ // Execute asynchronously
315
+ (async () => {
316
+ if (!bashInstance) {
317
+ const error = new Error('child_process not initialized');
318
+ child.emit('error', error);
319
+ return;
320
+ }
321
+
322
+ try {
323
+ const result = await bashInstance!.exec(fullCommand, {
324
+ cwd: spawnOptions.cwd,
325
+ env: spawnOptions.env,
326
+ });
327
+
328
+ const stdout = result.stdout || '';
329
+ const stderr = result.stderr || '';
330
+
331
+ // Emit data events
332
+ if (stdout) {
333
+ child.stdout?.push(Buffer.from(stdout));
334
+ }
335
+ child.stdout?.push(null);
336
+
337
+ if (stderr) {
338
+ child.stderr?.push(Buffer.from(stderr));
339
+ }
340
+ child.stderr?.push(null);
341
+
342
+ // Emit close/exit
343
+ child.emit('close', result.exitCode, null);
344
+ child.emit('exit', result.exitCode, null);
345
+ } catch (error) {
346
+ child.emit('error', error);
347
+ }
348
+ })();
349
+
350
+ return child;
351
+ }
352
+
353
+ /**
354
+ * Spawn a new process synchronously
355
+ */
356
+ export function spawnSync(
357
+ command: string,
358
+ args?: string[],
359
+ options?: SpawnOptions
360
+ ): { stdout: Buffer; stderr: Buffer; status: number; error?: Error } {
361
+ throw new Error(
362
+ 'spawnSync is not supported in browser environment. Use spawn() instead.'
363
+ );
364
+ }
365
+
366
+ /**
367
+ * Execute a file
368
+ */
369
+ export function execFile(
370
+ file: string,
371
+ args?: string[] | ExecOptions | ExecCallback,
372
+ options?: ExecOptions | ExecCallback,
373
+ callback?: ExecCallback
374
+ ): ChildProcess {
375
+ let execArgs: string[] = [];
376
+ let execOptions: ExecOptions = {};
377
+ let cb: ExecCallback | undefined;
378
+
379
+ if (Array.isArray(args)) {
380
+ execArgs = args;
381
+ if (typeof options === 'function') {
382
+ cb = options;
383
+ } else if (options) {
384
+ execOptions = options;
385
+ cb = callback;
386
+ }
387
+ } else if (typeof args === 'function') {
388
+ cb = args;
389
+ } else if (args) {
390
+ execOptions = args;
391
+ cb = options as ExecCallback;
392
+ }
393
+
394
+ const command = execArgs.length > 0 ? `${file} ${execArgs.join(' ')}` : file;
395
+ return exec(command, execOptions, cb);
396
+ }
397
+
398
+ /**
399
+ * Fork is not supported in browser
400
+ */
401
+ export function fork(): never {
402
+ throw new Error('fork is not supported in browser environment');
403
+ }
404
+
405
+ /**
406
+ * ChildProcess class
407
+ */
408
+ export class ChildProcess extends EventEmitter {
409
+ pid: number;
410
+ connected: boolean = false;
411
+ killed: boolean = false;
412
+ exitCode: number | null = null;
413
+ signalCode: string | null = null;
414
+ spawnargs: string[] = [];
415
+ spawnfile: string = '';
416
+
417
+ stdin: Writable | null;
418
+ stdout: Readable | null;
419
+ stderr: Readable | null;
420
+
421
+ constructor() {
422
+ super();
423
+ this.pid = Math.floor(Math.random() * 10000) + 1000;
424
+ this.stdin = new Writable();
425
+ this.stdout = new Readable();
426
+ this.stderr = new Readable();
427
+ }
428
+
429
+ kill(signal?: string): boolean {
430
+ this.killed = true;
431
+ this.emit('exit', null, signal || 'SIGTERM');
432
+ return true;
433
+ }
434
+
435
+ disconnect(): void {
436
+ this.connected = false;
437
+ }
438
+
439
+ send(message: unknown, callback?: (error: Error | null) => void): boolean {
440
+ // IPC not supported
441
+ if (callback) callback(new Error('IPC not supported'));
442
+ return false;
443
+ }
444
+
445
+ ref(): this {
446
+ return this;
447
+ }
448
+
449
+ unref(): this {
450
+ return this;
451
+ }
452
+ }
453
+
454
+ export default {
455
+ exec,
456
+ execSync,
457
+ execFile,
458
+ spawn,
459
+ spawnSync,
460
+ fork,
461
+ ChildProcess,
462
+ initChildProcess,
463
+ };