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,113 @@
1
+ /**
2
+ * v8 shim - V8 engine internals are not available in browser
3
+ * Provides stubs for common usage patterns
4
+ */
5
+
6
+ // Heap statistics stub
7
+ export function getHeapStatistics() {
8
+ return {
9
+ total_heap_size: 0,
10
+ total_heap_size_executable: 0,
11
+ total_physical_size: 0,
12
+ total_available_size: 0,
13
+ used_heap_size: 0,
14
+ heap_size_limit: 0,
15
+ malloced_memory: 0,
16
+ peak_malloced_memory: 0,
17
+ does_zap_garbage: 0,
18
+ number_of_native_contexts: 0,
19
+ number_of_detached_contexts: 0,
20
+ };
21
+ }
22
+
23
+ export function getHeapSpaceStatistics() {
24
+ return [];
25
+ }
26
+
27
+ export function getHeapCodeStatistics() {
28
+ return {
29
+ code_and_metadata_size: 0,
30
+ bytecode_and_metadata_size: 0,
31
+ external_script_source_size: 0,
32
+ };
33
+ }
34
+
35
+ export function getHeapSnapshot() {
36
+ return null;
37
+ }
38
+
39
+ export function writeHeapSnapshot() {
40
+ return '';
41
+ }
42
+
43
+ export function setFlagsFromString(_flags: string) {
44
+ // No-op
45
+ }
46
+
47
+ export function takeCoverage() {
48
+ // No-op
49
+ }
50
+
51
+ export function stopCoverage() {
52
+ // No-op
53
+ }
54
+
55
+ // Serialization (basic stubs)
56
+ export function serialize(value: unknown): Buffer {
57
+ const json = JSON.stringify(value);
58
+ return Buffer.from(json);
59
+ }
60
+
61
+ export function deserialize(buffer: Buffer): unknown {
62
+ return JSON.parse(buffer.toString());
63
+ }
64
+
65
+ export class Serializer {
66
+ writeHeader() {}
67
+ writeValue(_value: unknown) {}
68
+ releaseBuffer(): Buffer {
69
+ return Buffer.from('');
70
+ }
71
+ }
72
+
73
+ export class Deserializer {
74
+ constructor(_buffer: Buffer) {}
75
+ readHeader(): boolean {
76
+ return true;
77
+ }
78
+ readValue(): unknown {
79
+ return null;
80
+ }
81
+ }
82
+
83
+ export class DefaultSerializer extends Serializer {}
84
+ export class DefaultDeserializer extends Deserializer {}
85
+
86
+ // Promise hooks (stubs)
87
+ export function promiseHooks() {
88
+ return {
89
+ onInit: () => {},
90
+ onSettled: () => {},
91
+ onBefore: () => {},
92
+ onAfter: () => {},
93
+ createHook: () => ({ enable: () => {}, disable: () => {} }),
94
+ };
95
+ }
96
+
97
+ export default {
98
+ getHeapStatistics,
99
+ getHeapSpaceStatistics,
100
+ getHeapCodeStatistics,
101
+ getHeapSnapshot,
102
+ writeHeapSnapshot,
103
+ setFlagsFromString,
104
+ takeCoverage,
105
+ stopCoverage,
106
+ serialize,
107
+ deserialize,
108
+ Serializer,
109
+ Deserializer,
110
+ DefaultSerializer,
111
+ DefaultDeserializer,
112
+ promiseHooks,
113
+ };
@@ -0,0 +1,402 @@
1
+ /**
2
+ * VirtualFS Adapter for just-bash
3
+ * Implements IFileSystem interface to bridge VirtualFS with just-bash
4
+ */
5
+
6
+ import type {
7
+ IFileSystem,
8
+ FsStat,
9
+ MkdirOptions,
10
+ RmOptions,
11
+ CpOptions,
12
+ BufferEncoding,
13
+ FileContent,
14
+ } from 'just-bash';
15
+ import type { VirtualFS } from '../virtual-fs';
16
+ import { createNodeError } from '../virtual-fs';
17
+
18
+ // Local types for just-bash interface compatibility
19
+ // These are not exported from just-bash main entry point
20
+ interface DirentEntry {
21
+ name: string;
22
+ isFile: boolean;
23
+ isDirectory: boolean;
24
+ isSymbolicLink: boolean;
25
+ }
26
+
27
+ interface ReadFileOptions {
28
+ encoding?: BufferEncoding | null;
29
+ }
30
+
31
+ interface WriteFileOptions {
32
+ encoding?: BufferEncoding;
33
+ }
34
+
35
+ export class VirtualFSAdapter implements IFileSystem {
36
+ constructor(private vfs: VirtualFS) {}
37
+
38
+ /**
39
+ * Read the contents of a file as a string
40
+ */
41
+ async readFile(
42
+ path: string,
43
+ options?: ReadFileOptions | BufferEncoding
44
+ ): Promise<string> {
45
+ const encoding = typeof options === 'string' ? options : options?.encoding;
46
+
47
+ // VirtualFS only natively supports utf8/utf-8
48
+ // For other encodings, we need to handle the conversion ourselves
49
+ if (!encoding || encoding === 'utf8' || encoding === 'utf-8') {
50
+ return this.vfs.readFileSync(path, 'utf8');
51
+ }
52
+
53
+ // For binary/latin1 encoding, convert each byte to a character
54
+ if (encoding === 'binary' || encoding === 'latin1') {
55
+ const buffer = this.vfs.readFileSync(path);
56
+ return String.fromCharCode(...buffer);
57
+ }
58
+
59
+ // For other encodings, fall back to utf8
60
+ return this.vfs.readFileSync(path, 'utf8');
61
+ }
62
+
63
+ /**
64
+ * Read the contents of a file as a Uint8Array (binary)
65
+ */
66
+ async readFileBuffer(path: string): Promise<Uint8Array> {
67
+ return this.vfs.readFileSync(path);
68
+ }
69
+
70
+ /**
71
+ * Write content to a file, creating it if it doesn't exist
72
+ */
73
+ async writeFile(
74
+ path: string,
75
+ content: FileContent,
76
+ _options?: WriteFileOptions | BufferEncoding
77
+ ): Promise<void> {
78
+ this.vfs.writeFileSync(path, content);
79
+ }
80
+
81
+ /**
82
+ * Append content to a file, creating it if it doesn't exist
83
+ */
84
+ async appendFile(
85
+ path: string,
86
+ content: FileContent,
87
+ _options?: WriteFileOptions | BufferEncoding
88
+ ): Promise<void> {
89
+ let existing = '';
90
+ try {
91
+ existing = this.vfs.readFileSync(path, 'utf8');
92
+ } catch {
93
+ // File doesn't exist, start with empty content
94
+ }
95
+ const newContent =
96
+ typeof content === 'string' ? content : new TextDecoder().decode(content);
97
+ this.vfs.writeFileSync(path, existing + newContent);
98
+ }
99
+
100
+ /**
101
+ * Check if a path exists
102
+ */
103
+ async exists(path: string): Promise<boolean> {
104
+ return this.vfs.existsSync(path);
105
+ }
106
+
107
+ /**
108
+ * Get file/directory information
109
+ */
110
+ async stat(path: string): Promise<FsStat> {
111
+ const stats = this.vfs.statSync(path);
112
+ const isFile = stats.isFile();
113
+ const isDirectory = stats.isDirectory();
114
+
115
+ let size = 0;
116
+ if (isFile) {
117
+ try {
118
+ const content = this.vfs.readFileSync(path);
119
+ size = content.length;
120
+ } catch {
121
+ // Shouldn't happen, but default to 0
122
+ }
123
+ }
124
+
125
+ return {
126
+ isFile,
127
+ isDirectory,
128
+ isSymbolicLink: false,
129
+ mode: isDirectory ? 0o755 : 0o644,
130
+ size,
131
+ mtime: new Date(),
132
+ };
133
+ }
134
+
135
+ /**
136
+ * Create a directory
137
+ */
138
+ async mkdir(path: string, options?: MkdirOptions): Promise<void> {
139
+ this.vfs.mkdirSync(path, options);
140
+ }
141
+
142
+ /**
143
+ * Read directory contents
144
+ */
145
+ async readdir(path: string): Promise<string[]> {
146
+ return this.vfs.readdirSync(path);
147
+ }
148
+
149
+ /**
150
+ * Read directory contents with file type information
151
+ */
152
+ async readdirWithFileTypes(path: string): Promise<DirentEntry[]> {
153
+ const entries = this.vfs.readdirSync(path);
154
+ const result: DirentEntry[] = [];
155
+
156
+ for (const name of entries) {
157
+ const fullPath = path === '/' ? `/${name}` : `${path}/${name}`;
158
+ try {
159
+ const stats = this.vfs.statSync(fullPath);
160
+ result.push({
161
+ name,
162
+ isFile: stats.isFile(),
163
+ isDirectory: stats.isDirectory(),
164
+ isSymbolicLink: false,
165
+ });
166
+ } catch {
167
+ // Entry disappeared between readdir and stat, skip it
168
+ }
169
+ }
170
+
171
+ return result;
172
+ }
173
+
174
+ /**
175
+ * Remove a file or directory
176
+ */
177
+ async rm(path: string, options?: RmOptions): Promise<void> {
178
+ const exists = this.vfs.existsSync(path);
179
+
180
+ if (!exists) {
181
+ if (options?.force) {
182
+ return; // Force mode ignores missing files
183
+ }
184
+ throw createNodeError('ENOENT', 'rm', path);
185
+ }
186
+
187
+ const stats = this.vfs.statSync(path);
188
+
189
+ if (stats.isFile()) {
190
+ this.vfs.unlinkSync(path);
191
+ } else if (stats.isDirectory()) {
192
+ if (options?.recursive) {
193
+ await this.rmRecursive(path);
194
+ } else {
195
+ this.vfs.rmdirSync(path);
196
+ }
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Recursively remove a directory and its contents
202
+ */
203
+ private async rmRecursive(path: string): Promise<void> {
204
+ const entries = this.vfs.readdirSync(path);
205
+
206
+ for (const entry of entries) {
207
+ const fullPath = path === '/' ? `/${entry}` : `${path}/${entry}`;
208
+ const stats = this.vfs.statSync(fullPath);
209
+
210
+ if (stats.isDirectory()) {
211
+ await this.rmRecursive(fullPath);
212
+ } else {
213
+ this.vfs.unlinkSync(fullPath);
214
+ }
215
+ }
216
+
217
+ this.vfs.rmdirSync(path);
218
+ }
219
+
220
+ /**
221
+ * Copy a file or directory
222
+ */
223
+ async cp(src: string, dest: string, options?: CpOptions): Promise<void> {
224
+ const stats = this.vfs.statSync(src);
225
+
226
+ if (stats.isFile()) {
227
+ const content = this.vfs.readFileSync(src);
228
+ this.vfs.writeFileSync(dest, content);
229
+ } else if (stats.isDirectory()) {
230
+ if (!options?.recursive) {
231
+ throw new Error(
232
+ `EISDIR: illegal operation on a directory, cannot copy '${src}'`
233
+ );
234
+ }
235
+ await this.cpRecursive(src, dest);
236
+ }
237
+ }
238
+
239
+ /**
240
+ * Recursively copy a directory
241
+ */
242
+ private async cpRecursive(src: string, dest: string): Promise<void> {
243
+ // Create destination directory
244
+ this.vfs.mkdirSync(dest, { recursive: true });
245
+
246
+ const entries = this.vfs.readdirSync(src);
247
+
248
+ for (const entry of entries) {
249
+ const srcPath = src === '/' ? `/${entry}` : `${src}/${entry}`;
250
+ const destPath = dest === '/' ? `/${entry}` : `${dest}/${entry}`;
251
+ const stats = this.vfs.statSync(srcPath);
252
+
253
+ if (stats.isDirectory()) {
254
+ await this.cpRecursive(srcPath, destPath);
255
+ } else {
256
+ const content = this.vfs.readFileSync(srcPath);
257
+ this.vfs.writeFileSync(destPath, content);
258
+ }
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Move/rename a file or directory
264
+ */
265
+ async mv(src: string, dest: string): Promise<void> {
266
+ this.vfs.renameSync(src, dest);
267
+ }
268
+
269
+ /**
270
+ * Resolve a relative path against a base path
271
+ */
272
+ resolvePath(base: string, path: string): string {
273
+ // If path is absolute, return it as-is (normalized)
274
+ if (path.startsWith('/')) {
275
+ return this.normalizePath(path);
276
+ }
277
+
278
+ // Combine base and relative path
279
+ const combined = base.endsWith('/')
280
+ ? `${base}${path}`
281
+ : `${base}/${path}`;
282
+
283
+ return this.normalizePath(combined);
284
+ }
285
+
286
+ /**
287
+ * Normalize a path (resolve . and .. segments)
288
+ */
289
+ private normalizePath(path: string): string {
290
+ if (!path.startsWith('/')) {
291
+ path = '/' + path;
292
+ }
293
+
294
+ const parts = path.split('/').filter(Boolean);
295
+ const resolved: string[] = [];
296
+
297
+ for (const part of parts) {
298
+ if (part === '..') {
299
+ resolved.pop();
300
+ } else if (part !== '.') {
301
+ resolved.push(part);
302
+ }
303
+ }
304
+
305
+ return '/' + resolved.join('/');
306
+ }
307
+
308
+ /**
309
+ * Get all paths in the filesystem
310
+ */
311
+ getAllPaths(): string[] {
312
+ const paths: string[] = [];
313
+ this.collectPaths('/', paths);
314
+ return paths;
315
+ }
316
+
317
+ /**
318
+ * Recursively collect all paths
319
+ */
320
+ private collectPaths(dir: string, paths: string[]): void {
321
+ try {
322
+ const entries = this.vfs.readdirSync(dir);
323
+ for (const entry of entries) {
324
+ const fullPath = dir === '/' ? `/${entry}` : `${dir}/${entry}`;
325
+ paths.push(fullPath);
326
+ try {
327
+ const stats = this.vfs.statSync(fullPath);
328
+ if (stats.isDirectory()) {
329
+ this.collectPaths(fullPath, paths);
330
+ }
331
+ } catch {
332
+ // Skip if stat fails
333
+ }
334
+ }
335
+ } catch {
336
+ // Directory doesn't exist or can't be read
337
+ }
338
+ }
339
+
340
+ /**
341
+ * Change file/directory permissions (no-op - VFS doesn't track permissions)
342
+ */
343
+ async chmod(_path: string, _mode: number): Promise<void> {
344
+ // VFS doesn't track permissions, but we verify the path exists
345
+ if (!this.vfs.existsSync(_path)) {
346
+ throw createNodeError('ENOENT', 'chmod', _path);
347
+ }
348
+ // No-op
349
+ }
350
+
351
+ /**
352
+ * Create a symbolic link (not supported)
353
+ */
354
+ async symlink(_target: string, _linkPath: string): Promise<void> {
355
+ throw new Error('Symbolic links are not supported in VirtualFS');
356
+ }
357
+
358
+ /**
359
+ * Create a hard link (not supported)
360
+ */
361
+ async link(_existingPath: string, _newPath: string): Promise<void> {
362
+ throw new Error('Hard links are not supported in VirtualFS');
363
+ }
364
+
365
+ /**
366
+ * Read the target of a symbolic link (not supported)
367
+ */
368
+ async readlink(_path: string): Promise<string> {
369
+ throw new Error('Symbolic links are not supported in VirtualFS');
370
+ }
371
+
372
+ /**
373
+ * Get file/directory information without following symlinks
374
+ * Since VFS doesn't support symlinks, this is the same as stat
375
+ */
376
+ async lstat(path: string): Promise<FsStat> {
377
+ return this.stat(path);
378
+ }
379
+
380
+ /**
381
+ * Resolve all symlinks in a path
382
+ * Since VFS doesn't support symlinks, just normalize and return
383
+ */
384
+ async realpath(path: string): Promise<string> {
385
+ // Verify path exists
386
+ if (!this.vfs.existsSync(path)) {
387
+ throw createNodeError('ENOENT', 'realpath', path);
388
+ }
389
+ return this.normalizePath(path);
390
+ }
391
+
392
+ /**
393
+ * Set access and modification times (no-op - VFS doesn't track times)
394
+ */
395
+ async utimes(path: string, _atime: Date, _mtime: Date): Promise<void> {
396
+ // VFS doesn't track times, but we verify the path exists
397
+ if (!this.vfs.existsSync(path)) {
398
+ throw createNodeError('ENOENT', 'utimes', path);
399
+ }
400
+ // No-op
401
+ }
402
+ }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * vm shim - Basic VM functionality using eval
3
+ */
4
+
5
+ export class Script {
6
+ private code: string;
7
+
8
+ constructor(code: string, _options?: object) {
9
+ this.code = code;
10
+ }
11
+
12
+ runInThisContext(_options?: object): unknown {
13
+ return eval(this.code);
14
+ }
15
+
16
+ runInNewContext(contextObject?: object, _options?: object): unknown {
17
+ const keys = contextObject ? Object.keys(contextObject) : [];
18
+ const values = contextObject ? Object.values(contextObject) : [];
19
+ const fn = new Function(...keys, `return eval(${JSON.stringify(this.code)})`);
20
+ return fn(...values);
21
+ }
22
+
23
+ runInContext(_context: object, _options?: object): unknown {
24
+ return this.runInNewContext(_context, _options);
25
+ }
26
+
27
+ createCachedData(): Buffer {
28
+ return Buffer.from('');
29
+ }
30
+ }
31
+
32
+ export function createContext(contextObject?: object, _options?: object): object {
33
+ return contextObject || {};
34
+ }
35
+
36
+ export function isContext(_sandbox: object): boolean {
37
+ return true;
38
+ }
39
+
40
+ export function runInThisContext(code: string, _options?: object): unknown {
41
+ return eval(code);
42
+ }
43
+
44
+ export function runInNewContext(code: string, contextObject?: object, _options?: object): unknown {
45
+ const script = new Script(code);
46
+ return script.runInNewContext(contextObject);
47
+ }
48
+
49
+ export function runInContext(code: string, context: object, _options?: object): unknown {
50
+ return runInNewContext(code, context);
51
+ }
52
+
53
+ export function compileFunction(code: string, params?: string[], _options?: object): Function {
54
+ return new Function(...(params || []), code);
55
+ }
56
+
57
+ export class Module {
58
+ constructor(_code: string, _options?: object) {}
59
+ link(_linker: unknown): Promise<void> { return Promise.resolve(); }
60
+ evaluate(_options?: object): Promise<unknown> { return Promise.resolve(); }
61
+ get status(): string { return 'unlinked'; }
62
+ get identifier(): string { return ''; }
63
+ get context(): object { return {}; }
64
+ get namespace(): object { return {}; }
65
+ }
66
+
67
+ export class SourceTextModule extends Module {}
68
+ export class SyntheticModule extends Module {
69
+ setExport(_name: string, _value: unknown): void {}
70
+ }
71
+
72
+ export default {
73
+ Script,
74
+ createContext,
75
+ isContext,
76
+ runInThisContext,
77
+ runInNewContext,
78
+ runInContext,
79
+ compileFunction,
80
+ Module,
81
+ SourceTextModule,
82
+ SyntheticModule,
83
+ };
@@ -0,0 +1,111 @@
1
+ /**
2
+ * worker_threads shim - Worker threads API
3
+ * Stub implementation for browser environment
4
+ */
5
+
6
+ import { EventEmitter } from './events';
7
+
8
+ export const isMainThread = true;
9
+ export const parentPort = null;
10
+ export const workerData = null;
11
+ export const threadId = 0;
12
+
13
+ export class Worker extends EventEmitter {
14
+ threadId = 0;
15
+ resourceLimits = {};
16
+
17
+ constructor(filename: string, options?: { workerData?: unknown }) {
18
+ super();
19
+ console.warn('Worker threads are not fully supported in browser environment');
20
+ }
21
+
22
+ postMessage(value: unknown, transferList?: unknown[]): void {
23
+ // No-op
24
+ }
25
+
26
+ terminate(): Promise<number> {
27
+ return Promise.resolve(0);
28
+ }
29
+
30
+ ref(): void {}
31
+ unref(): void {}
32
+
33
+ getHeapSnapshot(): Promise<unknown> {
34
+ return Promise.resolve({});
35
+ }
36
+ }
37
+
38
+ export class MessageChannel {
39
+ port1 = new MessagePort();
40
+ port2 = new MessagePort();
41
+ }
42
+
43
+ export class MessagePort extends EventEmitter {
44
+ postMessage(value: unknown, transferList?: unknown[]): void {
45
+ // No-op
46
+ }
47
+
48
+ start(): void {}
49
+ close(): void {}
50
+ ref(): void {}
51
+ unref(): void {}
52
+ }
53
+
54
+ export class BroadcastChannel extends EventEmitter {
55
+ name: string;
56
+
57
+ constructor(name: string) {
58
+ super();
59
+ this.name = name;
60
+ }
61
+
62
+ postMessage(message: unknown): void {
63
+ // No-op in single-threaded environment
64
+ }
65
+
66
+ close(): void {}
67
+ ref(): void {}
68
+ unref(): void {}
69
+ }
70
+
71
+ export function moveMessagePortToContext(
72
+ port: MessagePort,
73
+ contextifiedSandbox: unknown
74
+ ): MessagePort {
75
+ return port;
76
+ }
77
+
78
+ export function receiveMessageOnPort(port: MessagePort): { message: unknown } | undefined {
79
+ return undefined;
80
+ }
81
+
82
+ export const SHARE_ENV = Symbol.for('nodejs.worker_threads.SHARE_ENV');
83
+
84
+ export function markAsUntransferable(object: unknown): void {
85
+ // No-op
86
+ }
87
+
88
+ export function getEnvironmentData(key: unknown): unknown {
89
+ return undefined;
90
+ }
91
+
92
+ export function setEnvironmentData(key: unknown, value: unknown): void {
93
+ // No-op
94
+ }
95
+
96
+ export default {
97
+ isMainThread,
98
+ parentPort,
99
+ workerData,
100
+ threadId,
101
+ Worker,
102
+ MessageChannel,
103
+ MessagePort,
104
+ BroadcastChannel,
105
+ moveMessagePortToContext,
106
+ receiveMessageOnPort,
107
+ SHARE_ENV,
108
+ markAsUntransferable,
109
+ getEnvironmentData,
110
+ setEnvironmentData,
111
+ };