@volter/tabnode 0.2.14-volter.88

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 (429) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +78 -0
  3. package/THIRD-PARTY-NOTICES.md +12 -0
  4. package/dist/__sw__.js +526 -0
  5. package/dist/assets/runtime-worker-4MKaHFVb.js +75221 -0
  6. package/dist/assets/runtime-worker-4MKaHFVb.js.map +1 -0
  7. package/dist/code-transforms.d.ts +21 -0
  8. package/dist/code-transforms.d.ts.map +1 -0
  9. package/dist/config/cdn.d.ts +12 -0
  10. package/dist/config/cdn.d.ts.map +1 -0
  11. package/dist/create-runtime.d.ts +22 -0
  12. package/dist/create-runtime.d.ts.map +1 -0
  13. package/dist/host-globals.d.ts +62 -0
  14. package/dist/host-globals.d.ts.map +1 -0
  15. package/dist/index.cjs +36021 -0
  16. package/dist/index.cjs.map +1 -0
  17. package/dist/index.d.ts +127 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.mjs +36020 -0
  20. package/dist/index.mjs.map +1 -0
  21. package/dist/node-internals.d.ts +68 -0
  22. package/dist/node-internals.d.ts.map +1 -0
  23. package/dist/node-lib/binding/blob.d.ts +12 -0
  24. package/dist/node-lib/binding/blob.d.ts.map +1 -0
  25. package/dist/node-lib/binding/buffer.d.ts +144 -0
  26. package/dist/node-lib/binding/buffer.d.ts.map +1 -0
  27. package/dist/node-lib/binding/cares_wrap.d.ts +14 -0
  28. package/dist/node-lib/binding/cares_wrap.d.ts.map +1 -0
  29. package/dist/node-lib/binding/fds.d.ts +30 -0
  30. package/dist/node-lib/binding/fds.d.ts.map +1 -0
  31. package/dist/node-lib/binding/fs.d.ts +157 -0
  32. package/dist/node-lib/binding/fs.d.ts.map +1 -0
  33. package/dist/node-lib/binding/handles.d.ts +81 -0
  34. package/dist/node-lib/binding/handles.d.ts.map +1 -0
  35. package/dist/node-lib/binding/http_parser.d.ts +122 -0
  36. package/dist/node-lib/binding/http_parser.d.ts.map +1 -0
  37. package/dist/node-lib/binding/index.d.ts +3 -0
  38. package/dist/node-lib/binding/index.d.ts.map +1 -0
  39. package/dist/node-lib/binding/llhttp-wasm.d.ts +22 -0
  40. package/dist/node-lib/binding/llhttp-wasm.d.ts.map +1 -0
  41. package/dist/node-lib/binding/misc.d.ts +123 -0
  42. package/dist/node-lib/binding/misc.d.ts.map +1 -0
  43. package/dist/node-lib/binding/pipe_wrap.d.ts +84 -0
  44. package/dist/node-lib/binding/pipe_wrap.d.ts.map +1 -0
  45. package/dist/node-lib/binding/process_wrap.d.ts +173 -0
  46. package/dist/node-lib/binding/process_wrap.d.ts.map +1 -0
  47. package/dist/node-lib/binding/spawn_sync.d.ts +30 -0
  48. package/dist/node-lib/binding/spawn_sync.d.ts.map +1 -0
  49. package/dist/node-lib/binding/stream_wrap.d.ts +191 -0
  50. package/dist/node-lib/binding/stream_wrap.d.ts.map +1 -0
  51. package/dist/node-lib/binding/stubs.d.ts +23 -0
  52. package/dist/node-lib/binding/stubs.d.ts.map +1 -0
  53. package/dist/node-lib/binding/tcp_wrap.d.ts +98 -0
  54. package/dist/node-lib/binding/tcp_wrap.d.ts.map +1 -0
  55. package/dist/node-lib/binding/tty_wrap.d.ts +36 -0
  56. package/dist/node-lib/binding/tty_wrap.d.ts.map +1 -0
  57. package/dist/node-lib/binding/util.d.ts +126 -0
  58. package/dist/node-lib/binding/util.d.ts.map +1 -0
  59. package/dist/node-lib/binding/uv.d.ts +32 -0
  60. package/dist/node-lib/binding/uv.d.ts.map +1 -0
  61. package/dist/node-lib/binding/zlib-pako.d.ts +22 -0
  62. package/dist/node-lib/binding/zlib-pako.d.ts.map +1 -0
  63. package/dist/node-lib/binding/zlib.d.ts +38 -0
  64. package/dist/node-lib/binding/zlib.d.ts.map +1 -0
  65. package/dist/node-lib/buffer-module.d.ts +51 -0
  66. package/dist/node-lib/buffer-module.d.ts.map +1 -0
  67. package/dist/node-lib/child-process-module.d.ts +26 -0
  68. package/dist/node-lib/child-process-module.d.ts.map +1 -0
  69. package/dist/node-lib/events-module.d.ts +58 -0
  70. package/dist/node-lib/events-module.d.ts.map +1 -0
  71. package/dist/node-lib/fs-module.d.ts +5 -0
  72. package/dist/node-lib/fs-module.d.ts.map +1 -0
  73. package/dist/node-lib/http-bridge.d.ts +43 -0
  74. package/dist/node-lib/http-bridge.d.ts.map +1 -0
  75. package/dist/node-lib/http-module.d.ts +35 -0
  76. package/dist/node-lib/http-module.d.ts.map +1 -0
  77. package/dist/node-lib/internals/addresses.d.ts +40 -0
  78. package/dist/node-lib/internals/addresses.d.ts.map +1 -0
  79. package/dist/node-lib/internals/buffer-and-streams.d.ts +96 -0
  80. package/dist/node-lib/internals/buffer-and-streams.d.ts.map +1 -0
  81. package/dist/node-lib/internals/child-process.d.ts +27 -0
  82. package/dist/node-lib/internals/child-process.d.ts.map +1 -0
  83. package/dist/node-lib/internals/events-util.d.ts +83 -0
  84. package/dist/node-lib/internals/events-util.d.ts.map +1 -0
  85. package/dist/node-lib/internals/index.d.ts +2 -0
  86. package/dist/node-lib/internals/index.d.ts.map +1 -0
  87. package/dist/node-lib/internals/modules.d.ts +67 -0
  88. package/dist/node-lib/internals/modules.d.ts.map +1 -0
  89. package/dist/node-lib/internals/readline-access.d.ts +2 -0
  90. package/dist/node-lib/internals/readline-access.d.ts.map +1 -0
  91. package/dist/node-lib/internals/runtime.d.ts +150 -0
  92. package/dist/node-lib/internals/runtime.d.ts.map +1 -0
  93. package/dist/node-lib/internals/util.d.ts +33 -0
  94. package/dist/node-lib/internals/util.d.ts.map +1 -0
  95. package/dist/node-lib/lazy.d.ts +31 -0
  96. package/dist/node-lib/lazy.d.ts.map +1 -0
  97. package/dist/node-lib/load.d.ts +27 -0
  98. package/dist/node-lib/load.d.ts.map +1 -0
  99. package/dist/node-lib/module-hooks.d.ts +89 -0
  100. package/dist/node-lib/module-hooks.d.ts.map +1 -0
  101. package/dist/node-lib/net-module.d.ts +181 -0
  102. package/dist/node-lib/net-module.d.ts.map +1 -0
  103. package/dist/node-lib/node-versions.d.ts +27 -0
  104. package/dist/node-lib/node-versions.d.ts.map +1 -0
  105. package/dist/node-lib/public-modules.d.ts +2 -0
  106. package/dist/node-lib/public-modules.d.ts.map +1 -0
  107. package/dist/node-lib/require-hook.d.ts +15 -0
  108. package/dist/node-lib/require-hook.d.ts.map +1 -0
  109. package/dist/node-lib/small-modules.d.ts +16 -0
  110. package/dist/node-lib/small-modules.d.ts.map +1 -0
  111. package/dist/node-lib/sources.d.ts +4 -0
  112. package/dist/node-lib/sources.d.ts.map +1 -0
  113. package/dist/node-lib/stream-module.d.ts +77 -0
  114. package/dist/node-lib/stream-module.d.ts.map +1 -0
  115. package/dist/node-lib/timers.d.ts +19 -0
  116. package/dist/node-lib/timers.d.ts.map +1 -0
  117. package/dist/node-lib/util-module.d.ts +76 -0
  118. package/dist/node-lib/util-module.d.ts.map +1 -0
  119. package/dist/node-resolution.d.ts +50 -0
  120. package/dist/node-resolution.d.ts.map +1 -0
  121. package/dist/node-resolver.d.ts +7 -0
  122. package/dist/node-resolver.d.ts.map +1 -0
  123. package/dist/npm/index.d.ts +73 -0
  124. package/dist/npm/index.d.ts.map +1 -0
  125. package/dist/npm/registry.d.ts +111 -0
  126. package/dist/npm/registry.d.ts.map +1 -0
  127. package/dist/npm/resolver.d.ts +79 -0
  128. package/dist/npm/resolver.d.ts.map +1 -0
  129. package/dist/npm/tarball.d.ts +28 -0
  130. package/dist/npm/tarball.d.ts.map +1 -0
  131. package/dist/process-tokens.d.ts +77 -0
  132. package/dist/process-tokens.d.ts.map +1 -0
  133. package/dist/punycode-source.d.ts +3 -0
  134. package/dist/punycode-source.d.ts.map +1 -0
  135. package/dist/runtime-interface.d.ts +74 -0
  136. package/dist/runtime-interface.d.ts.map +1 -0
  137. package/dist/runtime.d.ts +144 -0
  138. package/dist/runtime.d.ts.map +1 -0
  139. package/dist/server-bridge.d.ts +147 -0
  140. package/dist/server-bridge.d.ts.map +1 -0
  141. package/dist/shims/async_hooks.d.ts +50 -0
  142. package/dist/shims/async_hooks.d.ts.map +1 -0
  143. package/dist/shims/child_process.d.ts +104 -0
  144. package/dist/shims/child_process.d.ts.map +1 -0
  145. package/dist/shims/cluster.d.ts +52 -0
  146. package/dist/shims/cluster.d.ts.map +1 -0
  147. package/dist/shims/command-line.d.ts +43 -0
  148. package/dist/shims/command-line.d.ts.map +1 -0
  149. package/dist/shims/constants.d.ts +222 -0
  150. package/dist/shims/constants.d.ts.map +1 -0
  151. package/dist/shims/crypto-constants.d.ts +12 -0
  152. package/dist/shims/crypto-constants.d.ts.map +1 -0
  153. package/dist/shims/crypto.d.ts +144 -0
  154. package/dist/shims/crypto.d.ts.map +1 -0
  155. package/dist/shims/dgram.d.ts +34 -0
  156. package/dist/shims/dgram.d.ts.map +1 -0
  157. package/dist/shims/dns.d.ts +91 -0
  158. package/dist/shims/dns.d.ts.map +1 -0
  159. package/dist/shims/domain.d.ts +25 -0
  160. package/dist/shims/domain.d.ts.map +1 -0
  161. package/dist/shims/esbuild.d.ts +205 -0
  162. package/dist/shims/esbuild.d.ts.map +1 -0
  163. package/dist/shims/fs.d.ts +25 -0
  164. package/dist/shims/fs.d.ts.map +1 -0
  165. package/dist/shims/http2.d.ts +81 -0
  166. package/dist/shims/http2.d.ts.map +1 -0
  167. package/dist/shims/inspector.d.ts +25 -0
  168. package/dist/shims/inspector.d.ts.map +1 -0
  169. package/dist/shims/module.d.ts +22 -0
  170. package/dist/shims/module.d.ts.map +1 -0
  171. package/dist/shims/os.d.ts +159 -0
  172. package/dist/shims/os.d.ts.map +1 -0
  173. package/dist/shims/path.d.ts +52 -0
  174. package/dist/shims/path.d.ts.map +1 -0
  175. package/dist/shims/perf_hooks.d.ts +50 -0
  176. package/dist/shims/perf_hooks.d.ts.map +1 -0
  177. package/dist/shims/process.d.ts +226 -0
  178. package/dist/shims/process.d.ts.map +1 -0
  179. package/dist/shims/rollup.d.ts +71 -0
  180. package/dist/shims/rollup.d.ts.map +1 -0
  181. package/dist/shims/string_decoder.d.ts +41 -0
  182. package/dist/shims/string_decoder.d.ts.map +1 -0
  183. package/dist/shims/sync-child.d.ts +64 -0
  184. package/dist/shims/sync-child.d.ts.map +1 -0
  185. package/dist/shims/tls.d.ts +53 -0
  186. package/dist/shims/tls.d.ts.map +1 -0
  187. package/dist/shims/url.d.ts +84 -0
  188. package/dist/shims/url.d.ts.map +1 -0
  189. package/dist/shims/v8.d.ts +73 -0
  190. package/dist/shims/v8.d.ts.map +1 -0
  191. package/dist/shims/vfs-adapter.d.ts +126 -0
  192. package/dist/shims/vfs-adapter.d.ts.map +1 -0
  193. package/dist/shims/vm.d.ts +52 -0
  194. package/dist/shims/vm.d.ts.map +1 -0
  195. package/dist/shims/wasi.d.ts +78 -0
  196. package/dist/shims/wasi.d.ts.map +1 -0
  197. package/dist/shims/worker_threads.d.ts +66 -0
  198. package/dist/shims/worker_threads.d.ts.map +1 -0
  199. package/dist/shims/zlib-constants.d.ts +66 -0
  200. package/dist/shims/zlib-constants.d.ts.map +1 -0
  201. package/dist/shims/zlib.d.ts +102 -0
  202. package/dist/shims/zlib.d.ts.map +1 -0
  203. package/dist/transform.d.ts +24 -0
  204. package/dist/transform.d.ts.map +1 -0
  205. package/dist/types/package-json.d.ts +18 -0
  206. package/dist/types/package-json.d.ts.map +1 -0
  207. package/dist/utils/binary-encoding.d.ts +13 -0
  208. package/dist/utils/binary-encoding.d.ts.map +1 -0
  209. package/dist/utils/glob.d.ts +19 -0
  210. package/dist/utils/glob.d.ts.map +1 -0
  211. package/dist/utils/hash.d.ts +6 -0
  212. package/dist/utils/hash.d.ts.map +1 -0
  213. package/dist/virtual-fs.d.ts +259 -0
  214. package/dist/virtual-fs.d.ts.map +1 -0
  215. package/dist/vite-plugin.cjs +50 -0
  216. package/dist/vite-plugin.cjs.map +1 -0
  217. package/dist/vite-plugin.d.ts +36 -0
  218. package/dist/vite-plugin.d.ts.map +1 -0
  219. package/dist/vite-plugin.mjs +31 -0
  220. package/dist/vite-plugin.mjs.map +1 -0
  221. package/dist/worker/runtime-worker.d.ts +8 -0
  222. package/dist/worker/runtime-worker.d.ts.map +1 -0
  223. package/dist/worker-runtime.d.ts +50 -0
  224. package/dist/worker-runtime.d.ts.map +1 -0
  225. package/package.json +88 -0
  226. package/src/code-transforms.ts +560 -0
  227. package/src/config/cdn.ts +13 -0
  228. package/src/create-runtime.ts +89 -0
  229. package/src/host-globals.ts +121 -0
  230. package/src/index.ts +235 -0
  231. package/src/node-internals.ts +283 -0
  232. package/src/node-lib/LICENSE +47 -0
  233. package/src/node-lib/_http_agent.js +547 -0
  234. package/src/node-lib/_http_client.js +996 -0
  235. package/src/node-lib/_http_common.js +269 -0
  236. package/src/node-lib/_http_incoming.js +453 -0
  237. package/src/node-lib/_http_outgoing.js +1262 -0
  238. package/src/node-lib/_http_server.js +1230 -0
  239. package/src/node-lib/assert/strict.js +3 -0
  240. package/src/node-lib/assert.js +844 -0
  241. package/src/node-lib/binding/blob.ts +35 -0
  242. package/src/node-lib/binding/buffer.ts +465 -0
  243. package/src/node-lib/binding/cares_wrap.ts +57 -0
  244. package/src/node-lib/binding/fds.ts +80 -0
  245. package/src/node-lib/binding/fs.ts +857 -0
  246. package/src/node-lib/binding/handles.ts +187 -0
  247. package/src/node-lib/binding/http_parser.ts +536 -0
  248. package/src/node-lib/binding/index.ts +77 -0
  249. package/src/node-lib/binding/llhttp-wasm.ts +670 -0
  250. package/src/node-lib/binding/misc.ts +252 -0
  251. package/src/node-lib/binding/pipe_wrap.ts +166 -0
  252. package/src/node-lib/binding/process_wrap.ts +371 -0
  253. package/src/node-lib/binding/spawn_sync.ts +141 -0
  254. package/src/node-lib/binding/stream_wrap.ts +413 -0
  255. package/src/node-lib/binding/stubs.ts +19 -0
  256. package/src/node-lib/binding/tcp_wrap.ts +254 -0
  257. package/src/node-lib/binding/tty_wrap.ts +56 -0
  258. package/src/node-lib/binding/util.ts +274 -0
  259. package/src/node-lib/binding/uv.ts +102 -0
  260. package/src/node-lib/binding/zlib-pako.ts +50 -0
  261. package/src/node-lib/binding/zlib.ts +259 -0
  262. package/src/node-lib/buffer-module.ts +70 -0
  263. package/src/node-lib/buffer.js +1373 -0
  264. package/src/node-lib/child-process-module.ts +58 -0
  265. package/src/node-lib/child_process.js +1046 -0
  266. package/src/node-lib/constants.js +41 -0
  267. package/src/node-lib/diagnostics_channel.js +438 -0
  268. package/src/node-lib/events-module.ts +80 -0
  269. package/src/node-lib/events.js +1223 -0
  270. package/src/node-lib/fs-module.ts +43 -0
  271. package/src/node-lib/fs.js +3377 -0
  272. package/src/node-lib/http-bridge.ts +299 -0
  273. package/src/node-lib/http-module.ts +53 -0
  274. package/src/node-lib/http.js +198 -0
  275. package/src/node-lib/https.js +429 -0
  276. package/src/node-lib/internal/assert/assertion_error.js +417 -0
  277. package/src/node-lib/internal/assert/calltracker.js +153 -0
  278. package/src/node-lib/internal/assert/myers_diff.js +177 -0
  279. package/src/node-lib/internal/assert/utils.js +278 -0
  280. package/src/node-lib/internal/buffer.js +1120 -0
  281. package/src/node-lib/internal/child_process/serialization.js +169 -0
  282. package/src/node-lib/internal/child_process.js +1135 -0
  283. package/src/node-lib/internal/constants.js +56 -0
  284. package/src/node-lib/internal/deps/minimatch/index.js +1628 -0
  285. package/src/node-lib/internal/errors.js +1912 -0
  286. package/src/node-lib/internal/events/abort_listener.js +54 -0
  287. package/src/node-lib/internal/events/symbols.js +11 -0
  288. package/src/node-lib/internal/fixed_queue.js +119 -0
  289. package/src/node-lib/internal/freelist.js +30 -0
  290. package/src/node-lib/internal/fs/cp/cp-sync.js +242 -0
  291. package/src/node-lib/internal/fs/cp/cp.js +382 -0
  292. package/src/node-lib/internal/fs/dir.js +369 -0
  293. package/src/node-lib/internal/fs/glob.js +763 -0
  294. package/src/node-lib/internal/fs/promises.js +1312 -0
  295. package/src/node-lib/internal/fs/read/context.js +129 -0
  296. package/src/node-lib/internal/fs/recursive_watch.js +275 -0
  297. package/src/node-lib/internal/fs/rimraf.js +311 -0
  298. package/src/node-lib/internal/fs/streams.js +571 -0
  299. package/src/node-lib/internal/fs/sync_write_stream.js +49 -0
  300. package/src/node-lib/internal/fs/utils.js +987 -0
  301. package/src/node-lib/internal/fs/watchers.js +418 -0
  302. package/src/node-lib/internal/http.js +62 -0
  303. package/src/node-lib/internal/mime.js +389 -0
  304. package/src/node-lib/internal/modules/customization_hooks.js +406 -0
  305. package/src/node-lib/internal/net.js +95 -0
  306. package/src/node-lib/internal/querystring.js +119 -0
  307. package/src/node-lib/internal/readline/callbacks.js +132 -0
  308. package/src/node-lib/internal/readline/emitKeypressEvents.js +99 -0
  309. package/src/node-lib/internal/readline/interface.js +1418 -0
  310. package/src/node-lib/internal/readline/promises.js +144 -0
  311. package/src/node-lib/internal/readline/utils.js +405 -0
  312. package/src/node-lib/internal/socket_list.js +108 -0
  313. package/src/node-lib/internal/stream_base_commons.js +280 -0
  314. package/src/node-lib/internal/streams/add-abort-signal.js +60 -0
  315. package/src/node-lib/internal/streams/compose.js +257 -0
  316. package/src/node-lib/internal/streams/destroy.js +361 -0
  317. package/src/node-lib/internal/streams/duplex.js +203 -0
  318. package/src/node-lib/internal/streams/duplexify.js +379 -0
  319. package/src/node-lib/internal/streams/duplexpair.js +62 -0
  320. package/src/node-lib/internal/streams/end-of-stream.js +331 -0
  321. package/src/node-lib/internal/streams/from.js +208 -0
  322. package/src/node-lib/internal/streams/lazy_transform.js +57 -0
  323. package/src/node-lib/internal/streams/legacy.js +125 -0
  324. package/src/node-lib/internal/streams/operators.js +436 -0
  325. package/src/node-lib/internal/streams/passthrough.js +47 -0
  326. package/src/node-lib/internal/streams/pipeline.js +465 -0
  327. package/src/node-lib/internal/streams/readable.js +1762 -0
  328. package/src/node-lib/internal/streams/state.js +51 -0
  329. package/src/node-lib/internal/streams/transform.js +204 -0
  330. package/src/node-lib/internal/streams/utils.js +363 -0
  331. package/src/node-lib/internal/streams/writable.js +1163 -0
  332. package/src/node-lib/internal/tty.js +260 -0
  333. package/src/node-lib/internal/util/colors.js +40 -0
  334. package/src/node-lib/internal/util/comparisons.js +1028 -0
  335. package/src/node-lib/internal/util/debuglog.js +524 -0
  336. package/src/node-lib/internal/util/inspect.js +2535 -0
  337. package/src/node-lib/internal/util/parse_args/parse_args.js +412 -0
  338. package/src/node-lib/internal/util/parse_args/utils.js +197 -0
  339. package/src/node-lib/internal/util.js +1003 -0
  340. package/src/node-lib/internal/validators.js +654 -0
  341. package/src/node-lib/internals/addresses.ts +159 -0
  342. package/src/node-lib/internals/buffer-and-streams.ts +224 -0
  343. package/src/node-lib/internals/child-process.ts +64 -0
  344. package/src/node-lib/internals/events-util.ts +105 -0
  345. package/src/node-lib/internals/index.ts +66 -0
  346. package/src/node-lib/internals/modules.ts +117 -0
  347. package/src/node-lib/internals/readline-access.ts +16 -0
  348. package/src/node-lib/internals/runtime.ts +277 -0
  349. package/src/node-lib/internals/util.ts +98 -0
  350. package/src/node-lib/lazy.ts +158 -0
  351. package/src/node-lib/load.ts +390 -0
  352. package/src/node-lib/module-hooks.ts +281 -0
  353. package/src/node-lib/net-module.ts +248 -0
  354. package/src/node-lib/net.js +2540 -0
  355. package/src/node-lib/node-versions.ts +34 -0
  356. package/src/node-lib/os.js +356 -0
  357. package/src/node-lib/path.js +1694 -0
  358. package/src/node-lib/primordials.js +743 -0
  359. package/src/node-lib/public-modules.ts +109 -0
  360. package/src/node-lib/punycode.js +455 -0
  361. package/src/node-lib/querystring.js +484 -0
  362. package/src/node-lib/readline/promises.js +73 -0
  363. package/src/node-lib/readline.js +523 -0
  364. package/src/node-lib/require-hook.ts +27 -0
  365. package/src/node-lib/small-modules.ts +35 -0
  366. package/src/node-lib/sources.ts +200 -0
  367. package/src/node-lib/stream/promises.js +44 -0
  368. package/src/node-lib/stream-module.ts +101 -0
  369. package/src/node-lib/stream.js +152 -0
  370. package/src/node-lib/timers.ts +33 -0
  371. package/src/node-lib/tty.js +168 -0
  372. package/src/node-lib/util-module.ts +104 -0
  373. package/src/node-lib/util.js +689 -0
  374. package/src/node-lib/wasi.js +179 -0
  375. package/src/node-lib/zlib.js +1036 -0
  376. package/src/node-resolution.ts +241 -0
  377. package/src/node-resolver.ts +33 -0
  378. package/src/npm/index.ts +425 -0
  379. package/src/npm/registry.ts +235 -0
  380. package/src/npm/resolver.ts +589 -0
  381. package/src/npm/tarball.ts +246 -0
  382. package/src/process-tokens.ts +156 -0
  383. package/src/punycode-source.ts +6 -0
  384. package/src/runtime-interface.ts +85 -0
  385. package/src/runtime.ts +3073 -0
  386. package/src/server-bridge.ts +971 -0
  387. package/src/shims/async_hooks.ts +181 -0
  388. package/src/shims/child_process.ts +1591 -0
  389. package/src/shims/cluster.ts +79 -0
  390. package/src/shims/command-line.ts +79 -0
  391. package/src/shims/constants.ts +68 -0
  392. package/src/shims/crypto-constants.ts +11 -0
  393. package/src/shims/crypto.ts +1061 -0
  394. package/src/shims/dgram.ts +47 -0
  395. package/src/shims/dns.ts +185 -0
  396. package/src/shims/domain.ts +58 -0
  397. package/src/shims/esbuild.ts +1638 -0
  398. package/src/shims/fs.ts +82 -0
  399. package/src/shims/http2.ts +96 -0
  400. package/src/shims/inspector.ts +30 -0
  401. package/src/shims/module.ts +86 -0
  402. package/src/shims/os.ts +195 -0
  403. package/src/shims/path.ts +246 -0
  404. package/src/shims/perf_hooks.ts +92 -0
  405. package/src/shims/process.ts +804 -0
  406. package/src/shims/rollup.ts +149 -0
  407. package/src/shims/string_decoder.ts +396 -0
  408. package/src/shims/sync-child.ts +469 -0
  409. package/src/shims/tls.ts +94 -0
  410. package/src/shims/url.ts +217 -0
  411. package/src/shims/v8.ts +113 -0
  412. package/src/shims/vfs-adapter.ts +408 -0
  413. package/src/shims/vm.ts +132 -0
  414. package/src/shims/wasi.ts +1440 -0
  415. package/src/shims/worker_threads.ts +114 -0
  416. package/src/shims/zlib-constants.ts +65 -0
  417. package/src/shims/zlib.ts +228 -0
  418. package/src/transform.ts +324 -0
  419. package/src/types/external.d.ts +55 -0
  420. package/src/types/package-json.ts +17 -0
  421. package/src/types/pako-zlib.d.ts +30 -0
  422. package/src/types/sha.js.d.ts +14 -0
  423. package/src/utils/binary-encoding.ts +43 -0
  424. package/src/utils/glob.ts +54 -0
  425. package/src/utils/hash.ts +12 -0
  426. package/src/virtual-fs.ts +1048 -0
  427. package/src/vite-plugin.ts +76 -0
  428. package/src/worker/runtime-worker.ts +128 -0
  429. package/src/worker-runtime.ts +145 -0
@@ -0,0 +1,1048 @@
1
+ /**
2
+ * Virtual File System - In-memory file tree with POSIX-like operations
3
+ */
4
+
5
+ import type { VFSSnapshot, VFSFileEntry } from './runtime-interface';
6
+ import { uint8ToBase64, base64ToUint8 } from './utils/binary-encoding';
7
+ import { Readable } from './node-lib/stream-module';
8
+
9
+ /**
10
+ * A read stream is a real `Readable`, so a guest can pipe it, iterate it, or
11
+ * listen for `open` and `ready`; the hand-rolled object it used to answer had
12
+ * only `on` and `pipe`, so anything that treated it as a stream got nothing.
13
+ * `start`, `end` and `encoding` are honoured as Node honours them.
14
+ *
15
+ * What `createReadStream` accepts: the subset of Node's options bag used here.
16
+ */
17
+ export interface ReadStreamOptions {
18
+ encoding?: string;
19
+ start?: number;
20
+ end?: number;
21
+ }
22
+
23
+ /** A `Readable` carrying the two properties Node's fs read stream carries. */
24
+ export interface FsReadStream extends Readable {
25
+ path: string;
26
+ bytesRead: number;
27
+ }
28
+
29
+
30
+
31
+ export interface FSNode {
32
+ type: 'file' | 'directory' | 'symlink';
33
+ content?: Uint8Array;
34
+ /** Where a symlink points, exactly as it was written. */
35
+ target?: string;
36
+ children?: Map<string, FSNode>;
37
+ mtime: number;
38
+ /**
39
+ * When the file was last read. Node reports it apart from the write time
40
+ * and `utimes` sets the two separately; this filesystem reported the write
41
+ * time in its place, so a program that set an access time and read it back
42
+ * got the other one (Node's own test/wasi `stat` fixture asserts them
43
+ * apart). Absent until something sets it, which is the write time.
44
+ */
45
+ atime?: number;
46
+ }
47
+
48
+ // Simple EventEmitter for VFS change notifications
49
+ type VFSChangeListener = (path: string, content: string) => void;
50
+ type VFSDeleteListener = (path: string) => void;
51
+ type VFSEventListener = VFSChangeListener | VFSDeleteListener;
52
+
53
+ export interface Stats {
54
+ isFile(): boolean;
55
+ isDirectory(): boolean;
56
+ isSymbolicLink(): boolean;
57
+ isBlockDevice(): boolean;
58
+ isCharacterDevice(): boolean;
59
+ isFIFO(): boolean;
60
+ isSocket(): boolean;
61
+ size: number;
62
+ mode: number;
63
+ mtime: Date;
64
+ atime: Date;
65
+ ctime: Date;
66
+ birthtime: Date;
67
+ mtimeMs: number;
68
+ atimeMs: number;
69
+ ctimeMs: number;
70
+ birthtimeMs: number;
71
+ nlink: number;
72
+ uid: number;
73
+ gid: number;
74
+ dev: number;
75
+ ino: number;
76
+ rdev: number;
77
+ blksize: number;
78
+ blocks: number;
79
+ }
80
+
81
+ export type WatchEventType = 'change' | 'rename';
82
+ export type WatchListener = (eventType: WatchEventType, filename: string | null) => void;
83
+
84
+ export interface FSWatcher {
85
+ close(): void;
86
+ ref(): this;
87
+ unref(): this;
88
+ }
89
+
90
+ interface WatcherEntry {
91
+ listener: WatchListener;
92
+ recursive: boolean;
93
+ closed: boolean;
94
+ }
95
+
96
+ /**
97
+ * Create a Node.js-style error with code property
98
+ */
99
+ export interface NodeError extends Error {
100
+ code: string;
101
+ errno: number;
102
+ syscall: string;
103
+ path?: string;
104
+ }
105
+
106
+ export function createNodeError(
107
+ code: 'ENOENT' | 'ENOTDIR' | 'EISDIR' | 'EEXIST' | 'ENOTEMPTY' | 'ELOOP' | 'EINVAL',
108
+ syscall: string,
109
+ path: string,
110
+ message?: string
111
+ ): NodeError {
112
+ const errno: Record<string, number> = {
113
+ ENOENT: -2,
114
+ ENOTDIR: -20,
115
+ EISDIR: -21,
116
+ EEXIST: -17,
117
+ ENOTEMPTY: -39,
118
+ };
119
+
120
+ const messages: Record<string, string> = {
121
+ ENOENT: 'no such file or directory',
122
+ ENOTDIR: 'not a directory',
123
+ EISDIR: 'is a directory',
124
+ EEXIST: 'file already exists',
125
+ ENOTEMPTY: 'directory not empty',
126
+ };
127
+
128
+ const err = new Error(
129
+ message || `${code}: ${messages[code]}, ${syscall} '${path}'`
130
+ ) as NodeError;
131
+ err.code = code;
132
+ err.errno = errno[code];
133
+ err.syscall = syscall;
134
+ err.path = path;
135
+ return err;
136
+ }
137
+
138
+ export class VirtualFS {
139
+ private root: FSNode;
140
+ private encoder = new TextEncoder();
141
+ private decoder = new TextDecoder();
142
+ private watchers = new Map<string, Set<WatcherEntry>>();
143
+ private eventListeners = new Map<string, Set<VFSEventListener>>();
144
+
145
+ constructor() {
146
+ this.root = {
147
+ type: 'directory',
148
+ children: new Map(),
149
+ mtime: Date.now(),
150
+ };
151
+ }
152
+
153
+ /**
154
+ * Add event listener (for change notifications to workers)
155
+ */
156
+ on(event: 'change', listener: VFSChangeListener): this;
157
+ on(event: 'delete', listener: VFSDeleteListener): this;
158
+ on(event: string, listener: VFSEventListener): this {
159
+ if (!this.eventListeners.has(event)) {
160
+ this.eventListeners.set(event, new Set());
161
+ }
162
+ this.eventListeners.get(event)!.add(listener);
163
+ return this;
164
+ }
165
+
166
+ /**
167
+ * Remove event listener
168
+ */
169
+ off(event: 'change', listener: VFSChangeListener): this;
170
+ off(event: 'delete', listener: VFSDeleteListener): this;
171
+ off(event: string, listener: VFSEventListener): this {
172
+ const listeners = this.eventListeners.get(event);
173
+ if (listeners) {
174
+ listeners.delete(listener);
175
+ }
176
+ return this;
177
+ }
178
+
179
+ /**
180
+ * Emit event to listeners
181
+ */
182
+ private emit(event: 'change', path: string, content: string): void;
183
+ private emit(event: 'delete', path: string): void;
184
+ private emit(event: string, ...args: unknown[]): void {
185
+ const listeners = this.eventListeners.get(event);
186
+ if (listeners) {
187
+ for (const listener of listeners) {
188
+ try {
189
+ (listener as (...args: unknown[]) => void)(...args);
190
+ } catch (err) {
191
+ console.error('Error in VFS event listener:', err);
192
+ }
193
+ }
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Serialize the entire file tree to a snapshot (for worker transfer)
199
+ */
200
+ toSnapshot(): VFSSnapshot {
201
+ const files: VFSFileEntry[] = [];
202
+ this.serializeNode('/', this.root, files);
203
+ return { files };
204
+ }
205
+
206
+ private serializeNode(path: string, node: FSNode, files: VFSFileEntry[]): void {
207
+ if (node.type === 'file') {
208
+ // Encode binary content as base64
209
+ let content = '';
210
+ if (node.content && node.content.length > 0) {
211
+ content = uint8ToBase64(node.content);
212
+ }
213
+ files.push({ path, type: 'file', content });
214
+ } else if (node.type === 'symlink') {
215
+ files.push({ path, type: 'symlink', target: node.target } as unknown as VFSFileEntry);
216
+ } else if (node.type === 'directory') {
217
+ files.push({ path, type: 'directory' });
218
+ if (node.children) {
219
+ for (const [name, child] of node.children) {
220
+ const childPath = path === '/' ? `/${name}` : `${path}/${name}`;
221
+ this.serializeNode(childPath, child, files);
222
+ }
223
+ }
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Create a VirtualFS from a snapshot
229
+ */
230
+ static fromSnapshot(snapshot: VFSSnapshot): VirtualFS {
231
+ const vfs = new VirtualFS();
232
+
233
+ // Sort entries to ensure directories are created before their contents
234
+ const sortedFiles = snapshot.files
235
+ .map((entry, i) => ({ entry, depth: entry.path.split('/').length, i }))
236
+ .sort((a, b) => a.depth - b.depth || a.i - b.i)
237
+ .map(x => x.entry);
238
+
239
+ for (const entry of sortedFiles) {
240
+ if (entry.path === '/') continue; // Skip root
241
+
242
+ if (entry.type === 'directory') {
243
+ vfs.mkdirSync(entry.path, { recursive: true });
244
+ } else if ((entry as { type: string }).type === 'symlink') {
245
+ const parentPath = entry.path.substring(0, entry.path.lastIndexOf('/')) || '/';
246
+ if (parentPath !== '/' && !vfs.existsSync(parentPath)) {
247
+ vfs.mkdirSync(parentPath, { recursive: true });
248
+ }
249
+ vfs.symlinkSync((entry as unknown as { target: string }).target, entry.path);
250
+ } else if (entry.type === 'file') {
251
+ // Decode base64 content
252
+ let content: Uint8Array;
253
+ if (entry.content) {
254
+ content = base64ToUint8(entry.content);
255
+ } else {
256
+ content = new Uint8Array(0);
257
+ }
258
+ // Ensure parent directory exists
259
+ const parentPath = entry.path.substring(0, entry.path.lastIndexOf('/')) || '/';
260
+ if (parentPath !== '/' && !vfs.existsSync(parentPath)) {
261
+ vfs.mkdirSync(parentPath, { recursive: true });
262
+ }
263
+ vfs.writeFileSyncInternal(entry.path, content, false); // Don't emit events during restore
264
+ }
265
+ }
266
+
267
+ return vfs;
268
+ }
269
+
270
+ /**
271
+ * Internal write that optionally emits events
272
+ */
273
+ private writeFileSyncInternal(path: string, data: string | Uint8Array, emitEvent: boolean): void {
274
+ const normalized = this.normalizePath(path);
275
+ const parentPath = this.getParentPath(normalized);
276
+ const basename = this.getBasename(normalized);
277
+
278
+ if (!basename) {
279
+ throw new Error(`EISDIR: illegal operation on a directory, '${path}'`);
280
+ }
281
+
282
+ const parent = this.ensureDirectory(parentPath);
283
+ const existing = parent.children!.get(basename);
284
+ const existed = existing !== void 0;
285
+
286
+ const content = typeof data === 'string' ? this.encoder.encode(data) : data;
287
+
288
+ // A write changes a file's bytes; it does not make a new file. Replacing
289
+ // the node on every write moved the file's identity, and an inode or an
290
+ // open descriptor that held it was left pointing at a file nobody had.
291
+ if (existed && existing!.type === 'file') {
292
+ existing!.content = content;
293
+ existing!.mtime = Date.now();
294
+ } else {
295
+ parent.children!.set(basename, {
296
+ type: 'file',
297
+ content,
298
+ mtime: Date.now(),
299
+ });
300
+ }
301
+
302
+ if (emitEvent) {
303
+ // Notify watchers
304
+ this.notifyWatchers(normalized, existed ? 'change' : 'rename');
305
+ // Emit change event for worker sync
306
+ this.emit('change', normalized, typeof data === 'string' ? data : this.decoder.decode(data));
307
+ }
308
+ }
309
+
310
+ /**
311
+ * Normalize path - resolve . and .. segments, ensure leading /
312
+ */
313
+ private normalizePath(path: string): string {
314
+ if (!path.startsWith('/')) {
315
+ path = '/' + path;
316
+ }
317
+
318
+ const parts = path.split('/').filter(Boolean);
319
+ const resolved: string[] = [];
320
+
321
+ for (const part of parts) {
322
+ if (part === '..') {
323
+ resolved.pop();
324
+ } else if (part !== '.') {
325
+ resolved.push(part);
326
+ }
327
+ }
328
+
329
+ return '/' + resolved.join('/');
330
+ }
331
+
332
+ /**
333
+ * Get path segments from normalized path
334
+ */
335
+ private getPathSegments(path: string): string[] {
336
+ return this.normalizePath(path).split('/').filter(Boolean);
337
+ }
338
+
339
+ /**
340
+ * Get parent directory path
341
+ */
342
+ private getParentPath(path: string): string {
343
+ const normalized = this.normalizePath(path);
344
+ const lastSlash = normalized.lastIndexOf('/');
345
+ return lastSlash <= 0 ? '/' : normalized.slice(0, lastSlash);
346
+ }
347
+
348
+ /**
349
+ * Get basename from path
350
+ */
351
+ private getBasename(path: string): string {
352
+ const normalized = this.normalizePath(path);
353
+ const lastSlash = normalized.lastIndexOf('/');
354
+ return normalized.slice(lastSlash + 1);
355
+ }
356
+
357
+ /**
358
+ * Get node at path, returns undefined if not found
359
+ */
360
+ getNode(path: string): FSNode | undefined {
361
+ return this.__substrateNode(path, true, 0);
362
+ }
363
+ /** The node at a path, following every link on the way and, when `follow`, the last one too. */
364
+ __substrateNode(path: string, follow: boolean, depth: number): FSNode | undefined {
365
+ if (depth > 40) throw createNodeError('ELOOP', 'stat', path);
366
+ const segments = this.getPathSegments(path);
367
+ let current = this.root;
368
+ for (let index = 0; index < segments.length; index += 1) {
369
+ if (current.type !== 'directory' || !current.children) {
370
+ return undefined;
371
+ }
372
+ const child = current.children.get(segments[index]);
373
+ if (!child) {
374
+ return undefined;
375
+ }
376
+ if (child.type === 'symlink' && (follow || index < segments.length - 1)) {
377
+ const linkPath = '/' + segments.slice(0, index + 1).join('/');
378
+ const rest = segments.slice(index + 1).join('/');
379
+ const target = this.__substrateLinkTarget(linkPath, child.target!);
380
+ return this.__substrateNode(rest ? target + '/' + rest : target, follow, depth + 1);
381
+ }
382
+ current = child;
383
+ }
384
+ return current;
385
+ }
386
+ /** A link's target as an absolute path: absolute as written, or relative to the link's directory. */
387
+ __substrateLinkTarget(linkPath: string, target: string): string {
388
+ return this.normalizePath(target.startsWith('/') ? target : this.getParentPath(linkPath) + '/' + target);
389
+ }
390
+ symlinkSync(target: string, path: string): void {
391
+ const normalized = this.normalizePath(path);
392
+ const parentPath = this.getParentPath(normalized);
393
+ const basename = this.getBasename(normalized);
394
+ const parent = this.getNode(parentPath);
395
+ if (!parent || parent.type !== 'directory') {
396
+ throw createNodeError('ENOENT', 'symlink', path);
397
+ }
398
+ if (parent.children!.has(basename)) {
399
+ throw createNodeError('EEXIST', 'symlink', path);
400
+ }
401
+ parent.children!.set(basename, { type: 'symlink', target: String(target), mtime: Date.now() });
402
+ this.notifyWatchers(normalized, 'rename');
403
+ }
404
+ readlinkSync(path: string): string {
405
+ const node = this.__substrateNode(path, false, 0);
406
+ if (!node) {
407
+ throw createNodeError('ENOENT', 'readlink', path);
408
+ }
409
+ if (node.type !== 'symlink') {
410
+ throw createNodeError('EINVAL', 'readlink', path);
411
+ }
412
+ return node.target!;
413
+ }
414
+
415
+ /**
416
+ * Get or create directory at path (for mkdir -p behavior)
417
+ */
418
+ private ensureDirectory(path: string): FSNode {
419
+ const segments = this.getPathSegments(path);
420
+ let current = this.root;
421
+
422
+ for (let index = 0; index < segments.length; index += 1) {
423
+ const segment = segments[index];
424
+ if (!current.children) {
425
+ current.children = new Map();
426
+ }
427
+
428
+ let child = current.children.get(segment);
429
+ if (!child) {
430
+ child = { type: 'directory', children: new Map(), mtime: Date.now() };
431
+ current.children.set(segment, child);
432
+ // A directory that appears is a `rename` in its parent, as Node
433
+ // reports one, and it is the only event a watcher of a tree has to
434
+ // start watching the new directory from.
435
+ this.notifyWatchers('/' + segments.slice(0, index + 1).join('/'), 'rename');
436
+ } else if (child.type === 'symlink') {
437
+ // A directory reached through a link is the link's target.
438
+ const linkPath = '/' + segments.slice(0, index + 1).join('/');
439
+ const rest = segments.slice(index + 1).join('/');
440
+ const target = this.__substrateLinkTarget(linkPath, child.target!);
441
+ return this.ensureDirectory(rest ? target + '/' + rest : target);
442
+ } else if (child.type !== 'directory') {
443
+ throw new Error(`ENOTDIR: not a directory, '${path}'`);
444
+ }
445
+
446
+ current = child;
447
+ }
448
+
449
+ return current;
450
+ }
451
+
452
+ /**
453
+ * Check if path exists
454
+ */
455
+ existsSync(path: string): boolean {
456
+ return this.getNode(path) !== undefined;
457
+ }
458
+
459
+ /**
460
+ * Get stats for path
461
+ */
462
+ statSync(path: string): Stats {
463
+ const node = this.getNode(path);
464
+ if (!node) {
465
+ throw createNodeError('ENOENT', 'stat', path);
466
+ }
467
+
468
+ const size = node.type === 'file' ? (node.content?.length || 0) : 0;
469
+ const mtime = node.mtime;
470
+ const atime = node.atime ?? mtime;
471
+
472
+ return {
473
+ isFile: () => node.type === 'file',
474
+ isDirectory: () => node.type === 'directory',
475
+ isSymbolicLink: () => false,
476
+ isBlockDevice: () => false,
477
+ isCharacterDevice: () => false,
478
+ isFIFO: () => false,
479
+ isSocket: () => false,
480
+ size,
481
+ mode: node.type === 'directory' ? 0o755 : 0o644,
482
+ mtime: new Date(mtime),
483
+ atime: new Date(atime),
484
+ ctime: new Date(mtime),
485
+ birthtime: new Date(mtime),
486
+ mtimeMs: mtime,
487
+ atimeMs: atime,
488
+ ctimeMs: mtime,
489
+ birthtimeMs: mtime,
490
+ nlink: 1,
491
+ uid: 1000,
492
+ gid: 1000,
493
+ dev: 0,
494
+ ino: 0,
495
+ rdev: 0,
496
+ blksize: 4096,
497
+ blocks: Math.ceil(size / 512),
498
+ };
499
+ }
500
+
501
+ /**
502
+ * lstatSync - same as statSync for our virtual FS (no symlinks)
503
+ */
504
+ lstatSync(path: string): Stats {
505
+ const node = this.__substrateNode(path, false, 0);
506
+ if (!node) {
507
+ throw createNodeError('ENOENT', 'lstat', path);
508
+ }
509
+ if (node.type !== 'symlink') return this.statSync(path);
510
+ const mtime = node.mtime;
511
+ const atime = node.atime ?? mtime;
512
+ return {
513
+ isFile: () => false,
514
+ isDirectory: () => false,
515
+ isSymbolicLink: () => true,
516
+ isBlockDevice: () => false,
517
+ isCharacterDevice: () => false,
518
+ isFIFO: () => false,
519
+ isSocket: () => false,
520
+ size: node.target!.length,
521
+ mode: 41471,
522
+ mtime: new Date(mtime),
523
+ atime: new Date(atime),
524
+ ctime: new Date(mtime),
525
+ birthtime: new Date(mtime),
526
+ mtimeMs: mtime,
527
+ atimeMs: atime,
528
+ ctimeMs: mtime,
529
+ birthtimeMs: mtime,
530
+ nlink: 1,
531
+ uid: 1000,
532
+ gid: 1000,
533
+ dev: 0,
534
+ ino: 0,
535
+ rdev: 0,
536
+ blksize: 4096,
537
+ blocks: 0
538
+ } as unknown as Stats;
539
+ }
540
+
541
+ /**
542
+ * Read file contents as Uint8Array
543
+ */
544
+ readFileSync(path: string): Uint8Array;
545
+ readFileSync(path: string, encoding: 'utf8' | 'utf-8'): string;
546
+ readFileSync(path: string, encoding?: 'utf8' | 'utf-8'): Uint8Array | string {
547
+ const node = this.getNode(path);
548
+
549
+ if (!node) {
550
+ throw createNodeError('ENOENT', 'open', path);
551
+ }
552
+
553
+ if (node.type !== 'file') {
554
+ throw createNodeError('EISDIR', 'read', path);
555
+ }
556
+
557
+ const content = node.content || new Uint8Array(0);
558
+
559
+ if (encoding === 'utf8' || encoding === 'utf-8') {
560
+ return this.decoder.decode(content);
561
+ }
562
+
563
+ return content;
564
+ }
565
+
566
+ /**
567
+ * Write data to file, creating parent directories as needed
568
+ */
569
+ writeFileSync(path: string, data: string | Uint8Array): void {
570
+ this.writeFileSyncInternal(path, data, true);
571
+ }
572
+
573
+ /**
574
+ * Create directory, optionally with recursive parent creation
575
+ */
576
+ mkdirSync(path: string, options?: { recursive?: boolean }): void {
577
+ const normalized = this.normalizePath(path);
578
+
579
+ if (options?.recursive) {
580
+ this.ensureDirectory(normalized);
581
+ return;
582
+ }
583
+
584
+ const parentPath = this.getParentPath(normalized);
585
+ const basename = this.getBasename(normalized);
586
+
587
+ if (!basename) {
588
+ return; // Root directory already exists
589
+ }
590
+
591
+ const parent = this.getNode(parentPath);
592
+
593
+ if (!parent) {
594
+ throw createNodeError('ENOENT', 'mkdir', parentPath);
595
+ }
596
+
597
+ if (parent.type !== 'directory') {
598
+ throw createNodeError('ENOTDIR', 'mkdir', parentPath);
599
+ }
600
+
601
+ if (parent.children!.has(basename)) {
602
+ throw createNodeError('EEXIST', 'mkdir', path);
603
+ }
604
+
605
+ parent.children!.set(basename, {
606
+ type: 'directory',
607
+ children: new Map(),
608
+ mtime: Date.now(),
609
+ });
610
+ this.notifyWatchers(normalized, 'rename');
611
+ }
612
+
613
+ /**
614
+ * Read directory contents
615
+ */
616
+ readdirSync(path: string): string[] {
617
+ const node = this.getNode(path);
618
+
619
+ if (!node) {
620
+ throw createNodeError('ENOENT', 'scandir', path);
621
+ }
622
+
623
+ if (node.type !== 'directory') {
624
+ throw createNodeError('ENOTDIR', 'scandir', path);
625
+ }
626
+
627
+ return Array.from(node.children!.keys());
628
+ }
629
+
630
+ /**
631
+ * Remove file
632
+ */
633
+ unlinkSync(path: string): void {
634
+ const normalized = this.normalizePath(path);
635
+ const parentPath = this.getParentPath(normalized);
636
+ const basename = this.getBasename(normalized);
637
+
638
+ const parent = this.getNode(parentPath);
639
+
640
+ if (!parent || parent.type !== 'directory') {
641
+ throw createNodeError('ENOENT', 'unlink', path);
642
+ }
643
+
644
+ const node = parent.children!.get(basename);
645
+
646
+ if (!node) {
647
+ throw createNodeError('ENOENT', 'unlink', path);
648
+ }
649
+
650
+ if (node.type !== 'file' && node.type !== 'symlink') {
651
+ throw createNodeError('EISDIR', 'unlink', path);
652
+ }
653
+
654
+ parent.children!.delete(basename);
655
+
656
+ // Notify watchers
657
+ this.notifyWatchers(normalized, 'rename');
658
+ // Emit delete event for worker sync
659
+ this.emit('delete', normalized);
660
+ }
661
+
662
+ /**
663
+ * Remove directory (must be empty)
664
+ */
665
+ rmdirSync(path: string): void {
666
+ const normalized = this.normalizePath(path);
667
+ const parentPath = this.getParentPath(normalized);
668
+ const basename = this.getBasename(normalized);
669
+
670
+ if (!basename) {
671
+ throw new Error(`EPERM: operation not permitted, '${path}'`);
672
+ }
673
+
674
+ const parent = this.getNode(parentPath);
675
+
676
+ if (!parent || parent.type !== 'directory') {
677
+ throw createNodeError('ENOENT', 'rmdir', path);
678
+ }
679
+
680
+ const node = parent.children!.get(basename);
681
+
682
+ if (!node) {
683
+ throw createNodeError('ENOENT', 'rmdir', path);
684
+ }
685
+
686
+ if (node.type !== 'directory') {
687
+ throw createNodeError('ENOTDIR', 'rmdir', path);
688
+ }
689
+
690
+ if (node.children!.size > 0) {
691
+ throw createNodeError('ENOTEMPTY', 'rmdir', path);
692
+ }
693
+
694
+ parent.children!.delete(basename);
695
+ // A directory that goes is a `rename` in its parent too, as its removal is.
696
+ this.notifyWatchers(normalized, 'rename');
697
+ }
698
+
699
+ /**
700
+ * Rename/move file or directory
701
+ */
702
+ renameSync(oldPath: string, newPath: string): void {
703
+ const normalizedOld = this.normalizePath(oldPath);
704
+ const normalizedNew = this.normalizePath(newPath);
705
+
706
+ const oldParentPath = this.getParentPath(normalizedOld);
707
+ const oldBasename = this.getBasename(normalizedOld);
708
+ const newParentPath = this.getParentPath(normalizedNew);
709
+ const newBasename = this.getBasename(normalizedNew);
710
+
711
+ const oldParent = this.getNode(oldParentPath);
712
+
713
+ if (!oldParent || oldParent.type !== 'directory') {
714
+ throw createNodeError('ENOENT', 'rename', oldPath);
715
+ }
716
+
717
+ const node = oldParent.children!.get(oldBasename);
718
+
719
+ if (!node) {
720
+ throw createNodeError('ENOENT', 'rename', oldPath);
721
+ }
722
+
723
+ const newParent = this.ensureDirectory(newParentPath);
724
+
725
+ oldParent.children!.delete(oldBasename);
726
+ newParent.children!.set(newBasename, node);
727
+
728
+ // Notify watchers
729
+ this.notifyWatchers(normalizedOld, 'rename');
730
+ this.notifyWatchers(normalizedNew, 'rename');
731
+ }
732
+
733
+ /**
734
+ * Read file with optional options parameter
735
+ */
736
+ readFile(
737
+ path: string,
738
+ optionsOrCallback?: string | { encoding?: string } | ((err: Error | null, data?: Uint8Array | string) => void),
739
+ callback?: (err: Error | null, data?: Uint8Array | string) => void
740
+ ): void | Promise<Uint8Array | string> {
741
+ const actualCallback = typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
742
+ const encoding = typeof optionsOrCallback === 'string' ? optionsOrCallback
743
+ : optionsOrCallback && typeof optionsOrCallback === 'object' ? optionsOrCallback.encoding : void 0;
744
+ const read = () => encoding ? this.readFileSync(path, encoding as 'utf8') : this.readFileSync(path);
745
+ if (!actualCallback) {
746
+ return new Promise((resolve, reject) => {
747
+ try { resolve(read()); } catch (err) { reject(err); }
748
+ });
749
+ }
750
+ try {
751
+ const data = read();
752
+ queueMicrotask(() => actualCallback(null, data));
753
+ } catch (err) {
754
+ queueMicrotask(() => actualCallback(err as Error));
755
+ }
756
+ }
757
+
758
+ /**
759
+ * Async stat
760
+ */
761
+ stat(path: string, callback: (err: Error | null, stats?: Stats) => void): void {
762
+ try {
763
+ const stats = this.statSync(path);
764
+ queueMicrotask(() => callback(null, stats));
765
+ } catch (err) {
766
+ queueMicrotask(() => callback(err as Error));
767
+ }
768
+ }
769
+
770
+ /**
771
+ * Async lstat
772
+ */
773
+ lstat(path: string, callback: (err: Error | null, stats?: Stats) => void): void {
774
+ try {
775
+ const stats = this.lstatSync(path);
776
+ queueMicrotask(() => callback(null, stats));
777
+ } catch (err) {
778
+ queueMicrotask(() => callback(err as Error));
779
+ }
780
+ }
781
+
782
+ /**
783
+ * Async readdir
784
+ */
785
+ readdir(
786
+ path: string,
787
+ optionsOrCallback?: { withFileTypes?: boolean } | ((err: Error | null, files?: string[]) => void),
788
+ callback?: (err: Error | null, files?: string[]) => void
789
+ ): void {
790
+ const actualCallback = typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
791
+
792
+ try {
793
+ const files = this.readdirSync(path);
794
+ if (actualCallback) {
795
+ queueMicrotask(() => actualCallback(null, files));
796
+ }
797
+ } catch (err) {
798
+ if (actualCallback) {
799
+ queueMicrotask(() => actualCallback(err as Error));
800
+ }
801
+ }
802
+ }
803
+
804
+ /**
805
+ * Async realpath
806
+ */
807
+ realpath(path: string, callback: (err: Error | null, resolvedPath?: string) => void): void {
808
+ try {
809
+ const resolved = this.realpathSync(path);
810
+ queueMicrotask(() => callback(null, resolved));
811
+ } catch (err) {
812
+ queueMicrotask(() => callback(err as Error));
813
+ }
814
+ }
815
+
816
+ /**
817
+ * Sync realpath - in our VFS, just normalize the path
818
+ */
819
+ realpathSync(path: string): string {
820
+ let resolved = this.normalizePath(path);
821
+ for (let hops = 0; hops <= 40; hops += 1) {
822
+ const segments = resolved.split('/').filter(Boolean);
823
+ let current: FSNode | undefined = this.root;
824
+ let linked = false;
825
+ for (let index = 0; index < segments.length; index += 1) {
826
+ const child: FSNode | undefined = current && current.children ? current.children.get(segments[index]) : void 0;
827
+ if (!child) throw createNodeError('ENOENT', 'realpath', path);
828
+ if (child.type === 'symlink') {
829
+ const linkPath = '/' + segments.slice(0, index + 1).join('/');
830
+ const rest = segments.slice(index + 1).join('/');
831
+ const target = this.__substrateLinkTarget(linkPath, child.target!);
832
+ resolved = this.normalizePath(rest ? target + '/' + rest : target);
833
+ linked = true;
834
+ break;
835
+ }
836
+ current = child;
837
+ }
838
+ if (!linked) return resolved;
839
+ }
840
+ throw createNodeError('ELOOP', 'realpath', path);
841
+ }
842
+
843
+ /**
844
+ * Watch for file changes
845
+ */
846
+ watch(
847
+ filename: string,
848
+ optionsOrListener?: { persistent?: boolean; recursive?: boolean; encoding?: string } | WatchListener,
849
+ listener?: WatchListener
850
+ ): FSWatcher {
851
+ const normalized = this.normalizePath(filename);
852
+
853
+ // Parse arguments
854
+ let options: { persistent?: boolean; recursive?: boolean } = {};
855
+ let actualListener: WatchListener | undefined;
856
+
857
+ if (typeof optionsOrListener === 'function') {
858
+ actualListener = optionsOrListener;
859
+ } else if (optionsOrListener) {
860
+ options = optionsOrListener;
861
+ actualListener = listener;
862
+ } else {
863
+ actualListener = listener;
864
+ }
865
+
866
+ // Create watcher entry
867
+ const entry: WatcherEntry = {
868
+ listener: actualListener || (() => {}),
869
+ recursive: options.recursive || false,
870
+ closed: false,
871
+ };
872
+
873
+ // Add to watchers map
874
+ if (!this.watchers.has(normalized)) {
875
+ this.watchers.set(normalized, new Set());
876
+ }
877
+ this.watchers.get(normalized)!.add(entry);
878
+
879
+ // Return FSWatcher interface
880
+ const watcher: FSWatcher = {
881
+ close: () => {
882
+ entry.closed = true;
883
+ const watcherSet = this.watchers.get(normalized);
884
+ if (watcherSet) {
885
+ watcherSet.delete(entry);
886
+ if (watcherSet.size === 0) {
887
+ this.watchers.delete(normalized);
888
+ }
889
+ }
890
+ },
891
+ ref: () => watcher,
892
+ unref: () => watcher,
893
+ };
894
+
895
+ return watcher;
896
+ }
897
+
898
+ /**
899
+ * Notify watchers of file changes
900
+ */
901
+ private notifyWatchers(path: string, eventType: WatchEventType): void {
902
+ const normalized = this.normalizePath(path);
903
+ const basename = this.getBasename(normalized);
904
+
905
+ // Check direct watchers on this file
906
+ const directWatchers = this.watchers.get(normalized);
907
+ if (directWatchers) {
908
+ for (const entry of directWatchers) {
909
+ if (!entry.closed) {
910
+ try {
911
+ entry.listener(eventType, basename);
912
+ } catch (err) {
913
+ console.error('Error in file watcher:', err);
914
+ }
915
+ }
916
+ }
917
+ }
918
+
919
+ // Check parent directory watchers (recursive and non-recursive)
920
+ let currentPath = this.getParentPath(normalized);
921
+ let relativePath = basename;
922
+
923
+ while (currentPath) {
924
+ const parentWatchers = this.watchers.get(currentPath);
925
+ if (parentWatchers) {
926
+ for (const entry of parentWatchers) {
927
+ if (!entry.closed) {
928
+ // Non-recursive watchers only get notified for direct children
929
+ const isDirectChild = this.getParentPath(normalized) === currentPath;
930
+ if (entry.recursive || isDirectChild) {
931
+ try {
932
+ entry.listener(eventType, relativePath);
933
+ } catch (err) {
934
+ console.error('Error in file watcher:', err);
935
+ }
936
+ }
937
+ }
938
+ }
939
+ }
940
+
941
+ if (currentPath === '/') break;
942
+ relativePath = this.getBasename(currentPath) + '/' + relativePath;
943
+ currentPath = this.getParentPath(currentPath);
944
+ }
945
+ }
946
+
947
+ /**
948
+ * Access check - in our VFS, always succeeds if file exists
949
+ */
950
+ accessSync(path: string, mode?: number): void {
951
+ if (!this.existsSync(path)) {
952
+ throw createNodeError('ENOENT', 'access', path);
953
+ }
954
+ }
955
+
956
+ /**
957
+ * Async access
958
+ */
959
+ access(path: string, modeOrCallback?: number | ((err: Error | null) => void), callback?: (err: Error | null) => void): void {
960
+ const actualCallback = typeof modeOrCallback === 'function' ? modeOrCallback : callback;
961
+ try {
962
+ this.accessSync(path);
963
+ if (actualCallback) queueMicrotask(() => actualCallback(null));
964
+ } catch (err) {
965
+ if (actualCallback) queueMicrotask(() => actualCallback(err as Error));
966
+ }
967
+ }
968
+
969
+ /**
970
+ * Copy file
971
+ */
972
+ copyFileSync(src: string, dest: string): void {
973
+ const content = this.readFileSync(src);
974
+ this.writeFileSync(dest, content);
975
+ }
976
+
977
+ /**
978
+ * Create read stream - simplified implementation
979
+ */
980
+ createReadStream(path: string, options?: ReadStreamOptions | string): FsReadStream {
981
+ const self = this;
982
+ const opts = typeof options === 'string' ? { encoding: options } : options || {};
983
+ const stream = new Readable() as FsReadStream;
984
+ stream.path = path;
985
+ stream.bytesRead = 0;
986
+ if (opts.encoding) stream.setEncoding(opts.encoding);
987
+ setTimeout(() => {
988
+ try {
989
+ let data = self.readFileSync(path);
990
+ const start = typeof opts.start === 'number' ? opts.start : 0;
991
+ const end = typeof opts.end === 'number' ? opts.end + 1 : data.length;
992
+ if (start > 0 || end < data.length) data = data.subarray(start, Math.max(start, end));
993
+ stream.bytesRead = data.length;
994
+ stream.emit('open');
995
+ stream.emit('ready');
996
+ if (data.length > 0) stream.push(Buffer.from(data.buffer, data.byteOffset, data.byteLength));
997
+ stream.push(null);
998
+ } catch (err) {
999
+ stream.emit('error', err);
1000
+ }
1001
+ }, 0);
1002
+ return stream;
1003
+ }
1004
+
1005
+ /**
1006
+ * Create write stream - simplified implementation
1007
+ */
1008
+ createWriteStream(path: string): {
1009
+ write: (data: string | Uint8Array) => boolean;
1010
+ end: (data?: string | Uint8Array) => void;
1011
+ on: (event: string, cb: (...args: unknown[]) => void) => void;
1012
+ } {
1013
+ const self = this;
1014
+ const chunks: Uint8Array[] = [];
1015
+ const listeners: Record<string, ((...args: unknown[]) => void)[]> = {};
1016
+ const encoder = new TextEncoder();
1017
+
1018
+ return {
1019
+ write(data: string | Uint8Array): boolean {
1020
+ const chunk = typeof data === 'string' ? encoder.encode(data) : data;
1021
+ chunks.push(chunk);
1022
+ return true;
1023
+ },
1024
+ end(data?: string | Uint8Array): void {
1025
+ if (data) {
1026
+ const chunk = typeof data === 'string' ? encoder.encode(data) : data;
1027
+ chunks.push(chunk);
1028
+ }
1029
+ // Combine chunks
1030
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
1031
+ const combined = new Uint8Array(totalLength);
1032
+ let offset = 0;
1033
+ for (const chunk of chunks) {
1034
+ combined.set(chunk, offset);
1035
+ offset += chunk.length;
1036
+ }
1037
+ self.writeFileSync(path, combined);
1038
+ listeners['finish']?.forEach((cb) => cb());
1039
+ listeners['close']?.forEach((cb) => cb());
1040
+ },
1041
+ on(event: string, cb: (...args: unknown[]) => void) {
1042
+ if (!listeners[event]) listeners[event] = [];
1043
+ listeners[event].push(cb);
1044
+ return this;
1045
+ },
1046
+ };
1047
+ }
1048
+ }