@smthrs/platform-node 0.0.0-stage → 1.0.0-rc.4

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 (442) hide show
  1. package/CHANGELOG.md +211 -0
  2. package/LICENSE +21 -0
  3. package/README.md +165 -2
  4. package/bin/darwin-arm64/smithers-jj-export +0 -0
  5. package/bin/darwin-x64/smithers-jj-export +0 -0
  6. package/bin/linux-arm64/smithers-jj-export +0 -0
  7. package/bin/linux-x64/smithers-jj-export +4 -0
  8. package/bin/win32-x64/smithers-jj-export.exe +0 -0
  9. package/dist/cjs/AtomicFileSystem.d.ts +147 -0
  10. package/dist/cjs/AtomicFileSystem.d.ts.map +1 -0
  11. package/dist/cjs/AtomicFileSystem.js +234 -0
  12. package/dist/cjs/AtomicFileSystem.js.map +7 -0
  13. package/dist/cjs/EgressHttpClient.d.ts +106 -0
  14. package/dist/cjs/EgressHttpClient.d.ts.map +1 -0
  15. package/dist/cjs/EgressHttpClient.js +202 -0
  16. package/dist/cjs/EgressHttpClient.js.map +7 -0
  17. package/dist/cjs/HostLiveness.d.ts +81 -0
  18. package/dist/cjs/HostLiveness.d.ts.map +1 -0
  19. package/dist/cjs/HostLiveness.js +49 -0
  20. package/dist/cjs/HostLiveness.js.map +7 -0
  21. package/dist/cjs/NodeHost.d.ts +145 -0
  22. package/dist/cjs/NodeHost.d.ts.map +1 -0
  23. package/dist/cjs/NodeHost.js +128 -0
  24. package/dist/cjs/NodeHost.js.map +7 -0
  25. package/dist/cjs/ProcessConfinement.d.ts +61 -0
  26. package/dist/cjs/ProcessConfinement.d.ts.map +1 -0
  27. package/dist/cjs/ProcessConfinement.js +292 -0
  28. package/dist/cjs/ProcessConfinement.js.map +7 -0
  29. package/dist/cjs/ProcessReaper.d.ts +457 -0
  30. package/dist/cjs/ProcessReaper.d.ts.map +1 -0
  31. package/dist/cjs/ProcessReaper.js +349 -0
  32. package/dist/cjs/ProcessReaper.js.map +7 -0
  33. package/dist/cjs/ProcessSandbox.d.ts +391 -0
  34. package/dist/cjs/ProcessSandbox.d.ts.map +1 -0
  35. package/dist/cjs/ProcessSandbox.js +774 -0
  36. package/dist/cjs/ProcessSandbox.js.map +7 -0
  37. package/dist/cjs/ScopedProcess.d.ts +66 -0
  38. package/dist/cjs/ScopedProcess.d.ts.map +1 -0
  39. package/dist/cjs/ScopedProcess.js +87 -0
  40. package/dist/cjs/ScopedProcess.js.map +7 -0
  41. package/dist/cjs/index.d.ts +38 -0
  42. package/dist/cjs/index.d.ts.map +1 -0
  43. package/dist/cjs/index.js +47 -0
  44. package/dist/cjs/index.js.map +7 -0
  45. package/dist/cjs/internal/AtomicFileSystemExecutable.d.ts +61 -0
  46. package/dist/cjs/internal/AtomicFileSystemExecutable.d.ts.map +1 -0
  47. package/dist/cjs/internal/AtomicFileSystemExecutable.js +250 -0
  48. package/dist/cjs/internal/AtomicFileSystemExecutable.js.map +7 -0
  49. package/dist/cjs/internal/AtomicFileSystemProtocol.d.ts +78 -0
  50. package/dist/cjs/internal/AtomicFileSystemProtocol.d.ts.map +1 -0
  51. package/dist/cjs/internal/AtomicFileSystemProtocol.js +382 -0
  52. package/dist/cjs/internal/AtomicFileSystemProtocol.js.map +7 -0
  53. package/dist/cjs/internal/AtomicFileSystemTransport.d.ts +44 -0
  54. package/dist/cjs/internal/AtomicFileSystemTransport.d.ts.map +1 -0
  55. package/dist/cjs/internal/AtomicFileSystemTransport.js +197 -0
  56. package/dist/cjs/internal/AtomicFileSystemTransport.js.map +7 -0
  57. package/dist/cjs/internal/AtomicHelperError.d.ts +35 -0
  58. package/dist/cjs/internal/AtomicHelperError.d.ts.map +1 -0
  59. package/dist/cjs/internal/AtomicHelperError.js +45 -0
  60. package/dist/cjs/internal/AtomicHelperError.js.map +7 -0
  61. package/dist/cjs/internal/AtomicHelperFault.d.ts +59 -0
  62. package/dist/cjs/internal/AtomicHelperFault.d.ts.map +1 -0
  63. package/dist/cjs/internal/AtomicHelperFault.js +66 -0
  64. package/dist/cjs/internal/AtomicHelperFault.js.map +7 -0
  65. package/dist/cjs/internal/PipedProcess.d.ts +35 -0
  66. package/dist/cjs/internal/PipedProcess.d.ts.map +1 -0
  67. package/dist/cjs/internal/PipedProcess.js +309 -0
  68. package/dist/cjs/internal/PipedProcess.js.map +7 -0
  69. package/dist/cjs/internal/ProcSnapshot.d.ts +85 -0
  70. package/dist/cjs/internal/ProcSnapshot.d.ts.map +1 -0
  71. package/dist/cjs/internal/ProcSnapshot.js +123 -0
  72. package/dist/cjs/internal/ProcSnapshot.js.map +7 -0
  73. package/dist/cjs/internal/ProcessCleanup.d.ts +64 -0
  74. package/dist/cjs/internal/ProcessCleanup.d.ts.map +1 -0
  75. package/dist/cjs/internal/ProcessCleanup.js +62 -0
  76. package/dist/cjs/internal/ProcessCleanup.js.map +7 -0
  77. package/dist/cjs/internal/ProcessCleanupPolicyError.d.ts +30 -0
  78. package/dist/cjs/internal/ProcessCleanupPolicyError.d.ts.map +1 -0
  79. package/dist/cjs/internal/ProcessCleanupPolicyError.js +33 -0
  80. package/dist/cjs/internal/ProcessCleanupPolicyError.js.map +7 -0
  81. package/dist/cjs/internal/ProcessFault.d.ts +63 -0
  82. package/dist/cjs/internal/ProcessFault.d.ts.map +1 -0
  83. package/dist/cjs/internal/ProcessFault.js +63 -0
  84. package/dist/cjs/internal/ProcessFault.js.map +7 -0
  85. package/dist/cjs/internal/ProcessSupervisor.d.ts +143 -0
  86. package/dist/cjs/internal/ProcessSupervisor.d.ts.map +1 -0
  87. package/dist/cjs/internal/ProcessSupervisor.js +685 -0
  88. package/dist/cjs/internal/ProcessSupervisor.js.map +7 -0
  89. package/dist/cjs/internal/SupervisorProgram.d.ts +9 -0
  90. package/dist/cjs/internal/SupervisorProgram.d.ts.map +1 -0
  91. package/dist/cjs/internal/SupervisorProgram.js +326 -0
  92. package/dist/cjs/internal/SupervisorProgram.js.map +7 -0
  93. package/dist/cjs/internal/WindowsProcessJob.d.ts +39 -0
  94. package/dist/cjs/internal/WindowsProcessJob.d.ts.map +1 -0
  95. package/dist/cjs/internal/WindowsProcessJob.js +113 -0
  96. package/dist/cjs/internal/WindowsProcessJob.js.map +7 -0
  97. package/dist/cjs/package.json +1 -0
  98. package/dist/esm/AtomicFileSystem.d.ts +147 -0
  99. package/dist/esm/AtomicFileSystem.d.ts.map +1 -0
  100. package/dist/esm/AtomicFileSystem.js +290 -0
  101. package/dist/esm/AtomicFileSystem.js.map +1 -0
  102. package/dist/esm/EgressHttpClient.d.ts +106 -0
  103. package/dist/esm/EgressHttpClient.d.ts.map +1 -0
  104. package/dist/esm/EgressHttpClient.js +259 -0
  105. package/dist/esm/EgressHttpClient.js.map +1 -0
  106. package/dist/esm/HostLiveness.d.ts +81 -0
  107. package/dist/esm/HostLiveness.d.ts.map +1 -0
  108. package/dist/esm/HostLiveness.js +68 -0
  109. package/dist/esm/HostLiveness.js.map +1 -0
  110. package/dist/esm/NodeHost.d.ts +145 -0
  111. package/dist/esm/NodeHost.d.ts.map +1 -0
  112. package/dist/esm/NodeHost.js +162 -0
  113. package/dist/esm/NodeHost.js.map +1 -0
  114. package/dist/esm/ProcessConfinement.d.ts +61 -0
  115. package/dist/esm/ProcessConfinement.d.ts.map +1 -0
  116. package/dist/esm/ProcessConfinement.js +311 -0
  117. package/dist/esm/ProcessConfinement.js.map +1 -0
  118. package/dist/esm/ProcessReaper.d.ts +457 -0
  119. package/dist/esm/ProcessReaper.d.ts.map +1 -0
  120. package/dist/esm/ProcessReaper.js +711 -0
  121. package/dist/esm/ProcessReaper.js.map +1 -0
  122. package/dist/esm/ProcessSandbox.d.ts +391 -0
  123. package/dist/esm/ProcessSandbox.d.ts.map +1 -0
  124. package/dist/esm/ProcessSandbox.js +1043 -0
  125. package/dist/esm/ProcessSandbox.js.map +1 -0
  126. package/dist/esm/ScopedProcess.d.ts +66 -0
  127. package/dist/esm/ScopedProcess.d.ts.map +1 -0
  128. package/dist/esm/ScopedProcess.js +67 -0
  129. package/dist/esm/ScopedProcess.js.map +1 -0
  130. package/dist/esm/index.d.ts +38 -0
  131. package/dist/esm/index.d.ts.map +1 -0
  132. package/dist/esm/index.js +38 -0
  133. package/dist/esm/index.js.map +1 -0
  134. package/dist/esm/internal/AtomicFileSystemExecutable.d.ts +61 -0
  135. package/dist/esm/internal/AtomicFileSystemExecutable.d.ts.map +1 -0
  136. package/dist/esm/internal/AtomicFileSystemExecutable.js +350 -0
  137. package/dist/esm/internal/AtomicFileSystemExecutable.js.map +1 -0
  138. package/dist/esm/internal/AtomicFileSystemProtocol.d.ts +78 -0
  139. package/dist/esm/internal/AtomicFileSystemProtocol.d.ts.map +1 -0
  140. package/dist/esm/internal/AtomicFileSystemProtocol.js +412 -0
  141. package/dist/esm/internal/AtomicFileSystemProtocol.js.map +1 -0
  142. package/dist/esm/internal/AtomicFileSystemTransport.d.ts +44 -0
  143. package/dist/esm/internal/AtomicFileSystemTransport.d.ts.map +1 -0
  144. package/dist/esm/internal/AtomicFileSystemTransport.js +242 -0
  145. package/dist/esm/internal/AtomicFileSystemTransport.js.map +1 -0
  146. package/dist/esm/internal/AtomicHelperError.d.ts +35 -0
  147. package/dist/esm/internal/AtomicHelperError.d.ts.map +1 -0
  148. package/dist/esm/internal/AtomicHelperError.js +39 -0
  149. package/dist/esm/internal/AtomicHelperError.js.map +1 -0
  150. package/dist/esm/internal/AtomicHelperFault.d.ts +59 -0
  151. package/dist/esm/internal/AtomicHelperFault.d.ts.map +1 -0
  152. package/dist/esm/internal/AtomicHelperFault.js +66 -0
  153. package/dist/esm/internal/AtomicHelperFault.js.map +1 -0
  154. package/dist/esm/internal/PipedProcess.d.ts +35 -0
  155. package/dist/esm/internal/PipedProcess.d.ts.map +1 -0
  156. package/dist/esm/internal/PipedProcess.js +321 -0
  157. package/dist/esm/internal/PipedProcess.js.map +1 -0
  158. package/dist/esm/internal/ProcSnapshot.d.ts +85 -0
  159. package/dist/esm/internal/ProcSnapshot.d.ts.map +1 -0
  160. package/dist/esm/internal/ProcSnapshot.js +188 -0
  161. package/dist/esm/internal/ProcSnapshot.js.map +1 -0
  162. package/dist/esm/internal/ProcessCleanup.d.ts +64 -0
  163. package/dist/esm/internal/ProcessCleanup.d.ts.map +1 -0
  164. package/dist/esm/internal/ProcessCleanup.js +45 -0
  165. package/dist/esm/internal/ProcessCleanup.js.map +1 -0
  166. package/dist/esm/internal/ProcessCleanupPolicyError.d.ts +30 -0
  167. package/dist/esm/internal/ProcessCleanupPolicyError.d.ts.map +1 -0
  168. package/dist/esm/internal/ProcessCleanupPolicyError.js +25 -0
  169. package/dist/esm/internal/ProcessCleanupPolicyError.js.map +1 -0
  170. package/dist/esm/internal/ProcessFault.d.ts +63 -0
  171. package/dist/esm/internal/ProcessFault.d.ts.map +1 -0
  172. package/dist/esm/internal/ProcessFault.js +64 -0
  173. package/dist/esm/internal/ProcessFault.js.map +1 -0
  174. package/dist/esm/internal/ProcessSupervisor.d.ts +143 -0
  175. package/dist/esm/internal/ProcessSupervisor.d.ts.map +1 -0
  176. package/dist/esm/internal/ProcessSupervisor.js +689 -0
  177. package/dist/esm/internal/ProcessSupervisor.js.map +1 -0
  178. package/dist/esm/internal/SupervisorProgram.d.ts +9 -0
  179. package/dist/esm/internal/SupervisorProgram.d.ts.map +1 -0
  180. package/dist/esm/internal/SupervisorProgram.js +310 -0
  181. package/dist/esm/internal/SupervisorProgram.js.map +1 -0
  182. package/dist/esm/internal/WindowsProcessJob.d.ts +39 -0
  183. package/dist/esm/internal/WindowsProcessJob.d.ts.map +1 -0
  184. package/dist/esm/internal/WindowsProcessJob.js +115 -0
  185. package/dist/esm/internal/WindowsProcessJob.js.map +1 -0
  186. package/dist/vendor/adapters.json +1757 -0
  187. package/dist/vendor/chunk-2Y7WC4KU.js +109 -0
  188. package/dist/vendor/chunk-3GR5VZ2M.js +118 -0
  189. package/dist/vendor/chunk-42QKY6T6.js +40 -0
  190. package/dist/vendor/chunk-54RLBMTZ.js +61 -0
  191. package/dist/vendor/chunk-5ZMHBXIK.js +55 -0
  192. package/dist/vendor/chunk-6ME2W7TF.js +28 -0
  193. package/dist/vendor/chunk-AMQKOQNT.js +34 -0
  194. package/dist/vendor/chunk-B3FZ67QU.js +59 -0
  195. package/dist/vendor/chunk-BKTBUBQY.js +437 -0
  196. package/dist/vendor/chunk-DS7GF46S.js +34 -0
  197. package/dist/vendor/chunk-DVOAHXPG.js +104 -0
  198. package/dist/vendor/chunk-DWSHTSVX.js +229 -0
  199. package/dist/vendor/chunk-EGBNVEEW.js +14 -0
  200. package/dist/vendor/chunk-EZWY45HP.js +18 -0
  201. package/dist/vendor/chunk-FNZOJHSV.js +71 -0
  202. package/dist/vendor/chunk-GXCHI7BM.js +131 -0
  203. package/dist/vendor/chunk-IIJ52ZU6.js +20 -0
  204. package/dist/vendor/chunk-J7A4CZDO.js +92 -0
  205. package/dist/vendor/chunk-JG5TTWPT.js +85 -0
  206. package/dist/vendor/chunk-JJ24ARBQ.js +394 -0
  207. package/dist/vendor/chunk-KOZMM5PZ.js +426 -0
  208. package/dist/vendor/chunk-KUUXSID7.js +18 -0
  209. package/dist/vendor/chunk-LEUPYT3Q.js +36 -0
  210. package/dist/vendor/chunk-M32LDTW7.js +18 -0
  211. package/dist/vendor/chunk-M7CLUILA.js +0 -0
  212. package/dist/vendor/chunk-MBSKBQ5D.js +21 -0
  213. package/dist/vendor/chunk-MLKGABMK.js +9 -0
  214. package/dist/vendor/chunk-NBVRTDTV.js +129 -0
  215. package/dist/vendor/chunk-OXNGN5H7.js +81 -0
  216. package/dist/vendor/chunk-QPLDT6A6.js +564 -0
  217. package/dist/vendor/chunk-QYBKAIA6.js +18 -0
  218. package/dist/vendor/chunk-RO2R4MJH.js +62 -0
  219. package/dist/vendor/chunk-SIR62W3Y.js +398 -0
  220. package/dist/vendor/chunk-TFIKFFSC.js +26 -0
  221. package/dist/vendor/chunk-TXKLEBBL.js +143 -0
  222. package/dist/vendor/chunk-UFH5UUZK.js +48 -0
  223. package/dist/vendor/chunk-VANKHF46.js +96 -0
  224. package/dist/vendor/chunk-VZBDV3TV.js +18 -0
  225. package/dist/vendor/chunk-XDKNKFBW.js +22 -0
  226. package/dist/vendor/chunk-XH4U3JSV.js +249 -0
  227. package/dist/vendor/chunk-Y35ZAO5U.js +53 -0
  228. package/dist/vendor/chunk-ZJMRMY57.js +0 -0
  229. package/dist/vendor/cjs/node/NodeChildProcessSpawner.d.ts +7 -0
  230. package/dist/vendor/cjs/node/NodeChildProcessSpawner.js +1 -0
  231. package/dist/vendor/cjs/node/NodeClusterHttp.d.ts +63 -0
  232. package/dist/vendor/cjs/node/NodeClusterHttp.js +1 -0
  233. package/dist/vendor/cjs/node/NodeClusterSocket.d.ts +79 -0
  234. package/dist/vendor/cjs/node/NodeClusterSocket.js +1 -0
  235. package/dist/vendor/cjs/node/NodeCrypto.d.ts +10 -0
  236. package/dist/vendor/cjs/node/NodeCrypto.js +1 -0
  237. package/dist/vendor/cjs/node/NodeFileSystem.d.ts +10 -0
  238. package/dist/vendor/cjs/node/NodeFileSystem.js +1 -0
  239. package/dist/vendor/cjs/node/NodeHttpClient.d.ts +179 -0
  240. package/dist/vendor/cjs/node/NodeHttpClient.js +1 -0
  241. package/dist/vendor/cjs/node/NodeHttpIncomingMessage.d.ts +62 -0
  242. package/dist/vendor/cjs/node/NodeHttpIncomingMessage.js +1 -0
  243. package/dist/vendor/cjs/node/NodeHttpPlatform.d.ts +36 -0
  244. package/dist/vendor/cjs/node/NodeHttpPlatform.js +1 -0
  245. package/dist/vendor/cjs/node/NodeHttpServer.d.ts +120 -0
  246. package/dist/vendor/cjs/node/NodeHttpServer.js +1 -0
  247. package/dist/vendor/cjs/node/NodeHttpServerRequest.d.ts +29 -0
  248. package/dist/vendor/cjs/node/NodeHttpServerRequest.js +1 -0
  249. package/dist/vendor/cjs/node/NodeMultipart.d.ts +46 -0
  250. package/dist/vendor/cjs/node/NodeMultipart.js +1 -0
  251. package/dist/vendor/cjs/node/NodeMultipartParser.d.ts +97 -0
  252. package/dist/vendor/cjs/node/NodeMultipartParser.js +1 -0
  253. package/dist/vendor/cjs/node/NodePath.d.ts +27 -0
  254. package/dist/vendor/cjs/node/NodePath.js +1 -0
  255. package/dist/vendor/cjs/node/NodeRedis.d.ts +74 -0
  256. package/dist/vendor/cjs/node/NodeRedis.js +1 -0
  257. package/dist/vendor/cjs/node/NodeRuntime.d.ts +85 -0
  258. package/dist/vendor/cjs/node/NodeRuntime.js +1 -0
  259. package/dist/vendor/cjs/node/NodeServices.d.ts +34 -0
  260. package/dist/vendor/cjs/node/NodeServices.js +1 -0
  261. package/dist/vendor/cjs/node/NodeSink.d.ts +8 -0
  262. package/dist/vendor/cjs/node/NodeSink.js +1 -0
  263. package/dist/vendor/cjs/node/NodeSocket.d.ts +38 -0
  264. package/dist/vendor/cjs/node/NodeSocket.js +1 -0
  265. package/dist/vendor/cjs/node/NodeSocketServer.d.ts +8 -0
  266. package/dist/vendor/cjs/node/NodeSocketServer.js +1 -0
  267. package/dist/vendor/cjs/node/NodeStdio.d.ts +11 -0
  268. package/dist/vendor/cjs/node/NodeStdio.js +1 -0
  269. package/dist/vendor/cjs/node/NodeStream.d.ts +8 -0
  270. package/dist/vendor/cjs/node/NodeStream.js +1 -0
  271. package/dist/vendor/cjs/node/NodeTerminal.d.ts +21 -0
  272. package/dist/vendor/cjs/node/NodeTerminal.js +1 -0
  273. package/dist/vendor/cjs/node/NodeWorker.d.ts +22 -0
  274. package/dist/vendor/cjs/node/NodeWorker.js +1 -0
  275. package/dist/vendor/cjs/node/NodeWorkerRunner.d.ts +12 -0
  276. package/dist/vendor/cjs/node/NodeWorkerRunner.js +1 -0
  277. package/dist/vendor/cjs/node/Undici.d.ts +28 -0
  278. package/dist/vendor/cjs/node/Undici.js +1 -0
  279. package/dist/vendor/cjs/node/index.d.ts +100 -0
  280. package/dist/vendor/cjs/node/index.js +1 -0
  281. package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.d.ts +57 -0
  282. package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.js +1 -0
  283. package/dist/vendor/cjs/node-shared/NodeClusterSocket.d.ts +22 -0
  284. package/dist/vendor/cjs/node-shared/NodeClusterSocket.js +1 -0
  285. package/dist/vendor/cjs/node-shared/NodeCrypto.d.ts +27 -0
  286. package/dist/vendor/cjs/node-shared/NodeCrypto.js +1 -0
  287. package/dist/vendor/cjs/node-shared/NodeFileSystem.d.ts +11 -0
  288. package/dist/vendor/cjs/node-shared/NodeFileSystem.js +1 -0
  289. package/dist/vendor/cjs/node-shared/NodeHttpCompression.d.ts +36 -0
  290. package/dist/vendor/cjs/node-shared/NodeHttpCompression.js +1 -0
  291. package/dist/vendor/cjs/node-shared/NodePath.d.ts +27 -0
  292. package/dist/vendor/cjs/node-shared/NodePath.js +1 -0
  293. package/dist/vendor/cjs/node-shared/NodeRuntime.d.ts +47 -0
  294. package/dist/vendor/cjs/node-shared/NodeRuntime.js +1 -0
  295. package/dist/vendor/cjs/node-shared/NodeSink.d.ts +69 -0
  296. package/dist/vendor/cjs/node-shared/NodeSink.js +1 -0
  297. package/dist/vendor/cjs/node-shared/NodeSocket.d.ts +134 -0
  298. package/dist/vendor/cjs/node-shared/NodeSocket.js +1 -0
  299. package/dist/vendor/cjs/node-shared/NodeSocketServer.d.ts +80 -0
  300. package/dist/vendor/cjs/node-shared/NodeSocketServer.js +1 -0
  301. package/dist/vendor/cjs/node-shared/NodeStdio.d.ts +12 -0
  302. package/dist/vendor/cjs/node-shared/NodeStdio.js +1 -0
  303. package/dist/vendor/cjs/node-shared/NodeStream.d.ts +179 -0
  304. package/dist/vendor/cjs/node-shared/NodeStream.js +1 -0
  305. package/dist/vendor/cjs/node-shared/NodeTerminal.d.ts +22 -0
  306. package/dist/vendor/cjs/node-shared/NodeTerminal.js +1 -0
  307. package/dist/vendor/cjs/node-shared/index.d.ts +56 -0
  308. package/dist/vendor/cjs/node-shared/index.js +1 -0
  309. package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
  310. package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.js +1 -0
  311. package/dist/vendor/cjs/node-shared/internal/utils.d.ts +2 -0
  312. package/dist/vendor/cjs/node-shared/internal/utils.js +1 -0
  313. package/dist/vendor/cjs/package.json +1 -0
  314. package/dist/vendor/cjs/platform-node-shared.d.ts +56 -0
  315. package/dist/vendor/cjs/platform-node-shared.js +1 -0
  316. package/dist/vendor/cjs/platform-node.d.ts +100 -0
  317. package/dist/vendor/cjs/platform-node.js +1 -0
  318. package/dist/vendor/node/LICENSE +21 -0
  319. package/dist/vendor/node/NodeChildProcessSpawner.d.ts +7 -0
  320. package/dist/vendor/node/NodeChildProcessSpawner.js +14 -0
  321. package/dist/vendor/node/NodeClusterHttp.d.ts +63 -0
  322. package/dist/vendor/node/NodeClusterHttp.js +43 -0
  323. package/dist/vendor/node/NodeClusterSocket.d.ts +79 -0
  324. package/dist/vendor/node/NodeClusterSocket.js +30 -0
  325. package/dist/vendor/node/NodeCrypto.d.ts +10 -0
  326. package/dist/vendor/node/NodeCrypto.js +8 -0
  327. package/dist/vendor/node/NodeFileSystem.d.ts +10 -0
  328. package/dist/vendor/node/NodeFileSystem.js +9 -0
  329. package/dist/vendor/node/NodeHttpClient.d.ts +179 -0
  330. package/dist/vendor/node/NodeHttpClient.js +46 -0
  331. package/dist/vendor/node/NodeHttpIncomingMessage.d.ts +62 -0
  332. package/dist/vendor/node/NodeHttpIncomingMessage.js +10 -0
  333. package/dist/vendor/node/NodeHttpPlatform.d.ts +36 -0
  334. package/dist/vendor/node/NodeHttpPlatform.js +16 -0
  335. package/dist/vendor/node/NodeHttpServer.d.ts +120 -0
  336. package/dist/vendor/node/NodeHttpServer.js +46 -0
  337. package/dist/vendor/node/NodeHttpServerRequest.d.ts +29 -0
  338. package/dist/vendor/node/NodeHttpServerRequest.js +9 -0
  339. package/dist/vendor/node/NodeMultipart.d.ts +46 -0
  340. package/dist/vendor/node/NodeMultipart.js +15 -0
  341. package/dist/vendor/node/NodeMultipartParser.d.ts +97 -0
  342. package/dist/vendor/node/NodeMultipartParser.js +11 -0
  343. package/dist/vendor/node/NodePath.d.ts +27 -0
  344. package/dist/vendor/node/NodePath.js +12 -0
  345. package/dist/vendor/node/NodeRedis.d.ts +74 -0
  346. package/dist/vendor/node/NodeRedis.js +11 -0
  347. package/dist/vendor/node/NodeRuntime.d.ts +85 -0
  348. package/dist/vendor/node/NodeRuntime.js +8 -0
  349. package/dist/vendor/node/NodeServices.d.ts +34 -0
  350. package/dist/vendor/node/NodeServices.js +23 -0
  351. package/dist/vendor/node/NodeSink.d.ts +8 -0
  352. package/dist/vendor/node/NodeSink.js +12 -0
  353. package/dist/vendor/node/NodeSocket.d.ts +38 -0
  354. package/dist/vendor/node/NodeSocket.js +31 -0
  355. package/dist/vendor/node/NodeSocketServer.d.ts +8 -0
  356. package/dist/vendor/node/NodeSocketServer.js +21 -0
  357. package/dist/vendor/node/NodeStdio.d.ts +11 -0
  358. package/dist/vendor/node/NodeStdio.js +10 -0
  359. package/dist/vendor/node/NodeStream.d.ts +8 -0
  360. package/dist/vendor/node/NodeStream.js +27 -0
  361. package/dist/vendor/node/NodeTerminal.d.ts +21 -0
  362. package/dist/vendor/node/NodeTerminal.js +10 -0
  363. package/dist/vendor/node/NodeWorker.d.ts +22 -0
  364. package/dist/vendor/node/NodeWorker.js +9 -0
  365. package/dist/vendor/node/NodeWorkerRunner.d.ts +12 -0
  366. package/dist/vendor/node/NodeWorkerRunner.js +7 -0
  367. package/dist/vendor/node/Undici.d.ts +28 -0
  368. package/dist/vendor/node/Undici.js +9 -0
  369. package/dist/vendor/node/index.d.ts +100 -0
  370. package/dist/vendor/node/index.js +115 -0
  371. package/dist/vendor/node-shared/LICENSE +21 -0
  372. package/dist/vendor/node-shared/NodeChildProcessSpawner.d.ts +57 -0
  373. package/dist/vendor/node-shared/NodeChildProcessSpawner.js +13 -0
  374. package/dist/vendor/node-shared/NodeClusterSocket.d.ts +22 -0
  375. package/dist/vendor/node-shared/NodeClusterSocket.js +11 -0
  376. package/dist/vendor/node-shared/NodeCrypto.d.ts +27 -0
  377. package/dist/vendor/node-shared/NodeCrypto.js +9 -0
  378. package/dist/vendor/node-shared/NodeFileSystem.d.ts +11 -0
  379. package/dist/vendor/node-shared/NodeFileSystem.js +8 -0
  380. package/dist/vendor/node-shared/NodeHttpCompression.d.ts +36 -0
  381. package/dist/vendor/node-shared/NodeHttpCompression.js +13 -0
  382. package/dist/vendor/node-shared/NodePath.d.ts +27 -0
  383. package/dist/vendor/node-shared/NodePath.js +11 -0
  384. package/dist/vendor/node-shared/NodeRuntime.d.ts +47 -0
  385. package/dist/vendor/node-shared/NodeRuntime.js +7 -0
  386. package/dist/vendor/node-shared/NodeSink.d.ts +69 -0
  387. package/dist/vendor/node-shared/NodeSink.js +11 -0
  388. package/dist/vendor/node-shared/NodeSocket.d.ts +134 -0
  389. package/dist/vendor/node-shared/NodeSocket.js +23 -0
  390. package/dist/vendor/node-shared/NodeSocketServer.d.ts +80 -0
  391. package/dist/vendor/node-shared/NodeSocketServer.js +20 -0
  392. package/dist/vendor/node-shared/NodeStdio.d.ts +12 -0
  393. package/dist/vendor/node-shared/NodeStdio.js +9 -0
  394. package/dist/vendor/node-shared/NodeStream.d.ts +179 -0
  395. package/dist/vendor/node-shared/NodeStream.js +26 -0
  396. package/dist/vendor/node-shared/NodeTerminal.d.ts +22 -0
  397. package/dist/vendor/node-shared/NodeTerminal.js +9 -0
  398. package/dist/vendor/node-shared/index.d.ts +56 -0
  399. package/dist/vendor/node-shared/index.js +58 -0
  400. package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
  401. package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.js +7 -0
  402. package/dist/vendor/node-shared/internal/utils.d.ts +2 -0
  403. package/dist/vendor/node-shared/internal/utils.js +7 -0
  404. package/dist/vendor/platform-node-shared.d.ts +56 -0
  405. package/dist/vendor/platform-node-shared.js +58 -0
  406. package/dist/vendor/platform-node.d.ts +100 -0
  407. package/dist/vendor/platform-node.js +115 -0
  408. package/docs/README.md +129 -0
  409. package/docs/api.md +553 -0
  410. package/docs/concepts/descriptor-relative-filesystem.md +181 -0
  411. package/docs/concepts/host-bundle.md +125 -0
  412. package/docs/concepts/process-containment.md +190 -0
  413. package/docs/guides/answer-run-ownership.md +87 -0
  414. package/docs/guides/configure-the-filesystem-helper.md +152 -0
  415. package/docs/guides/contain-child-processes.md +139 -0
  416. package/docs/guides/match-files-with-glob.md +151 -0
  417. package/docs/installation.md +204 -0
  418. package/docs/quickstart.md +147 -0
  419. package/docs/troubleshooting.md +130 -0
  420. package/package.json +202 -3
  421. package/src/AtomicFileSystem.ts +415 -0
  422. package/src/EgressHttpClient.ts +327 -0
  423. package/src/HostLiveness.ts +103 -0
  424. package/src/NodeHost.ts +253 -0
  425. package/src/ProcessConfinement.ts +363 -0
  426. package/src/ProcessReaper.ts +951 -0
  427. package/src/ProcessSandbox.ts +1307 -0
  428. package/src/ScopedProcess.ts +124 -0
  429. package/src/index.ts +44 -0
  430. package/src/internal/AtomicFileSystemExecutable.ts +379 -0
  431. package/src/internal/AtomicFileSystemProtocol.ts +502 -0
  432. package/src/internal/AtomicFileSystemTransport.ts +272 -0
  433. package/src/internal/AtomicHelperError.ts +50 -0
  434. package/src/internal/AtomicHelperFault.ts +84 -0
  435. package/src/internal/PipedProcess.ts +357 -0
  436. package/src/internal/ProcSnapshot.ts +193 -0
  437. package/src/internal/ProcessCleanup.ts +99 -0
  438. package/src/internal/ProcessCleanupPolicyError.ts +30 -0
  439. package/src/internal/ProcessFault.ts +82 -0
  440. package/src/internal/ProcessSupervisor.ts +807 -0
  441. package/src/internal/SupervisorProgram.ts +309 -0
  442. package/src/internal/WindowsProcessJob.ts +114 -0
@@ -0,0 +1,502 @@
1
+ /**
2
+ * The adapter's half of the helper wire protocol: the request frame it sends,
3
+ * the response frame it accepts, and the typed value or `PlatformError` each
4
+ * operation's answer decodes to. Every check a helper answer has to pass lives
5
+ * here, so a malformed or hostile response fails closed in one place.
6
+ * @since 1.0.0
7
+ */
8
+
9
+ import type * as KernelFileSystem from "@smthrs/kernel/FileSystem"
10
+ import { Effect, type FileSystem, Option, PlatformError, Result } from "effect"
11
+ import * as ByteSize from "effect/ByteSize"
12
+ import { TextDecoder } from "node:util"
13
+ import type { Limits } from "../AtomicFileSystem.ts"
14
+ import { atomicHelperFault, AtomicHelperRejection } from "./AtomicHelperFault.ts"
15
+
16
+ /**
17
+ * One helper answer: a value, or a rejection carrying the errno name and the
18
+ * syscall the helper observed.
19
+ * @private
20
+ * @since 1.0.0
21
+ */
22
+ export interface HelperResult {
23
+ readonly ok: boolean
24
+ readonly value?: unknown
25
+ readonly code?: string | null
26
+ readonly syscall?: string | null
27
+ readonly badArgument?: boolean
28
+ readonly message?: string
29
+ }
30
+
31
+ /**
32
+ * The `module` every `PlatformError` this adapter reports names.
33
+ * @private
34
+ * @since 1.0.0
35
+ */
36
+ export const moduleName = "AtomicFileSystem"
37
+
38
+ const protocol = "flows-atomic/1"
39
+ /**
40
+ * Room for `flows-atomic/1 <digits>\n` above the payload ceiling.
41
+ * @private
42
+ * @since 1.0.0
43
+ */
44
+ export const frameHeaderBytes = 64
45
+ const decimal = /^[0-9]+$/
46
+ const fatalUtf8 = new TextDecoder("utf-8", { fatal: true })
47
+
48
+ /**
49
+ * The errno-to-reason table `@effect/platform-node` applies to a Node
50
+ * `ErrnoException`, so a caller reads the same typed reason it would get from
51
+ * the native filesystem. `EPERM` and `ENOTSUP` are added because they are how
52
+ * this helper reports its own refusals — outside the pinned root, a hard link,
53
+ * a symlink, a special file, the root itself, or a host without
54
+ * descriptor-relative POSIX. `EFBIG` and `ENXIO` are how it reports a payload
55
+ * over the documented limit and a write-only open of a reader-less FIFO.
56
+ * `EPROTO` is a framing failure and stays fail-closed. `EOPNOTSUPP` is the
57
+ * same number as `ENOTSUP` on Linux, where which of the two names Python
58
+ * reports for it is an implementation detail.
59
+ */
60
+ const reasons: Record<string, PlatformError.SystemErrorTag | undefined> = {
61
+ EACCES: "PermissionDenied",
62
+ EBUSY: "Busy",
63
+ EEXIST: "AlreadyExists",
64
+ EFBIG: "BadResource",
65
+ EISDIR: "BadResource",
66
+ ELOOP: "BadResource",
67
+ ENOENT: "NotFound",
68
+ ENOTDIR: "BadResource",
69
+ ENOTSUP: "PermissionDenied",
70
+ ENXIO: "BadResource",
71
+ EOPNOTSUPP: "PermissionDenied",
72
+ EPERM: "PermissionDenied",
73
+ EPROTO: "PermissionDenied"
74
+ }
75
+
76
+ /**
77
+ * A request framed for the helper: one atomic operation, or one member of a
78
+ * batch. The two protocols name their operands differently — a batch `glob`
79
+ * carries the `path` it expands where an atomic `glob` carries a `pattern` —
80
+ * so the reporting helpers read the operand by narrowing on the operation
81
+ * rather than by taking whichever of three optional fields happened to be set.
82
+ * @private
83
+ * @since 1.0.0
84
+ */
85
+ export type FramedRequest = KernelFileSystem.AtomicRequest | KernelFileSystem.AtomicBatchRequest
86
+
87
+ /** The operand a framed request names, for a failure's `pathOrDescriptor`. */
88
+ const operand = (request: FramedRequest): string | undefined =>
89
+ "path" in request ?
90
+ request.path :
91
+ request.operation === "rename" ?
92
+ request.from :
93
+ request.operation === "glob" ?
94
+ request.pattern :
95
+ undefined
96
+
97
+ /**
98
+ * A rejection carrying no errno is a transport or host failure — an absent
99
+ * helper, a killed child, output that is not a helper result — and stays
100
+ * `PermissionDenied` so the boundary fails closed rather than reporting a
101
+ * benign-looking reason for an operation that never ran.
102
+ * @private
103
+ * @since 1.0.0
104
+ */
105
+ export const failure = (
106
+ request: FramedRequest,
107
+ cause: unknown,
108
+ rejection?: HelperResult
109
+ ): PlatformError.PlatformError => {
110
+ const method = request.operation
111
+ if (rejection?.badArgument === true) {
112
+ return PlatformError.badArgument({ module: moduleName, method, description: rejection.message, cause })
113
+ }
114
+ const code = rejection?.code ?? undefined
115
+ return PlatformError.systemError({
116
+ module: moduleName,
117
+ method,
118
+ pathOrDescriptor: operand(request),
119
+ // `@effect/platform-node` sets `syscall` on every system error it reports,
120
+ // so a consumer that switches on it has to read a populated field here too.
121
+ // It names the operation's own syscall rather than whichever of the calls
122
+ // that operation makes actually raised, so it says what was attempted, not
123
+ // which step failed. A transport failure names no syscall at all, because
124
+ // no syscall ran.
125
+ syscall: rejection?.syscall ?? undefined,
126
+ _tag: code === undefined ? "PermissionDenied" : reasons[code] ?? "Unknown",
127
+ // The cause is repeated into the description because a fail-closed refusal
128
+ // that says only "failed closed" is unactionable: an absent helper, a
129
+ // response over the limit, and a mangled frame all look alike otherwise.
130
+ description: code === undefined
131
+ ? `descriptor-relative filesystem isolation failed closed: ${String(cause)}`
132
+ : rejection?.message,
133
+ // Match the native Node adapter's errno contract. Artifact path checks
134
+ // distinguish a non-link (EINVAL) from a helper or transport failure.
135
+ cause: code === undefined ? cause : new AtomicHelperRejection({
136
+ code,
137
+ syscall: rejection?.syscall ?? undefined,
138
+ message: rejection?.message ?? "",
139
+ cause
140
+ })
141
+ })
142
+ }
143
+
144
+ /**
145
+ * Frames a serialized request: the protocol tag, the body length, and the
146
+ * request, content, and response ceilings the helper enforces on its side,
147
+ * then the body.
148
+ * @private
149
+ * @since 1.0.0
150
+ */
151
+ export const encode = (body: Buffer, limits: Limits): Buffer => {
152
+ const header = Buffer.from(
153
+ `${protocol} ${body.byteLength} ${limits.request} ${limits.content} ${limits.response}\n`,
154
+ "ascii"
155
+ )
156
+ return Buffer.concat([header, body], header.byteLength + body.byteLength)
157
+ }
158
+
159
+ /**
160
+ * Decodes one complete response frame into a result envelope. Anything that
161
+ * is not exactly one well-formed frame within the response ceiling throws.
162
+ * @private
163
+ * @since 1.0.0
164
+ */
165
+ export const decode = (frame: Buffer, limits: Limits): HelperResult => {
166
+ const newline = frame.indexOf(10)
167
+ if (newline < 0 || newline >= frameHeaderBytes) {
168
+ throw atomicHelperFault("response_unframed", "atomic helper response is not framed")
169
+ }
170
+ const fields = frame.subarray(0, newline).toString("ascii").split(" ")
171
+ if (fields.length !== 2 || fields[0] !== protocol) {
172
+ throw atomicHelperFault("response_tag_unknown", "atomic helper response carries an unknown protocol tag")
173
+ }
174
+ const declared = fields[1]!
175
+ if (!decimal.test(declared)) {
176
+ throw atomicHelperFault(
177
+ "response_length_invalid",
178
+ `atomic helper declared a non-decimal response length: ${declared}`
179
+ )
180
+ }
181
+ const length = Number(declared)
182
+ if (!Number.isSafeInteger(length) || length < 0 || length > limits.response) {
183
+ throw atomicHelperFault(
184
+ "response_length_invalid",
185
+ `atomic helper declared an out-of-range response length: ${declared}`
186
+ )
187
+ }
188
+ const body = frame.subarray(newline + 1)
189
+ if (body.byteLength !== length) {
190
+ // Fewer bytes is a truncated response (a killed helper); more is a second
191
+ // frame appended to the first. Either way the stream is not one answer.
192
+ throw atomicHelperFault(
193
+ "response_length_mismatch",
194
+ `atomic helper declared ${length} response bytes and wrote ${body.byteLength}`
195
+ )
196
+ }
197
+ // Decoded from the complete frame, so a multi-byte character split across
198
+ // two stdout chunks is never mangled on the way in.
199
+ return resultEnvelope(JSON.parse(fatalUtf8.decode(body)))
200
+ }
201
+
202
+ const resultEnvelope = (input: unknown): HelperResult => {
203
+ const value = input as HelperResult
204
+ if (value === null || typeof value !== "object" || typeof value.ok !== "boolean") {
205
+ throw atomicHelperFault("envelope_malformed", "atomic helper response is not a result envelope")
206
+ }
207
+ if (value.code !== undefined && value.code !== null && typeof value.code !== "string") {
208
+ throw atomicHelperFault("envelope_malformed", "atomic helper response carries a non-string error code")
209
+ }
210
+ if (value.syscall !== undefined && value.syscall !== null && typeof value.syscall !== "string") {
211
+ throw atomicHelperFault("envelope_malformed", "atomic helper response carries a non-string syscall")
212
+ }
213
+ if (value.badArgument !== undefined && typeof value.badArgument !== "boolean") {
214
+ throw atomicHelperFault("envelope_malformed", "atomic helper response carries a non-boolean badArgument flag")
215
+ }
216
+ if (value.message !== undefined && typeof value.message !== "string") {
217
+ throw atomicHelperFault("envelope_malformed", "atomic helper response carries a non-string message")
218
+ }
219
+ return value
220
+ }
221
+
222
+ const record = (value: unknown, what: string): Record<string, unknown> => {
223
+ if (value === null || typeof value !== "object") {
224
+ throw atomicHelperFault("field_malformed", `atomic helper returned a non-object ${what}`)
225
+ }
226
+ return value as Record<string, unknown>
227
+ }
228
+
229
+ const finite = (value: unknown, field: string): number => {
230
+ if (typeof value !== "number" || !Number.isFinite(value)) {
231
+ throw atomicHelperFault("field_malformed", `atomic helper returned a non-numeric ${field}`)
232
+ }
233
+ return value
234
+ }
235
+
236
+ const integer = (value: unknown, field: string): number => {
237
+ const numeric = finite(value, field)
238
+ if (!Number.isSafeInteger(numeric) || numeric < 0) {
239
+ throw atomicHelperFault("field_malformed", `atomic helper returned an out-of-range ${field}: ${numeric}`)
240
+ }
241
+ return numeric
242
+ }
243
+
244
+ const date = (value: unknown, field: string): Date => {
245
+ const result = new Date(finite(value, field))
246
+ if (!Number.isFinite(result.getTime())) {
247
+ throw atomicHelperFault("field_malformed", `atomic helper returned an out-of-range ${field}`)
248
+ }
249
+ return result
250
+ }
251
+
252
+ const size = (value: unknown, field: string): ByteSize.ByteSize => {
253
+ if (typeof value === "string" && decimal.test(value)) {
254
+ return ByteSize.bytes(BigInt(value))
255
+ }
256
+ return ByteSize.bytes(BigInt(integer(value, field)))
257
+ }
258
+
259
+ const optional = <A>(value: unknown, read: (value: unknown) => A): Option.Option<A> =>
260
+ value === null || value === undefined ? Option.none() : Option.some(read(value))
261
+
262
+ /** Effect's own `FileSystem.File.Type`; anything else is a helper defect. */
263
+ const fileTypes = new Set<string>([
264
+ "File",
265
+ "Directory",
266
+ "SymbolicLink",
267
+ "BlockDevice",
268
+ "CharacterDevice",
269
+ "FIFO",
270
+ "Socket",
271
+ "Unknown"
272
+ ])
273
+
274
+ const toInfo = (value: unknown): FileSystem.File.Info => {
275
+ const info = record(value, "stat")
276
+ if (!fileTypes.has(info.type as string)) {
277
+ throw atomicHelperFault("file_type_unknown", `atomic helper returned an unknown file type: ${String(info.type)}`)
278
+ }
279
+ return {
280
+ type: info.type as FileSystem.File.Type,
281
+ mtime: Option.some(date(info.mtime, "mtime")),
282
+ atime: Option.some(date(info.atime, "atime")),
283
+ birthtime: optional(info.birthtime, (raw) => date(raw, "birthtime")),
284
+ dev: integer(info.dev, "dev"),
285
+ ino: optional(info.ino, (raw) => integer(raw, "ino")),
286
+ mode: integer(info.mode, "mode"),
287
+ nlink: Option.some(integer(info.nlink, "nlink")),
288
+ uid: Option.some(integer(info.uid, "uid")),
289
+ gid: Option.some(integer(info.gid, "gid")),
290
+ rdev: Option.some(integer(info.rdev, "rdev")),
291
+ size: size(info.size, "size"),
292
+ blksize: optional(info.blksize, (raw) => size(raw, "blksize")),
293
+ blocks: optional(info.blocks, (raw) => integer(raw, "blocks"))
294
+ }
295
+ }
296
+
297
+ const isBase64 = (encoded: string): boolean => {
298
+ if (encoded.length % 4 !== 0) return false
299
+ let end = encoded.length
300
+ if (encoded.endsWith("=")) {
301
+ end--
302
+ if (encoded[end - 1] === "=") end--
303
+ }
304
+ // A repeated-group regexp exhausts V8's stack on ordinary multi-MiB reads.
305
+ // Scan the alphabet once, excluding at most two trailing padding characters.
306
+ for (let index = 0; index < end; index++) {
307
+ const code = encoded.charCodeAt(index)
308
+ if (
309
+ !(code >= 65 && code <= 90) && !(code >= 97 && code <= 122) &&
310
+ !(code >= 48 && code <= 57) && code !== 43 && code !== 47
311
+ ) return false
312
+ }
313
+ return true
314
+ }
315
+
316
+ const toBytes = (value: unknown, limit: number): Uint8Array => {
317
+ const payload = record(value, "read result")
318
+ const encoded = payload.base64
319
+ // Buffer.from silently drops characters it does not recognise, so the shape
320
+ // is checked before the decode rather than inferred from its output.
321
+ if (typeof encoded !== "string" || !isBase64(encoded)) {
322
+ throw atomicHelperFault("payload_malformed", "atomic helper returned a malformed base64 payload")
323
+ }
324
+ const bytes = Buffer.from(encoded, "base64")
325
+ if (bytes.byteLength > limit) {
326
+ throw atomicHelperFault(
327
+ "read_limit_exceeded",
328
+ `atomic helper returned ${bytes.byteLength} bytes, over the ${limit} byte read limit`
329
+ )
330
+ }
331
+ return Uint8Array.from(bytes)
332
+ }
333
+
334
+ const toStringResult = (value: unknown, what: string): string => {
335
+ if (typeof value !== "string" || value.includes("\0")) {
336
+ throw atomicHelperFault("entries_malformed", `atomic helper returned an invalid ${what}`)
337
+ }
338
+ return value
339
+ }
340
+
341
+ const maxListingEntries = 100_000
342
+
343
+ const toStringArray = (value: unknown, what: string): Array<string> => {
344
+ if (!Array.isArray(value) || value.length > maxListingEntries) {
345
+ throw atomicHelperFault("entries_malformed", `atomic helper returned an invalid ${what}`)
346
+ }
347
+ const result = value.map((entry) => toStringResult(entry, `${what} entry`))
348
+ if (new Set(result).size !== result.length) {
349
+ throw atomicHelperFault("entries_malformed", `atomic helper returned duplicate ${what} entries`)
350
+ }
351
+ return result
352
+ }
353
+
354
+ /**
355
+ * Converts a successful helper value into the result the request's operation
356
+ * promises, and throws when the value does not have that shape.
357
+ * @private
358
+ * @since 1.0.0
359
+ */
360
+ export const convert = <A>(
361
+ request: FramedRequest,
362
+ value: unknown,
363
+ limits: Limits
364
+ ): Effect.Effect<A, PlatformError.PlatformError> => {
365
+ if (request.operation === "batch") {
366
+ const response = record(value, "batch")
367
+ const requests = request.requests
368
+ if (
369
+ response.rootIdentity !== request.rootIdentity || !Array.isArray(response.entries) ||
370
+ response.entries.length !== requests.length
371
+ ) {
372
+ throw atomicHelperFault("batch_malformed", "atomic helper returned a foreign or incomplete batch")
373
+ }
374
+ const seen = new Set<number>()
375
+ let previous = ""
376
+ let previousIndex = -1
377
+ const pending = response.entries.map((raw) => {
378
+ const entry = record(raw, "batch entry")
379
+ const index = integer(entry.index, "batch index")
380
+ const member = requests[index]
381
+ if (
382
+ member === undefined || seen.has(index) || entry.path !== member.path ||
383
+ member.path < previous || (member.path === previous && index <= previousIndex)
384
+ ) {
385
+ throw atomicHelperFault("batch_malformed", "atomic helper returned an invalid batch member identity or order")
386
+ }
387
+ seen.add(index)
388
+ previous = member.path
389
+ previousIndex = index
390
+ if (Buffer.byteLength(JSON.stringify(entry.result), "utf8") > limits.batchEntry) {
391
+ throw atomicHelperFault("batch_malformed", "atomic helper returned an oversized batch entry")
392
+ }
393
+ const envelope = resultEnvelope(entry.result)
394
+ const identity = { index, path: member.path }
395
+ if (!envelope.ok) {
396
+ return Effect.succeed({
397
+ ...identity,
398
+ result: Result.fail(
399
+ failure(
400
+ member,
401
+ atomicHelperFault("helper_rejected", envelope.message ?? "atomic batch member failed"),
402
+ envelope
403
+ )
404
+ )
405
+ })
406
+ }
407
+ if (member.operation === "digest") {
408
+ const measured = record(envelope.value, "digest")
409
+ if (typeof measured.digest !== "string" || !/^[a-f0-9]{64}$/.test(measured.digest)) {
410
+ throw atomicHelperFault("digest_malformed", "atomic helper returned an invalid SHA-256 digest")
411
+ }
412
+ const sizeBytes = integer(measured.sizeBytes, "digest size")
413
+ if (sizeBytes > limits.content) {
414
+ throw atomicHelperFault("digest_malformed", "atomic helper returned an oversized digest measurement")
415
+ }
416
+ const bytes = member.content === true ? toBytes(measured, limits.content) : undefined
417
+ if (bytes !== undefined && bytes.length !== sizeBytes) {
418
+ throw atomicHelperFault("digest_malformed", "atomic helper returned a mismatched digest size")
419
+ }
420
+ return Effect.succeed({
421
+ ...identity,
422
+ result: Result.succeed<KernelFileSystem.AtomicBatchValue>({
423
+ operation: "digest",
424
+ digest: measured.digest,
425
+ sizeBytes,
426
+ ...(bytes === undefined ? {} : { bytes })
427
+ })
428
+ })
429
+ }
430
+ return Effect.map(convert(member, envelope.value, limits), (converted) => ({
431
+ ...identity,
432
+ result: Result.succeed<KernelFileSystem.AtomicBatchValue>(
433
+ member.operation === "stat"
434
+ ? { operation: "stat", info: converted as FileSystem.File.Info }
435
+ : member.operation === "resolve"
436
+ ? { operation: "resolve", resolution: converted as KernelFileSystem.Resolution }
437
+ : { operation: member.operation, paths: (converted as Array<string>).sort() }
438
+ )
439
+ }))
440
+ })
441
+ return Effect.map(Effect.all(pending), (entries) => ({ rootIdentity: response.rootIdentity, entries }) as A)
442
+ }
443
+ if (request.operation === "readFile" || request.operation === "readFileString") {
444
+ // An empty file encodes to an empty string, so the payload is read by
445
+ // shape: truthiness would return the raw envelope for it instead.
446
+ const bytes = toBytes(value, limits.content)
447
+ if (request.operation === "readFile") {
448
+ return Effect.succeed(bytes as A)
449
+ }
450
+ try {
451
+ return Effect.succeed(new TextDecoder(request.encoding).decode(bytes) as A)
452
+ } catch (cause) {
453
+ // Effect's own `readFileString` reports a rejected encoding as a
454
+ // BadArgument, not as a filesystem failure.
455
+ return Effect.fail(PlatformError.badArgument({
456
+ module: "FileSystem",
457
+ method: "readFileString",
458
+ description: "invalid encoding",
459
+ cause
460
+ }))
461
+ }
462
+ }
463
+ if (request.operation === "stat") {
464
+ return Effect.succeed(toInfo(value) as A)
465
+ }
466
+ if (request.operation === "exists") {
467
+ if (typeof value !== "boolean") {
468
+ throw atomicHelperFault("result_malformed", "atomic helper returned a non-boolean exists result")
469
+ }
470
+ return Effect.succeed(value as A)
471
+ }
472
+ if (request.operation === "readLink" || request.operation === "realPath") {
473
+ return Effect.succeed(toStringResult(value, `${request.operation} result`) as A)
474
+ }
475
+ if (request.operation === "resolve") {
476
+ const resolution = record(value, "resolve result")
477
+ const target = resolution.target === null ? null : toStringResult(resolution.target, "resolve target")
478
+ const answer: KernelFileSystem.Resolution = { path: toStringResult(resolution.path, "resolve path"), target }
479
+ return Effect.succeed(answer as A)
480
+ }
481
+ if (request.operation === "readDirectory" || request.operation === "glob") {
482
+ return Effect.succeed(toStringArray(value, `${request.operation} result`) as A)
483
+ }
484
+ if (
485
+ request.operation === "writeFile" ||
486
+ request.operation === "writeFileString" ||
487
+ request.operation === "chmod" ||
488
+ request.operation === "chown" ||
489
+ request.operation === "makeDirectory" ||
490
+ request.operation === "remove" ||
491
+ request.operation === "rename"
492
+ ) {
493
+ if (value !== null) {
494
+ throw atomicHelperFault("result_malformed", `atomic helper returned a non-null ${request.operation} result`)
495
+ }
496
+ return Effect.succeed(undefined as A)
497
+ }
498
+ throw atomicHelperFault(
499
+ "operation_unsupported",
500
+ `atomic helper returned success for unsupported operation ${(request as FramedRequest).operation}`
501
+ )
502
+ }