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.
- package/LICENSE +21 -0
- package/README.md +731 -0
- package/dist/__sw__.js +394 -0
- package/dist/ai-chatbot-demo-entry.d.ts +6 -0
- package/dist/ai-chatbot-demo-entry.d.ts.map +1 -0
- package/dist/ai-chatbot-demo.d.ts +42 -0
- package/dist/ai-chatbot-demo.d.ts.map +1 -0
- package/dist/assets/runtime-worker-D9x_Ddwz.js +60543 -0
- package/dist/assets/runtime-worker-D9x_Ddwz.js.map +1 -0
- package/dist/convex-app-demo-entry.d.ts +6 -0
- package/dist/convex-app-demo-entry.d.ts.map +1 -0
- package/dist/convex-app-demo.d.ts +68 -0
- package/dist/convex-app-demo.d.ts.map +1 -0
- package/dist/cors-proxy.d.ts +46 -0
- package/dist/cors-proxy.d.ts.map +1 -0
- package/dist/create-runtime.d.ts +42 -0
- package/dist/create-runtime.d.ts.map +1 -0
- package/dist/demo.d.ts +6 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/dev-server.d.ts +97 -0
- package/dist/dev-server.d.ts.map +1 -0
- package/dist/frameworks/next-dev-server.d.ts +202 -0
- package/dist/frameworks/next-dev-server.d.ts.map +1 -0
- package/dist/frameworks/vite-dev-server.d.ts +85 -0
- package/dist/frameworks/vite-dev-server.d.ts.map +1 -0
- package/dist/index.cjs +14965 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +14867 -0
- package/dist/index.mjs.map +1 -0
- package/dist/next-demo.d.ts +49 -0
- package/dist/next-demo.d.ts.map +1 -0
- package/dist/npm/index.d.ts +71 -0
- package/dist/npm/index.d.ts.map +1 -0
- package/dist/npm/registry.d.ts +66 -0
- package/dist/npm/registry.d.ts.map +1 -0
- package/dist/npm/resolver.d.ts +52 -0
- package/dist/npm/resolver.d.ts.map +1 -0
- package/dist/npm/tarball.d.ts +29 -0
- package/dist/npm/tarball.d.ts.map +1 -0
- package/dist/runtime-interface.d.ts +90 -0
- package/dist/runtime-interface.d.ts.map +1 -0
- package/dist/runtime.d.ts +103 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/sandbox-helpers.d.ts +43 -0
- package/dist/sandbox-helpers.d.ts.map +1 -0
- package/dist/sandbox-runtime.d.ts +65 -0
- package/dist/sandbox-runtime.d.ts.map +1 -0
- package/dist/server-bridge.d.ts +89 -0
- package/dist/server-bridge.d.ts.map +1 -0
- package/dist/shims/assert.d.ts +51 -0
- package/dist/shims/assert.d.ts.map +1 -0
- package/dist/shims/async_hooks.d.ts +37 -0
- package/dist/shims/async_hooks.d.ts.map +1 -0
- package/dist/shims/buffer.d.ts +20 -0
- package/dist/shims/buffer.d.ts.map +1 -0
- package/dist/shims/child_process-browser.d.ts +92 -0
- package/dist/shims/child_process-browser.d.ts.map +1 -0
- package/dist/shims/child_process.d.ts +93 -0
- package/dist/shims/child_process.d.ts.map +1 -0
- package/dist/shims/chokidar.d.ts +55 -0
- package/dist/shims/chokidar.d.ts.map +1 -0
- package/dist/shims/cluster.d.ts +52 -0
- package/dist/shims/cluster.d.ts.map +1 -0
- package/dist/shims/crypto.d.ts +122 -0
- package/dist/shims/crypto.d.ts.map +1 -0
- package/dist/shims/dgram.d.ts +34 -0
- package/dist/shims/dgram.d.ts.map +1 -0
- package/dist/shims/diagnostics_channel.d.ts +80 -0
- package/dist/shims/diagnostics_channel.d.ts.map +1 -0
- package/dist/shims/dns.d.ts +87 -0
- package/dist/shims/dns.d.ts.map +1 -0
- package/dist/shims/domain.d.ts +25 -0
- package/dist/shims/domain.d.ts.map +1 -0
- package/dist/shims/esbuild.d.ts +105 -0
- package/dist/shims/esbuild.d.ts.map +1 -0
- package/dist/shims/events.d.ts +37 -0
- package/dist/shims/events.d.ts.map +1 -0
- package/dist/shims/fs.d.ts +115 -0
- package/dist/shims/fs.d.ts.map +1 -0
- package/dist/shims/fsevents.d.ts +67 -0
- package/dist/shims/fsevents.d.ts.map +1 -0
- package/dist/shims/http.d.ts +217 -0
- package/dist/shims/http.d.ts.map +1 -0
- package/dist/shims/http2.d.ts +81 -0
- package/dist/shims/http2.d.ts.map +1 -0
- package/dist/shims/https.d.ts +36 -0
- package/dist/shims/https.d.ts.map +1 -0
- package/dist/shims/inspector.d.ts +25 -0
- package/dist/shims/inspector.d.ts.map +1 -0
- package/dist/shims/module.d.ts +22 -0
- package/dist/shims/module.d.ts.map +1 -0
- package/dist/shims/net.d.ts +100 -0
- package/dist/shims/net.d.ts.map +1 -0
- package/dist/shims/os.d.ts +159 -0
- package/dist/shims/os.d.ts.map +1 -0
- package/dist/shims/path.d.ts +72 -0
- package/dist/shims/path.d.ts.map +1 -0
- package/dist/shims/perf_hooks.d.ts +50 -0
- package/dist/shims/perf_hooks.d.ts.map +1 -0
- package/dist/shims/process.d.ts +93 -0
- package/dist/shims/process.d.ts.map +1 -0
- package/dist/shims/querystring.d.ts +23 -0
- package/dist/shims/querystring.d.ts.map +1 -0
- package/dist/shims/readdirp.d.ts +52 -0
- package/dist/shims/readdirp.d.ts.map +1 -0
- package/dist/shims/readline.d.ts +62 -0
- package/dist/shims/readline.d.ts.map +1 -0
- package/dist/shims/rollup.d.ts +34 -0
- package/dist/shims/rollup.d.ts.map +1 -0
- package/dist/shims/sentry.d.ts +163 -0
- package/dist/shims/sentry.d.ts.map +1 -0
- package/dist/shims/stream.d.ts +181 -0
- package/dist/shims/stream.d.ts.map +1 -0
- package/dist/shims/tls.d.ts +53 -0
- package/dist/shims/tls.d.ts.map +1 -0
- package/dist/shims/tty.d.ts +30 -0
- package/dist/shims/tty.d.ts.map +1 -0
- package/dist/shims/url.d.ts +64 -0
- package/dist/shims/url.d.ts.map +1 -0
- package/dist/shims/util.d.ts +106 -0
- package/dist/shims/util.d.ts.map +1 -0
- package/dist/shims/v8.d.ts +73 -0
- package/dist/shims/v8.d.ts.map +1 -0
- package/dist/shims/vfs-adapter.d.ts +126 -0
- package/dist/shims/vfs-adapter.d.ts.map +1 -0
- package/dist/shims/vm.d.ts +45 -0
- package/dist/shims/vm.d.ts.map +1 -0
- package/dist/shims/worker_threads.d.ts +66 -0
- package/dist/shims/worker_threads.d.ts.map +1 -0
- package/dist/shims/ws.d.ts +66 -0
- package/dist/shims/ws.d.ts.map +1 -0
- package/dist/shims/zlib.d.ts +161 -0
- package/dist/shims/zlib.d.ts.map +1 -0
- package/dist/transform.d.ts +24 -0
- package/dist/transform.d.ts.map +1 -0
- package/dist/virtual-fs.d.ts +226 -0
- package/dist/virtual-fs.d.ts.map +1 -0
- package/dist/vite-demo.d.ts +35 -0
- package/dist/vite-demo.d.ts.map +1 -0
- package/dist/vite-sw.js +132 -0
- package/dist/worker/runtime-worker.d.ts +8 -0
- package/dist/worker/runtime-worker.d.ts.map +1 -0
- package/dist/worker-runtime.d.ts +50 -0
- package/dist/worker-runtime.d.ts.map +1 -0
- package/package.json +85 -0
- package/src/ai-chatbot-demo-entry.ts +244 -0
- package/src/ai-chatbot-demo.ts +509 -0
- package/src/convex-app-demo-entry.ts +1107 -0
- package/src/convex-app-demo.ts +1316 -0
- package/src/cors-proxy.ts +81 -0
- package/src/create-runtime.ts +147 -0
- package/src/demo.ts +304 -0
- package/src/dev-server.ts +274 -0
- package/src/frameworks/next-dev-server.ts +2224 -0
- package/src/frameworks/vite-dev-server.ts +702 -0
- package/src/index.ts +101 -0
- package/src/next-demo.ts +1784 -0
- package/src/npm/index.ts +347 -0
- package/src/npm/registry.ts +152 -0
- package/src/npm/resolver.ts +385 -0
- package/src/npm/tarball.ts +209 -0
- package/src/runtime-interface.ts +103 -0
- package/src/runtime.ts +1046 -0
- package/src/sandbox-helpers.ts +173 -0
- package/src/sandbox-runtime.ts +252 -0
- package/src/server-bridge.ts +426 -0
- package/src/shims/assert.ts +664 -0
- package/src/shims/async_hooks.ts +86 -0
- package/src/shims/buffer.ts +75 -0
- package/src/shims/child_process-browser.ts +217 -0
- package/src/shims/child_process.ts +463 -0
- package/src/shims/chokidar.ts +313 -0
- package/src/shims/cluster.ts +67 -0
- package/src/shims/crypto.ts +830 -0
- package/src/shims/dgram.ts +47 -0
- package/src/shims/diagnostics_channel.ts +196 -0
- package/src/shims/dns.ts +172 -0
- package/src/shims/domain.ts +58 -0
- package/src/shims/esbuild.ts +805 -0
- package/src/shims/events.ts +195 -0
- package/src/shims/fs.ts +803 -0
- package/src/shims/fsevents.ts +63 -0
- package/src/shims/http.ts +904 -0
- package/src/shims/http2.ts +96 -0
- package/src/shims/https.ts +86 -0
- package/src/shims/inspector.ts +30 -0
- package/src/shims/module.ts +82 -0
- package/src/shims/net.ts +359 -0
- package/src/shims/os.ts +195 -0
- package/src/shims/path.ts +199 -0
- package/src/shims/perf_hooks.ts +92 -0
- package/src/shims/process.ts +346 -0
- package/src/shims/querystring.ts +97 -0
- package/src/shims/readdirp.ts +228 -0
- package/src/shims/readline.ts +110 -0
- package/src/shims/rollup.ts +80 -0
- package/src/shims/sentry.ts +133 -0
- package/src/shims/stream.ts +1126 -0
- package/src/shims/tls.ts +95 -0
- package/src/shims/tty.ts +64 -0
- package/src/shims/url.ts +171 -0
- package/src/shims/util.ts +312 -0
- package/src/shims/v8.ts +113 -0
- package/src/shims/vfs-adapter.ts +402 -0
- package/src/shims/vm.ts +83 -0
- package/src/shims/worker_threads.ts +111 -0
- package/src/shims/ws.ts +382 -0
- package/src/shims/zlib.ts +289 -0
- package/src/transform.ts +313 -0
- package/src/types/external.d.ts +67 -0
- package/src/virtual-fs.ts +903 -0
- package/src/vite-demo.ts +577 -0
- package/src/worker/runtime-worker.ts +128 -0
- package/src/worker-runtime.ts +145 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js process shim
|
|
3
|
+
* Provides minimal process object for browser environment
|
|
4
|
+
* Process is an EventEmitter in Node.js
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { EventEmitter, EventListener } from './events';
|
|
8
|
+
|
|
9
|
+
export interface ProcessEnv {
|
|
10
|
+
[key: string]: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Stream-like interface with EventEmitter methods
|
|
14
|
+
interface ProcessStream {
|
|
15
|
+
isTTY: boolean;
|
|
16
|
+
on: (event: string, listener: EventListener) => ProcessStream;
|
|
17
|
+
once: (event: string, listener: EventListener) => ProcessStream;
|
|
18
|
+
off: (event: string, listener: EventListener) => ProcessStream;
|
|
19
|
+
emit: (event: string, ...args: unknown[]) => boolean;
|
|
20
|
+
addListener: (event: string, listener: EventListener) => ProcessStream;
|
|
21
|
+
removeListener: (event: string, listener: EventListener) => ProcessStream;
|
|
22
|
+
removeAllListeners: (event?: string) => ProcessStream;
|
|
23
|
+
setMaxListeners: (n: number) => ProcessStream;
|
|
24
|
+
pause?: () => ProcessStream;
|
|
25
|
+
resume?: () => ProcessStream;
|
|
26
|
+
setEncoding?: (encoding: string) => ProcessStream;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface ProcessWritableStream extends ProcessStream {
|
|
30
|
+
write: (data: string | Buffer, encoding?: string, callback?: () => void) => boolean;
|
|
31
|
+
end?: (data?: string, callback?: () => void) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface ProcessReadableStream extends ProcessStream {
|
|
35
|
+
read?: (size?: number) => string | Buffer | null;
|
|
36
|
+
setRawMode?: (mode: boolean) => ProcessReadableStream;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface Process {
|
|
40
|
+
env: ProcessEnv;
|
|
41
|
+
cwd: () => string;
|
|
42
|
+
chdir: (directory: string) => void;
|
|
43
|
+
platform: string;
|
|
44
|
+
version: string;
|
|
45
|
+
versions: { node: string; v8: string; uv: string };
|
|
46
|
+
argv: string[];
|
|
47
|
+
argv0: string;
|
|
48
|
+
execPath: string;
|
|
49
|
+
execArgv: string[];
|
|
50
|
+
pid: number;
|
|
51
|
+
ppid: number;
|
|
52
|
+
exit: (code?: number) => never;
|
|
53
|
+
nextTick: (callback: (...args: unknown[]) => void, ...args: unknown[]) => void;
|
|
54
|
+
stdout: ProcessWritableStream;
|
|
55
|
+
stderr: ProcessWritableStream;
|
|
56
|
+
stdin: ProcessReadableStream;
|
|
57
|
+
hrtime: {
|
|
58
|
+
(time?: [number, number]): [number, number];
|
|
59
|
+
bigint: () => bigint;
|
|
60
|
+
};
|
|
61
|
+
memoryUsage: () => { rss: number; heapTotal: number; heapUsed: number; external: number; arrayBuffers: number };
|
|
62
|
+
uptime: () => number;
|
|
63
|
+
cpuUsage: () => { user: number; system: number };
|
|
64
|
+
// EventEmitter methods
|
|
65
|
+
on: (event: string, listener: EventListener) => Process;
|
|
66
|
+
once: (event: string, listener: EventListener) => Process;
|
|
67
|
+
off: (event: string, listener: EventListener) => Process;
|
|
68
|
+
emit: (event: string, ...args: unknown[]) => boolean;
|
|
69
|
+
addListener: (event: string, listener: EventListener) => Process;
|
|
70
|
+
removeListener: (event: string, listener: EventListener) => Process;
|
|
71
|
+
removeAllListeners: (event?: string) => Process;
|
|
72
|
+
listeners: (event: string) => EventListener[];
|
|
73
|
+
listenerCount: (event: string) => number;
|
|
74
|
+
prependListener: (event: string, listener: EventListener) => Process;
|
|
75
|
+
prependOnceListener: (event: string, listener: EventListener) => Process;
|
|
76
|
+
eventNames: () => string[];
|
|
77
|
+
setMaxListeners: (n: number) => Process;
|
|
78
|
+
getMaxListeners: () => number;
|
|
79
|
+
// Internal debug counter
|
|
80
|
+
_cwdCallCount?: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Helper to create a stream-like object with EventEmitter methods
|
|
84
|
+
function createProcessStream(
|
|
85
|
+
isWritable: boolean,
|
|
86
|
+
writeImpl?: (data: string) => boolean
|
|
87
|
+
): ProcessWritableStream | ProcessReadableStream {
|
|
88
|
+
const emitter = new EventEmitter();
|
|
89
|
+
|
|
90
|
+
const stream: ProcessWritableStream & ProcessReadableStream = {
|
|
91
|
+
isTTY: false,
|
|
92
|
+
|
|
93
|
+
on(event: string, listener: EventListener) {
|
|
94
|
+
emitter.on(event, listener);
|
|
95
|
+
return stream;
|
|
96
|
+
},
|
|
97
|
+
once(event: string, listener: EventListener) {
|
|
98
|
+
emitter.once(event, listener);
|
|
99
|
+
return stream;
|
|
100
|
+
},
|
|
101
|
+
off(event: string, listener: EventListener) {
|
|
102
|
+
emitter.off(event, listener);
|
|
103
|
+
return stream;
|
|
104
|
+
},
|
|
105
|
+
emit(event: string, ...args: unknown[]) {
|
|
106
|
+
return emitter.emit(event, ...args);
|
|
107
|
+
},
|
|
108
|
+
addListener(event: string, listener: EventListener) {
|
|
109
|
+
emitter.addListener(event, listener);
|
|
110
|
+
return stream;
|
|
111
|
+
},
|
|
112
|
+
removeListener(event: string, listener: EventListener) {
|
|
113
|
+
emitter.removeListener(event, listener);
|
|
114
|
+
return stream;
|
|
115
|
+
},
|
|
116
|
+
removeAllListeners(event?: string) {
|
|
117
|
+
emitter.removeAllListeners(event);
|
|
118
|
+
return stream;
|
|
119
|
+
},
|
|
120
|
+
setMaxListeners(n: number) {
|
|
121
|
+
emitter.setMaxListeners(n);
|
|
122
|
+
return stream;
|
|
123
|
+
},
|
|
124
|
+
pause() {
|
|
125
|
+
return stream;
|
|
126
|
+
},
|
|
127
|
+
resume() {
|
|
128
|
+
return stream;
|
|
129
|
+
},
|
|
130
|
+
setEncoding(_encoding: string) {
|
|
131
|
+
return stream;
|
|
132
|
+
},
|
|
133
|
+
// Default write implementation (no-op for readable streams)
|
|
134
|
+
write(_data: string | Buffer, _encoding?: string, callback?: () => void) {
|
|
135
|
+
if (callback) queueMicrotask(callback);
|
|
136
|
+
return true;
|
|
137
|
+
},
|
|
138
|
+
end(_data?: string, callback?: () => void) {
|
|
139
|
+
if (callback) queueMicrotask(callback);
|
|
140
|
+
},
|
|
141
|
+
// Default read implementation (for stdin)
|
|
142
|
+
read() {
|
|
143
|
+
return null;
|
|
144
|
+
},
|
|
145
|
+
setRawMode(_mode: boolean) {
|
|
146
|
+
return stream;
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// Override write for actual writable streams
|
|
151
|
+
if (isWritable && writeImpl) {
|
|
152
|
+
stream.write = (data: string | Buffer, _encoding?: string, callback?: () => void) => {
|
|
153
|
+
const result = writeImpl(typeof data === 'string' ? data : data.toString());
|
|
154
|
+
if (callback) queueMicrotask(callback);
|
|
155
|
+
return result;
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return stream;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function createProcess(options?: {
|
|
163
|
+
cwd?: string;
|
|
164
|
+
env?: ProcessEnv;
|
|
165
|
+
onExit?: (code: number) => void;
|
|
166
|
+
}): Process {
|
|
167
|
+
let currentDir = options?.cwd || '/';
|
|
168
|
+
const env: ProcessEnv = {
|
|
169
|
+
NODE_ENV: 'development',
|
|
170
|
+
PATH: '/usr/local/bin:/usr/bin:/bin',
|
|
171
|
+
HOME: '/',
|
|
172
|
+
...options?.env,
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// Create an EventEmitter for process events
|
|
176
|
+
const emitter = new EventEmitter();
|
|
177
|
+
const startTime = Date.now();
|
|
178
|
+
|
|
179
|
+
const proc: Process = {
|
|
180
|
+
env,
|
|
181
|
+
|
|
182
|
+
cwd() {
|
|
183
|
+
// Debug: Log cwd calls (limited to first 5)
|
|
184
|
+
if (!proc._cwdCallCount) proc._cwdCallCount = 0;
|
|
185
|
+
proc._cwdCallCount++;
|
|
186
|
+
if (proc._cwdCallCount <= 5 || proc._cwdCallCount % 100 === 0) {
|
|
187
|
+
console.log(`[process] cwd() called (${proc._cwdCallCount}x), returning:`, currentDir);
|
|
188
|
+
}
|
|
189
|
+
return currentDir;
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
chdir(directory: string) {
|
|
193
|
+
console.log('[process] chdir called:', directory, 'from:', currentDir);
|
|
194
|
+
if (!directory.startsWith('/')) {
|
|
195
|
+
directory = currentDir + '/' + directory;
|
|
196
|
+
}
|
|
197
|
+
currentDir = directory;
|
|
198
|
+
console.log('[process] chdir result:', currentDir);
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
platform: 'linux', // Pretend to be linux for better compatibility
|
|
202
|
+
version: 'v20.0.0',
|
|
203
|
+
versions: { node: '20.0.0', v8: '11.3.244.8', uv: '1.44.2' },
|
|
204
|
+
|
|
205
|
+
argv: ['node', '/index.js'],
|
|
206
|
+
argv0: 'node',
|
|
207
|
+
execPath: '/usr/local/bin/node',
|
|
208
|
+
execArgv: [],
|
|
209
|
+
|
|
210
|
+
pid: 1,
|
|
211
|
+
ppid: 0,
|
|
212
|
+
|
|
213
|
+
exit(code = 0) {
|
|
214
|
+
emitter.emit('exit', code);
|
|
215
|
+
if (options?.onExit) {
|
|
216
|
+
options.onExit(code);
|
|
217
|
+
}
|
|
218
|
+
throw new Error(`Process exited with code ${code}`);
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
nextTick(callback, ...args) {
|
|
222
|
+
queueMicrotask(() => callback(...args));
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
stdout: createProcessStream(true, (data: string) => {
|
|
226
|
+
console.log(data);
|
|
227
|
+
return true;
|
|
228
|
+
}) as ProcessWritableStream,
|
|
229
|
+
|
|
230
|
+
stderr: createProcessStream(true, (data: string) => {
|
|
231
|
+
console.error(data);
|
|
232
|
+
return true;
|
|
233
|
+
}) as ProcessWritableStream,
|
|
234
|
+
|
|
235
|
+
stdin: createProcessStream(false) as ProcessReadableStream,
|
|
236
|
+
|
|
237
|
+
hrtime: Object.assign(
|
|
238
|
+
function hrtime(time?: [number, number]): [number, number] {
|
|
239
|
+
const now = performance.now();
|
|
240
|
+
const seconds = Math.floor(now / 1000);
|
|
241
|
+
const nanoseconds = Math.floor((now % 1000) * 1e6);
|
|
242
|
+
if (time) {
|
|
243
|
+
const diffSeconds = seconds - time[0];
|
|
244
|
+
const diffNanos = nanoseconds - time[1];
|
|
245
|
+
return [diffSeconds, diffNanos];
|
|
246
|
+
}
|
|
247
|
+
return [seconds, nanoseconds];
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
bigint: (): bigint => BigInt(Math.floor(performance.now() * 1e6)),
|
|
251
|
+
}
|
|
252
|
+
),
|
|
253
|
+
|
|
254
|
+
memoryUsage() {
|
|
255
|
+
// Return mock values since we can't access real memory in browser
|
|
256
|
+
return {
|
|
257
|
+
rss: 50 * 1024 * 1024,
|
|
258
|
+
heapTotal: 30 * 1024 * 1024,
|
|
259
|
+
heapUsed: 20 * 1024 * 1024,
|
|
260
|
+
external: 1 * 1024 * 1024,
|
|
261
|
+
arrayBuffers: 0,
|
|
262
|
+
};
|
|
263
|
+
},
|
|
264
|
+
|
|
265
|
+
uptime() {
|
|
266
|
+
return (Date.now() - startTime) / 1000;
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
cpuUsage() {
|
|
270
|
+
return { user: 0, system: 0 };
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
// EventEmitter methods - delegate to emitter but return proc for chaining
|
|
274
|
+
on(event: string, listener: EventListener): Process {
|
|
275
|
+
emitter.on(event, listener);
|
|
276
|
+
return proc;
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
once(event: string, listener: EventListener): Process {
|
|
280
|
+
emitter.once(event, listener);
|
|
281
|
+
return proc;
|
|
282
|
+
},
|
|
283
|
+
|
|
284
|
+
off(event: string, listener: EventListener): Process {
|
|
285
|
+
emitter.off(event, listener);
|
|
286
|
+
return proc;
|
|
287
|
+
},
|
|
288
|
+
|
|
289
|
+
emit(event: string, ...args: unknown[]): boolean {
|
|
290
|
+
return emitter.emit(event, ...args);
|
|
291
|
+
},
|
|
292
|
+
|
|
293
|
+
addListener(event: string, listener: EventListener): Process {
|
|
294
|
+
emitter.addListener(event, listener);
|
|
295
|
+
return proc;
|
|
296
|
+
},
|
|
297
|
+
|
|
298
|
+
removeListener(event: string, listener: EventListener): Process {
|
|
299
|
+
emitter.removeListener(event, listener);
|
|
300
|
+
return proc;
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
removeAllListeners(event?: string): Process {
|
|
304
|
+
emitter.removeAllListeners(event);
|
|
305
|
+
return proc;
|
|
306
|
+
},
|
|
307
|
+
|
|
308
|
+
listeners(event: string): EventListener[] {
|
|
309
|
+
return emitter.listeners(event);
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
listenerCount(event: string): number {
|
|
313
|
+
return emitter.listenerCount(event);
|
|
314
|
+
},
|
|
315
|
+
|
|
316
|
+
prependListener(event: string, listener: EventListener): Process {
|
|
317
|
+
emitter.prependListener(event, listener);
|
|
318
|
+
return proc;
|
|
319
|
+
},
|
|
320
|
+
|
|
321
|
+
prependOnceListener(event: string, listener: EventListener): Process {
|
|
322
|
+
emitter.prependOnceListener(event, listener);
|
|
323
|
+
return proc;
|
|
324
|
+
},
|
|
325
|
+
|
|
326
|
+
eventNames(): string[] {
|
|
327
|
+
return emitter.eventNames();
|
|
328
|
+
},
|
|
329
|
+
|
|
330
|
+
setMaxListeners(n: number): Process {
|
|
331
|
+
emitter.setMaxListeners(n);
|
|
332
|
+
return proc;
|
|
333
|
+
},
|
|
334
|
+
|
|
335
|
+
getMaxListeners(): number {
|
|
336
|
+
return emitter.getMaxListeners();
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
return proc;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Default process instance
|
|
344
|
+
export const process = createProcess();
|
|
345
|
+
|
|
346
|
+
export default process;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js querystring module shim
|
|
3
|
+
* Uses browser's URLSearchParams
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type ParsedUrlQuery = Record<string, string | string[]>;
|
|
7
|
+
|
|
8
|
+
export function parse(
|
|
9
|
+
str: string,
|
|
10
|
+
sep: string = '&',
|
|
11
|
+
eq: string = '=',
|
|
12
|
+
options?: { maxKeys?: number }
|
|
13
|
+
): ParsedUrlQuery {
|
|
14
|
+
const result: ParsedUrlQuery = {};
|
|
15
|
+
|
|
16
|
+
if (!str || typeof str !== 'string') {
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const maxKeys = options?.maxKeys || 1000;
|
|
21
|
+
const pairs = str.split(sep).slice(0, maxKeys > 0 ? maxKeys : undefined);
|
|
22
|
+
|
|
23
|
+
for (const pair of pairs) {
|
|
24
|
+
const idx = pair.indexOf(eq);
|
|
25
|
+
let key: string;
|
|
26
|
+
let value: string;
|
|
27
|
+
|
|
28
|
+
if (idx >= 0) {
|
|
29
|
+
key = decodeURIComponent(pair.slice(0, idx).replace(/\+/g, ' '));
|
|
30
|
+
value = decodeURIComponent(pair.slice(idx + 1).replace(/\+/g, ' '));
|
|
31
|
+
} else {
|
|
32
|
+
key = decodeURIComponent(pair.replace(/\+/g, ' '));
|
|
33
|
+
value = '';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (key in result) {
|
|
37
|
+
const existing = result[key];
|
|
38
|
+
if (Array.isArray(existing)) {
|
|
39
|
+
existing.push(value);
|
|
40
|
+
} else {
|
|
41
|
+
result[key] = [existing, value];
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
result[key] = value;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function stringify(
|
|
52
|
+
obj: Record<string, string | string[] | number | boolean | undefined>,
|
|
53
|
+
sep: string = '&',
|
|
54
|
+
eq: string = '='
|
|
55
|
+
): string {
|
|
56
|
+
if (!obj || typeof obj !== 'object') {
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const pairs: string[] = [];
|
|
61
|
+
|
|
62
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
63
|
+
if (value === undefined) continue;
|
|
64
|
+
|
|
65
|
+
const encodedKey = encodeURIComponent(key);
|
|
66
|
+
|
|
67
|
+
if (Array.isArray(value)) {
|
|
68
|
+
for (const v of value) {
|
|
69
|
+
pairs.push(`${encodedKey}${eq}${encodeURIComponent(String(v))}`);
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
pairs.push(`${encodedKey}${eq}${encodeURIComponent(String(value))}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return pairs.join(sep);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function escape(str: string): string {
|
|
80
|
+
return encodeURIComponent(str);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function unescape(str: string): string {
|
|
84
|
+
return decodeURIComponent(str.replace(/\+/g, ' '));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const encode = stringify;
|
|
88
|
+
export const decode = parse;
|
|
89
|
+
|
|
90
|
+
export default {
|
|
91
|
+
parse,
|
|
92
|
+
stringify,
|
|
93
|
+
escape,
|
|
94
|
+
unescape,
|
|
95
|
+
encode,
|
|
96
|
+
decode,
|
|
97
|
+
};
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* readdirp shim - Recursive directory reader
|
|
3
|
+
* Used by some build tools for file discovery
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { VirtualFS, Stats } from '../virtual-fs';
|
|
7
|
+
|
|
8
|
+
// Global reference to VFS - set by runtime
|
|
9
|
+
let globalVFS: VirtualFS | null = null;
|
|
10
|
+
|
|
11
|
+
export function setVFS(vfs: VirtualFS): void {
|
|
12
|
+
globalVFS = vfs;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ReaddirpOptions {
|
|
16
|
+
root?: string;
|
|
17
|
+
fileFilter?: string | string[] | ((entry: EntryInfo) => boolean);
|
|
18
|
+
directoryFilter?: string | string[] | ((entry: EntryInfo) => boolean);
|
|
19
|
+
depth?: number;
|
|
20
|
+
type?: 'files' | 'directories' | 'files_directories' | 'all';
|
|
21
|
+
lstat?: boolean;
|
|
22
|
+
alwaysStat?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface EntryInfo {
|
|
26
|
+
path: string;
|
|
27
|
+
fullPath: string;
|
|
28
|
+
basename: string;
|
|
29
|
+
stats?: Stats;
|
|
30
|
+
dirent?: { isFile(): boolean; isDirectory(): boolean; name: string };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
class ReaddirpStream {
|
|
34
|
+
private options: ReaddirpOptions;
|
|
35
|
+
private root: string;
|
|
36
|
+
private entries: EntryInfo[] = [];
|
|
37
|
+
private index = 0;
|
|
38
|
+
private collected = false;
|
|
39
|
+
|
|
40
|
+
constructor(root: string, options: ReaddirpOptions = {}) {
|
|
41
|
+
this.root = root;
|
|
42
|
+
this.options = options;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private matchFilter(
|
|
46
|
+
entry: EntryInfo,
|
|
47
|
+
filter?: string | string[] | ((entry: EntryInfo) => boolean)
|
|
48
|
+
): boolean {
|
|
49
|
+
if (!filter) return true;
|
|
50
|
+
|
|
51
|
+
if (typeof filter === 'function') {
|
|
52
|
+
return filter(entry);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const patterns = Array.isArray(filter) ? filter : [filter];
|
|
56
|
+
for (const pattern of patterns) {
|
|
57
|
+
if (pattern.startsWith('!')) {
|
|
58
|
+
// Negation pattern
|
|
59
|
+
const posPattern = pattern.slice(1);
|
|
60
|
+
if (this.matchGlob(entry.basename, posPattern)) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
} else if (this.matchGlob(entry.basename, pattern)) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return patterns.length === 0 || patterns.every((p) => p.startsWith('!'));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private matchGlob(name: string, pattern: string): boolean {
|
|
72
|
+
// Simple glob matching
|
|
73
|
+
if (pattern === '*') return true;
|
|
74
|
+
if (pattern.startsWith('*.')) {
|
|
75
|
+
const ext = pattern.slice(1);
|
|
76
|
+
return name.endsWith(ext);
|
|
77
|
+
}
|
|
78
|
+
if (pattern.endsWith('*')) {
|
|
79
|
+
const prefix = pattern.slice(0, -1);
|
|
80
|
+
return name.startsWith(prefix);
|
|
81
|
+
}
|
|
82
|
+
return name === pattern;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private collect(dir: string, depth: number, relativePath: string = ''): void {
|
|
86
|
+
if (!globalVFS) return;
|
|
87
|
+
if (this.options.depth !== undefined && depth > this.options.depth) return;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const entries = globalVFS.readdirSync(dir);
|
|
91
|
+
|
|
92
|
+
for (const name of entries) {
|
|
93
|
+
const fullPath = dir === '/' ? '/' + name : dir + '/' + name;
|
|
94
|
+
const relPath = relativePath ? relativePath + '/' + name : name;
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
const stats = globalVFS.statSync(fullPath);
|
|
98
|
+
const isDir = stats.isDirectory();
|
|
99
|
+
|
|
100
|
+
const entry: EntryInfo = {
|
|
101
|
+
path: relPath,
|
|
102
|
+
fullPath,
|
|
103
|
+
basename: name,
|
|
104
|
+
stats: this.options.alwaysStat ? stats : undefined,
|
|
105
|
+
dirent: {
|
|
106
|
+
isFile: () => !isDir,
|
|
107
|
+
isDirectory: () => isDir,
|
|
108
|
+
name,
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const type = this.options.type || 'files';
|
|
113
|
+
|
|
114
|
+
if (isDir) {
|
|
115
|
+
// Check directory filter
|
|
116
|
+
if (!this.matchFilter(entry, this.options.directoryFilter)) {
|
|
117
|
+
continue; // Skip this directory entirely
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (type === 'directories' || type === 'files_directories' || type === 'all') {
|
|
121
|
+
this.entries.push(entry);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Recurse into directory
|
|
125
|
+
this.collect(fullPath, depth + 1, relPath);
|
|
126
|
+
} else {
|
|
127
|
+
if (type === 'files' || type === 'files_directories' || type === 'all') {
|
|
128
|
+
// Check file filter
|
|
129
|
+
if (this.matchFilter(entry, this.options.fileFilter)) {
|
|
130
|
+
this.entries.push(entry);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
} catch {
|
|
135
|
+
// Skip entries that can't be stat'd
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} catch {
|
|
139
|
+
// Skip directories that can't be read
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Async iterator
|
|
144
|
+
async *[Symbol.asyncIterator](): AsyncIterableIterator<EntryInfo> {
|
|
145
|
+
if (!this.collected) {
|
|
146
|
+
this.collect(this.root, 0);
|
|
147
|
+
this.collected = true;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
for (const entry of this.entries) {
|
|
151
|
+
yield entry;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Promise-based API
|
|
156
|
+
async toArray(): Promise<EntryInfo[]> {
|
|
157
|
+
if (!this.collected) {
|
|
158
|
+
this.collect(this.root, 0);
|
|
159
|
+
this.collected = true;
|
|
160
|
+
}
|
|
161
|
+
return [...this.entries];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Stream-like API for compatibility
|
|
165
|
+
on(event: string, callback: (...args: unknown[]) => void): this {
|
|
166
|
+
if (event === 'data') {
|
|
167
|
+
// Emit entries asynchronously
|
|
168
|
+
setTimeout(async () => {
|
|
169
|
+
if (!this.collected) {
|
|
170
|
+
this.collect(this.root, 0);
|
|
171
|
+
this.collected = true;
|
|
172
|
+
}
|
|
173
|
+
for (const entry of this.entries) {
|
|
174
|
+
callback(entry);
|
|
175
|
+
}
|
|
176
|
+
// Emit 'end' after all data
|
|
177
|
+
this.emit('end');
|
|
178
|
+
}, 0);
|
|
179
|
+
}
|
|
180
|
+
return this;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
private listeners: Map<string, ((...args: unknown[]) => void)[]> = new Map();
|
|
184
|
+
|
|
185
|
+
private emit(event: string, ...args: unknown[]): void {
|
|
186
|
+
const handlers = this.listeners.get(event);
|
|
187
|
+
if (handlers) {
|
|
188
|
+
for (const handler of handlers) {
|
|
189
|
+
handler(...args);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
once(event: string, callback: (...args: unknown[]) => void): this {
|
|
195
|
+
const wrapper = (...args: unknown[]) => {
|
|
196
|
+
callback(...args);
|
|
197
|
+
this.off(event, wrapper);
|
|
198
|
+
};
|
|
199
|
+
return this.on(event, wrapper);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
off(event: string, callback: (...args: unknown[]) => void): this {
|
|
203
|
+
const handlers = this.listeners.get(event);
|
|
204
|
+
if (handlers) {
|
|
205
|
+
const index = handlers.indexOf(callback);
|
|
206
|
+
if (index !== -1) {
|
|
207
|
+
handlers.splice(index, 1);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return this;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Read directory recursively
|
|
216
|
+
*/
|
|
217
|
+
export function readdirp(root: string, options?: ReaddirpOptions): ReaddirpStream {
|
|
218
|
+
return new ReaddirpStream(root, options);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Promise-based helper
|
|
222
|
+
export async function readdirpPromise(root: string, options?: ReaddirpOptions): Promise<EntryInfo[]> {
|
|
223
|
+
const stream = new ReaddirpStream(root, options);
|
|
224
|
+
return stream.toArray();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export default readdirp;
|
|
228
|
+
export { ReaddirpStream };
|