@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.
- package/CHANGELOG.md +211 -0
- package/LICENSE +21 -0
- package/README.md +165 -2
- package/bin/darwin-arm64/smithers-jj-export +0 -0
- package/bin/darwin-x64/smithers-jj-export +0 -0
- package/bin/linux-arm64/smithers-jj-export +0 -0
- package/bin/linux-x64/smithers-jj-export +4 -0
- package/bin/win32-x64/smithers-jj-export.exe +0 -0
- package/dist/cjs/AtomicFileSystem.d.ts +147 -0
- package/dist/cjs/AtomicFileSystem.d.ts.map +1 -0
- package/dist/cjs/AtomicFileSystem.js +234 -0
- package/dist/cjs/AtomicFileSystem.js.map +7 -0
- package/dist/cjs/EgressHttpClient.d.ts +106 -0
- package/dist/cjs/EgressHttpClient.d.ts.map +1 -0
- package/dist/cjs/EgressHttpClient.js +202 -0
- package/dist/cjs/EgressHttpClient.js.map +7 -0
- package/dist/cjs/HostLiveness.d.ts +81 -0
- package/dist/cjs/HostLiveness.d.ts.map +1 -0
- package/dist/cjs/HostLiveness.js +49 -0
- package/dist/cjs/HostLiveness.js.map +7 -0
- package/dist/cjs/NodeHost.d.ts +145 -0
- package/dist/cjs/NodeHost.d.ts.map +1 -0
- package/dist/cjs/NodeHost.js +128 -0
- package/dist/cjs/NodeHost.js.map +7 -0
- package/dist/cjs/ProcessConfinement.d.ts +61 -0
- package/dist/cjs/ProcessConfinement.d.ts.map +1 -0
- package/dist/cjs/ProcessConfinement.js +292 -0
- package/dist/cjs/ProcessConfinement.js.map +7 -0
- package/dist/cjs/ProcessReaper.d.ts +457 -0
- package/dist/cjs/ProcessReaper.d.ts.map +1 -0
- package/dist/cjs/ProcessReaper.js +349 -0
- package/dist/cjs/ProcessReaper.js.map +7 -0
- package/dist/cjs/ProcessSandbox.d.ts +391 -0
- package/dist/cjs/ProcessSandbox.d.ts.map +1 -0
- package/dist/cjs/ProcessSandbox.js +774 -0
- package/dist/cjs/ProcessSandbox.js.map +7 -0
- package/dist/cjs/ScopedProcess.d.ts +66 -0
- package/dist/cjs/ScopedProcess.d.ts.map +1 -0
- package/dist/cjs/ScopedProcess.js +87 -0
- package/dist/cjs/ScopedProcess.js.map +7 -0
- package/dist/cjs/index.d.ts +38 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +47 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/AtomicFileSystemExecutable.d.ts +61 -0
- package/dist/cjs/internal/AtomicFileSystemExecutable.d.ts.map +1 -0
- package/dist/cjs/internal/AtomicFileSystemExecutable.js +250 -0
- package/dist/cjs/internal/AtomicFileSystemExecutable.js.map +7 -0
- package/dist/cjs/internal/AtomicFileSystemProtocol.d.ts +78 -0
- package/dist/cjs/internal/AtomicFileSystemProtocol.d.ts.map +1 -0
- package/dist/cjs/internal/AtomicFileSystemProtocol.js +382 -0
- package/dist/cjs/internal/AtomicFileSystemProtocol.js.map +7 -0
- package/dist/cjs/internal/AtomicFileSystemTransport.d.ts +44 -0
- package/dist/cjs/internal/AtomicFileSystemTransport.d.ts.map +1 -0
- package/dist/cjs/internal/AtomicFileSystemTransport.js +197 -0
- package/dist/cjs/internal/AtomicFileSystemTransport.js.map +7 -0
- package/dist/cjs/internal/AtomicHelperError.d.ts +35 -0
- package/dist/cjs/internal/AtomicHelperError.d.ts.map +1 -0
- package/dist/cjs/internal/AtomicHelperError.js +45 -0
- package/dist/cjs/internal/AtomicHelperError.js.map +7 -0
- package/dist/cjs/internal/AtomicHelperFault.d.ts +59 -0
- package/dist/cjs/internal/AtomicHelperFault.d.ts.map +1 -0
- package/dist/cjs/internal/AtomicHelperFault.js +66 -0
- package/dist/cjs/internal/AtomicHelperFault.js.map +7 -0
- package/dist/cjs/internal/PipedProcess.d.ts +35 -0
- package/dist/cjs/internal/PipedProcess.d.ts.map +1 -0
- package/dist/cjs/internal/PipedProcess.js +309 -0
- package/dist/cjs/internal/PipedProcess.js.map +7 -0
- package/dist/cjs/internal/ProcSnapshot.d.ts +85 -0
- package/dist/cjs/internal/ProcSnapshot.d.ts.map +1 -0
- package/dist/cjs/internal/ProcSnapshot.js +123 -0
- package/dist/cjs/internal/ProcSnapshot.js.map +7 -0
- package/dist/cjs/internal/ProcessCleanup.d.ts +64 -0
- package/dist/cjs/internal/ProcessCleanup.d.ts.map +1 -0
- package/dist/cjs/internal/ProcessCleanup.js +62 -0
- package/dist/cjs/internal/ProcessCleanup.js.map +7 -0
- package/dist/cjs/internal/ProcessCleanupPolicyError.d.ts +30 -0
- package/dist/cjs/internal/ProcessCleanupPolicyError.d.ts.map +1 -0
- package/dist/cjs/internal/ProcessCleanupPolicyError.js +33 -0
- package/dist/cjs/internal/ProcessCleanupPolicyError.js.map +7 -0
- package/dist/cjs/internal/ProcessFault.d.ts +63 -0
- package/dist/cjs/internal/ProcessFault.d.ts.map +1 -0
- package/dist/cjs/internal/ProcessFault.js +63 -0
- package/dist/cjs/internal/ProcessFault.js.map +7 -0
- package/dist/cjs/internal/ProcessSupervisor.d.ts +143 -0
- package/dist/cjs/internal/ProcessSupervisor.d.ts.map +1 -0
- package/dist/cjs/internal/ProcessSupervisor.js +685 -0
- package/dist/cjs/internal/ProcessSupervisor.js.map +7 -0
- package/dist/cjs/internal/SupervisorProgram.d.ts +9 -0
- package/dist/cjs/internal/SupervisorProgram.d.ts.map +1 -0
- package/dist/cjs/internal/SupervisorProgram.js +326 -0
- package/dist/cjs/internal/SupervisorProgram.js.map +7 -0
- package/dist/cjs/internal/WindowsProcessJob.d.ts +39 -0
- package/dist/cjs/internal/WindowsProcessJob.d.ts.map +1 -0
- package/dist/cjs/internal/WindowsProcessJob.js +113 -0
- package/dist/cjs/internal/WindowsProcessJob.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/AtomicFileSystem.d.ts +147 -0
- package/dist/esm/AtomicFileSystem.d.ts.map +1 -0
- package/dist/esm/AtomicFileSystem.js +290 -0
- package/dist/esm/AtomicFileSystem.js.map +1 -0
- package/dist/esm/EgressHttpClient.d.ts +106 -0
- package/dist/esm/EgressHttpClient.d.ts.map +1 -0
- package/dist/esm/EgressHttpClient.js +259 -0
- package/dist/esm/EgressHttpClient.js.map +1 -0
- package/dist/esm/HostLiveness.d.ts +81 -0
- package/dist/esm/HostLiveness.d.ts.map +1 -0
- package/dist/esm/HostLiveness.js +68 -0
- package/dist/esm/HostLiveness.js.map +1 -0
- package/dist/esm/NodeHost.d.ts +145 -0
- package/dist/esm/NodeHost.d.ts.map +1 -0
- package/dist/esm/NodeHost.js +162 -0
- package/dist/esm/NodeHost.js.map +1 -0
- package/dist/esm/ProcessConfinement.d.ts +61 -0
- package/dist/esm/ProcessConfinement.d.ts.map +1 -0
- package/dist/esm/ProcessConfinement.js +311 -0
- package/dist/esm/ProcessConfinement.js.map +1 -0
- package/dist/esm/ProcessReaper.d.ts +457 -0
- package/dist/esm/ProcessReaper.d.ts.map +1 -0
- package/dist/esm/ProcessReaper.js +711 -0
- package/dist/esm/ProcessReaper.js.map +1 -0
- package/dist/esm/ProcessSandbox.d.ts +391 -0
- package/dist/esm/ProcessSandbox.d.ts.map +1 -0
- package/dist/esm/ProcessSandbox.js +1043 -0
- package/dist/esm/ProcessSandbox.js.map +1 -0
- package/dist/esm/ScopedProcess.d.ts +66 -0
- package/dist/esm/ScopedProcess.d.ts.map +1 -0
- package/dist/esm/ScopedProcess.js +67 -0
- package/dist/esm/ScopedProcess.js.map +1 -0
- package/dist/esm/index.d.ts +38 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +38 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/AtomicFileSystemExecutable.d.ts +61 -0
- package/dist/esm/internal/AtomicFileSystemExecutable.d.ts.map +1 -0
- package/dist/esm/internal/AtomicFileSystemExecutable.js +350 -0
- package/dist/esm/internal/AtomicFileSystemExecutable.js.map +1 -0
- package/dist/esm/internal/AtomicFileSystemProtocol.d.ts +78 -0
- package/dist/esm/internal/AtomicFileSystemProtocol.d.ts.map +1 -0
- package/dist/esm/internal/AtomicFileSystemProtocol.js +412 -0
- package/dist/esm/internal/AtomicFileSystemProtocol.js.map +1 -0
- package/dist/esm/internal/AtomicFileSystemTransport.d.ts +44 -0
- package/dist/esm/internal/AtomicFileSystemTransport.d.ts.map +1 -0
- package/dist/esm/internal/AtomicFileSystemTransport.js +242 -0
- package/dist/esm/internal/AtomicFileSystemTransport.js.map +1 -0
- package/dist/esm/internal/AtomicHelperError.d.ts +35 -0
- package/dist/esm/internal/AtomicHelperError.d.ts.map +1 -0
- package/dist/esm/internal/AtomicHelperError.js +39 -0
- package/dist/esm/internal/AtomicHelperError.js.map +1 -0
- package/dist/esm/internal/AtomicHelperFault.d.ts +59 -0
- package/dist/esm/internal/AtomicHelperFault.d.ts.map +1 -0
- package/dist/esm/internal/AtomicHelperFault.js +66 -0
- package/dist/esm/internal/AtomicHelperFault.js.map +1 -0
- package/dist/esm/internal/PipedProcess.d.ts +35 -0
- package/dist/esm/internal/PipedProcess.d.ts.map +1 -0
- package/dist/esm/internal/PipedProcess.js +321 -0
- package/dist/esm/internal/PipedProcess.js.map +1 -0
- package/dist/esm/internal/ProcSnapshot.d.ts +85 -0
- package/dist/esm/internal/ProcSnapshot.d.ts.map +1 -0
- package/dist/esm/internal/ProcSnapshot.js +188 -0
- package/dist/esm/internal/ProcSnapshot.js.map +1 -0
- package/dist/esm/internal/ProcessCleanup.d.ts +64 -0
- package/dist/esm/internal/ProcessCleanup.d.ts.map +1 -0
- package/dist/esm/internal/ProcessCleanup.js +45 -0
- package/dist/esm/internal/ProcessCleanup.js.map +1 -0
- package/dist/esm/internal/ProcessCleanupPolicyError.d.ts +30 -0
- package/dist/esm/internal/ProcessCleanupPolicyError.d.ts.map +1 -0
- package/dist/esm/internal/ProcessCleanupPolicyError.js +25 -0
- package/dist/esm/internal/ProcessCleanupPolicyError.js.map +1 -0
- package/dist/esm/internal/ProcessFault.d.ts +63 -0
- package/dist/esm/internal/ProcessFault.d.ts.map +1 -0
- package/dist/esm/internal/ProcessFault.js +64 -0
- package/dist/esm/internal/ProcessFault.js.map +1 -0
- package/dist/esm/internal/ProcessSupervisor.d.ts +143 -0
- package/dist/esm/internal/ProcessSupervisor.d.ts.map +1 -0
- package/dist/esm/internal/ProcessSupervisor.js +689 -0
- package/dist/esm/internal/ProcessSupervisor.js.map +1 -0
- package/dist/esm/internal/SupervisorProgram.d.ts +9 -0
- package/dist/esm/internal/SupervisorProgram.d.ts.map +1 -0
- package/dist/esm/internal/SupervisorProgram.js +310 -0
- package/dist/esm/internal/SupervisorProgram.js.map +1 -0
- package/dist/esm/internal/WindowsProcessJob.d.ts +39 -0
- package/dist/esm/internal/WindowsProcessJob.d.ts.map +1 -0
- package/dist/esm/internal/WindowsProcessJob.js +115 -0
- package/dist/esm/internal/WindowsProcessJob.js.map +1 -0
- package/dist/vendor/adapters.json +1757 -0
- package/dist/vendor/chunk-2Y7WC4KU.js +109 -0
- package/dist/vendor/chunk-3GR5VZ2M.js +118 -0
- package/dist/vendor/chunk-42QKY6T6.js +40 -0
- package/dist/vendor/chunk-54RLBMTZ.js +61 -0
- package/dist/vendor/chunk-5ZMHBXIK.js +55 -0
- package/dist/vendor/chunk-6ME2W7TF.js +28 -0
- package/dist/vendor/chunk-AMQKOQNT.js +34 -0
- package/dist/vendor/chunk-B3FZ67QU.js +59 -0
- package/dist/vendor/chunk-BKTBUBQY.js +437 -0
- package/dist/vendor/chunk-DS7GF46S.js +34 -0
- package/dist/vendor/chunk-DVOAHXPG.js +104 -0
- package/dist/vendor/chunk-DWSHTSVX.js +229 -0
- package/dist/vendor/chunk-EGBNVEEW.js +14 -0
- package/dist/vendor/chunk-EZWY45HP.js +18 -0
- package/dist/vendor/chunk-FNZOJHSV.js +71 -0
- package/dist/vendor/chunk-GXCHI7BM.js +131 -0
- package/dist/vendor/chunk-IIJ52ZU6.js +20 -0
- package/dist/vendor/chunk-J7A4CZDO.js +92 -0
- package/dist/vendor/chunk-JG5TTWPT.js +85 -0
- package/dist/vendor/chunk-JJ24ARBQ.js +394 -0
- package/dist/vendor/chunk-KOZMM5PZ.js +426 -0
- package/dist/vendor/chunk-KUUXSID7.js +18 -0
- package/dist/vendor/chunk-LEUPYT3Q.js +36 -0
- package/dist/vendor/chunk-M32LDTW7.js +18 -0
- package/dist/vendor/chunk-M7CLUILA.js +0 -0
- package/dist/vendor/chunk-MBSKBQ5D.js +21 -0
- package/dist/vendor/chunk-MLKGABMK.js +9 -0
- package/dist/vendor/chunk-NBVRTDTV.js +129 -0
- package/dist/vendor/chunk-OXNGN5H7.js +81 -0
- package/dist/vendor/chunk-QPLDT6A6.js +564 -0
- package/dist/vendor/chunk-QYBKAIA6.js +18 -0
- package/dist/vendor/chunk-RO2R4MJH.js +62 -0
- package/dist/vendor/chunk-SIR62W3Y.js +398 -0
- package/dist/vendor/chunk-TFIKFFSC.js +26 -0
- package/dist/vendor/chunk-TXKLEBBL.js +143 -0
- package/dist/vendor/chunk-UFH5UUZK.js +48 -0
- package/dist/vendor/chunk-VANKHF46.js +96 -0
- package/dist/vendor/chunk-VZBDV3TV.js +18 -0
- package/dist/vendor/chunk-XDKNKFBW.js +22 -0
- package/dist/vendor/chunk-XH4U3JSV.js +249 -0
- package/dist/vendor/chunk-Y35ZAO5U.js +53 -0
- package/dist/vendor/chunk-ZJMRMY57.js +0 -0
- package/dist/vendor/cjs/node/NodeChildProcessSpawner.d.ts +7 -0
- package/dist/vendor/cjs/node/NodeChildProcessSpawner.js +1 -0
- package/dist/vendor/cjs/node/NodeClusterHttp.d.ts +63 -0
- package/dist/vendor/cjs/node/NodeClusterHttp.js +1 -0
- package/dist/vendor/cjs/node/NodeClusterSocket.d.ts +79 -0
- package/dist/vendor/cjs/node/NodeClusterSocket.js +1 -0
- package/dist/vendor/cjs/node/NodeCrypto.d.ts +10 -0
- package/dist/vendor/cjs/node/NodeCrypto.js +1 -0
- package/dist/vendor/cjs/node/NodeFileSystem.d.ts +10 -0
- package/dist/vendor/cjs/node/NodeFileSystem.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpClient.d.ts +179 -0
- package/dist/vendor/cjs/node/NodeHttpClient.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpIncomingMessage.d.ts +62 -0
- package/dist/vendor/cjs/node/NodeHttpIncomingMessage.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpPlatform.d.ts +36 -0
- package/dist/vendor/cjs/node/NodeHttpPlatform.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpServer.d.ts +120 -0
- package/dist/vendor/cjs/node/NodeHttpServer.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpServerRequest.d.ts +29 -0
- package/dist/vendor/cjs/node/NodeHttpServerRequest.js +1 -0
- package/dist/vendor/cjs/node/NodeMultipart.d.ts +46 -0
- package/dist/vendor/cjs/node/NodeMultipart.js +1 -0
- package/dist/vendor/cjs/node/NodeMultipartParser.d.ts +97 -0
- package/dist/vendor/cjs/node/NodeMultipartParser.js +1 -0
- package/dist/vendor/cjs/node/NodePath.d.ts +27 -0
- package/dist/vendor/cjs/node/NodePath.js +1 -0
- package/dist/vendor/cjs/node/NodeRedis.d.ts +74 -0
- package/dist/vendor/cjs/node/NodeRedis.js +1 -0
- package/dist/vendor/cjs/node/NodeRuntime.d.ts +85 -0
- package/dist/vendor/cjs/node/NodeRuntime.js +1 -0
- package/dist/vendor/cjs/node/NodeServices.d.ts +34 -0
- package/dist/vendor/cjs/node/NodeServices.js +1 -0
- package/dist/vendor/cjs/node/NodeSink.d.ts +8 -0
- package/dist/vendor/cjs/node/NodeSink.js +1 -0
- package/dist/vendor/cjs/node/NodeSocket.d.ts +38 -0
- package/dist/vendor/cjs/node/NodeSocket.js +1 -0
- package/dist/vendor/cjs/node/NodeSocketServer.d.ts +8 -0
- package/dist/vendor/cjs/node/NodeSocketServer.js +1 -0
- package/dist/vendor/cjs/node/NodeStdio.d.ts +11 -0
- package/dist/vendor/cjs/node/NodeStdio.js +1 -0
- package/dist/vendor/cjs/node/NodeStream.d.ts +8 -0
- package/dist/vendor/cjs/node/NodeStream.js +1 -0
- package/dist/vendor/cjs/node/NodeTerminal.d.ts +21 -0
- package/dist/vendor/cjs/node/NodeTerminal.js +1 -0
- package/dist/vendor/cjs/node/NodeWorker.d.ts +22 -0
- package/dist/vendor/cjs/node/NodeWorker.js +1 -0
- package/dist/vendor/cjs/node/NodeWorkerRunner.d.ts +12 -0
- package/dist/vendor/cjs/node/NodeWorkerRunner.js +1 -0
- package/dist/vendor/cjs/node/Undici.d.ts +28 -0
- package/dist/vendor/cjs/node/Undici.js +1 -0
- package/dist/vendor/cjs/node/index.d.ts +100 -0
- package/dist/vendor/cjs/node/index.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.d.ts +57 -0
- package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeClusterSocket.d.ts +22 -0
- package/dist/vendor/cjs/node-shared/NodeClusterSocket.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeCrypto.d.ts +27 -0
- package/dist/vendor/cjs/node-shared/NodeCrypto.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeFileSystem.d.ts +11 -0
- package/dist/vendor/cjs/node-shared/NodeFileSystem.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeHttpCompression.d.ts +36 -0
- package/dist/vendor/cjs/node-shared/NodeHttpCompression.js +1 -0
- package/dist/vendor/cjs/node-shared/NodePath.d.ts +27 -0
- package/dist/vendor/cjs/node-shared/NodePath.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeRuntime.d.ts +47 -0
- package/dist/vendor/cjs/node-shared/NodeRuntime.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeSink.d.ts +69 -0
- package/dist/vendor/cjs/node-shared/NodeSink.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeSocket.d.ts +134 -0
- package/dist/vendor/cjs/node-shared/NodeSocket.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeSocketServer.d.ts +80 -0
- package/dist/vendor/cjs/node-shared/NodeSocketServer.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeStdio.d.ts +12 -0
- package/dist/vendor/cjs/node-shared/NodeStdio.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeStream.d.ts +179 -0
- package/dist/vendor/cjs/node-shared/NodeStream.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeTerminal.d.ts +22 -0
- package/dist/vendor/cjs/node-shared/NodeTerminal.js +1 -0
- package/dist/vendor/cjs/node-shared/index.d.ts +56 -0
- package/dist/vendor/cjs/node-shared/index.js +1 -0
- package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
- package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.js +1 -0
- package/dist/vendor/cjs/node-shared/internal/utils.d.ts +2 -0
- package/dist/vendor/cjs/node-shared/internal/utils.js +1 -0
- package/dist/vendor/cjs/package.json +1 -0
- package/dist/vendor/cjs/platform-node-shared.d.ts +56 -0
- package/dist/vendor/cjs/platform-node-shared.js +1 -0
- package/dist/vendor/cjs/platform-node.d.ts +100 -0
- package/dist/vendor/cjs/platform-node.js +1 -0
- package/dist/vendor/node/LICENSE +21 -0
- package/dist/vendor/node/NodeChildProcessSpawner.d.ts +7 -0
- package/dist/vendor/node/NodeChildProcessSpawner.js +14 -0
- package/dist/vendor/node/NodeClusterHttp.d.ts +63 -0
- package/dist/vendor/node/NodeClusterHttp.js +43 -0
- package/dist/vendor/node/NodeClusterSocket.d.ts +79 -0
- package/dist/vendor/node/NodeClusterSocket.js +30 -0
- package/dist/vendor/node/NodeCrypto.d.ts +10 -0
- package/dist/vendor/node/NodeCrypto.js +8 -0
- package/dist/vendor/node/NodeFileSystem.d.ts +10 -0
- package/dist/vendor/node/NodeFileSystem.js +9 -0
- package/dist/vendor/node/NodeHttpClient.d.ts +179 -0
- package/dist/vendor/node/NodeHttpClient.js +46 -0
- package/dist/vendor/node/NodeHttpIncomingMessage.d.ts +62 -0
- package/dist/vendor/node/NodeHttpIncomingMessage.js +10 -0
- package/dist/vendor/node/NodeHttpPlatform.d.ts +36 -0
- package/dist/vendor/node/NodeHttpPlatform.js +16 -0
- package/dist/vendor/node/NodeHttpServer.d.ts +120 -0
- package/dist/vendor/node/NodeHttpServer.js +46 -0
- package/dist/vendor/node/NodeHttpServerRequest.d.ts +29 -0
- package/dist/vendor/node/NodeHttpServerRequest.js +9 -0
- package/dist/vendor/node/NodeMultipart.d.ts +46 -0
- package/dist/vendor/node/NodeMultipart.js +15 -0
- package/dist/vendor/node/NodeMultipartParser.d.ts +97 -0
- package/dist/vendor/node/NodeMultipartParser.js +11 -0
- package/dist/vendor/node/NodePath.d.ts +27 -0
- package/dist/vendor/node/NodePath.js +12 -0
- package/dist/vendor/node/NodeRedis.d.ts +74 -0
- package/dist/vendor/node/NodeRedis.js +11 -0
- package/dist/vendor/node/NodeRuntime.d.ts +85 -0
- package/dist/vendor/node/NodeRuntime.js +8 -0
- package/dist/vendor/node/NodeServices.d.ts +34 -0
- package/dist/vendor/node/NodeServices.js +23 -0
- package/dist/vendor/node/NodeSink.d.ts +8 -0
- package/dist/vendor/node/NodeSink.js +12 -0
- package/dist/vendor/node/NodeSocket.d.ts +38 -0
- package/dist/vendor/node/NodeSocket.js +31 -0
- package/dist/vendor/node/NodeSocketServer.d.ts +8 -0
- package/dist/vendor/node/NodeSocketServer.js +21 -0
- package/dist/vendor/node/NodeStdio.d.ts +11 -0
- package/dist/vendor/node/NodeStdio.js +10 -0
- package/dist/vendor/node/NodeStream.d.ts +8 -0
- package/dist/vendor/node/NodeStream.js +27 -0
- package/dist/vendor/node/NodeTerminal.d.ts +21 -0
- package/dist/vendor/node/NodeTerminal.js +10 -0
- package/dist/vendor/node/NodeWorker.d.ts +22 -0
- package/dist/vendor/node/NodeWorker.js +9 -0
- package/dist/vendor/node/NodeWorkerRunner.d.ts +12 -0
- package/dist/vendor/node/NodeWorkerRunner.js +7 -0
- package/dist/vendor/node/Undici.d.ts +28 -0
- package/dist/vendor/node/Undici.js +9 -0
- package/dist/vendor/node/index.d.ts +100 -0
- package/dist/vendor/node/index.js +115 -0
- package/dist/vendor/node-shared/LICENSE +21 -0
- package/dist/vendor/node-shared/NodeChildProcessSpawner.d.ts +57 -0
- package/dist/vendor/node-shared/NodeChildProcessSpawner.js +13 -0
- package/dist/vendor/node-shared/NodeClusterSocket.d.ts +22 -0
- package/dist/vendor/node-shared/NodeClusterSocket.js +11 -0
- package/dist/vendor/node-shared/NodeCrypto.d.ts +27 -0
- package/dist/vendor/node-shared/NodeCrypto.js +9 -0
- package/dist/vendor/node-shared/NodeFileSystem.d.ts +11 -0
- package/dist/vendor/node-shared/NodeFileSystem.js +8 -0
- package/dist/vendor/node-shared/NodeHttpCompression.d.ts +36 -0
- package/dist/vendor/node-shared/NodeHttpCompression.js +13 -0
- package/dist/vendor/node-shared/NodePath.d.ts +27 -0
- package/dist/vendor/node-shared/NodePath.js +11 -0
- package/dist/vendor/node-shared/NodeRuntime.d.ts +47 -0
- package/dist/vendor/node-shared/NodeRuntime.js +7 -0
- package/dist/vendor/node-shared/NodeSink.d.ts +69 -0
- package/dist/vendor/node-shared/NodeSink.js +11 -0
- package/dist/vendor/node-shared/NodeSocket.d.ts +134 -0
- package/dist/vendor/node-shared/NodeSocket.js +23 -0
- package/dist/vendor/node-shared/NodeSocketServer.d.ts +80 -0
- package/dist/vendor/node-shared/NodeSocketServer.js +20 -0
- package/dist/vendor/node-shared/NodeStdio.d.ts +12 -0
- package/dist/vendor/node-shared/NodeStdio.js +9 -0
- package/dist/vendor/node-shared/NodeStream.d.ts +179 -0
- package/dist/vendor/node-shared/NodeStream.js +26 -0
- package/dist/vendor/node-shared/NodeTerminal.d.ts +22 -0
- package/dist/vendor/node-shared/NodeTerminal.js +9 -0
- package/dist/vendor/node-shared/index.d.ts +56 -0
- package/dist/vendor/node-shared/index.js +58 -0
- package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
- package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.js +7 -0
- package/dist/vendor/node-shared/internal/utils.d.ts +2 -0
- package/dist/vendor/node-shared/internal/utils.js +7 -0
- package/dist/vendor/platform-node-shared.d.ts +56 -0
- package/dist/vendor/platform-node-shared.js +58 -0
- package/dist/vendor/platform-node.d.ts +100 -0
- package/dist/vendor/platform-node.js +115 -0
- package/docs/README.md +129 -0
- package/docs/api.md +553 -0
- package/docs/concepts/descriptor-relative-filesystem.md +181 -0
- package/docs/concepts/host-bundle.md +125 -0
- package/docs/concepts/process-containment.md +190 -0
- package/docs/guides/answer-run-ownership.md +87 -0
- package/docs/guides/configure-the-filesystem-helper.md +152 -0
- package/docs/guides/contain-child-processes.md +139 -0
- package/docs/guides/match-files-with-glob.md +151 -0
- package/docs/installation.md +204 -0
- package/docs/quickstart.md +147 -0
- package/docs/troubleshooting.md +130 -0
- package/package.json +202 -3
- package/src/AtomicFileSystem.ts +415 -0
- package/src/EgressHttpClient.ts +327 -0
- package/src/HostLiveness.ts +103 -0
- package/src/NodeHost.ts +253 -0
- package/src/ProcessConfinement.ts +363 -0
- package/src/ProcessReaper.ts +951 -0
- package/src/ProcessSandbox.ts +1307 -0
- package/src/ScopedProcess.ts +124 -0
- package/src/index.ts +44 -0
- package/src/internal/AtomicFileSystemExecutable.ts +379 -0
- package/src/internal/AtomicFileSystemProtocol.ts +502 -0
- package/src/internal/AtomicFileSystemTransport.ts +272 -0
- package/src/internal/AtomicHelperError.ts +50 -0
- package/src/internal/AtomicHelperFault.ts +84 -0
- package/src/internal/PipedProcess.ts +357 -0
- package/src/internal/ProcSnapshot.ts +193 -0
- package/src/internal/ProcessCleanup.ts +99 -0
- package/src/internal/ProcessCleanupPolicyError.ts +30 -0
- package/src/internal/ProcessFault.ts +82 -0
- package/src/internal/ProcessSupervisor.ts +807 -0
- package/src/internal/SupervisorProgram.ts +309 -0
- package/src/internal/WindowsProcessJob.ts +114 -0
|
@@ -0,0 +1,689 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Private parent connection for a POSIX process owner. Effect retains ownership
|
|
3
|
+
* of the caller's streams; separate sockets carry requests and lifetime status.
|
|
4
|
+
* @since 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
import * as Channel from "effect/Channel";
|
|
7
|
+
import * as Clock from "effect/Clock";
|
|
8
|
+
import * as Effect from "effect/Effect";
|
|
9
|
+
import * as PlatformError from "effect/PlatformError";
|
|
10
|
+
import * as Sink from "effect/Sink";
|
|
11
|
+
import * as Stream from "effect/Stream";
|
|
12
|
+
import * as ChildProcess from "effect/unstable/process/ChildProcess";
|
|
13
|
+
import { ExitCode, makeHandle } from "effect/unstable/process/ChildProcessSpawner";
|
|
14
|
+
import { randomBytes } from "node:crypto";
|
|
15
|
+
import { chmodSync, mkdtempSync, rmdirSync, rmSync } from "node:fs";
|
|
16
|
+
import { createConnection, createServer } from "node:net";
|
|
17
|
+
import { tmpdir } from "node:os";
|
|
18
|
+
import { join, parse, resolve } from "node:path";
|
|
19
|
+
import * as Tls from "node:tls";
|
|
20
|
+
import { standardFdsOf } from "./PipedProcess.js";
|
|
21
|
+
import { NativeProcessError, processFault } from "./ProcessFault.js";
|
|
22
|
+
import { source } from "./SupervisorProgram.js";
|
|
23
|
+
import { resolveJobExecutable, WindowsProcessJob } from "./WindowsProcessJob.js";
|
|
24
|
+
const startupMs = 5000;
|
|
25
|
+
const deliveryMs = 500;
|
|
26
|
+
const exitAllowanceMs = 2500;
|
|
27
|
+
// Host-wide process observations can exceed a socket-delivery deadline on a
|
|
28
|
+
// loaded machine. Keep verification bounded without mistaking that delay for
|
|
29
|
+
// an unclean exit; an unknown observation still never counts as success.
|
|
30
|
+
const verificationMs = 2500;
|
|
31
|
+
const targets = new WeakMap();
|
|
32
|
+
// Native owners and sockets keep running when the caller freezes its Clock.
|
|
33
|
+
// Their delivery bounds and cleanup retries must keep running with them.
|
|
34
|
+
const processClock = Clock.Clock.defaultValue();
|
|
35
|
+
/**
|
|
36
|
+
* Actual service pid, distinct from the owner recorded by the host.
|
|
37
|
+
* @private
|
|
38
|
+
* @since 1.0.0
|
|
39
|
+
*/
|
|
40
|
+
export const targetPidOf = (handle) => targets.get(handle)?.targetPid;
|
|
41
|
+
/** Native error fields remain data on the public PlatformError cause. */
|
|
42
|
+
const nativeError = (cause) => {
|
|
43
|
+
if (cause instanceof Error)
|
|
44
|
+
return cause;
|
|
45
|
+
const value = (cause ?? {});
|
|
46
|
+
const text = (field) => typeof value[field] === "string" ? value[field] : undefined;
|
|
47
|
+
return new NativeProcessError({
|
|
48
|
+
message: text("message") ?? "The process supervisor failed",
|
|
49
|
+
code: text("code"),
|
|
50
|
+
errno: typeof value.errno === "number" ? value.errno : undefined,
|
|
51
|
+
reason: text("reason"),
|
|
52
|
+
syscall: text("syscall"),
|
|
53
|
+
path: text("path"),
|
|
54
|
+
signal: text("signal")
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Preserve the platform's errno and signal vocabulary across the private wire.
|
|
59
|
+
* @private
|
|
60
|
+
* @since 1.0.0
|
|
61
|
+
*/
|
|
62
|
+
export const failure = (method, command, cause) => {
|
|
63
|
+
const error = nativeError(cause);
|
|
64
|
+
const tags = {
|
|
65
|
+
ENOENT: "NotFound",
|
|
66
|
+
EACCES: "PermissionDenied",
|
|
67
|
+
EEXIST: "AlreadyExists",
|
|
68
|
+
EISDIR: "BadResource",
|
|
69
|
+
ENOTDIR: "BadResource",
|
|
70
|
+
ELOOP: "BadResource",
|
|
71
|
+
EBUSY: "Busy"
|
|
72
|
+
};
|
|
73
|
+
return PlatformError.systemError({
|
|
74
|
+
_tag: tags[error.code ?? ""] ?? "Unknown",
|
|
75
|
+
module: "ChildProcess",
|
|
76
|
+
method,
|
|
77
|
+
pathOrDescriptor: command,
|
|
78
|
+
syscall: error.syscall,
|
|
79
|
+
description: error.message,
|
|
80
|
+
cause: error
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* The observation behind an unverified cleanup, in the message itself: a
|
|
85
|
+
* failure report usually shows only the message, and whether the receipt, the
|
|
86
|
+
* kernel or the snapshot was missing decides host load versus a live survivor.
|
|
87
|
+
* @private
|
|
88
|
+
* @since 1.0.0
|
|
89
|
+
*/
|
|
90
|
+
export const unverifiedCleanup = (control, cleanupRequired, vacant, observed) => [
|
|
91
|
+
`target exited: ${control.targetDone}`,
|
|
92
|
+
`cleanup receipt: ${control.cleanupFailed
|
|
93
|
+
? "failed"
|
|
94
|
+
: !cleanupRequired
|
|
95
|
+
? "not required"
|
|
96
|
+
: control.cleanupAcknowledged
|
|
97
|
+
? "acknowledged"
|
|
98
|
+
: "missing"}`,
|
|
99
|
+
`group vacant: ${vacant}`,
|
|
100
|
+
observed === undefined
|
|
101
|
+
? "group snapshot: unavailable"
|
|
102
|
+
: `group members: ${observed.members.length === 0
|
|
103
|
+
? "none"
|
|
104
|
+
: observed.members.map((member) => `${member.pid} ${member.zombie ? "zombie" : "live"}`).join(", ")}; host group ${observed.ownGroup}`,
|
|
105
|
+
...(control.fault === undefined
|
|
106
|
+
? []
|
|
107
|
+
: [`fault: ${String(control.fault?.message ?? control.fault)}`])
|
|
108
|
+
].join("; ");
|
|
109
|
+
const promise = () => {
|
|
110
|
+
let resolve;
|
|
111
|
+
let reject;
|
|
112
|
+
const promise = new Promise((yes, no) => {
|
|
113
|
+
resolve = yes;
|
|
114
|
+
reject = no;
|
|
115
|
+
});
|
|
116
|
+
// A status may arrive before its Effect consumer starts waiting.
|
|
117
|
+
void promise.catch(() => { });
|
|
118
|
+
return { promise, resolve, reject };
|
|
119
|
+
};
|
|
120
|
+
const wait = (value, method, command) => Effect.tryPromise({ try: () => value, catch: (cause) => failure(method, command, cause) });
|
|
121
|
+
const bounded = (effect, millis, method, command) => effect.pipe(Effect.timeoutOrElse({
|
|
122
|
+
duration: millis,
|
|
123
|
+
orElse: () => Effect.fail(failure(method, command, processFault("supervisor_timeout", `Process supervisor ${method} timed out`)))
|
|
124
|
+
}), Effect.provideService(Clock.Clock, processClock));
|
|
125
|
+
/**
|
|
126
|
+
* Standalone application executables do not implement the runtime's eval CLI.
|
|
127
|
+
* Refuse them before spawning rather than recursively launching the application.
|
|
128
|
+
* @private
|
|
129
|
+
* @since 1.0.0
|
|
130
|
+
*/
|
|
131
|
+
export const bootstrapArguments = (runtime) => runtime.sea || runtime.main.startsWith("/$bunfs/")
|
|
132
|
+
? Effect.fail(failure("spawn", process.execPath, processFault("runtime_unsupported", "Process supervision requires a Node or Bun runtime executable, not a compiled application")))
|
|
133
|
+
: Effect.succeed(runtime.bun ? ["--no-env-file", "--config=/dev/null"] : []);
|
|
134
|
+
const channelEnvironment = "SMITHERS_PROCESS_CHANNEL";
|
|
135
|
+
const tlsOptions = { minVersion: "TLSv1.3", maxVersion: "TLSv1.3", ciphers: "TLS_AES_128_GCM_SHA256" };
|
|
136
|
+
/**
|
|
137
|
+
* Connect an owner to its authenticated private channel.
|
|
138
|
+
* @private
|
|
139
|
+
* @since 1.0.0
|
|
140
|
+
*/
|
|
141
|
+
export const connectOwner = (path, environment) => {
|
|
142
|
+
const encoded = environment[channelEnvironment];
|
|
143
|
+
if (encoded === undefined)
|
|
144
|
+
return createConnection(path);
|
|
145
|
+
const channel = JSON.parse(encoded);
|
|
146
|
+
return Tls.connect({
|
|
147
|
+
...tlsOptions,
|
|
148
|
+
host: "127.0.0.1",
|
|
149
|
+
port: path.endsWith("/r") ? channel.requests : channel.status,
|
|
150
|
+
pskCallback: () => ({ identity: "smithers-owner", psk: Buffer.from(channel.key, "hex") })
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Kept separate from Effect scopes so native socket callbacks only settle
|
|
155
|
+
* promises; none can start an unowned fiber or signal an observed process id.
|
|
156
|
+
* @private
|
|
157
|
+
* @since 1.0.0
|
|
158
|
+
*/
|
|
159
|
+
export class Control {
|
|
160
|
+
ready = promise();
|
|
161
|
+
started = promise();
|
|
162
|
+
exited = promise();
|
|
163
|
+
lost = promise();
|
|
164
|
+
ended = promise();
|
|
165
|
+
requestsReady = promise();
|
|
166
|
+
directory;
|
|
167
|
+
path;
|
|
168
|
+
requestPath;
|
|
169
|
+
server;
|
|
170
|
+
requestServer;
|
|
171
|
+
listening;
|
|
172
|
+
key;
|
|
173
|
+
connections = new Set();
|
|
174
|
+
socket;
|
|
175
|
+
requestSocket;
|
|
176
|
+
targetDone = false;
|
|
177
|
+
ownerCreation;
|
|
178
|
+
targetPid;
|
|
179
|
+
/** The owner's group guardian: a member that is neither target nor owner. */
|
|
180
|
+
guardianPid;
|
|
181
|
+
ownerDone = false;
|
|
182
|
+
spawnFailed = false;
|
|
183
|
+
cleanupFailed = false;
|
|
184
|
+
cleanupAcknowledged = false;
|
|
185
|
+
activationSent = false;
|
|
186
|
+
closeSent = false;
|
|
187
|
+
fault;
|
|
188
|
+
onTargetExit = () => { };
|
|
189
|
+
onCleanup = () => { };
|
|
190
|
+
receivedReady = false;
|
|
191
|
+
receivedStarted = false;
|
|
192
|
+
withdrawn = false;
|
|
193
|
+
constructor(transport = "native") {
|
|
194
|
+
this.key = transport === "tls" || process.platform === "win32" ? randomBytes(32) : undefined;
|
|
195
|
+
this.directory = mkdtempSync(this.key === undefined ? "/tmp/sm-p-" : join(tmpdir(), "sm-p-"));
|
|
196
|
+
this.path = `${this.directory}/s`;
|
|
197
|
+
this.requestPath = `${this.directory}/r`;
|
|
198
|
+
const servers = [];
|
|
199
|
+
try {
|
|
200
|
+
chmodSync(this.directory, 0o700);
|
|
201
|
+
this.server = this.makeServer((socket) => this.accept(socket));
|
|
202
|
+
servers.push(this.server);
|
|
203
|
+
this.requestServer = this.makeServer((socket) => this.acceptRequests(socket));
|
|
204
|
+
servers.push(this.requestServer);
|
|
205
|
+
this.listening = Promise.all([
|
|
206
|
+
new Promise((resolve, reject) => {
|
|
207
|
+
this.server.once("error", reject);
|
|
208
|
+
if (this.key === undefined)
|
|
209
|
+
this.server.listen(this.path, resolve);
|
|
210
|
+
else
|
|
211
|
+
this.server.listen(0, "127.0.0.1", resolve);
|
|
212
|
+
}),
|
|
213
|
+
new Promise((resolve, reject) => {
|
|
214
|
+
this.requestServer.once("error", reject);
|
|
215
|
+
if (this.key === undefined)
|
|
216
|
+
this.requestServer.listen(this.requestPath, resolve);
|
|
217
|
+
else
|
|
218
|
+
this.requestServer.listen(0, "127.0.0.1", resolve);
|
|
219
|
+
})
|
|
220
|
+
]).then(() => { });
|
|
221
|
+
}
|
|
222
|
+
catch (cause) {
|
|
223
|
+
for (const server of servers)
|
|
224
|
+
server.close();
|
|
225
|
+
rmSync(this.directory, { recursive: true, force: true });
|
|
226
|
+
throw cause;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
makeServer(accept) {
|
|
230
|
+
if (this.key === undefined)
|
|
231
|
+
return createServer(accept);
|
|
232
|
+
const server = Tls.createServer({
|
|
233
|
+
...tlsOptions,
|
|
234
|
+
handshakeTimeout: startupMs,
|
|
235
|
+
pskCallback: (_socket, identity) => identity === "smithers-owner" ? this.key : null
|
|
236
|
+
}, accept);
|
|
237
|
+
server.on("connection", (socket) => {
|
|
238
|
+
this.connections.add(socket);
|
|
239
|
+
socket.once("close", () => this.connections.delete(socket));
|
|
240
|
+
});
|
|
241
|
+
server.on("tlsClientError", (_error, socket) => socket.destroy());
|
|
242
|
+
return server;
|
|
243
|
+
}
|
|
244
|
+
/** Only the trusted owner receives this environment; target configuration replaces it. */
|
|
245
|
+
environment() {
|
|
246
|
+
if (this.key === undefined)
|
|
247
|
+
return {};
|
|
248
|
+
const status = this.server.address();
|
|
249
|
+
const requests = this.requestServer.address();
|
|
250
|
+
return {
|
|
251
|
+
[channelEnvironment]: JSON.stringify({
|
|
252
|
+
key: this.key.toString("hex"),
|
|
253
|
+
status: status.port,
|
|
254
|
+
requests: requests.port
|
|
255
|
+
})
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/** The test peer uses the same authenticated transport as the isolated owner. */
|
|
259
|
+
connect(requests = false) {
|
|
260
|
+
return connectOwner(requests ? this.requestPath : this.path, this.environment());
|
|
261
|
+
}
|
|
262
|
+
/** Validate the stored READY after the raw spawn effect has returned its pid. */
|
|
263
|
+
withdraw(pid, actual) {
|
|
264
|
+
if (pid !== actual)
|
|
265
|
+
throw processFault("identity_mismatch", "Wrong supervisor identity");
|
|
266
|
+
this.server.close();
|
|
267
|
+
this.server.unref();
|
|
268
|
+
this.requestServer.close();
|
|
269
|
+
this.requestServer.unref();
|
|
270
|
+
// Node may unlink the owned socket synchronously inside server.close().
|
|
271
|
+
rmSync(this.path, { force: true });
|
|
272
|
+
rmSync(this.requestPath, { force: true });
|
|
273
|
+
rmdirSync(this.directory);
|
|
274
|
+
this.withdrawn = true;
|
|
275
|
+
}
|
|
276
|
+
/** Request EOF asks for cleanup; leave its independent status reader intact. */
|
|
277
|
+
disconnect() {
|
|
278
|
+
this.requestSocket?.destroy();
|
|
279
|
+
}
|
|
280
|
+
dispose() {
|
|
281
|
+
for (const socket of this.connections)
|
|
282
|
+
socket.destroy();
|
|
283
|
+
this.disconnect();
|
|
284
|
+
this.socket?.destroy();
|
|
285
|
+
this.server.close();
|
|
286
|
+
this.requestServer.close();
|
|
287
|
+
if (!this.withdrawn)
|
|
288
|
+
rmSync(this.directory, { recursive: true, force: true });
|
|
289
|
+
}
|
|
290
|
+
rawEnded() {
|
|
291
|
+
this.ownerDone = true;
|
|
292
|
+
// An accepted socket may still have buffered status frames. Its close event
|
|
293
|
+
// rejects missing outcomes only after Node has delivered those frames.
|
|
294
|
+
if (this.socket === undefined)
|
|
295
|
+
this.closed();
|
|
296
|
+
}
|
|
297
|
+
write(message) {
|
|
298
|
+
return new Promise((resolve, reject) => {
|
|
299
|
+
const socket = this.requestSocket;
|
|
300
|
+
if (socket === undefined || socket.destroyed || !socket.writable) {
|
|
301
|
+
reject(processFault("control_channel_closed", "Private process control channel closed"));
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const data = `${JSON.stringify(message)}\n`;
|
|
305
|
+
if (Buffer.byteLength(data) > 4 * 1024 * 1024) {
|
|
306
|
+
reject(processFault("configuration_too_large", "Process configuration exceeds the private frame limit"));
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
socket.write(data, (error) => error ? reject(error) : resolve());
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
closed() {
|
|
313
|
+
this.disconnect();
|
|
314
|
+
const cause = this.fault ??
|
|
315
|
+
processFault("outcome_missing", "Process supervisor closed before reporting its outcome");
|
|
316
|
+
if (this.activationSent && !this.targetDone && !this.spawnFailed)
|
|
317
|
+
this.lost.reject(cause);
|
|
318
|
+
this.ready.reject(cause);
|
|
319
|
+
this.requestsReady.reject(cause);
|
|
320
|
+
this.started.reject(cause);
|
|
321
|
+
this.exited.reject(cause);
|
|
322
|
+
this.ended.resolve();
|
|
323
|
+
}
|
|
324
|
+
acceptRequests(socket) {
|
|
325
|
+
if (this.requestSocket !== undefined) {
|
|
326
|
+
socket.destroy();
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
this.requestSocket = socket;
|
|
330
|
+
// A late write may fail after the owner has sent its last status frames.
|
|
331
|
+
// Destroying this socket must never discard those frames on the reader.
|
|
332
|
+
socket.on("error", (cause) => {
|
|
333
|
+
this.fault = cause;
|
|
334
|
+
});
|
|
335
|
+
this.requestsReady.resolve();
|
|
336
|
+
}
|
|
337
|
+
accept(socket) {
|
|
338
|
+
if (this.socket !== undefined) {
|
|
339
|
+
socket.destroy();
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
this.socket = socket;
|
|
343
|
+
let buffer = "";
|
|
344
|
+
socket.setEncoding("utf8");
|
|
345
|
+
socket.on("data", (data) => {
|
|
346
|
+
try {
|
|
347
|
+
buffer += data;
|
|
348
|
+
if (Buffer.byteLength(buffer) > 16 * 1024) {
|
|
349
|
+
throw processFault("status_too_large", "Process status frame exceeds its limit");
|
|
350
|
+
}
|
|
351
|
+
for (;;) {
|
|
352
|
+
const end = buffer.indexOf("\n");
|
|
353
|
+
if (end < 0)
|
|
354
|
+
break;
|
|
355
|
+
const line = buffer.slice(0, end);
|
|
356
|
+
buffer = buffer.slice(end + 1);
|
|
357
|
+
this.receive(JSON.parse(line));
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
catch (cause) {
|
|
361
|
+
this.fault = cause;
|
|
362
|
+
socket.destroy();
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
socket.on("error", (cause) => {
|
|
366
|
+
this.fault = cause;
|
|
367
|
+
});
|
|
368
|
+
socket.once("close", () => this.closed());
|
|
369
|
+
}
|
|
370
|
+
receive(value) {
|
|
371
|
+
if (typeof value !== "object" || value === null)
|
|
372
|
+
throw processFault("status_invalid", "Invalid process status");
|
|
373
|
+
const message = value;
|
|
374
|
+
switch (message.type) {
|
|
375
|
+
case "ready":
|
|
376
|
+
if (this.receivedReady || message.version !== 1 || !Number.isSafeInteger(message.pid) || Number(message.pid) <= 1) {
|
|
377
|
+
throw processFault("status_invalid", "Invalid process readiness");
|
|
378
|
+
}
|
|
379
|
+
this.receivedReady = true;
|
|
380
|
+
this.ownerCreation = message.created;
|
|
381
|
+
this.ready.resolve(Number(message.pid));
|
|
382
|
+
return;
|
|
383
|
+
case "spawned":
|
|
384
|
+
if (!this.activationSent || this.receivedStarted || !Number.isSafeInteger(message.pid) ||
|
|
385
|
+
Number(message.pid) <= 1 ||
|
|
386
|
+
message.guardian !== undefined && (!Number.isSafeInteger(message.guardian) || Number(message.guardian) <= 1)) {
|
|
387
|
+
throw processFault("status_invalid", "Invalid target startup");
|
|
388
|
+
}
|
|
389
|
+
this.receivedStarted = true;
|
|
390
|
+
this.targetPid = Number(message.pid);
|
|
391
|
+
if (message.guardian !== undefined)
|
|
392
|
+
this.guardianPid = Number(message.guardian);
|
|
393
|
+
this.started.resolve();
|
|
394
|
+
return;
|
|
395
|
+
case "spawn_error":
|
|
396
|
+
if (!this.activationSent || this.receivedStarted) {
|
|
397
|
+
throw processFault("status_invalid", "Invalid target spawn failure");
|
|
398
|
+
}
|
|
399
|
+
this.spawnFailed = true;
|
|
400
|
+
this.fault = message;
|
|
401
|
+
this.started.reject(message);
|
|
402
|
+
this.exited.reject(message);
|
|
403
|
+
return;
|
|
404
|
+
case "fault":
|
|
405
|
+
this.fault = message;
|
|
406
|
+
this.started.reject(message);
|
|
407
|
+
this.exited.reject(message);
|
|
408
|
+
return;
|
|
409
|
+
case "exit":
|
|
410
|
+
if (!this.receivedStarted || this.targetDone ||
|
|
411
|
+
!(Number.isInteger(message.code) && Number(message.code) >= 0 && message.signal === null ||
|
|
412
|
+
message.code === null && typeof message.signal === "string" && /^SIG[A-Z0-9]+$/.test(message.signal))) {
|
|
413
|
+
throw processFault("status_invalid", "Invalid target exit status");
|
|
414
|
+
}
|
|
415
|
+
this.targetDone = true;
|
|
416
|
+
if (message.code === null) {
|
|
417
|
+
this.exited.reject({
|
|
418
|
+
message: `Process interrupted due to receipt of signal: '${message.signal}'`,
|
|
419
|
+
signal: message.signal
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
else
|
|
423
|
+
this.exited.resolve(ExitCode(Number(message.code)));
|
|
424
|
+
this.onTargetExit();
|
|
425
|
+
return;
|
|
426
|
+
case "cleanup_error":
|
|
427
|
+
this.cleanupFailed = true;
|
|
428
|
+
this.fault = message;
|
|
429
|
+
return;
|
|
430
|
+
case "cleanup":
|
|
431
|
+
this.cleanupAcknowledged = true;
|
|
432
|
+
this.onCleanup();
|
|
433
|
+
return;
|
|
434
|
+
default:
|
|
435
|
+
throw processFault("status_unknown", "Unknown process status");
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Prepare a private, independently bounded process owner before target launch.
|
|
441
|
+
* @private
|
|
442
|
+
* @since 1.0.0
|
|
443
|
+
*/
|
|
444
|
+
export const prepare = (system, policy, transport = "native") => (command, spawn) => Effect.gen(function* () {
|
|
445
|
+
const initial = yield* policy(command.options);
|
|
446
|
+
const bun = process.versions.bun !== undefined;
|
|
447
|
+
const sea = bun ? false : (yield* Effect.tryPromise({
|
|
448
|
+
try: () => import("node:sea"),
|
|
449
|
+
catch: (cause) => failure("spawn", process.execPath, cause)
|
|
450
|
+
})).isSea();
|
|
451
|
+
const bootstrap = yield* bootstrapArguments({
|
|
452
|
+
bun,
|
|
453
|
+
sea,
|
|
454
|
+
main: globalThis.Bun?.main ?? ""
|
|
455
|
+
});
|
|
456
|
+
const windows = system.platform === "win32";
|
|
457
|
+
const grouped = !windows && (command.options.detached ?? true);
|
|
458
|
+
const jobExecutable = windows ?
|
|
459
|
+
yield* Effect.try({
|
|
460
|
+
try: resolveJobExecutable,
|
|
461
|
+
catch: (cause) => failure("spawn", command.command, cause)
|
|
462
|
+
}) :
|
|
463
|
+
undefined;
|
|
464
|
+
const control = yield* Effect.acquireRelease(Effect.try({ try: () => new Control(transport), catch: (cause) => failure("spawn", command.command, cause) }), (control) => Effect.sync(() => control.dispose()));
|
|
465
|
+
yield* bounded(wait(control.listening, "spawn", command.command), startupMs, "spawn", command.command);
|
|
466
|
+
const raw = yield* spawn(ChildProcess.make(process.execPath, [
|
|
467
|
+
...bootstrap,
|
|
468
|
+
"-e",
|
|
469
|
+
source,
|
|
470
|
+
control.path,
|
|
471
|
+
grouped ? "group" : "direct"
|
|
472
|
+
], {
|
|
473
|
+
...command.options,
|
|
474
|
+
cwd: parse(process.execPath).root,
|
|
475
|
+
env: {
|
|
476
|
+
PATH: "/usr/bin:/bin",
|
|
477
|
+
HOME: "/",
|
|
478
|
+
XDG_CONFIG_HOME: "/",
|
|
479
|
+
BUN_RUNTIME_TRANSPILER_CACHE_PATH: "0",
|
|
480
|
+
...control.environment(),
|
|
481
|
+
...(jobExecutable === undefined ? {} : { SMITHERS_PROCESS_JOB_HELPER: jobExecutable })
|
|
482
|
+
},
|
|
483
|
+
extendEnv: false,
|
|
484
|
+
shell: false,
|
|
485
|
+
detached: grouped,
|
|
486
|
+
killSignal: "SIGTERM",
|
|
487
|
+
forceKillAfter: initial.graceMs
|
|
488
|
+
}));
|
|
489
|
+
yield* Effect.exit(raw.exitCode).pipe(Effect.andThen(Effect.sync(() => control.rawEnded())), Effect.forkScoped);
|
|
490
|
+
let job;
|
|
491
|
+
let settled = false;
|
|
492
|
+
let referenced = true;
|
|
493
|
+
let reref = Effect.void;
|
|
494
|
+
let selected = initial;
|
|
495
|
+
let requireCleanupReceipt = false;
|
|
496
|
+
const snapshot = () => system.snapshot(raw.pid);
|
|
497
|
+
const alone = () => {
|
|
498
|
+
if (!grouped)
|
|
499
|
+
return control.targetDone;
|
|
500
|
+
const observed = snapshot();
|
|
501
|
+
if (observed === undefined || observed.ownGroup === raw.pid)
|
|
502
|
+
return false;
|
|
503
|
+
// The guardian leaves with the owner's final group SIGKILL.
|
|
504
|
+
const running = observed.members.filter((member) => !member.zombie && member.pid !== control.guardianPid);
|
|
505
|
+
return running.length === 1 && running[0].pid === raw.pid;
|
|
506
|
+
};
|
|
507
|
+
// This observation only shortens the owner's deadline. The live owner makes
|
|
508
|
+
// the signal, so neither a stale observation nor a reused pid grants a kill.
|
|
509
|
+
control.onTargetExit = () => {
|
|
510
|
+
// An explicit stop already owns its deadline and escaped-child sweep.
|
|
511
|
+
// Natural exit must not replace that policy with a second fast stop.
|
|
512
|
+
if (control.closeSent)
|
|
513
|
+
return;
|
|
514
|
+
if (!alone())
|
|
515
|
+
return;
|
|
516
|
+
control.closeSent = true;
|
|
517
|
+
void control.write({ type: "stop", killSignal: "SIGKILL", fast: true }).catch(() => control.disconnect());
|
|
518
|
+
};
|
|
519
|
+
const finish = yield* Effect.cached(Effect.gen(function* () {
|
|
520
|
+
yield* bounded(Effect.exit(raw.exitCode), selected.graceMs + exitAllowanceMs, "kill", command.command).pipe(Effect.catch((cause) => job === undefined ? Effect.fail(cause) : Effect.gen(function* () {
|
|
521
|
+
// The native guardian can terminate a stalled owner independently.
|
|
522
|
+
job.stop();
|
|
523
|
+
yield* bounded(Effect.exit(raw.exitCode), exitAllowanceMs, "kill", command.command);
|
|
524
|
+
})));
|
|
525
|
+
if (job !== undefined) {
|
|
526
|
+
yield* bounded(wait(job.settled.promise, "kill", command.command), 5500, "kill", command.command);
|
|
527
|
+
settled = true;
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
yield* bounded(wait(control.ended.promise, "kill", command.command), deliveryMs, "kill", command.command).pipe(Effect.ignore);
|
|
531
|
+
const deadline = Date.now() + verificationMs;
|
|
532
|
+
for (;;) {
|
|
533
|
+
// The kernel's ESRCH proves the group empty with no fork. A `ps`
|
|
534
|
+
// snapshot can go unanswered on a loaded host, so it only decides what
|
|
535
|
+
// the kernel cannot: a group still holding zombies, or an unknown one.
|
|
536
|
+
// A live member keeps both answers false. This host is alive, so a
|
|
537
|
+
// vacant group is never this host's own group.
|
|
538
|
+
const vacant = grouped && system.vacant(raw.pid);
|
|
539
|
+
const observed = grouped && !vacant ? snapshot() : undefined;
|
|
540
|
+
settled = !control.cleanupFailed && (!requireCleanupReceipt || control.cleanupAcknowledged) && (grouped
|
|
541
|
+
? vacant ||
|
|
542
|
+
observed !== undefined && observed.ownGroup !== raw.pid && observed.members.every((member) => member.zombie)
|
|
543
|
+
: control.targetDone || control.spawnFailed || !control.activationSent);
|
|
544
|
+
if (settled)
|
|
545
|
+
return;
|
|
546
|
+
if (Date.now() >= deadline) {
|
|
547
|
+
return yield* Effect.fail(failure("kill", command.command, processFault("cleanup_unverified", "Process cleanup could not be verified; its ledger record is retained " +
|
|
548
|
+
`(${unverifiedCleanup(control, requireCleanupReceipt, vacant, observed)})`, {
|
|
549
|
+
cause: {
|
|
550
|
+
fault: control.fault,
|
|
551
|
+
cleanupFailed: control.cleanupFailed,
|
|
552
|
+
cleanupRequired: requireCleanupReceipt,
|
|
553
|
+
cleanupAcknowledged: control.cleanupAcknowledged,
|
|
554
|
+
targetDone: control.targetDone,
|
|
555
|
+
groupVacant: vacant,
|
|
556
|
+
ownerObserved: observed !== undefined,
|
|
557
|
+
members: observed?.members
|
|
558
|
+
}
|
|
559
|
+
})));
|
|
560
|
+
}
|
|
561
|
+
yield* Effect.sleep(10).pipe(Effect.provideService(Clock.Clock, processClock));
|
|
562
|
+
}
|
|
563
|
+
}));
|
|
564
|
+
const kill = (options = {}) => Effect.gen(function* () {
|
|
565
|
+
const requested = yield* policy(options, command.options);
|
|
566
|
+
if (!referenced) {
|
|
567
|
+
job?.reference(true);
|
|
568
|
+
control.socket?.ref();
|
|
569
|
+
control.requestSocket?.ref();
|
|
570
|
+
yield* reref;
|
|
571
|
+
referenced = true;
|
|
572
|
+
}
|
|
573
|
+
if (!control.closeSent) {
|
|
574
|
+
control.closeSent = true;
|
|
575
|
+
selected = requested;
|
|
576
|
+
// An empty original group cannot prove an explicit escaped-descendant
|
|
577
|
+
// sweep succeeded if its status frames were lost. Startup and natural
|
|
578
|
+
// completion have no such additional contract.
|
|
579
|
+
requireCleanupReceipt = grouped && control.activationSent && !control.spawnFailed && !control.targetDone;
|
|
580
|
+
yield* bounded(wait(control.write({
|
|
581
|
+
type: "stop",
|
|
582
|
+
explicit: true,
|
|
583
|
+
...requested,
|
|
584
|
+
// A live target can move out of this group with setsid().
|
|
585
|
+
// Only an owner whose target was never activated can replace
|
|
586
|
+
// the requested signal; natural exit has its own fast path.
|
|
587
|
+
killSignal: !control.activationSent && alone() ? "SIGKILL" : requested.killSignal
|
|
588
|
+
}), "kill", command.command), deliveryMs, "kill", command.command)
|
|
589
|
+
.pipe(Effect.catch(() => Effect.sync(() => control.disconnect())));
|
|
590
|
+
}
|
|
591
|
+
yield* finish;
|
|
592
|
+
}).pipe(Effect.uninterruptible);
|
|
593
|
+
yield* Effect.addFinalizer(() => kill().pipe(
|
|
594
|
+
// A stuck owner keeps its ledger entry. Disable the underlying spawner's
|
|
595
|
+
// unconditional group-kill finalizer rather than signal a stale identity.
|
|
596
|
+
Effect.ensuring(Effect.suspend(() => settled ? Effect.void : Effect.andThen(raw.unref, Effect.sync(() => {
|
|
597
|
+
job?.stop();
|
|
598
|
+
job?.reference(false);
|
|
599
|
+
control.disconnect();
|
|
600
|
+
}))).pipe(Effect.orDie)), Effect.orDie));
|
|
601
|
+
const ready = yield* bounded(wait(control.ready.promise, "spawn", command.command), startupMs, "spawn", command.command);
|
|
602
|
+
yield* bounded(wait(control.requestsReady.promise, "spawn", command.command), startupMs, "spawn", command.command);
|
|
603
|
+
yield* Effect.try({
|
|
604
|
+
try: () => control.withdraw(ready, raw.pid),
|
|
605
|
+
catch: (cause) => failure("spawn", command.command, cause)
|
|
606
|
+
});
|
|
607
|
+
if (windows) {
|
|
608
|
+
job = yield* Effect.try({
|
|
609
|
+
try: () => new WindowsProcessJob(raw.pid, control.ownerCreation, jobExecutable),
|
|
610
|
+
catch: (cause) => failure("spawn", command.command, cause)
|
|
611
|
+
});
|
|
612
|
+
yield* bounded(wait(job.ready.promise, "spawn", command.command), startupMs, "spawn", command.command);
|
|
613
|
+
}
|
|
614
|
+
const acknowledgeCleanup = windows || transport === "tls";
|
|
615
|
+
if (acknowledgeCleanup) {
|
|
616
|
+
control.onCleanup = () => {
|
|
617
|
+
if (!control.ownerDone) {
|
|
618
|
+
void control.write({ type: "cleanup_ack" }).catch(() => control.disconnect());
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
const options = command.options;
|
|
623
|
+
// Match Effect/Node's undefined-vs-empty environment semantics in the host,
|
|
624
|
+
// before replacing the helper's environment with its isolated bootstrap.
|
|
625
|
+
const env = options.extendEnv ? { ...process.env, ...options.env } : options.env ?? { ...process.env };
|
|
626
|
+
yield* bounded(wait(control.write({
|
|
627
|
+
type: "configure",
|
|
628
|
+
acknowledgeCleanup,
|
|
629
|
+
command: command.command,
|
|
630
|
+
args: command.args,
|
|
631
|
+
cwd: resolve(options.cwd ?? process.cwd()),
|
|
632
|
+
env,
|
|
633
|
+
shell: options.shell,
|
|
634
|
+
windowsHide: options.windowsHide ?? true,
|
|
635
|
+
windowsVerbatimArguments: options
|
|
636
|
+
.windowsVerbatimArguments,
|
|
637
|
+
standardFds: standardFdsOf(raw),
|
|
638
|
+
userFds: [
|
|
639
|
+
...new Set(Object.keys(options.additionalFds ?? {}).map(ChildProcess.parseFdName)
|
|
640
|
+
.filter((fd) => fd !== undefined))
|
|
641
|
+
],
|
|
642
|
+
...initial
|
|
643
|
+
}), "spawn", command.command), deliveryMs, "spawn", command.command);
|
|
644
|
+
const activate = yield* Effect.cached(Effect.gen(function* () {
|
|
645
|
+
control.activationSent = true;
|
|
646
|
+
yield* bounded(wait(control.write({ type: "start" }), "spawn", command.command), deliveryMs, "spawn", command.command);
|
|
647
|
+
yield* bounded(wait(control.started.promise, "spawn", command.command), startupMs, "spawn", command.command);
|
|
648
|
+
}));
|
|
649
|
+
const unref = Effect.gen(function* () {
|
|
650
|
+
if (referenced) {
|
|
651
|
+
reref = yield* raw.unref;
|
|
652
|
+
job?.reference(false);
|
|
653
|
+
control.socket?.unref();
|
|
654
|
+
control.requestSocket?.unref();
|
|
655
|
+
referenced = false;
|
|
656
|
+
}
|
|
657
|
+
return Effect.gen(function* () {
|
|
658
|
+
if (!referenced) {
|
|
659
|
+
job?.reference(true);
|
|
660
|
+
control.socket?.ref();
|
|
661
|
+
control.requestSocket?.ref();
|
|
662
|
+
yield* reref;
|
|
663
|
+
referenced = true;
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
});
|
|
667
|
+
const output = (stream) => stream.pipe(Stream.interruptWhen(wait(control.lost.promise, "read", command.command)));
|
|
668
|
+
const input = (sink) => Sink.fromChannel(Sink.toChannel(sink).pipe(Channel.interruptWhen(wait(control.lost.promise, "write", command.command))));
|
|
669
|
+
const handle = makeHandle({
|
|
670
|
+
...raw,
|
|
671
|
+
exitCode: wait(control.exited.promise, "exitCode", command.command),
|
|
672
|
+
isRunning: Effect.sync(() => !control.targetDone && !control.ownerDone),
|
|
673
|
+
stdin: input(raw.stdin),
|
|
674
|
+
getInputFd: (fd) => input(raw.getInputFd(fd)),
|
|
675
|
+
stdout: output(raw.stdout),
|
|
676
|
+
stderr: output(raw.stderr),
|
|
677
|
+
all: output(raw.all),
|
|
678
|
+
getOutputFd: (fd) => output(raw.getOutputFd(fd)),
|
|
679
|
+
kill,
|
|
680
|
+
unref
|
|
681
|
+
});
|
|
682
|
+
targets.set(handle, control);
|
|
683
|
+
return {
|
|
684
|
+
handle,
|
|
685
|
+
activate,
|
|
686
|
+
settled: Effect.sync(() => settled)
|
|
687
|
+
};
|
|
688
|
+
});
|
|
689
|
+
//# sourceMappingURL=ProcessSupervisor.js.map
|