@smthrs/platform-node 1.0.0-rc.5 → 1.0.0-rc.7
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/README.md +12 -12
- package/bin/win32-x64/smithers-jj-export.exe +0 -0
- package/dist/cjs/EgressHttpClient.d.ts +1 -1
- package/dist/cjs/EgressHttpClient.d.ts.map +1 -1
- package/dist/cjs/EgressHttpClient.js +4 -4
- package/dist/cjs/EgressHttpClient.js.map +2 -2
- package/dist/cjs/NodeHost.d.ts +2 -2
- package/dist/cjs/NodeHost.d.ts.map +1 -1
- package/dist/cjs/NodeHost.js.map +2 -2
- package/dist/cjs/ProcessConfinement.js +1 -1
- package/dist/cjs/ProcessConfinement.js.map +2 -2
- package/dist/cjs/ProcessReaper.d.ts +1 -1
- package/dist/cjs/ProcessReaper.d.ts.map +1 -1
- package/dist/cjs/ProcessReaper.js +1 -1
- package/dist/cjs/ProcessReaper.js.map +1 -1
- package/dist/cjs/ScopedProcess.d.ts +2 -2
- package/dist/cjs/ScopedProcess.d.ts.map +1 -1
- package/dist/cjs/ScopedProcess.js +1 -1
- package/dist/cjs/ScopedProcess.js.map +2 -2
- package/dist/cjs/internal/PipedProcess.d.ts +2 -2
- package/dist/cjs/internal/PipedProcess.d.ts.map +1 -1
- package/dist/cjs/internal/PipedProcess.js +2 -2
- package/dist/cjs/internal/PipedProcess.js.map +2 -2
- package/dist/cjs/internal/ProcessCleanup.d.ts +1 -1
- package/dist/cjs/internal/ProcessCleanup.d.ts.map +1 -1
- package/dist/cjs/internal/ProcessCleanup.js.map +1 -1
- package/dist/cjs/internal/ProcessSupervisor.d.ts +2 -2
- package/dist/cjs/internal/ProcessSupervisor.d.ts.map +1 -1
- package/dist/cjs/internal/ProcessSupervisor.js +2 -2
- package/dist/cjs/internal/ProcessSupervisor.js.map +2 -2
- package/dist/esm/EgressHttpClient.d.ts +1 -1
- package/dist/esm/EgressHttpClient.d.ts.map +1 -1
- package/dist/esm/EgressHttpClient.js +4 -4
- package/dist/esm/EgressHttpClient.js.map +1 -1
- package/dist/esm/NodeHost.d.ts +2 -2
- package/dist/esm/NodeHost.d.ts.map +1 -1
- package/dist/esm/NodeHost.js.map +1 -1
- package/dist/esm/ProcessConfinement.js +1 -1
- package/dist/esm/ProcessConfinement.js.map +1 -1
- package/dist/esm/ProcessReaper.d.ts +1 -1
- package/dist/esm/ProcessReaper.d.ts.map +1 -1
- package/dist/esm/ProcessReaper.js +1 -1
- package/dist/esm/ProcessReaper.js.map +1 -1
- package/dist/esm/ScopedProcess.d.ts +2 -2
- package/dist/esm/ScopedProcess.d.ts.map +1 -1
- package/dist/esm/ScopedProcess.js +1 -1
- package/dist/esm/ScopedProcess.js.map +1 -1
- package/dist/esm/internal/PipedProcess.d.ts +2 -2
- package/dist/esm/internal/PipedProcess.d.ts.map +1 -1
- package/dist/esm/internal/PipedProcess.js +2 -2
- package/dist/esm/internal/PipedProcess.js.map +1 -1
- package/dist/esm/internal/ProcessCleanup.d.ts +1 -1
- package/dist/esm/internal/ProcessCleanup.d.ts.map +1 -1
- package/dist/esm/internal/ProcessCleanup.js.map +1 -1
- package/dist/esm/internal/ProcessSupervisor.d.ts +2 -2
- package/dist/esm/internal/ProcessSupervisor.d.ts.map +1 -1
- package/dist/esm/internal/ProcessSupervisor.js +2 -2
- package/dist/esm/internal/ProcessSupervisor.js.map +1 -1
- package/dist/vendor/adapters.json +622 -382
- package/dist/vendor/{chunk-42QKY6T6.js → chunk-2ZAGBWTH.js} +1 -1
- package/dist/vendor/{chunk-3GR5VZ2M.js → chunk-3SL3HKQA.js} +3 -3
- package/dist/vendor/{chunk-VANKHF46.js → chunk-423HXGL6.js} +55 -23
- package/dist/vendor/{chunk-6ME2W7TF.js → chunk-4WIQ2XN7.js} +2 -2
- package/dist/vendor/{chunk-Y35ZAO5U.js → chunk-6FSJ2PMW.js} +8 -8
- package/dist/vendor/{chunk-5ZMHBXIK.js → chunk-6L2NJEOV.js} +11 -4
- package/dist/vendor/{chunk-TFIKFFSC.js → chunk-7NMJM44J.js} +2 -2
- package/dist/vendor/{chunk-OXNGN5H7.js → chunk-A7UXCEJA.js} +1 -1
- package/dist/vendor/chunk-ADP5LRUF.js +274 -0
- package/dist/vendor/{chunk-DS7GF46S.js → chunk-AWNTTSHL.js} +2 -2
- package/dist/vendor/{chunk-IIJ52ZU6.js → chunk-BUKVIAEM.js} +2 -2
- package/dist/vendor/{chunk-BKTBUBQY.js → chunk-BY3SDXID.js} +71 -7
- package/dist/vendor/{chunk-JJ24ARBQ.js → chunk-C3PGUWW5.js} +53 -33
- package/dist/vendor/{chunk-J7A4CZDO.js → chunk-D2ZL4PLZ.js} +8 -7
- package/dist/vendor/{chunk-XDKNKFBW.js → chunk-D4HEMNGU.js} +2 -2
- package/dist/vendor/{chunk-DVOAHXPG.js → chunk-FFD6R5JZ.js} +3 -3
- package/dist/vendor/{chunk-UFH5UUZK.js → chunk-HDV6VIRM.js} +1 -1
- package/dist/vendor/chunk-IWSDM4CG.js +16 -0
- package/dist/vendor/{chunk-KUUXSID7.js → chunk-KABHKTVG.js} +2 -2
- package/dist/vendor/{chunk-B3FZ67QU.js → chunk-KFDBU6RR.js} +4 -3
- package/dist/vendor/chunk-LNWGIDIG.js +20 -0
- package/dist/vendor/{chunk-TXKLEBBL.js → chunk-MUEED3C3.js} +3 -2
- package/dist/vendor/{chunk-EZWY45HP.js → chunk-N6TK35N5.js} +2 -2
- package/dist/vendor/{chunk-QPLDT6A6.js → chunk-NQO6V4KI.js} +29 -13
- package/dist/vendor/{chunk-AMQKOQNT.js → chunk-NTEWGPPG.js} +9 -9
- package/dist/vendor/chunk-NUJQMLJP.js +325 -0
- package/dist/vendor/{chunk-54RLBMTZ.js → chunk-OF3N2FN4.js} +1 -1
- package/dist/vendor/{chunk-RO2R4MJH.js → chunk-PA32ARKD.js} +17 -17
- package/dist/vendor/{chunk-JG5TTWPT.js → chunk-PECOFLCU.js} +3 -3
- package/dist/vendor/{chunk-VZBDV3TV.js → chunk-PU7QVYND.js} +2 -2
- package/dist/vendor/{chunk-2Y7WC4KU.js → chunk-QHR2RC5M.js} +2 -2
- package/dist/vendor/{chunk-QYBKAIA6.js → chunk-R327POEZ.js} +2 -2
- package/dist/vendor/chunk-RKVXYKHJ.js +29 -0
- package/dist/vendor/{chunk-XH4U3JSV.js → chunk-RQH5DSBA.js} +2 -2
- package/dist/vendor/{chunk-DWSHTSVX.js → chunk-S6QUQLBV.js} +5 -5
- package/dist/vendor/{chunk-KOZMM5PZ.js → chunk-UPIQ52FQ.js} +12 -12
- package/dist/vendor/{chunk-EGBNVEEW.js → chunk-UUQXJRMK.js} +1 -1
- package/dist/vendor/{chunk-LEUPYT3Q.js → chunk-UUYTTEDH.js} +1 -1
- package/dist/vendor/{chunk-NBVRTDTV.js → chunk-V2EB7FHY.js} +2 -2
- package/dist/vendor/{chunk-M32LDTW7.js → chunk-VIWU4EBF.js} +2 -2
- package/dist/vendor/{chunk-SIR62W3Y.js → chunk-VWSWEUN5.js} +51 -31
- package/dist/vendor/{chunk-MBSKBQ5D.js → chunk-WPZDL2D7.js} +1 -1
- package/dist/vendor/chunk-YDY5P7GL.js +20 -0
- package/dist/vendor/{chunk-FNZOJHSV.js → chunk-YFD4QFIL.js} +17 -17
- package/dist/vendor/{chunk-GXCHI7BM.js → chunk-ZVJCBTJG.js} +5 -5
- package/dist/vendor/cjs/node/NodeAddressResolver.d.ts +16 -0
- package/dist/vendor/cjs/node/NodeAddressResolver.js +1 -0
- package/dist/vendor/cjs/node/NodeChildProcessSpawner.d.ts +1 -0
- package/dist/vendor/cjs/node/NodeClusterHttp.d.ts +13 -22
- package/dist/vendor/cjs/node/NodeClusterSocket.d.ts +14 -8
- package/dist/vendor/cjs/node/NodeCrypto.d.ts +1 -0
- package/dist/vendor/cjs/node/NodeDatagramSocket.d.ts +10 -0
- package/dist/vendor/cjs/node/NodeDatagramSocket.js +1 -0
- package/dist/vendor/cjs/node/NodeDns.d.ts +51 -0
- package/dist/vendor/cjs/node/NodeDns.js +1 -0
- package/dist/vendor/cjs/node/NodeFileSystem.d.ts +1 -0
- package/dist/vendor/cjs/node/NodeHttpClient.d.ts +21 -2
- package/dist/vendor/cjs/node/NodeHttpIncomingMessage.d.ts +5 -3
- package/dist/vendor/cjs/node/NodeHttpPlatform.d.ts +8 -6
- package/dist/vendor/cjs/node/NodeHttpServer.d.ts +21 -10
- package/dist/vendor/cjs/node/NodeHttpServerRequest.d.ts +4 -1
- package/dist/vendor/cjs/node/NodeMultipart.d.ts +5 -1
- package/dist/vendor/cjs/node/NodeMultipartParser.d.ts +9 -1
- package/dist/vendor/cjs/node/NodePath.d.ts +3 -0
- package/dist/vendor/cjs/node/NodeRedis.d.ts +5 -1
- package/dist/vendor/cjs/node/NodeRuntime.d.ts +3 -0
- package/dist/vendor/cjs/node/NodeServices.d.ts +4 -1
- package/dist/vendor/cjs/node/NodeSink.d.ts +1 -0
- package/dist/vendor/cjs/node/NodeSocket.d.ts +10 -3
- package/dist/vendor/cjs/node/NodeSocketServer.d.ts +1 -0
- package/dist/vendor/cjs/node/NodeStdio.d.ts +1 -0
- package/dist/vendor/cjs/node/NodeStream.d.ts +1 -0
- package/dist/vendor/cjs/node/NodeTerminal.d.ts +6 -3
- package/dist/vendor/cjs/node/NodeWorker.d.ts +3 -1
- package/dist/vendor/cjs/node/NodeWorkerRunner.d.ts +2 -1
- package/dist/vendor/cjs/node/Undici.d.ts +3 -0
- package/dist/vendor/cjs/node/index.d.ts +40 -0
- package/dist/vendor/cjs/node-shared/NodeAddressResolver.d.ts +13 -0
- package/dist/vendor/cjs/node-shared/NodeAddressResolver.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.d.ts +12 -3
- package/dist/vendor/cjs/node-shared/NodeClusterSocket.d.ts +17 -4
- package/dist/vendor/cjs/node-shared/NodeCrypto.d.ts +3 -0
- package/dist/vendor/cjs/node-shared/NodeDatagramSocket.d.ts +246 -0
- package/dist/vendor/cjs/node-shared/NodeDatagramSocket.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeDns.d.ts +221 -0
- package/dist/vendor/cjs/node-shared/NodeDns.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeFileSystem.d.ts +1 -0
- package/dist/vendor/cjs/node-shared/NodeHttpCompression.d.ts +5 -1
- package/dist/vendor/cjs/node-shared/NodePath.d.ts +3 -0
- package/dist/vendor/cjs/node-shared/NodeRuntime.d.ts +4 -0
- package/dist/vendor/cjs/node-shared/NodeSink.d.ts +4 -0
- package/dist/vendor/cjs/node-shared/NodeSocket.d.ts +11 -1
- package/dist/vendor/cjs/node-shared/NodeSocketServer.d.ts +8 -1
- package/dist/vendor/cjs/node-shared/NodeStdio.d.ts +1 -0
- package/dist/vendor/cjs/node-shared/NodeStream.d.ts +15 -0
- package/dist/vendor/cjs/node-shared/NodeTerminal.d.ts +6 -4
- package/dist/vendor/cjs/node-shared/index.d.ts +29 -0
- package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.d.ts +1 -1
- package/dist/vendor/cjs/platform-node-shared.d.ts +29 -0
- package/dist/vendor/cjs/platform-node.d.ts +40 -0
- package/dist/vendor/node/NodeAddressResolver.d.ts +16 -0
- package/dist/vendor/node/NodeAddressResolver.js +8 -0
- package/dist/vendor/node/NodeChildProcessSpawner.d.ts +1 -0
- package/dist/vendor/node/NodeChildProcessSpawner.js +6 -6
- package/dist/vendor/node/NodeClusterHttp.d.ts +13 -22
- package/dist/vendor/node/NodeClusterHttp.js +32 -32
- package/dist/vendor/node/NodeClusterSocket.d.ts +14 -8
- package/dist/vendor/node/NodeClusterSocket.js +15 -15
- package/dist/vendor/node/NodeCrypto.d.ts +1 -0
- package/dist/vendor/node/NodeCrypto.js +2 -2
- package/dist/vendor/node/NodeDatagramSocket.d.ts +10 -0
- package/dist/vendor/node/NodeDatagramSocket.js +12 -0
- package/dist/vendor/node/NodeDns.d.ts +51 -0
- package/dist/vendor/node/NodeDns.js +12 -0
- package/dist/vendor/node/NodeFileSystem.d.ts +1 -0
- package/dist/vendor/node/NodeFileSystem.js +3 -3
- package/dist/vendor/node/NodeHttpClient.d.ts +21 -2
- package/dist/vendor/node/NodeHttpClient.js +6 -6
- package/dist/vendor/node/NodeHttpIncomingMessage.d.ts +5 -3
- package/dist/vendor/node/NodeHttpIncomingMessage.js +4 -4
- package/dist/vendor/node/NodeHttpPlatform.d.ts +8 -6
- package/dist/vendor/node/NodeHttpPlatform.js +8 -8
- package/dist/vendor/node/NodeHttpServer.d.ts +21 -10
- package/dist/vendor/node/NodeHttpServer.js +26 -26
- package/dist/vendor/node/NodeHttpServerRequest.d.ts +4 -1
- package/dist/vendor/node/NodeHttpServerRequest.js +1 -1
- package/dist/vendor/node/NodeMultipart.d.ts +5 -1
- package/dist/vendor/node/NodeMultipart.js +5 -5
- package/dist/vendor/node/NodeMultipartParser.d.ts +9 -1
- package/dist/vendor/node/NodeMultipartParser.js +1 -1
- package/dist/vendor/node/NodePath.d.ts +3 -0
- package/dist/vendor/node/NodePath.js +2 -2
- package/dist/vendor/node/NodeRedis.d.ts +5 -1
- package/dist/vendor/node/NodeRedis.js +1 -1
- package/dist/vendor/node/NodeRuntime.d.ts +3 -0
- package/dist/vendor/node/NodeRuntime.js +2 -2
- package/dist/vendor/node/NodeServices.d.ts +4 -1
- package/dist/vendor/node/NodeServices.js +17 -17
- package/dist/vendor/node/NodeSink.d.ts +1 -0
- package/dist/vendor/node/NodeSink.js +2 -2
- package/dist/vendor/node/NodeSocket.d.ts +10 -3
- package/dist/vendor/node/NodeSocket.js +2 -2
- package/dist/vendor/node/NodeSocketServer.d.ts +1 -0
- package/dist/vendor/node/NodeSocketServer.js +3 -3
- package/dist/vendor/node/NodeStdio.d.ts +1 -0
- package/dist/vendor/node/NodeStdio.js +4 -4
- package/dist/vendor/node/NodeStream.d.ts +1 -0
- package/dist/vendor/node/NodeStream.js +3 -3
- package/dist/vendor/node/NodeTerminal.d.ts +6 -3
- package/dist/vendor/node/NodeTerminal.js +2 -2
- package/dist/vendor/node/NodeWorker.d.ts +3 -1
- package/dist/vendor/node/NodeWorker.js +1 -1
- package/dist/vendor/node/NodeWorkerRunner.d.ts +2 -1
- package/dist/vendor/node/NodeWorkerRunner.js +1 -1
- package/dist/vendor/node/Undici.d.ts +3 -0
- package/dist/vendor/node/Undici.js +1 -1
- package/dist/vendor/node/index.d.ts +40 -0
- package/dist/vendor/node/index.js +70 -55
- package/dist/vendor/node-shared/NodeAddressResolver.d.ts +13 -0
- package/dist/vendor/node-shared/NodeAddressResolver.js +7 -0
- package/dist/vendor/node-shared/NodeChildProcessSpawner.d.ts +12 -3
- package/dist/vendor/node-shared/NodeChildProcessSpawner.js +5 -5
- package/dist/vendor/node-shared/NodeClusterSocket.d.ts +17 -4
- package/dist/vendor/node-shared/NodeClusterSocket.js +3 -3
- package/dist/vendor/node-shared/NodeCrypto.d.ts +3 -0
- package/dist/vendor/node-shared/NodeCrypto.js +1 -1
- package/dist/vendor/node-shared/NodeDatagramSocket.d.ts +246 -0
- package/dist/vendor/node-shared/NodeDatagramSocket.js +11 -0
- package/dist/vendor/node-shared/NodeDns.d.ts +221 -0
- package/dist/vendor/node-shared/NodeDns.js +31 -0
- package/dist/vendor/node-shared/NodeFileSystem.d.ts +1 -0
- package/dist/vendor/node-shared/NodeFileSystem.js +2 -2
- package/dist/vendor/node-shared/NodeHttpCompression.d.ts +5 -1
- package/dist/vendor/node-shared/NodeHttpCompression.js +1 -1
- package/dist/vendor/node-shared/NodePath.d.ts +3 -0
- package/dist/vendor/node-shared/NodePath.js +1 -1
- package/dist/vendor/node-shared/NodeRuntime.d.ts +4 -0
- package/dist/vendor/node-shared/NodeRuntime.js +1 -1
- package/dist/vendor/node-shared/NodeSink.d.ts +4 -0
- package/dist/vendor/node-shared/NodeSink.js +1 -1
- package/dist/vendor/node-shared/NodeSocket.d.ts +11 -1
- package/dist/vendor/node-shared/NodeSocket.js +1 -1
- package/dist/vendor/node-shared/NodeSocketServer.d.ts +8 -1
- package/dist/vendor/node-shared/NodeSocketServer.js +2 -2
- package/dist/vendor/node-shared/NodeStdio.d.ts +1 -0
- package/dist/vendor/node-shared/NodeStdio.js +3 -3
- package/dist/vendor/node-shared/NodeStream.d.ts +15 -0
- package/dist/vendor/node-shared/NodeStream.js +2 -2
- package/dist/vendor/node-shared/NodeTerminal.d.ts +6 -4
- package/dist/vendor/node-shared/NodeTerminal.js +1 -1
- package/dist/vendor/node-shared/index.d.ts +29 -0
- package/dist/vendor/node-shared/index.js +34 -22
- package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.d.ts +1 -1
- package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.js +1 -1
- package/dist/vendor/node-shared/internal/utils.js +1 -1
- package/dist/vendor/platform-node-shared.d.ts +29 -0
- package/dist/vendor/platform-node-shared.js +34 -22
- package/dist/vendor/platform-node.d.ts +40 -0
- package/dist/vendor/platform-node.js +70 -55
- package/docs/README.md +2 -2
- package/docs/api.md +2 -2
- package/docs/concepts/host-bundle.md +2 -2
- package/docs/installation.md +8 -9
- package/docs/quickstart.md +2 -2
- package/package.json +12 -12
- package/src/EgressHttpClient.ts +4 -4
- package/src/NodeHost.ts +2 -2
- package/src/ProcessConfinement.ts +1 -1
- package/src/ProcessReaper.ts +2 -2
- package/src/ScopedProcess.ts +2 -2
- package/src/internal/PipedProcess.ts +2 -2
- package/src/internal/ProcessCleanup.ts +1 -1
- package/src/internal/ProcessSupervisor.ts +2 -2
- /package/dist/vendor/{chunk-M7CLUILA.js → chunk-3WUGYBFU.js} +0 -0
- /package/dist/vendor/{chunk-ZJMRMY57.js → chunk-ASGOJ3XA.js} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/internal/ProcessSupervisor.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Private parent connection for a POSIX process owner. Effect retains ownership\n * of the caller's streams; separate sockets carry requests and lifetime status.\n * @since 1.0.0\n */\n\nimport type { Lifecycle } from \"@smthrs/kernel/ContainedSpawner\"\nimport * as Channel from \"effect/Channel\"\nimport * as Clock from \"effect/Clock\"\nimport * as Effect from \"effect/Effect\"\nimport * as PlatformError from \"effect/PlatformError\"\nimport * as Sink from \"effect/Sink\"\nimport * as Stream from \"effect/Stream\"\nimport * as ChildProcess from \"effect/unstable/process/ChildProcess\"\nimport { type ChildProcessHandle, ExitCode, makeHandle } from \"effect/unstable/process/ChildProcessSpawner\"\nimport { randomBytes } from \"node:crypto\"\nimport { chmodSync, mkdtempSync, rmdirSync, rmSync } from \"node:fs\"\nimport { createConnection, createServer, type Socket } from \"node:net\"\nimport { tmpdir } from \"node:os\"\nimport { join, parse, resolve } from \"node:path\"\nimport * as Tls from \"node:tls\"\nimport { standardFdsOf } from \"./PipedProcess.ts\"\nimport type { Policy, Snapshot, System } from \"./ProcessCleanup.ts\"\nimport { NativeProcessError, processFault } from \"./ProcessFault.ts\"\nimport { source } from \"./SupervisorProgram.ts\"\nimport { resolveJobExecutable, WindowsProcessJob } from \"./WindowsProcessJob.ts\"\n\nconst startupMs = 5000\nconst deliveryMs = 500\nconst exitAllowanceMs = 2500\n// Host-wide process observations can exceed a socket-delivery deadline on a\n// loaded machine. Keep verification bounded without mistaking that delay for\n// an unclean exit; an unknown observation still never counts as success.\nconst verificationMs = 2500\nconst targets = new WeakMap<ChildProcessHandle, Control>()\n// Native owners and sockets keep running when the caller freezes its Clock.\n// Their delivery bounds and cleanup retries must keep running with them.\nconst processClock = Clock.Clock.defaultValue()\n\n/**\n * Actual service pid, distinct from the owner recorded by the host.\n * @private\n * @since 1.0.0\n */\nexport const targetPidOf = (handle: ChildProcessHandle): number | undefined => targets.get(handle)?.targetPid\n\n/** Native error fields remain data on the public PlatformError cause. */\nconst nativeError = (cause: unknown): Error & { code?: string | undefined; syscall?: string | undefined } => {\n if (cause instanceof Error) return cause\n const value = (cause ?? {}) as Record<string, unknown>\n const text = (field: string): string | undefined => typeof value[field] === \"string\" ? value[field] : undefined\n return new NativeProcessError({\n message: text(\"message\") ?? \"The process supervisor failed\",\n code: text(\"code\"),\n errno: typeof value.errno === \"number\" ? value.errno : undefined,\n reason: text(\"reason\"),\n syscall: text(\"syscall\"),\n path: text(\"path\"),\n signal: text(\"signal\")\n })\n}\n\n/**\n * Preserve the platform's errno and signal vocabulary across the private wire.\n * @private\n * @since 1.0.0\n */\nexport const failure = (method: string, command: string, cause: unknown): PlatformError.PlatformError => {\n const error = nativeError(cause)\n const tags: Readonly<Record<string, PlatformError.SystemErrorTag>> = {\n ENOENT: \"NotFound\",\n EACCES: \"PermissionDenied\",\n EEXIST: \"AlreadyExists\",\n EISDIR: \"BadResource\",\n ENOTDIR: \"BadResource\",\n ELOOP: \"BadResource\",\n EBUSY: \"Busy\"\n }\n return PlatformError.systemError({\n _tag: tags[error.code ?? \"\"] ?? \"Unknown\",\n module: \"ChildProcess\",\n method,\n pathOrDescriptor: command,\n syscall: error.syscall,\n description: error.message,\n cause: error\n })\n}\n\n/**\n * The observation behind an unverified cleanup, in the message itself: a\n * failure report usually shows only the message, and whether the receipt, the\n * kernel or the snapshot was missing decides host load versus a live survivor.\n * @private\n * @since 1.0.0\n */\nexport const unverifiedCleanup = (\n control: {\n readonly fault: unknown\n readonly cleanupFailed: boolean\n readonly cleanupAcknowledged: boolean\n readonly targetDone: boolean\n },\n cleanupRequired: boolean,\n vacant: boolean,\n observed: Snapshot | undefined\n): string =>\n [\n `target exited: ${control.targetDone}`,\n `cleanup receipt: ${\n control.cleanupFailed\n ? \"failed\"\n : !cleanupRequired\n ? \"not required\"\n : control.cleanupAcknowledged\n ? \"acknowledged\"\n : \"missing\"\n }`,\n `group vacant: ${vacant}`,\n observed === undefined\n ? \"group snapshot: unavailable\"\n : `group members: ${\n observed.members.length === 0\n ? \"none\"\n : observed.members.map((member) => `${member.pid} ${member.zombie ? \"zombie\" : \"live\"}`).join(\", \")\n }; host group ${observed.ownGroup}`,\n ...(control.fault === undefined\n ? []\n : [`fault: ${String((control.fault as { message?: unknown })?.message ?? control.fault)}`])\n ].join(\"; \")\n\nconst promise = <A>() => {\n let resolve!: (value: A) => void\n let reject!: (cause: unknown) => void\n const promise = new Promise<A>((yes, no) => {\n resolve = yes\n reject = no\n })\n // A status may arrive before its Effect consumer starts waiting.\n void promise.catch(() => {})\n return { promise, resolve, reject }\n}\n\nconst wait = <A>(value: Promise<A>, method: string, command: string) =>\n Effect.tryPromise({ try: () => value, catch: (cause) => failure(method, command, cause) })\n\nconst bounded = <A, E, R>(effect: Effect.Effect<A, E, R>, millis: number, method: string, command: string) =>\n effect.pipe(\n Effect.timeoutOrElse({\n duration: millis,\n orElse: () =>\n Effect.fail(\n failure(method, command, processFault(\"supervisor_timeout\", `Process supervisor ${method} timed out`))\n )\n }),\n Effect.provideService(Clock.Clock, processClock)\n )\n\n/**\n * Standalone application executables do not implement the runtime's eval CLI.\n * Refuse them before spawning rather than recursively launching the application.\n * @private\n * @since 1.0.0\n */\nexport const bootstrapArguments = (runtime: { readonly bun: boolean; readonly main: string; readonly sea: boolean }) =>\n runtime.sea || runtime.main.startsWith(\"/$bunfs/\")\n ? Effect.fail(\n failure(\n \"spawn\",\n process.execPath,\n processFault(\n \"runtime_unsupported\",\n \"Process supervision requires a Node or Bun runtime executable, not a compiled application\"\n )\n )\n )\n : Effect.succeed(runtime.bun ? [\"--no-env-file\", \"--config=/dev/null\"] : [])\n\nconst channelEnvironment = \"SMITHERS_PROCESS_CHANNEL\"\nconst tlsOptions = { minVersion: \"TLSv1.3\", maxVersion: \"TLSv1.3\", ciphers: \"TLS_AES_128_GCM_SHA256\" } as const\n\n/**\n * Connect an owner to its authenticated private channel.\n * @private\n * @since 1.0.0\n */\nexport const connectOwner = (path: string, environment: Readonly<Record<string, string | undefined>>): Socket => {\n const encoded = environment[channelEnvironment]\n if (encoded === undefined) return createConnection(path)\n const channel = JSON.parse(encoded) as { key: string; status: number; requests: number }\n return Tls.connect({\n ...tlsOptions,\n host: \"127.0.0.1\",\n port: path.endsWith(\"/r\") ? channel.requests : channel.status,\n pskCallback: () => ({ identity: \"smithers-owner\", psk: Buffer.from(channel.key, \"hex\") })\n })\n}\n\n/**\n * Kept separate from Effect scopes so native socket callbacks only settle\n * promises; none can start an unowned fiber or signal an observed process id.\n * @private\n * @since 1.0.0\n */\nexport class Control {\n readonly ready = promise<number>()\n readonly started = promise<void>()\n readonly exited = promise<ExitCode>()\n readonly lost = promise<never>()\n readonly ended = promise<void>()\n readonly requestsReady = promise<void>()\n readonly directory: string\n readonly path: string\n readonly requestPath: string\n readonly server\n readonly requestServer\n readonly listening: Promise<void>\n private readonly key: Buffer | undefined\n private readonly connections = new Set<Socket>()\n socket: Socket | undefined\n requestSocket: Socket | undefined\n targetDone = false\n ownerCreation: unknown\n targetPid: number | undefined\n /** The owner's group guardian: a member that is neither target nor owner. */\n guardianPid: number | undefined\n ownerDone = false\n spawnFailed = false\n cleanupFailed = false\n cleanupAcknowledged = false\n activationSent = false\n closeSent = false\n fault: unknown\n onTargetExit: () => void = () => {}\n onCleanup: () => void = () => {}\n private receivedReady = false\n private receivedStarted = false\n private withdrawn = false\n\n constructor(transport: \"native\" | \"tls\" = \"native\") {\n this.key = transport === \"tls\" || process.platform === \"win32\" ? randomBytes(32) : undefined\n this.directory = mkdtempSync(this.key === undefined ? \"/tmp/sm-p-\" : join(tmpdir(), \"sm-p-\"))\n this.path = `${this.directory}/s`\n this.requestPath = `${this.directory}/r`\n const servers: Array<ReturnType<typeof createServer>> = []\n try {\n chmodSync(this.directory, 0o700)\n this.server = this.makeServer((socket) => this.accept(socket))\n servers.push(this.server)\n this.requestServer = this.makeServer((socket) => this.acceptRequests(socket))\n servers.push(this.requestServer)\n this.listening = Promise.all([\n new Promise<void>((resolve, reject) => {\n this.server.once(\"error\", reject)\n if (this.key === undefined) this.server.listen(this.path, resolve)\n else this.server.listen(0, \"127.0.0.1\", resolve)\n }),\n new Promise<void>((resolve, reject) => {\n this.requestServer.once(\"error\", reject)\n if (this.key === undefined) this.requestServer.listen(this.requestPath, resolve)\n else this.requestServer.listen(0, \"127.0.0.1\", resolve)\n })\n ]).then(() => {})\n } catch (cause) {\n for (const server of servers) server.close()\n rmSync(this.directory, { recursive: true, force: true })\n throw cause\n }\n }\n\n private makeServer(accept: (socket: Socket) => void): ReturnType<typeof createServer> {\n if (this.key === undefined) return createServer(accept)\n const server = Tls.createServer({\n ...tlsOptions,\n handshakeTimeout: startupMs,\n pskCallback: (_socket, identity) => identity === \"smithers-owner\" ? this.key! : null\n }, accept)\n server.on(\"connection\", (socket) => {\n this.connections.add(socket)\n socket.once(\"close\", () => this.connections.delete(socket))\n })\n server.on(\"tlsClientError\", (_error, socket) => socket.destroy())\n return server\n }\n\n /** Only the trusted owner receives this environment; target configuration replaces it. */\n environment(): Readonly<Record<string, string>> {\n if (this.key === undefined) return {}\n const status = this.server.address() as { port: number }\n const requests = this.requestServer.address() as { port: number }\n return {\n [channelEnvironment]: JSON.stringify({\n key: this.key.toString(\"hex\"),\n status: status.port,\n requests: requests.port\n })\n }\n }\n\n /** The test peer uses the same authenticated transport as the isolated owner. */\n connect(requests = false): Socket {\n return connectOwner(requests ? this.requestPath : this.path, this.environment())\n }\n\n /** Validate the stored READY after the raw spawn effect has returned its pid. */\n withdraw(pid: number, actual: number): void {\n if (pid !== actual) throw processFault(\"identity_mismatch\", \"Wrong supervisor identity\")\n this.server.close()\n this.server.unref()\n this.requestServer.close()\n this.requestServer.unref()\n // Node may unlink the owned socket synchronously inside server.close().\n rmSync(this.path, { force: true })\n rmSync(this.requestPath, { force: true })\n rmdirSync(this.directory)\n this.withdrawn = true\n }\n\n /** Request EOF asks for cleanup; leave its independent status reader intact. */\n disconnect(): void {\n this.requestSocket?.destroy()\n }\n\n dispose(): void {\n for (const socket of this.connections) socket.destroy()\n this.disconnect()\n this.socket?.destroy()\n this.server.close()\n this.requestServer.close()\n if (!this.withdrawn) rmSync(this.directory, { recursive: true, force: true })\n }\n\n rawEnded(): void {\n this.ownerDone = true\n // An accepted socket may still have buffered status frames. Its close event\n // rejects missing outcomes only after Node has delivered those frames.\n if (this.socket === undefined) this.closed()\n }\n\n write(message: unknown): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = this.requestSocket\n if (socket === undefined || socket.destroyed || !socket.writable) {\n reject(processFault(\"control_channel_closed\", \"Private process control channel closed\"))\n return\n }\n const data = `${JSON.stringify(message)}\\n`\n if (Buffer.byteLength(data) > 4 * 1024 * 1024) {\n reject(processFault(\"configuration_too_large\", \"Process configuration exceeds the private frame limit\"))\n return\n }\n socket.write(data, (error) => error ? reject(error) : resolve())\n })\n }\n\n private closed(): void {\n this.disconnect()\n const cause = this.fault ??\n processFault(\"outcome_missing\", \"Process supervisor closed before reporting its outcome\")\n if (this.activationSent && !this.targetDone && !this.spawnFailed) this.lost.reject(cause)\n this.ready.reject(cause)\n this.requestsReady.reject(cause)\n this.started.reject(cause)\n this.exited.reject(cause)\n this.ended.resolve()\n }\n\n private acceptRequests(socket: Socket): void {\n if (this.requestSocket !== undefined) {\n socket.destroy()\n return\n }\n this.requestSocket = socket\n // A late write may fail after the owner has sent its last status frames.\n // Destroying this socket must never discard those frames on the reader.\n socket.on(\"error\", (cause) => {\n this.fault = cause\n })\n this.requestsReady.resolve()\n }\n\n private accept(socket: Socket): void {\n if (this.socket !== undefined) {\n socket.destroy()\n return\n }\n this.socket = socket\n let buffer = \"\"\n socket.setEncoding(\"utf8\")\n socket.on(\"data\", (data: string) => {\n try {\n buffer += data\n if (Buffer.byteLength(buffer) > 16 * 1024) {\n throw processFault(\"status_too_large\", \"Process status frame exceeds its limit\")\n }\n for (;;) {\n const end = buffer.indexOf(\"\\n\")\n if (end < 0) break\n const line = buffer.slice(0, end)\n buffer = buffer.slice(end + 1)\n this.receive(JSON.parse(line))\n }\n } catch (cause) {\n this.fault = cause\n socket.destroy()\n }\n })\n socket.on(\"error\", (cause) => {\n this.fault = cause\n })\n socket.once(\"close\", () => this.closed())\n }\n\n private receive(value: unknown): void {\n if (typeof value !== \"object\" || value === null) throw processFault(\"status_invalid\", \"Invalid process status\")\n const message = value as Record<string, unknown>\n switch (message.type) {\n case \"ready\":\n if (\n this.receivedReady || message.version !== 1 || !Number.isSafeInteger(message.pid) || Number(message.pid) <= 1\n ) {\n throw processFault(\"status_invalid\", \"Invalid process readiness\")\n }\n this.receivedReady = true\n this.ownerCreation = message.created\n this.ready.resolve(Number(message.pid))\n return\n case \"spawned\":\n if (\n !this.activationSent || this.receivedStarted || !Number.isSafeInteger(message.pid) ||\n Number(message.pid) <= 1 ||\n message.guardian !== undefined && (!Number.isSafeInteger(message.guardian) || Number(message.guardian) <= 1)\n ) {\n throw processFault(\"status_invalid\", \"Invalid target startup\")\n }\n this.receivedStarted = true\n this.targetPid = Number(message.pid)\n if (message.guardian !== undefined) this.guardianPid = Number(message.guardian)\n this.started.resolve()\n return\n case \"spawn_error\":\n if (!this.activationSent || this.receivedStarted) {\n throw processFault(\"status_invalid\", \"Invalid target spawn failure\")\n }\n this.spawnFailed = true\n this.fault = message\n this.started.reject(message)\n this.exited.reject(message)\n return\n case \"fault\":\n this.fault = message\n this.started.reject(message)\n this.exited.reject(message)\n return\n case \"exit\":\n if (\n !this.receivedStarted || this.targetDone ||\n !(Number.isInteger(message.code) && Number(message.code) >= 0 && message.signal === null ||\n message.code === null && typeof message.signal === \"string\" && /^SIG[A-Z0-9]+$/.test(message.signal))\n ) {\n throw processFault(\"status_invalid\", \"Invalid target exit status\")\n }\n this.targetDone = true\n if (message.code === null) {\n this.exited.reject({\n message: `Process interrupted due to receipt of signal: '${message.signal}'`,\n signal: message.signal\n })\n } else this.exited.resolve(ExitCode(Number(message.code)))\n this.onTargetExit()\n return\n case \"cleanup_error\":\n this.cleanupFailed = true\n this.fault = message\n return\n case \"cleanup\":\n this.cleanupAcknowledged = true\n this.onCleanup()\n return\n default:\n throw processFault(\"status_unknown\", \"Unknown process status\")\n }\n }\n}\n\n/**\n * Prepare a private, independently bounded process owner before target launch.\n * @private\n * @since 1.0.0\n */\nexport const prepare = (\n system: System,\n policy: (\n options: ChildProcess.KillOptions,\n defaults?: ChildProcess.KillOptions\n ) => Effect.Effect<Policy, PlatformError.PlatformError>,\n transport: \"native\" | \"tls\" = \"native\"\n): Lifecycle =>\n(command, spawn) =>\n Effect.gen(function*() {\n const initial = yield* policy(command.options)\n const bun = process.versions.bun !== undefined\n const sea = bun ? false : (yield* Effect.tryPromise({\n try: () => import(\"node:sea\"),\n catch: (cause) => failure(\"spawn\", process.execPath, cause)\n })).isSea()\n const bootstrap = yield* bootstrapArguments({\n bun,\n sea,\n main: (globalThis as { readonly Bun?: { readonly main?: string } }).Bun?.main ?? \"\"\n })\n const windows = system.platform === \"win32\"\n const grouped = !windows && (command.options.detached ?? true)\n const jobExecutable = windows ?\n yield* Effect.try({\n try: resolveJobExecutable,\n catch: (cause) => failure(\"spawn\", command.command, cause)\n }) :\n undefined\n const control = yield* Effect.acquireRelease(\n Effect.try({ try: () => new Control(transport), catch: (cause) => failure(\"spawn\", command.command, cause) }),\n (control) => Effect.sync(() => control.dispose())\n )\n yield* bounded(wait(control.listening, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n const raw = yield* spawn(ChildProcess.make(process.execPath, [\n ...bootstrap,\n \"-e\",\n source,\n control.path,\n grouped ? \"group\" : \"direct\"\n ], {\n ...command.options,\n cwd: parse(process.execPath).root,\n env: {\n PATH: \"/usr/bin:/bin\",\n HOME: \"/\",\n XDG_CONFIG_HOME: \"/\",\n BUN_RUNTIME_TRANSPILER_CACHE_PATH: \"0\",\n ...control.environment(),\n ...(jobExecutable === undefined ? {} : { SMITHERS_PROCESS_JOB_HELPER: jobExecutable })\n },\n extendEnv: false,\n shell: false,\n detached: grouped,\n killSignal: \"SIGTERM\",\n forceKillAfter: initial.graceMs\n }))\n yield* Effect.exit(raw.exitCode).pipe(Effect.andThen(Effect.sync(() => control.rawEnded())), Effect.forkScoped)\n let job: WindowsProcessJob | undefined\n let settled = false\n let referenced = true\n let reref: Effect.Effect<void, PlatformError.PlatformError> = Effect.void\n let selected = initial\n let requireCleanupReceipt = false\n const snapshot = () => system.snapshot(raw.pid)\n const alone = () => {\n if (!grouped) return control.targetDone\n const observed = snapshot()\n if (observed === undefined || observed.ownGroup === raw.pid) return false\n // The guardian leaves with the owner's final group SIGKILL.\n const running = observed.members.filter((member) => !member.zombie && member.pid !== control.guardianPid)\n return running.length === 1 && running[0]!.pid === raw.pid\n }\n // This observation only shortens the owner's deadline. The live owner makes\n // the signal, so neither a stale observation nor a reused pid grants a kill.\n control.onTargetExit = () => {\n // An explicit stop already owns its deadline and escaped-child sweep.\n // Natural exit must not replace that policy with a second fast stop.\n if (control.closeSent) return\n if (!alone()) return\n control.closeSent = true\n void control.write({ type: \"stop\", killSignal: \"SIGKILL\", fast: true }).catch(() => control.disconnect())\n }\n const finish = yield* Effect.cached(Effect.gen(function*() {\n yield* bounded(Effect.exit(raw.exitCode), selected.graceMs + exitAllowanceMs, \"kill\", command.command).pipe(\n Effect.catch((cause) =>\n job === undefined ? Effect.fail(cause) : Effect.gen(function*() {\n // The native guardian can terminate a stalled owner independently.\n job!.stop()\n yield* bounded(Effect.exit(raw.exitCode), exitAllowanceMs, \"kill\", command.command)\n })\n )\n )\n if (job !== undefined) {\n yield* bounded(wait(job.settled.promise, \"kill\", command.command), 5500, \"kill\", command.command)\n settled = true\n return\n }\n yield* bounded(wait(control.ended.promise, \"kill\", command.command), deliveryMs, \"kill\", command.command).pipe(\n Effect.ignore\n )\n const deadline = Date.now() + verificationMs\n for (;;) {\n // The kernel's ESRCH proves the group empty with no fork. A `ps`\n // snapshot can go unanswered on a loaded host, so it only decides what\n // the kernel cannot: a group still holding zombies, or an unknown one.\n // A live member keeps both answers false. This host is alive, so a\n // vacant group is never this host's own group.\n const vacant = grouped && system.vacant(raw.pid)\n const observed = grouped && !vacant ? snapshot() : undefined\n settled = !control.cleanupFailed && (!requireCleanupReceipt || control.cleanupAcknowledged) && (grouped\n ? vacant ||\n observed !== undefined && observed.ownGroup !== raw.pid && observed.members.every((member) => member.zombie)\n : control.targetDone || control.spawnFailed || !control.activationSent)\n if (settled) return\n if (Date.now() >= deadline) {\n return yield* Effect.fail(\n failure(\n \"kill\",\n command.command,\n processFault(\n \"cleanup_unverified\",\n \"Process cleanup could not be verified; its ledger record is retained \" +\n `(${unverifiedCleanup(control, requireCleanupReceipt, vacant, observed)})`,\n {\n cause: {\n fault: control.fault,\n cleanupFailed: control.cleanupFailed,\n cleanupRequired: requireCleanupReceipt,\n cleanupAcknowledged: control.cleanupAcknowledged,\n targetDone: control.targetDone,\n groupVacant: vacant,\n ownerObserved: observed !== undefined,\n members: observed?.members\n }\n }\n )\n )\n )\n }\n yield* Effect.sleep(10).pipe(Effect.provideService(Clock.Clock, processClock))\n }\n }))\n const kill = (options: ChildProcess.KillOptions = {}) =>\n Effect.gen(function*() {\n const requested = yield* policy(options, command.options)\n if (!referenced) {\n job?.reference(true)\n control.socket?.ref()\n control.requestSocket?.ref()\n yield* reref\n referenced = true\n }\n if (!control.closeSent) {\n control.closeSent = true\n selected = requested\n // An empty original group cannot prove an explicit escaped-descendant\n // sweep succeeded if its status frames were lost. Startup and natural\n // completion have no such additional contract.\n requireCleanupReceipt = grouped && control.activationSent && !control.spawnFailed && !control.targetDone\n yield* bounded(\n wait(\n control.write({\n type: \"stop\",\n explicit: true,\n ...requested,\n // A live target can move out of this group with setsid().\n // Only an owner whose target was never activated can replace\n // the requested signal; natural exit has its own fast path.\n killSignal: !control.activationSent && alone() ? \"SIGKILL\" : requested.killSignal\n }),\n \"kill\",\n command.command\n ),\n deliveryMs,\n \"kill\",\n command.command\n )\n .pipe(Effect.catch(() => Effect.sync(() => control.disconnect())))\n }\n yield* finish\n }).pipe(Effect.uninterruptible)\n yield* Effect.addFinalizer(() =>\n kill().pipe(\n // A stuck owner keeps its ledger entry. Disable the underlying spawner's\n // unconditional group-kill finalizer rather than signal a stale identity.\n Effect.ensuring(\n Effect.suspend(() =>\n settled ? Effect.void : Effect.andThen(\n raw.unref,\n Effect.sync(() => {\n job?.stop()\n job?.reference(false)\n control.disconnect()\n })\n )\n ).pipe(Effect.orDie)\n ),\n Effect.orDie\n )\n )\n const ready = yield* bounded(\n wait(control.ready.promise, \"spawn\", command.command),\n startupMs,\n \"spawn\",\n command.command\n )\n yield* bounded(wait(control.requestsReady.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n yield* Effect.try({\n try: () => control.withdraw(ready, raw.pid),\n catch: (cause) => failure(\"spawn\", command.command, cause)\n })\n if (windows) {\n job = yield* Effect.try({\n try: () => new WindowsProcessJob(raw.pid, control.ownerCreation, jobExecutable!),\n catch: (cause) => failure(\"spawn\", command.command, cause)\n })\n yield* bounded(wait(job.ready.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n }\n const acknowledgeCleanup = windows || transport === \"tls\"\n if (acknowledgeCleanup) {\n control.onCleanup = () => {\n if (!control.ownerDone) {\n void control.write({ type: \"cleanup_ack\" }).catch(() => control.disconnect())\n }\n }\n }\n const options = command.options\n // Match Effect/Node's undefined-vs-empty environment semantics in the host,\n // before replacing the helper's environment with its isolated bootstrap.\n const env = options.extendEnv ? { ...process.env, ...options.env } : options.env ?? { ...process.env }\n yield* bounded(\n wait(\n control.write({\n type: \"configure\",\n acknowledgeCleanup,\n command: command.command,\n args: command.args,\n cwd: resolve(options.cwd ?? process.cwd()),\n env,\n shell: options.shell,\n windowsHide: options.windowsHide ?? true,\n windowsVerbatimArguments:\n (options as ChildProcess.CommandOptions & { readonly windowsVerbatimArguments?: boolean })\n .windowsVerbatimArguments,\n standardFds: standardFdsOf(raw),\n userFds: [\n ...new Set(\n Object.keys(options.additionalFds ?? {}).map(ChildProcess.parseFdName)\n .filter((fd): fd is number => fd !== undefined)\n )\n ],\n ...initial\n }),\n \"spawn\",\n command.command\n ),\n deliveryMs,\n \"spawn\",\n command.command\n )\n const activate = yield* Effect.cached(Effect.gen(function*() {\n control.activationSent = true\n yield* bounded(\n wait(control.write({ type: \"start\" }), \"spawn\", command.command),\n deliveryMs,\n \"spawn\",\n command.command\n )\n yield* bounded(wait(control.started.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n }))\n const unref = Effect.gen(function*() {\n if (referenced) {\n reref = yield* raw.unref\n job?.reference(false)\n control.socket?.unref()\n control.requestSocket?.unref()\n referenced = false\n }\n return Effect.gen(function*() {\n if (!referenced) {\n job?.reference(true)\n control.socket?.ref()\n control.requestSocket?.ref()\n yield* reref\n referenced = true\n }\n })\n })\n const output = <A>(stream: Stream.Stream<A, PlatformError.PlatformError>) =>\n stream.pipe(\n Stream.interruptWhen(wait(control.lost.promise, \"read\", command.command))\n )\n const input = <A>(sink: Sink.Sink<A, Uint8Array, never, PlatformError.PlatformError>) =>\n Sink.fromChannel(\n Sink.toChannel(sink).pipe(Channel.interruptWhen(wait(control.lost.promise, \"write\", command.command)))\n )\n const handle = makeHandle({\n ...raw,\n exitCode: wait(control.exited.promise, \"exitCode\", command.command),\n isRunning: Effect.sync(() => !control.targetDone && !control.ownerDone),\n stdin: input(raw.stdin),\n getInputFd: (fd) => input(raw.getInputFd(fd)),\n stdout: output(raw.stdout),\n stderr: output(raw.stderr),\n all: output(raw.all),\n getOutputFd: (fd) => output(raw.getOutputFd(fd)),\n kill,\n unref\n })\n targets.set(handle, control)\n return {\n handle,\n activate,\n settled: Effect.sync(() => settled)\n }\n })\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Private parent connection for a POSIX process owner. Effect retains ownership\n * of the caller's streams; separate sockets carry requests and lifetime status.\n * @since 1.0.0\n */\n\nimport type { Lifecycle } from \"@smthrs/kernel/ContainedSpawner\"\nimport * as Channel from \"effect/Channel\"\nimport * as Clock from \"effect/Clock\"\nimport * as Effect from \"effect/Effect\"\nimport * as PlatformError from \"effect/PlatformError\"\nimport * as ChildProcess from \"effect/process/ChildProcess\"\nimport { type ChildProcessHandle, ExitCode, makeHandle } from \"effect/process/ChildProcessSpawner\"\nimport * as Sink from \"effect/Sink\"\nimport * as Stream from \"effect/Stream\"\nimport { randomBytes } from \"node:crypto\"\nimport { chmodSync, mkdtempSync, rmdirSync, rmSync } from \"node:fs\"\nimport { createConnection, createServer, type Socket } from \"node:net\"\nimport { tmpdir } from \"node:os\"\nimport { join, parse, resolve } from \"node:path\"\nimport * as Tls from \"node:tls\"\nimport { standardFdsOf } from \"./PipedProcess.ts\"\nimport type { Policy, Snapshot, System } from \"./ProcessCleanup.ts\"\nimport { NativeProcessError, processFault } from \"./ProcessFault.ts\"\nimport { source } from \"./SupervisorProgram.ts\"\nimport { resolveJobExecutable, WindowsProcessJob } from \"./WindowsProcessJob.ts\"\n\nconst startupMs = 5000\nconst deliveryMs = 500\nconst exitAllowanceMs = 2500\n// Host-wide process observations can exceed a socket-delivery deadline on a\n// loaded machine. Keep verification bounded without mistaking that delay for\n// an unclean exit; an unknown observation still never counts as success.\nconst verificationMs = 2500\nconst targets = new WeakMap<ChildProcessHandle, Control>()\n// Native owners and sockets keep running when the caller freezes its Clock.\n// Their delivery bounds and cleanup retries must keep running with them.\nconst processClock = Clock.Clock.defaultValue()\n\n/**\n * Actual service pid, distinct from the owner recorded by the host.\n * @private\n * @since 1.0.0\n */\nexport const targetPidOf = (handle: ChildProcessHandle): number | undefined => targets.get(handle)?.targetPid\n\n/** Native error fields remain data on the public PlatformError cause. */\nconst nativeError = (cause: unknown): Error & { code?: string | undefined; syscall?: string | undefined } => {\n if (cause instanceof Error) return cause\n const value = (cause ?? {}) as Record<string, unknown>\n const text = (field: string): string | undefined => typeof value[field] === \"string\" ? value[field] : undefined\n return new NativeProcessError({\n message: text(\"message\") ?? \"The process supervisor failed\",\n code: text(\"code\"),\n errno: typeof value.errno === \"number\" ? value.errno : undefined,\n reason: text(\"reason\"),\n syscall: text(\"syscall\"),\n path: text(\"path\"),\n signal: text(\"signal\")\n })\n}\n\n/**\n * Preserve the platform's errno and signal vocabulary across the private wire.\n * @private\n * @since 1.0.0\n */\nexport const failure = (method: string, command: string, cause: unknown): PlatformError.PlatformError => {\n const error = nativeError(cause)\n const tags: Readonly<Record<string, PlatformError.SystemErrorTag>> = {\n ENOENT: \"NotFound\",\n EACCES: \"PermissionDenied\",\n EEXIST: \"AlreadyExists\",\n EISDIR: \"BadResource\",\n ENOTDIR: \"BadResource\",\n ELOOP: \"BadResource\",\n EBUSY: \"Busy\"\n }\n return PlatformError.systemError({\n _tag: tags[error.code ?? \"\"] ?? \"Unknown\",\n module: \"ChildProcess\",\n method,\n pathOrDescriptor: command,\n syscall: error.syscall,\n description: error.message,\n cause: error\n })\n}\n\n/**\n * The observation behind an unverified cleanup, in the message itself: a\n * failure report usually shows only the message, and whether the receipt, the\n * kernel or the snapshot was missing decides host load versus a live survivor.\n * @private\n * @since 1.0.0\n */\nexport const unverifiedCleanup = (\n control: {\n readonly fault: unknown\n readonly cleanupFailed: boolean\n readonly cleanupAcknowledged: boolean\n readonly targetDone: boolean\n },\n cleanupRequired: boolean,\n vacant: boolean,\n observed: Snapshot | undefined\n): string =>\n [\n `target exited: ${control.targetDone}`,\n `cleanup receipt: ${\n control.cleanupFailed\n ? \"failed\"\n : !cleanupRequired\n ? \"not required\"\n : control.cleanupAcknowledged\n ? \"acknowledged\"\n : \"missing\"\n }`,\n `group vacant: ${vacant}`,\n observed === undefined\n ? \"group snapshot: unavailable\"\n : `group members: ${\n observed.members.length === 0\n ? \"none\"\n : observed.members.map((member) => `${member.pid} ${member.zombie ? \"zombie\" : \"live\"}`).join(\", \")\n }; host group ${observed.ownGroup}`,\n ...(control.fault === undefined\n ? []\n : [`fault: ${String((control.fault as { message?: unknown })?.message ?? control.fault)}`])\n ].join(\"; \")\n\nconst promise = <A>() => {\n let resolve!: (value: A) => void\n let reject!: (cause: unknown) => void\n const promise = new Promise<A>((yes, no) => {\n resolve = yes\n reject = no\n })\n // A status may arrive before its Effect consumer starts waiting.\n void promise.catch(() => {})\n return { promise, resolve, reject }\n}\n\nconst wait = <A>(value: Promise<A>, method: string, command: string) =>\n Effect.tryPromise({ try: () => value, catch: (cause) => failure(method, command, cause) })\n\nconst bounded = <A, E, R>(effect: Effect.Effect<A, E, R>, millis: number, method: string, command: string) =>\n effect.pipe(\n Effect.timeoutOrElse({\n duration: millis,\n orElse: () =>\n Effect.fail(\n failure(method, command, processFault(\"supervisor_timeout\", `Process supervisor ${method} timed out`))\n )\n }),\n Effect.provideService(Clock.Clock, processClock)\n )\n\n/**\n * Standalone application executables do not implement the runtime's eval CLI.\n * Refuse them before spawning rather than recursively launching the application.\n * @private\n * @since 1.0.0\n */\nexport const bootstrapArguments = (runtime: { readonly bun: boolean; readonly main: string; readonly sea: boolean }) =>\n runtime.sea || runtime.main.startsWith(\"/$bunfs/\")\n ? Effect.fail(\n failure(\n \"spawn\",\n process.execPath,\n processFault(\n \"runtime_unsupported\",\n \"Process supervision requires a Node or Bun runtime executable, not a compiled application\"\n )\n )\n )\n : Effect.succeed(runtime.bun ? [\"--no-env-file\", \"--config=/dev/null\"] : [])\n\nconst channelEnvironment = \"SMITHERS_PROCESS_CHANNEL\"\nconst tlsOptions = { minVersion: \"TLSv1.3\", maxVersion: \"TLSv1.3\", ciphers: \"TLS_AES_128_GCM_SHA256\" } as const\n\n/**\n * Connect an owner to its authenticated private channel.\n * @private\n * @since 1.0.0\n */\nexport const connectOwner = (path: string, environment: Readonly<Record<string, string | undefined>>): Socket => {\n const encoded = environment[channelEnvironment]\n if (encoded === undefined) return createConnection(path)\n const channel = JSON.parse(encoded) as { key: string; status: number; requests: number }\n return Tls.connect({\n ...tlsOptions,\n host: \"127.0.0.1\",\n port: path.endsWith(\"/r\") ? channel.requests : channel.status,\n pskCallback: () => ({ identity: \"smithers-owner\", psk: Buffer.from(channel.key, \"hex\") })\n })\n}\n\n/**\n * Kept separate from Effect scopes so native socket callbacks only settle\n * promises; none can start an unowned fiber or signal an observed process id.\n * @private\n * @since 1.0.0\n */\nexport class Control {\n readonly ready = promise<number>()\n readonly started = promise<void>()\n readonly exited = promise<ExitCode>()\n readonly lost = promise<never>()\n readonly ended = promise<void>()\n readonly requestsReady = promise<void>()\n readonly directory: string\n readonly path: string\n readonly requestPath: string\n readonly server\n readonly requestServer\n readonly listening: Promise<void>\n private readonly key: Buffer | undefined\n private readonly connections = new Set<Socket>()\n socket: Socket | undefined\n requestSocket: Socket | undefined\n targetDone = false\n ownerCreation: unknown\n targetPid: number | undefined\n /** The owner's group guardian: a member that is neither target nor owner. */\n guardianPid: number | undefined\n ownerDone = false\n spawnFailed = false\n cleanupFailed = false\n cleanupAcknowledged = false\n activationSent = false\n closeSent = false\n fault: unknown\n onTargetExit: () => void = () => {}\n onCleanup: () => void = () => {}\n private receivedReady = false\n private receivedStarted = false\n private withdrawn = false\n\n constructor(transport: \"native\" | \"tls\" = \"native\") {\n this.key = transport === \"tls\" || process.platform === \"win32\" ? randomBytes(32) : undefined\n this.directory = mkdtempSync(this.key === undefined ? \"/tmp/sm-p-\" : join(tmpdir(), \"sm-p-\"))\n this.path = `${this.directory}/s`\n this.requestPath = `${this.directory}/r`\n const servers: Array<ReturnType<typeof createServer>> = []\n try {\n chmodSync(this.directory, 0o700)\n this.server = this.makeServer((socket) => this.accept(socket))\n servers.push(this.server)\n this.requestServer = this.makeServer((socket) => this.acceptRequests(socket))\n servers.push(this.requestServer)\n this.listening = Promise.all([\n new Promise<void>((resolve, reject) => {\n this.server.once(\"error\", reject)\n if (this.key === undefined) this.server.listen(this.path, resolve)\n else this.server.listen(0, \"127.0.0.1\", resolve)\n }),\n new Promise<void>((resolve, reject) => {\n this.requestServer.once(\"error\", reject)\n if (this.key === undefined) this.requestServer.listen(this.requestPath, resolve)\n else this.requestServer.listen(0, \"127.0.0.1\", resolve)\n })\n ]).then(() => {})\n } catch (cause) {\n for (const server of servers) server.close()\n rmSync(this.directory, { recursive: true, force: true })\n throw cause\n }\n }\n\n private makeServer(accept: (socket: Socket) => void): ReturnType<typeof createServer> {\n if (this.key === undefined) return createServer(accept)\n const server = Tls.createServer({\n ...tlsOptions,\n handshakeTimeout: startupMs,\n pskCallback: (_socket, identity) => identity === \"smithers-owner\" ? this.key! : null\n }, accept)\n server.on(\"connection\", (socket) => {\n this.connections.add(socket)\n socket.once(\"close\", () => this.connections.delete(socket))\n })\n server.on(\"tlsClientError\", (_error, socket) => socket.destroy())\n return server\n }\n\n /** Only the trusted owner receives this environment; target configuration replaces it. */\n environment(): Readonly<Record<string, string>> {\n if (this.key === undefined) return {}\n const status = this.server.address() as { port: number }\n const requests = this.requestServer.address() as { port: number }\n return {\n [channelEnvironment]: JSON.stringify({\n key: this.key.toString(\"hex\"),\n status: status.port,\n requests: requests.port\n })\n }\n }\n\n /** The test peer uses the same authenticated transport as the isolated owner. */\n connect(requests = false): Socket {\n return connectOwner(requests ? this.requestPath : this.path, this.environment())\n }\n\n /** Validate the stored READY after the raw spawn effect has returned its pid. */\n withdraw(pid: number, actual: number): void {\n if (pid !== actual) throw processFault(\"identity_mismatch\", \"Wrong supervisor identity\")\n this.server.close()\n this.server.unref()\n this.requestServer.close()\n this.requestServer.unref()\n // Node may unlink the owned socket synchronously inside server.close().\n rmSync(this.path, { force: true })\n rmSync(this.requestPath, { force: true })\n rmdirSync(this.directory)\n this.withdrawn = true\n }\n\n /** Request EOF asks for cleanup; leave its independent status reader intact. */\n disconnect(): void {\n this.requestSocket?.destroy()\n }\n\n dispose(): void {\n for (const socket of this.connections) socket.destroy()\n this.disconnect()\n this.socket?.destroy()\n this.server.close()\n this.requestServer.close()\n if (!this.withdrawn) rmSync(this.directory, { recursive: true, force: true })\n }\n\n rawEnded(): void {\n this.ownerDone = true\n // An accepted socket may still have buffered status frames. Its close event\n // rejects missing outcomes only after Node has delivered those frames.\n if (this.socket === undefined) this.closed()\n }\n\n write(message: unknown): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = this.requestSocket\n if (socket === undefined || socket.destroyed || !socket.writable) {\n reject(processFault(\"control_channel_closed\", \"Private process control channel closed\"))\n return\n }\n const data = `${JSON.stringify(message)}\\n`\n if (Buffer.byteLength(data) > 4 * 1024 * 1024) {\n reject(processFault(\"configuration_too_large\", \"Process configuration exceeds the private frame limit\"))\n return\n }\n socket.write(data, (error) => error ? reject(error) : resolve())\n })\n }\n\n private closed(): void {\n this.disconnect()\n const cause = this.fault ??\n processFault(\"outcome_missing\", \"Process supervisor closed before reporting its outcome\")\n if (this.activationSent && !this.targetDone && !this.spawnFailed) this.lost.reject(cause)\n this.ready.reject(cause)\n this.requestsReady.reject(cause)\n this.started.reject(cause)\n this.exited.reject(cause)\n this.ended.resolve()\n }\n\n private acceptRequests(socket: Socket): void {\n if (this.requestSocket !== undefined) {\n socket.destroy()\n return\n }\n this.requestSocket = socket\n // A late write may fail after the owner has sent its last status frames.\n // Destroying this socket must never discard those frames on the reader.\n socket.on(\"error\", (cause) => {\n this.fault = cause\n })\n this.requestsReady.resolve()\n }\n\n private accept(socket: Socket): void {\n if (this.socket !== undefined) {\n socket.destroy()\n return\n }\n this.socket = socket\n let buffer = \"\"\n socket.setEncoding(\"utf8\")\n socket.on(\"data\", (data: string) => {\n try {\n buffer += data\n if (Buffer.byteLength(buffer) > 16 * 1024) {\n throw processFault(\"status_too_large\", \"Process status frame exceeds its limit\")\n }\n for (;;) {\n const end = buffer.indexOf(\"\\n\")\n if (end < 0) break\n const line = buffer.slice(0, end)\n buffer = buffer.slice(end + 1)\n this.receive(JSON.parse(line))\n }\n } catch (cause) {\n this.fault = cause\n socket.destroy()\n }\n })\n socket.on(\"error\", (cause) => {\n this.fault = cause\n })\n socket.once(\"close\", () => this.closed())\n }\n\n private receive(value: unknown): void {\n if (typeof value !== \"object\" || value === null) throw processFault(\"status_invalid\", \"Invalid process status\")\n const message = value as Record<string, unknown>\n switch (message.type) {\n case \"ready\":\n if (\n this.receivedReady || message.version !== 1 || !Number.isSafeInteger(message.pid) || Number(message.pid) <= 1\n ) {\n throw processFault(\"status_invalid\", \"Invalid process readiness\")\n }\n this.receivedReady = true\n this.ownerCreation = message.created\n this.ready.resolve(Number(message.pid))\n return\n case \"spawned\":\n if (\n !this.activationSent || this.receivedStarted || !Number.isSafeInteger(message.pid) ||\n Number(message.pid) <= 1 ||\n message.guardian !== undefined && (!Number.isSafeInteger(message.guardian) || Number(message.guardian) <= 1)\n ) {\n throw processFault(\"status_invalid\", \"Invalid target startup\")\n }\n this.receivedStarted = true\n this.targetPid = Number(message.pid)\n if (message.guardian !== undefined) this.guardianPid = Number(message.guardian)\n this.started.resolve()\n return\n case \"spawn_error\":\n if (!this.activationSent || this.receivedStarted) {\n throw processFault(\"status_invalid\", \"Invalid target spawn failure\")\n }\n this.spawnFailed = true\n this.fault = message\n this.started.reject(message)\n this.exited.reject(message)\n return\n case \"fault\":\n this.fault = message\n this.started.reject(message)\n this.exited.reject(message)\n return\n case \"exit\":\n if (\n !this.receivedStarted || this.targetDone ||\n !(Number.isInteger(message.code) && Number(message.code) >= 0 && message.signal === null ||\n message.code === null && typeof message.signal === \"string\" && /^SIG[A-Z0-9]+$/.test(message.signal))\n ) {\n throw processFault(\"status_invalid\", \"Invalid target exit status\")\n }\n this.targetDone = true\n if (message.code === null) {\n this.exited.reject({\n message: `Process interrupted due to receipt of signal: '${message.signal}'`,\n signal: message.signal\n })\n } else this.exited.resolve(ExitCode(Number(message.code)))\n this.onTargetExit()\n return\n case \"cleanup_error\":\n this.cleanupFailed = true\n this.fault = message\n return\n case \"cleanup\":\n this.cleanupAcknowledged = true\n this.onCleanup()\n return\n default:\n throw processFault(\"status_unknown\", \"Unknown process status\")\n }\n }\n}\n\n/**\n * Prepare a private, independently bounded process owner before target launch.\n * @private\n * @since 1.0.0\n */\nexport const prepare = (\n system: System,\n policy: (\n options: ChildProcess.KillOptions,\n defaults?: ChildProcess.KillOptions\n ) => Effect.Effect<Policy, PlatformError.PlatformError>,\n transport: \"native\" | \"tls\" = \"native\"\n): Lifecycle =>\n(command, spawn) =>\n Effect.gen(function*() {\n const initial = yield* policy(command.options)\n const bun = process.versions.bun !== undefined\n const sea = bun ? false : (yield* Effect.tryPromise({\n try: () => import(\"node:sea\"),\n catch: (cause) => failure(\"spawn\", process.execPath, cause)\n })).isSea()\n const bootstrap = yield* bootstrapArguments({\n bun,\n sea,\n main: (globalThis as { readonly Bun?: { readonly main?: string } }).Bun?.main ?? \"\"\n })\n const windows = system.platform === \"win32\"\n const grouped = !windows && (command.options.detached ?? true)\n const jobExecutable = windows ?\n yield* Effect.try({\n try: resolveJobExecutable,\n catch: (cause) => failure(\"spawn\", command.command, cause)\n }) :\n undefined\n const control = yield* Effect.acquireRelease(\n Effect.try({ try: () => new Control(transport), catch: (cause) => failure(\"spawn\", command.command, cause) }),\n (control) => Effect.sync(() => control.dispose())\n )\n yield* bounded(wait(control.listening, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n const raw = yield* spawn(ChildProcess.make(process.execPath, [\n ...bootstrap,\n \"-e\",\n source,\n control.path,\n grouped ? \"group\" : \"direct\"\n ], {\n ...command.options,\n cwd: parse(process.execPath).root,\n env: {\n PATH: \"/usr/bin:/bin\",\n HOME: \"/\",\n XDG_CONFIG_HOME: \"/\",\n BUN_RUNTIME_TRANSPILER_CACHE_PATH: \"0\",\n ...control.environment(),\n ...(jobExecutable === undefined ? {} : { SMITHERS_PROCESS_JOB_HELPER: jobExecutable })\n },\n extendEnv: false,\n shell: false,\n detached: grouped,\n killSignal: \"SIGTERM\",\n forceKillAfter: initial.graceMs\n }))\n yield* Effect.exit(raw.exitCode).pipe(Effect.andThen(Effect.sync(() => control.rawEnded())), Effect.forkScoped)\n let job: WindowsProcessJob | undefined\n let settled = false\n let referenced = true\n let reref: Effect.Effect<void, PlatformError.PlatformError> = Effect.void\n let selected = initial\n let requireCleanupReceipt = false\n const snapshot = () => system.snapshot(raw.pid)\n const alone = () => {\n if (!grouped) return control.targetDone\n const observed = snapshot()\n if (observed === undefined || observed.ownGroup === raw.pid) return false\n // The guardian leaves with the owner's final group SIGKILL.\n const running = observed.members.filter((member) => !member.zombie && member.pid !== control.guardianPid)\n return running.length === 1 && running[0]!.pid === raw.pid\n }\n // This observation only shortens the owner's deadline. The live owner makes\n // the signal, so neither a stale observation nor a reused pid grants a kill.\n control.onTargetExit = () => {\n // An explicit stop already owns its deadline and escaped-child sweep.\n // Natural exit must not replace that policy with a second fast stop.\n if (control.closeSent) return\n if (!alone()) return\n control.closeSent = true\n void control.write({ type: \"stop\", killSignal: \"SIGKILL\", fast: true }).catch(() => control.disconnect())\n }\n const finish = yield* Effect.cached(Effect.gen(function*() {\n yield* bounded(Effect.exit(raw.exitCode), selected.graceMs + exitAllowanceMs, \"kill\", command.command).pipe(\n Effect.catch((cause) =>\n job === undefined ? Effect.fail(cause) : Effect.gen(function*() {\n // The native guardian can terminate a stalled owner independently.\n job!.stop()\n yield* bounded(Effect.exit(raw.exitCode), exitAllowanceMs, \"kill\", command.command)\n })\n )\n )\n if (job !== undefined) {\n yield* bounded(wait(job.settled.promise, \"kill\", command.command), 5500, \"kill\", command.command)\n settled = true\n return\n }\n yield* bounded(wait(control.ended.promise, \"kill\", command.command), deliveryMs, \"kill\", command.command).pipe(\n Effect.ignore\n )\n const deadline = Date.now() + verificationMs\n for (;;) {\n // The kernel's ESRCH proves the group empty with no fork. A `ps`\n // snapshot can go unanswered on a loaded host, so it only decides what\n // the kernel cannot: a group still holding zombies, or an unknown one.\n // A live member keeps both answers false. This host is alive, so a\n // vacant group is never this host's own group.\n const vacant = grouped && system.vacant(raw.pid)\n const observed = grouped && !vacant ? snapshot() : undefined\n settled = !control.cleanupFailed && (!requireCleanupReceipt || control.cleanupAcknowledged) && (grouped\n ? vacant ||\n observed !== undefined && observed.ownGroup !== raw.pid && observed.members.every((member) => member.zombie)\n : control.targetDone || control.spawnFailed || !control.activationSent)\n if (settled) return\n if (Date.now() >= deadline) {\n return yield* Effect.fail(\n failure(\n \"kill\",\n command.command,\n processFault(\n \"cleanup_unverified\",\n \"Process cleanup could not be verified; its ledger record is retained \" +\n `(${unverifiedCleanup(control, requireCleanupReceipt, vacant, observed)})`,\n {\n cause: {\n fault: control.fault,\n cleanupFailed: control.cleanupFailed,\n cleanupRequired: requireCleanupReceipt,\n cleanupAcknowledged: control.cleanupAcknowledged,\n targetDone: control.targetDone,\n groupVacant: vacant,\n ownerObserved: observed !== undefined,\n members: observed?.members\n }\n }\n )\n )\n )\n }\n yield* Effect.sleep(10).pipe(Effect.provideService(Clock.Clock, processClock))\n }\n }))\n const kill = (options: ChildProcess.KillOptions = {}) =>\n Effect.gen(function*() {\n const requested = yield* policy(options, command.options)\n if (!referenced) {\n job?.reference(true)\n control.socket?.ref()\n control.requestSocket?.ref()\n yield* reref\n referenced = true\n }\n if (!control.closeSent) {\n control.closeSent = true\n selected = requested\n // An empty original group cannot prove an explicit escaped-descendant\n // sweep succeeded if its status frames were lost. Startup and natural\n // completion have no such additional contract.\n requireCleanupReceipt = grouped && control.activationSent && !control.spawnFailed && !control.targetDone\n yield* bounded(\n wait(\n control.write({\n type: \"stop\",\n explicit: true,\n ...requested,\n // A live target can move out of this group with setsid().\n // Only an owner whose target was never activated can replace\n // the requested signal; natural exit has its own fast path.\n killSignal: !control.activationSent && alone() ? \"SIGKILL\" : requested.killSignal\n }),\n \"kill\",\n command.command\n ),\n deliveryMs,\n \"kill\",\n command.command\n )\n .pipe(Effect.catch(() => Effect.sync(() => control.disconnect())))\n }\n yield* finish\n }).pipe(Effect.uninterruptible)\n yield* Effect.addFinalizer(() =>\n kill().pipe(\n // A stuck owner keeps its ledger entry. Disable the underlying spawner's\n // unconditional group-kill finalizer rather than signal a stale identity.\n Effect.ensuring(\n Effect.suspend(() =>\n settled ? Effect.void : Effect.andThen(\n raw.unref,\n Effect.sync(() => {\n job?.stop()\n job?.reference(false)\n control.disconnect()\n })\n )\n ).pipe(Effect.orDie)\n ),\n Effect.orDie\n )\n )\n const ready = yield* bounded(\n wait(control.ready.promise, \"spawn\", command.command),\n startupMs,\n \"spawn\",\n command.command\n )\n yield* bounded(wait(control.requestsReady.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n yield* Effect.try({\n try: () => control.withdraw(ready, raw.pid),\n catch: (cause) => failure(\"spawn\", command.command, cause)\n })\n if (windows) {\n job = yield* Effect.try({\n try: () => new WindowsProcessJob(raw.pid, control.ownerCreation, jobExecutable!),\n catch: (cause) => failure(\"spawn\", command.command, cause)\n })\n yield* bounded(wait(job.ready.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n }\n const acknowledgeCleanup = windows || transport === \"tls\"\n if (acknowledgeCleanup) {\n control.onCleanup = () => {\n if (!control.ownerDone) {\n void control.write({ type: \"cleanup_ack\" }).catch(() => control.disconnect())\n }\n }\n }\n const options = command.options\n // Match Effect/Node's undefined-vs-empty environment semantics in the host,\n // before replacing the helper's environment with its isolated bootstrap.\n const env = options.extendEnv ? { ...process.env, ...options.env } : options.env ?? { ...process.env }\n yield* bounded(\n wait(\n control.write({\n type: \"configure\",\n acknowledgeCleanup,\n command: command.command,\n args: command.args,\n cwd: resolve(options.cwd ?? process.cwd()),\n env,\n shell: options.shell,\n windowsHide: options.windowsHide ?? true,\n windowsVerbatimArguments:\n (options as ChildProcess.CommandOptions & { readonly windowsVerbatimArguments?: boolean })\n .windowsVerbatimArguments,\n standardFds: standardFdsOf(raw),\n userFds: [\n ...new Set(\n Object.keys(options.additionalFds ?? {}).map(ChildProcess.parseFdName)\n .filter((fd): fd is number => fd !== undefined)\n )\n ],\n ...initial\n }),\n \"spawn\",\n command.command\n ),\n deliveryMs,\n \"spawn\",\n command.command\n )\n const activate = yield* Effect.cached(Effect.gen(function*() {\n control.activationSent = true\n yield* bounded(\n wait(control.write({ type: \"start\" }), \"spawn\", command.command),\n deliveryMs,\n \"spawn\",\n command.command\n )\n yield* bounded(wait(control.started.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n }))\n const unref = Effect.gen(function*() {\n if (referenced) {\n reref = yield* raw.unref\n job?.reference(false)\n control.socket?.unref()\n control.requestSocket?.unref()\n referenced = false\n }\n return Effect.gen(function*() {\n if (!referenced) {\n job?.reference(true)\n control.socket?.ref()\n control.requestSocket?.ref()\n yield* reref\n referenced = true\n }\n })\n })\n const output = <A>(stream: Stream.Stream<A, PlatformError.PlatformError>) =>\n stream.pipe(\n Stream.interruptWhen(wait(control.lost.promise, \"read\", command.command))\n )\n const input = <A>(sink: Sink.Sink<A, Uint8Array, never, PlatformError.PlatformError>) =>\n Sink.fromChannel(\n Sink.toChannel(sink).pipe(Channel.interruptWhen(wait(control.lost.promise, \"write\", command.command)))\n )\n const handle = makeHandle({\n ...raw,\n exitCode: wait(control.exited.promise, \"exitCode\", command.command),\n isRunning: Effect.sync(() => !control.targetDone && !control.ownerDone),\n stdin: input(raw.stdin),\n getInputFd: (fd) => input(raw.getInputFd(fd)),\n stdout: output(raw.stdout),\n stderr: output(raw.stderr),\n all: output(raw.all),\n getOutputFd: (fd) => output(raw.getOutputFd(fd)),\n kill,\n unref\n })\n targets.set(handle, control)\n return {\n handle,\n activate,\n settled: Effect.sync(() => settled)\n }\n })\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["resolve", "promise", "control", "options"]
|
|
7
7
|
}
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
import type * as Undici from "../vendor/node/Undici.js";
|
|
30
30
|
import { GrantStore } from "@smthrs/kernel/GrantStore";
|
|
31
31
|
import * as Effect from "effect/Effect";
|
|
32
|
+
import { HttpClient } from "effect/http/HttpClient";
|
|
32
33
|
import * as Layer from "effect/Layer";
|
|
33
34
|
import * as Schema from "effect/Schema";
|
|
34
35
|
import * as Scope from "effect/Scope";
|
|
35
|
-
import { HttpClient } from "effect/unstable/http/HttpClient";
|
|
36
36
|
declare const EgressAddressError_base: Schema.Class<EgressAddressError, Schema.TaggedStruct<"@smthrs/platform-node/EgressAddressError", {
|
|
37
37
|
readonly code: Schema.Literal<"no_approved_address">;
|
|
38
38
|
readonly message: Schema.String;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EgressHttpClient.d.ts","sourceRoot":"","sources":["../../src/EgressHttpClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,KAAK,MAAM,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAGtD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,
|
|
1
|
+
{"version":3,"file":"EgressHttpClient.d.ts","sourceRoot":"","sources":["../../src/EgressHttpClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,KAAK,MAAM,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAGtD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAInD,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;;;;;AAIrC;;;;;;;GAOG;AACH,qBAAa,kBAAmB,SAAQ,uBAGvC;IACC,SAAkB,IAAI,wBAAuB;CAC9C;AAoCD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,UAAU,GACrB,aAAa,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,KACxD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAsBlD,CAAA;AAEJ;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,KAAK,GAChB,aAAa,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,KACxD,KAAK,CAAC,KAAK,CAAC,UAAU,CAqHtB,CAAA;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC/B,SAAS,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAC7D,WAAU,CAAC,MAAM,EAAE,UAAU,KAAK,MAAM,CAAC,MAAM,CAAC,UAAU,CAAkB,KAC3E,MAAM,CAAC,MAAM,CACd;IACE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;CAC5C,EACD,KAAK,EACL,KAAK,CAAC,KAAK,CAqBT,CAAA;AAEJ;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,aAAa,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;qBAlCrE,UAAU;sBACT,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;mCAyC3C,CAAA"}
|
|
@@ -32,14 +32,14 @@ import * as KernelHttpClient from "@smthrs/kernel/HttpClient";
|
|
|
32
32
|
import { Destination, withDestinationPinning } from "@smthrs/kernel/HttpClient";
|
|
33
33
|
import * as Effect from "effect/Effect";
|
|
34
34
|
import * as Exit from "effect/Exit";
|
|
35
|
+
import { HttpClient } from "effect/http/HttpClient";
|
|
36
|
+
import * as EffectHttpClient from "effect/http/HttpClient";
|
|
37
|
+
import * as HttpClientError from "effect/http/HttpClientError";
|
|
38
|
+
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
35
39
|
import * as Layer from "effect/Layer";
|
|
36
40
|
import * as Schema from "effect/Schema";
|
|
37
41
|
import * as Scope from "effect/Scope";
|
|
38
42
|
import * as Semaphore from "effect/Semaphore";
|
|
39
|
-
import { HttpClient } from "effect/unstable/http/HttpClient";
|
|
40
|
-
import * as EffectHttpClient from "effect/unstable/http/HttpClient";
|
|
41
|
-
import * as HttpClientError from "effect/unstable/http/HttpClientError";
|
|
42
|
-
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
|
|
43
43
|
import { isIP } from "node:net";
|
|
44
44
|
/**
|
|
45
45
|
* A pinned connection asked for an address family none of the authorized
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EgressHttpClient.js","sourceRoot":"","sources":["../../src/EgressHttpClient.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The outbound HTTP client a Node process should use, read off its environment.\n *\n * `@effect/platform-node` ships `NodeHttpClient.layerUndici`, and its\n * dispatcher is a bare Undici `Agent`. A bare `Agent` dials every origin\n * directly: it does not read `HTTP_PROXY`, `HTTPS_PROXY` or `NO_PROXY`, and\n * nothing at the call site says so. That is invisible on a developer machine\n * with open egress and fatal inside a sandbox whose egress is default-deny\n * behind a named proxy — the request leaves for the origin, the firewall drops\n * it, and the only symptom is a transport failure far from the composition\n * that chose the client.\n *\n * This module is the one place that decision is made. {@link layer} is the\n * client every Node host composition installs; it honours the proxy the\n * environment names. Requests without a web destination use a shared pool;\n * web requests receive a fresh pinned dispatcher.\n *\n * The rule for loopback is fixed here, not by the environment: `localhost`,\n * `127.0.0.1` and `[::1]` are always reached directly, even when the\n * environment names a proxy and no exclusion, and every other origin follows\n * `NO_PROXY`. A proxy is how a process leaves its machine, and\n * `--remote http://127.0.0.1:3000` is not leaving it. The exemption is those\n * three names and nothing wider: Undici matches `NO_PROXY` entries by name,\n * never by resolved address, so `127.0.0.2` or a hostname that resolves to\n * loopback is an origin like any other and goes through the proxy.\n *\n * @since 1.0.0-rc.0\n */\n\nimport * as NodeHttpClient from \"@effect/platform-node/NodeHttpClient\"\nimport type * as Undici from \"@effect/platform-node/Undici\"\nimport { GrantStore } from \"@smthrs/kernel/GrantStore\"\nimport * as KernelHttpClient from \"@smthrs/kernel/HttpClient\"\nimport { Destination, withDestinationPinning } from \"@smthrs/kernel/HttpClient\"\nimport * as Effect from \"effect/Effect\"\nimport * as Exit from \"effect/Exit\"\nimport * as Layer from \"effect/Layer\"\nimport * as Schema from \"effect/Schema\"\nimport * as Scope from \"effect/Scope\"\nimport * as Semaphore from \"effect/Semaphore\"\nimport { HttpClient } from \"effect/unstable/http/HttpClient\"\nimport * as EffectHttpClient from \"effect/unstable/http/HttpClient\"\nimport * as HttpClientError from \"effect/unstable/http/HttpClientError\"\nimport * as HttpClientRequest from \"effect/unstable/http/HttpClientRequest\"\nimport { isIP } from \"node:net\"\n\n/**\n * A pinned connection asked for an address family none of the authorized\n * addresses has. It is the `cause` of the `TransportError` the request fails\n * with; `code` is always `no_approved_address`.\n *\n * @category errors\n * @since 1.0.0\n */\nexport class EgressAddressError extends Schema.TaggedError<EgressAddressError>()(\n \"@smthrs/platform-node/EgressAddressError\",\n { code: Schema.Literal(\"no_approved_address\"), message: Schema.String }\n) {\n override readonly name = \"EgressAddressError\"\n}\n\n/**\n * The hosts a proxy is never for. A proxy is how a process leaves its machine;\n * these names are the machine itself. Matched by name, the way Undici matches\n * every `NO_PROXY` entry, so the list is exactly these three and not\n * `127.0.0.0/8`.\n */\nconst loopback = [\"localhost\", \"127.0.0.1\", \"::1\"] as const\n\n/**\n * The exclusion list to hand Undici, given the one the environment names.\n *\n * Undici proxies *every* origin when `NO_PROXY` is empty — `#shouldProxy`\n * returns early with \"Always proxy if NO_PROXY is not set or empty\" — so a host\n * that names a proxy to reach the internet would also send `smthrs --remote\n * http://127.0.0.1:3000` and a local Ollama at `http://localhost:11434` to it.\n * Nothing in this repository has ever needed `NO_PROXY=127.0.0.1`, because the\n * client these compositions used before ignored the proxy variables outright.\n * So loopback is always excluded, the way Go's `net/http.ProxyFromEnvironment`\n * excludes it, and the environment's own entries are kept beside it.\n *\n * `*` is returned untouched: Undici recognises the wildcard only as the entire\n * value, and it already means every origin is direct.\n */\nconst exclusions = (declared: string): string =>\n declared === \"*\" ? declared : [declared, ...loopback].filter((entry) => entry !== \"\").join(\",\")\n\n// Split ESM bundles expose CommonJS Undici through default, without synthetic\n// named exports. Node and Bun also expose its constructors through default.\n// Its typings declare `default` as a namespace without them, and `bundler`\n// resolution reads that, so the value is typed as the module it carries.\nconst loadUndici = Effect.promise(\n async () => (await import(\"undici/index.js\")).default as unknown as typeof Undici\n)\n\n/**\n * An Undici dispatcher that routes through the egress proxy the supplied\n * environment names, or a direct one when it names none.\n *\n * The proxy variables are read in the order Undici itself reads them,\n * lowercase first, and passed explicitly rather than left to\n * `EnvHttpProxyAgent`'s own ambient lookup: a host serving a guest's\n * environment is not the guest, and the pool has to follow the record it was\n * handed. Loopback is always direct; see {@link exclusions}. Each dispatcher is\n * acquired in the caller's scope and destroyed with it, so a composition that\n * builds several still owns every pool it opened.\n *\n * @param environment the environment record whose proxy variables decide the route\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const dispatcher = (\n environment: Readonly<Record<string, string | undefined>>\n): Effect.Effect<Undici.Dispatcher, never, Scope.Scope> =>\n Effect.suspend(() => {\n const httpProxy = environment.http_proxy ?? environment.HTTP_PROXY ?? \"\"\n const httpsProxy = environment.https_proxy ?? environment.HTTPS_PROXY ?? \"\"\n const noProxy = exclusions(environment.no_proxy ?? environment.NO_PROXY ?? \"\")\n // Explicit empty values prevent Undici from falling back to a different\n // ambient environment. Each replacement pool uses the same proxy policy.\n //\n // Undici is loaded here rather than imported at the top, the way\n // `NodeHttpClient.makeDispatcher` loads it, because this module is imported\n // by `NodeHost` and every bundle built on it. A static import pulls the\n // whole of Undici into any process that merely composes a host, whose\n // side effects a host bundle must not carry: it reddened the Node host's\n // own `FileSystem` contract case, which never makes a request. The explicit\n // package entry also avoids Bun's incomplete built-in \"undici\" substitute.\n return Effect.acquireRelease(\n Effect.map(\n loadUndici,\n (undici) => new undici.EnvHttpProxyAgent({ httpProxy, httpsProxy, noProxy })\n ),\n (dispatcher) => Effect.promise(() => dispatcher.destroy())\n )\n })\n\n/**\n * The Undici `HttpClient` to install, given the environment the process runs in.\n *\n * Use this wherever `NodeHttpClient.layerUndici` would otherwise be provided\n * under a layer that takes `HttpClient` from context — a model transport, a\n * judge, a fetch rule, a host bundle. The two differ only in whether the pool\n * honours `HTTP_PROXY`/`HTTPS_PROXY`/`NO_PROXY`, which is the difference\n * between a request that reaches the gateway from inside a default-deny\n * sandbox and one the firewall drops.\n *\n * @param environment the environment record whose proxy variables decide the route\n * @category layers\n * @since 1.0.0-rc.0\n */\nexport const layer = (\n environment: Readonly<Record<string, string | undefined>>\n): Layer.Layer<HttpClient> =>\n Layer.effect(\n HttpClient,\n Effect.gen(function*() {\n const shared = yield* dispatcher(environment)\n const ordinary = yield* NodeHttpClient.makeUndici.pipe(Effect.provideService(NodeHttpClient.Dispatcher, shared))\n return withDestinationPinning(EffectHttpClient.transform(ordinary, (execute, request) =>\n Effect.gen(function*() {\n const destination = yield* Destination\n if (destination === undefined) return yield* execute\n const url = new URL(request.url)\n if (\n url.origin !== destination.origin || destination.addresses.length === 0 ||\n destination.addresses.some((address) => isIP(address) === 0)\n ) {\n return yield* Effect.fail(\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({\n request,\n description: \"Invalid pinned HTTP destination\"\n })\n })\n )\n }\n const proxies = [\n environment.http_proxy ?? environment.HTTP_PROXY,\n environment.https_proxy ?? environment.HTTPS_PROXY\n ]\n // The record is read per request, and a live one such as NodeHost's\n // `process.env` can name an unparsable proxy after the shared pool\n // was built from it; that is a refusal here, never a thrown URL error.\n const validProxies = proxies.every((proxy) => {\n if (!proxy) return true\n try {\n return [\"http:\", \"https:\"].includes(new URL(proxy).protocol)\n } catch {\n return false\n }\n })\n if (!validProxies) {\n return yield* Effect.fail(\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({\n request,\n description: \"Pinned HTTP requests require HTTP or HTTPS proxies\"\n })\n })\n )\n }\n const undici = yield* loadUndici\n const addresses = destination.addresses.map((address) => ({ address, family: isIP(address) }))\n // Construction and its disposal are one uninterruptible step: an\n // interruption that lands after the agent exists but before the request\n // owns it would otherwise leave the agent neither destroyed nor closed.\n return yield* Effect.uninterruptibleMask((restore) => {\n const pinned = new undici.EnvHttpProxyAgent({\n httpProxy: environment.http_proxy ?? environment.HTTP_PROXY ?? \"\",\n httpsProxy: environment.https_proxy ?? environment.HTTPS_PROXY ?? \"\",\n noProxy: exclusions(environment.no_proxy ?? environment.NO_PROXY ?? \"\"),\n // Tunnelling HTTP too prevents the proxy resolving the target hostname.\n proxyTunnel: true,\n connect: {\n lookup: (_hostname, options, callback) => {\n const candidates = options.family\n ? addresses.filter((item) => item.family === options.family)\n : addresses\n const first = candidates[0]\n if (first === undefined) {\n return callback(\n new EgressAddressError({\n code: \"no_approved_address\",\n message: \"No approved address for family\"\n }),\n \"\",\n 4\n )\n }\n if (options.all) callback(null, candidates)\n else callback(null, first.address, first.family)\n }\n },\n clientFactory: (origin, options) => {\n const proxy = new undici.Pool(origin, options)\n const connect = proxy.connect.bind(proxy)\n // EnvHttpProxyAgent selects the route using the ORIGINAL hostname.\n // Only the proxy tunnel destination changes; endpoint TLS still uses\n // the original hostname for SNI and certificate verification.\n proxy.connect = (options: Undici.Dispatcher.ConnectOptions) => {\n const address = addresses[0]!.address\n const host = isIP(address) === 6 ? `[${address}]` : address\n const authority = `${host}:${url.port || (url.protocol === \"https:\" ? \"443\" : \"80\")}`\n return connect({ ...options, path: authority, headers: { ...options.headers, host: authority } })\n }\n return proxy\n }\n })\n const pinnedRequest = request.pipe(\n HttpClientRequest.setHeader(\"host\", url.host),\n HttpClientRequest.removeHeader(\"proxy-authorization\"),\n HttpClientRequest.removeHeader(\"connection\"),\n HttpClientRequest.removeHeader(\"transfer-encoding\"),\n HttpClientRequest.removeHeader(\"content-length\")\n )\n return restore(NodeHttpClient.makeUndici.pipe(\n Effect.provideService(NodeHttpClient.Dispatcher, pinned),\n Effect.flatMap((client) => client.execute(pinnedRequest))\n )).pipe(Effect.onExit((exit) =>\n Exit.isFailure(exit)\n ? Effect.promise(() => pinned.destroy())\n // close prevents reuse immediately, but lets the active body drain.\n : Effect.sync(() => {\n void pinned.close().catch(() => pinned.destroy())\n })\n ))\n })\n })))\n })\n )\n\n/**\n * Owns one replaceable Undici pool in the caller's scope. Each replacement\n * receives the same middleware and closes the previous pool.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const rebuildableTransport = (\n acquire: Effect.Effect<Undici.Dispatcher, never, Scope.Scope>,\n decorate: (client: HttpClient) => Effect.Effect<HttpClient> = Effect.succeed\n): Effect.Effect<\n {\n readonly client: HttpClient\n readonly rebuild: Effect.Effect<HttpClient>\n },\n never,\n Scope.Scope\n> =>\n Effect.gen(function*() {\n const scope = yield* Scope.Scope\n const gate = yield* Semaphore.make(1)\n let held: Scope.Closeable | undefined = undefined\n const rebuild = gate.withPermit(Effect.uninterruptibleMask((restore) =>\n Effect.gen(function*() {\n const owned = yield* Scope.fork(scope)\n const client = yield* restore(NodeHttpClient.makeUndici.pipe(\n Effect.provideServiceEffect(NodeHttpClient.Dispatcher, acquire),\n Effect.flatMap(decorate),\n Effect.provideService(Scope.Scope, owned)\n )).pipe(Effect.onExit((exit) => Exit.isSuccess(exit) ? Effect.void : Scope.close(owned, exit)))\n const previous = held\n held = owned\n if (previous !== undefined) yield* Scope.close(previous, Exit.void)\n return client\n })\n ))\n return { client: yield* rebuild, rebuild }\n })\n\n/**\n * A model transport whose replacements retain the caller's grant store and\n * environment proxy policy. Pass it to RequestExecutor.makeWith in the host scope.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const guardedTransport = (environment: Readonly<Record<string, string | undefined>>) =>\n Effect.gen(function*() {\n const grants = yield* GrantStore\n return yield* rebuildableTransport(dispatcher(environment), (client) =>\n HttpClient.pipe(Effect.provide(KernelHttpClient.layer.pipe(\n Layer.provide(Layer.succeed(HttpClient)(client)),\n Layer.provide(Layer.succeed(GrantStore)(grants))\n ))))\n })\n"]}
|
|
1
|
+
{"version":3,"file":"EgressHttpClient.js","sourceRoot":"","sources":["../../src/EgressHttpClient.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The outbound HTTP client a Node process should use, read off its environment.\n *\n * `@effect/platform-node` ships `NodeHttpClient.layerUndici`, and its\n * dispatcher is a bare Undici `Agent`. A bare `Agent` dials every origin\n * directly: it does not read `HTTP_PROXY`, `HTTPS_PROXY` or `NO_PROXY`, and\n * nothing at the call site says so. That is invisible on a developer machine\n * with open egress and fatal inside a sandbox whose egress is default-deny\n * behind a named proxy — the request leaves for the origin, the firewall drops\n * it, and the only symptom is a transport failure far from the composition\n * that chose the client.\n *\n * This module is the one place that decision is made. {@link layer} is the\n * client every Node host composition installs; it honours the proxy the\n * environment names. Requests without a web destination use a shared pool;\n * web requests receive a fresh pinned dispatcher.\n *\n * The rule for loopback is fixed here, not by the environment: `localhost`,\n * `127.0.0.1` and `[::1]` are always reached directly, even when the\n * environment names a proxy and no exclusion, and every other origin follows\n * `NO_PROXY`. A proxy is how a process leaves its machine, and\n * `--remote http://127.0.0.1:3000` is not leaving it. The exemption is those\n * three names and nothing wider: Undici matches `NO_PROXY` entries by name,\n * never by resolved address, so `127.0.0.2` or a hostname that resolves to\n * loopback is an origin like any other and goes through the proxy.\n *\n * @since 1.0.0-rc.0\n */\n\nimport * as NodeHttpClient from \"@effect/platform-node/NodeHttpClient\"\nimport type * as Undici from \"@effect/platform-node/Undici\"\nimport { GrantStore } from \"@smthrs/kernel/GrantStore\"\nimport * as KernelHttpClient from \"@smthrs/kernel/HttpClient\"\nimport { Destination, withDestinationPinning } from \"@smthrs/kernel/HttpClient\"\nimport * as Effect from \"effect/Effect\"\nimport * as Exit from \"effect/Exit\"\nimport { HttpClient } from \"effect/http/HttpClient\"\nimport * as EffectHttpClient from \"effect/http/HttpClient\"\nimport * as HttpClientError from \"effect/http/HttpClientError\"\nimport * as HttpClientRequest from \"effect/http/HttpClientRequest\"\nimport * as Layer from \"effect/Layer\"\nimport * as Schema from \"effect/Schema\"\nimport * as Scope from \"effect/Scope\"\nimport * as Semaphore from \"effect/Semaphore\"\nimport { isIP } from \"node:net\"\n\n/**\n * A pinned connection asked for an address family none of the authorized\n * addresses has. It is the `cause` of the `TransportError` the request fails\n * with; `code` is always `no_approved_address`.\n *\n * @category errors\n * @since 1.0.0\n */\nexport class EgressAddressError extends Schema.TaggedError<EgressAddressError>()(\n \"@smthrs/platform-node/EgressAddressError\",\n { code: Schema.Literal(\"no_approved_address\"), message: Schema.String }\n) {\n override readonly name = \"EgressAddressError\"\n}\n\n/**\n * The hosts a proxy is never for. A proxy is how a process leaves its machine;\n * these names are the machine itself. Matched by name, the way Undici matches\n * every `NO_PROXY` entry, so the list is exactly these three and not\n * `127.0.0.0/8`.\n */\nconst loopback = [\"localhost\", \"127.0.0.1\", \"::1\"] as const\n\n/**\n * The exclusion list to hand Undici, given the one the environment names.\n *\n * Undici proxies *every* origin when `NO_PROXY` is empty — `#shouldProxy`\n * returns early with \"Always proxy if NO_PROXY is not set or empty\" — so a host\n * that names a proxy to reach the internet would also send `smthrs --remote\n * http://127.0.0.1:3000` and a local Ollama at `http://localhost:11434` to it.\n * Nothing in this repository has ever needed `NO_PROXY=127.0.0.1`, because the\n * client these compositions used before ignored the proxy variables outright.\n * So loopback is always excluded, the way Go's `net/http.ProxyFromEnvironment`\n * excludes it, and the environment's own entries are kept beside it.\n *\n * `*` is returned untouched: Undici recognises the wildcard only as the entire\n * value, and it already means every origin is direct.\n */\nconst exclusions = (declared: string): string =>\n declared === \"*\" ? declared : [declared, ...loopback].filter((entry) => entry !== \"\").join(\",\")\n\n// Split ESM bundles expose CommonJS Undici through default, without synthetic\n// named exports. Node and Bun also expose its constructors through default.\n// Its typings declare `default` as a namespace without them, and `bundler`\n// resolution reads that, so the value is typed as the module it carries.\nconst loadUndici = Effect.promise(\n async () => (await import(\"undici/index.js\")).default as unknown as typeof Undici\n)\n\n/**\n * An Undici dispatcher that routes through the egress proxy the supplied\n * environment names, or a direct one when it names none.\n *\n * The proxy variables are read in the order Undici itself reads them,\n * lowercase first, and passed explicitly rather than left to\n * `EnvHttpProxyAgent`'s own ambient lookup: a host serving a guest's\n * environment is not the guest, and the pool has to follow the record it was\n * handed. Loopback is always direct; see {@link exclusions}. Each dispatcher is\n * acquired in the caller's scope and destroyed with it, so a composition that\n * builds several still owns every pool it opened.\n *\n * @param environment the environment record whose proxy variables decide the route\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const dispatcher = (\n environment: Readonly<Record<string, string | undefined>>\n): Effect.Effect<Undici.Dispatcher, never, Scope.Scope> =>\n Effect.suspend(() => {\n const httpProxy = environment.http_proxy ?? environment.HTTP_PROXY ?? \"\"\n const httpsProxy = environment.https_proxy ?? environment.HTTPS_PROXY ?? \"\"\n const noProxy = exclusions(environment.no_proxy ?? environment.NO_PROXY ?? \"\")\n // Explicit empty values prevent Undici from falling back to a different\n // ambient environment. Each replacement pool uses the same proxy policy.\n //\n // Undici is loaded here rather than imported at the top, the way\n // `NodeHttpClient.makeDispatcher` loads it, because this module is imported\n // by `NodeHost` and every bundle built on it. A static import pulls the\n // whole of Undici into any process that merely composes a host, whose\n // side effects a host bundle must not carry: it reddened the Node host's\n // own `FileSystem` contract case, which never makes a request. The explicit\n // package entry also avoids Bun's incomplete built-in \"undici\" substitute.\n return Effect.acquireRelease(\n Effect.map(\n loadUndici,\n (undici) => new undici.EnvHttpProxyAgent({ httpProxy, httpsProxy, noProxy })\n ),\n (dispatcher) => Effect.promise(() => dispatcher.destroy())\n )\n })\n\n/**\n * The Undici `HttpClient` to install, given the environment the process runs in.\n *\n * Use this wherever `NodeHttpClient.layerUndici` would otherwise be provided\n * under a layer that takes `HttpClient` from context — a model transport, a\n * judge, a fetch rule, a host bundle. The two differ only in whether the pool\n * honours `HTTP_PROXY`/`HTTPS_PROXY`/`NO_PROXY`, which is the difference\n * between a request that reaches the gateway from inside a default-deny\n * sandbox and one the firewall drops.\n *\n * @param environment the environment record whose proxy variables decide the route\n * @category layers\n * @since 1.0.0-rc.0\n */\nexport const layer = (\n environment: Readonly<Record<string, string | undefined>>\n): Layer.Layer<HttpClient> =>\n Layer.effect(\n HttpClient,\n Effect.gen(function*() {\n const shared = yield* dispatcher(environment)\n const ordinary = yield* NodeHttpClient.makeUndici.pipe(Effect.provideService(NodeHttpClient.Dispatcher, shared))\n return withDestinationPinning(EffectHttpClient.transform(ordinary, (execute, request) =>\n Effect.gen(function*() {\n const destination = yield* Destination\n if (destination === undefined) return yield* execute\n const url = new URL(request.url)\n if (\n url.origin !== destination.origin || destination.addresses.length === 0 ||\n destination.addresses.some((address) => isIP(address) === 0)\n ) {\n return yield* Effect.fail(\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({\n request,\n description: \"Invalid pinned HTTP destination\"\n })\n })\n )\n }\n const proxies = [\n environment.http_proxy ?? environment.HTTP_PROXY,\n environment.https_proxy ?? environment.HTTPS_PROXY\n ]\n // The record is read per request, and a live one such as NodeHost's\n // `process.env` can name an unparsable proxy after the shared pool\n // was built from it; that is a refusal here, never a thrown URL error.\n const validProxies = proxies.every((proxy) => {\n if (!proxy) return true\n try {\n return [\"http:\", \"https:\"].includes(new URL(proxy).protocol)\n } catch {\n return false\n }\n })\n if (!validProxies) {\n return yield* Effect.fail(\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({\n request,\n description: \"Pinned HTTP requests require HTTP or HTTPS proxies\"\n })\n })\n )\n }\n const undici = yield* loadUndici\n const addresses = destination.addresses.map((address) => ({ address, family: isIP(address) }))\n // Construction and its disposal are one uninterruptible step: an\n // interruption that lands after the agent exists but before the request\n // owns it would otherwise leave the agent neither destroyed nor closed.\n return yield* Effect.uninterruptibleMask((restore) => {\n const pinned = new undici.EnvHttpProxyAgent({\n httpProxy: environment.http_proxy ?? environment.HTTP_PROXY ?? \"\",\n httpsProxy: environment.https_proxy ?? environment.HTTPS_PROXY ?? \"\",\n noProxy: exclusions(environment.no_proxy ?? environment.NO_PROXY ?? \"\"),\n // Tunnelling HTTP too prevents the proxy resolving the target hostname.\n proxyTunnel: true,\n connect: {\n lookup: (_hostname, options, callback) => {\n const candidates = options.family\n ? addresses.filter((item) => item.family === options.family)\n : addresses\n const first = candidates[0]\n if (first === undefined) {\n return callback(\n new EgressAddressError({\n code: \"no_approved_address\",\n message: \"No approved address for family\"\n }),\n \"\",\n 4\n )\n }\n if (options.all) callback(null, candidates)\n else callback(null, first.address, first.family)\n }\n },\n clientFactory: (origin, options) => {\n const proxy = new undici.Pool(origin, options)\n const connect = proxy.connect.bind(proxy)\n // EnvHttpProxyAgent selects the route using the ORIGINAL hostname.\n // Only the proxy tunnel destination changes; endpoint TLS still uses\n // the original hostname for SNI and certificate verification.\n proxy.connect = (options: Undici.Dispatcher.ConnectOptions) => {\n const address = addresses[0]!.address\n const host = isIP(address) === 6 ? `[${address}]` : address\n const authority = `${host}:${url.port || (url.protocol === \"https:\" ? \"443\" : \"80\")}`\n return connect({ ...options, path: authority, headers: { ...options.headers, host: authority } })\n }\n return proxy\n }\n })\n const pinnedRequest = request.pipe(\n HttpClientRequest.setHeader(\"host\", url.host),\n HttpClientRequest.removeHeader(\"proxy-authorization\"),\n HttpClientRequest.removeHeader(\"connection\"),\n HttpClientRequest.removeHeader(\"transfer-encoding\"),\n HttpClientRequest.removeHeader(\"content-length\")\n )\n return restore(NodeHttpClient.makeUndici.pipe(\n Effect.provideService(NodeHttpClient.Dispatcher, pinned),\n Effect.flatMap((client) => client.execute(pinnedRequest))\n )).pipe(Effect.onExit((exit) =>\n Exit.isFailure(exit)\n ? Effect.promise(() => pinned.destroy())\n // close prevents reuse immediately, but lets the active body drain.\n : Effect.sync(() => {\n void pinned.close().catch(() => pinned.destroy())\n })\n ))\n })\n })))\n })\n )\n\n/**\n * Owns one replaceable Undici pool in the caller's scope. Each replacement\n * receives the same middleware and closes the previous pool.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const rebuildableTransport = (\n acquire: Effect.Effect<Undici.Dispatcher, never, Scope.Scope>,\n decorate: (client: HttpClient) => Effect.Effect<HttpClient> = Effect.succeed\n): Effect.Effect<\n {\n readonly client: HttpClient\n readonly rebuild: Effect.Effect<HttpClient>\n },\n never,\n Scope.Scope\n> =>\n Effect.gen(function*() {\n const scope = yield* Scope.Scope\n const gate = yield* Semaphore.make(1)\n let held: Scope.Closeable | undefined = undefined\n const rebuild = gate.withPermit(Effect.uninterruptibleMask((restore) =>\n Effect.gen(function*() {\n const owned = yield* Scope.fork(scope)\n const client = yield* restore(NodeHttpClient.makeUndici.pipe(\n Effect.provideServiceEffect(NodeHttpClient.Dispatcher, acquire),\n Effect.flatMap(decorate),\n Effect.provideService(Scope.Scope, owned)\n )).pipe(Effect.onExit((exit) => Exit.isSuccess(exit) ? Effect.void : Scope.close(owned, exit)))\n const previous = held\n held = owned\n if (previous !== undefined) yield* Scope.close(previous, Exit.void)\n return client\n })\n ))\n return { client: yield* rebuild, rebuild }\n })\n\n/**\n * A model transport whose replacements retain the caller's grant store and\n * environment proxy policy. Pass it to RequestExecutor.makeWith in the host scope.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const guardedTransport = (environment: Readonly<Record<string, string | undefined>>) =>\n Effect.gen(function*() {\n const grants = yield* GrantStore\n return yield* rebuildableTransport(dispatcher(environment), (client) =>\n HttpClient.pipe(Effect.provide(KernelHttpClient.layer.pipe(\n Layer.provide(Layer.succeed(HttpClient)(client)),\n Layer.provide(Layer.succeed(GrantStore)(grants))\n ))))\n })\n"]}
|
package/dist/esm/NodeHost.d.ts
CHANGED
|
@@ -29,11 +29,11 @@ import type { HostServiceIds } from "@smthrs/kernel/HostServices";
|
|
|
29
29
|
import type * as KernelProcessConfinement from "@smthrs/kernel/ProcessConfinement";
|
|
30
30
|
import type * as ProcessLedger from "@smthrs/kernel/ProcessLedger";
|
|
31
31
|
import type { FileSystem } from "effect/FileSystem";
|
|
32
|
+
import type { HttpClient } from "effect/http/HttpClient";
|
|
32
33
|
import * as Layer from "effect/Layer";
|
|
33
34
|
import type * as Path from "effect/Path";
|
|
35
|
+
import type { ChildProcessSpawner } from "effect/process/ChildProcessSpawner";
|
|
34
36
|
import * as Schema from "effect/Schema";
|
|
35
|
-
import type { HttpClient } from "effect/unstable/http/HttpClient";
|
|
36
|
-
import type { ChildProcessSpawner } from "effect/unstable/process/ChildProcessSpawner";
|
|
37
37
|
import * as AtomicFileSystem from "./AtomicFileSystem.ts";
|
|
38
38
|
import * as EgressHttpClient from "./EgressHttpClient.ts";
|
|
39
39
|
import * as ProcessReaper from "./ProcessReaper.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeHost.d.ts","sourceRoot":"","sources":["../../src/NodeHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,uBAAuB,MAAM,+CAA+C,CAAA;AACxF,OAAO,KAAK,UAAU,MAAM,kCAAkC,CAAA;AAC9D,OAAO,KAAK,cAAc,MAAM,sCAAsC,CAAA;AACtE,OAAO,KAAK,cAAc,MAAM,sCAAsC,CAAA;AAEtE,OAAO,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,KAAK,KAAK,wBAAwB,MAAM,mCAAmC,CAAA;AAClF,OAAO,KAAK,KAAK,aAAa,MAAM,8BAA8B,CAAA;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"NodeHost.d.ts","sourceRoot":"","sources":["../../src/NodeHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,uBAAuB,MAAM,+CAA+C,CAAA;AACxF,OAAO,KAAK,UAAU,MAAM,kCAAkC,CAAA;AAC9D,OAAO,KAAK,cAAc,MAAM,sCAAsC,CAAA;AACtE,OAAO,KAAK,cAAc,MAAM,sCAAsC,CAAA;AAEtE,OAAO,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,KAAK,KAAK,wBAAwB,MAAM,mCAAmC,CAAA;AAClF,OAAO,KAAK,KAAK,aAAa,MAAM,8BAA8B,CAAA;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,KAAK,IAAI,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAA;AAC7E,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AAEzD,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;;;;;;;;;;;;GAaG;AACH,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,UAAU,EACV,cAAc,EACd,cAAc,EACd,aAAa,EACd,CAAA;AAcD;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAChB,UAAU,GACV,IAAI,CAAC,IAAI,GACT,mBAAmB,GACnB,EAAE,GACF,UAAU,GACV,wBAAwB,CAAC,kBAAkB,CAAA;;;;;AAE/C;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,kBAGjC;IACA,SAAkB,IAAI,mBAAkB;CACzC;AAYD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAMvF,CAAA;AAKD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,cAAc,GAAG,aAAa,CAAC,OAAO,CAAA;AAQnF;;;;;GAKG;AACH,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAMhD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,OAAO,GAAI,gBAAgB,MAAM,KAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAO3E,CAAA;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,cAAc,GACzB,UAAU,gBAAgB,KACzB,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,aAAa,CAgB5D,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC3B,gBAAgB,MAAM,EACtB,UAAU,gBAAgB,KACzB,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,aAAa,CAW5D,CAAA"}
|
package/dist/esm/NodeHost.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeHost.js","sourceRoot":"","sources":["../../src/NodeHost.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Aggregate Node.js Host bundle.\n *\n * This module defines the `NodeHost` service union and a single `layer` that\n * provides the closed Host surface backed by Node: `@effect/platform-node`'s\n * filesystem, child-process spawner, Undici `HttpClient`, native `Path`,\n * and the Node `Jj` adapter from its own package. Use the layer when a Node\n * program wants every host capability from one place; use the individual\n * modules when a program should only be able to reach part of the host. The\n * bundle also supplies native `ProcessConfinement` for the kernel spawner.\n *\n * There is no Node HTTP module either: outgoing requests are Effect's\n * `HttpClient`, and `@effect/platform-node` already ships the Undici-backed\n * implementation. Undici follows no redirect unless a redirect interceptor is\n * installed, so every hop stays visible to `@smthrs/kernel`'s decorator.\n *\n * There is no Node shell module: running a command is Effect's\n * `ChildProcessSpawner`, and `@effect/platform-node` already ships the\n * implementation.\n *\n * @since 0.1.0\n */\n\nimport * as NodeChildProcessSpawner from \"@effect/platform-node/NodeChildProcessSpawner\"\nimport * as NodeCrypto from \"@effect/platform-node/NodeCrypto\"\nimport * as NodeFileSystem from \"@effect/platform-node/NodeFileSystem\"\nimport * as NodeHttpClient from \"@effect/platform-node/NodeHttpClient\"\nimport * as NodePath from \"@effect/platform-node/NodePath\"\nimport type { Jj, JjError } from \"@smthrs/jj\"\nimport * as NodeJj from \"@smthrs/jj/node/NodeJj\"\nimport type { HostServiceIds } from \"@smthrs/kernel/HostServices\"\nimport type * as KernelProcessConfinement from \"@smthrs/kernel/ProcessConfinement\"\nimport type * as ProcessLedger from \"@smthrs/kernel/ProcessLedger\"\nimport type { FileSystem } from \"effect/FileSystem\"\nimport * as Layer from \"effect/Layer\"\nimport type * as Path from \"effect/Path\"\nimport * as Schema from \"effect/Schema\"\nimport type { HttpClient } from \"effect/unstable/http/HttpClient\"\nimport type { ChildProcessSpawner } from \"effect/unstable/process/ChildProcessSpawner\"\nimport { isAbsolute } from \"node:path\"\nimport * as AtomicFileSystem from \"./AtomicFileSystem.ts\"\nimport * as EgressHttpClient from \"./EgressHttpClient.ts\"\nimport * as ProcessConfinement from \"./ProcessConfinement.ts\"\nimport * as ProcessReaper from \"./ProcessReaper.ts\"\n\n/**\n * The Node platform modules Effect ships, re-exported so a program that wants\n * only part of the host has one place to reach for them. `NodeJj` belongs to\n * `@smthrs/jj`; import it from there.\n *\n * `NodeCrypto` is here for a different reason than the rest. `Crypto` is not a\n * Host service — it carries no host authority the kernel could attenuate, so\n * it is not in {@link NodeHost} and not in the closed list — but every durable\n * composition needs one, and a program that already depends on this package\n * for its host should not have to add a second dependency for the digest.\n *\n * @category re-exports\n * @since 0.1.0\n */\nexport {\n AtomicFileSystem,\n EgressHttpClient,\n NodeChildProcessSpawner,\n NodeCrypto,\n NodeFileSystem,\n NodeHttpClient,\n ProcessReaper\n}\n\n/**\n * The `HttpClient` every bundle below installs: Undici through the egress\n * proxy this process's environment names, and a direct Undici pool when it\n * names none.\n *\n * `NodeHttpClient.layerUndici` is the direct pool unconditionally. It is still\n * re-exported above for a program composing its own services, but a bundle\n * that spans a whole host has to work inside a sandbox whose only way out is a\n * proxy, so the bundles read the environment. See {@link EgressHttpClient}.\n */\nconst httpClient = EgressHttpClient.layer(process.env)\n\n/**\n * The union of host services provided by the Node host layer.\n *\n * @category models\n * @since 0.1.0\n */\nexport type NodeHost =\n | FileSystem\n | Path.Path\n | ChildProcessSpawner\n | Jj\n | HttpClient\n | KernelProcessConfinement.ProcessConfinement\n\n/**\n * Invalid repository-root configuration, refused before layer construction.\n * @category errors\n * @since 1.0.0-rc.0\n */\nexport class NodeHostError extends Schema.TaggedError<NodeHostError>()(\"@smthrs/platform-node/NodeHostError\", {\n code: Schema.Literal(\"invalid_repository_root\"),\n message: Schema.String\n}) {\n override readonly name = \"NodeHostError\"\n}\n\nconst absoluteRoot = (root: string): string => {\n if (isAbsolute(root)) return root\n throw new NodeHostError({\n code: \"invalid_repository_root\",\n message: `NodeHost requires an absolute repository root, got ${\n JSON.stringify(Array.from(root).slice(0, 64).join(\"\"))\n }`\n })\n}\n\n/**\n * Stable implementation identities for the raw bundle's five Host slots.\n * Contained POSIX factories replace its spawner with {@link ProcessReaper.layerSpawner}.\n * @category models\n * @since 1.0.0-rc.0\n */\nexport const implementationIds: Readonly<Record<(typeof HostServiceIds)[number], string>> = {\n \"effect/FileSystem\": \"@smthrs/platform-node/AtomicFileSystem\",\n \"effect/Path\": \"@effect/platform-node/NodePath\",\n \"effect/process/ChildProcessSpawner\": \"@effect/platform-node/NodeChildProcessSpawner\",\n \"@smthrs/jj/Jj\": \"@smthrs/jj/node/NodeJj\",\n \"effect/HttpClient\": \"@smthrs/platform-node/EgressHttpClient\"\n}\n\n/** The two services `NodeChildProcessSpawner` resolves paths and files with. */\nconst platform = Layer.mergeAll(AtomicFileSystem.layer, NodePath.layer)\n\n/**\n * What a caller may configure about a contained Node host.\n *\n * `platform` is deliberately absent. `ContainedSpawner.Options` declares it so a\n * caller that supplies its own spawner can describe one, but this native host\n * detaches by `process.platform` whatever a record claims. A caller-supplied\n * `\"win32\"` on a POSIX host would therefore\n * record `pgid: null` for a child that really does lead a group, and\n * {@link ProcessReaper.reap} would retire that record as `no-group` and leave\n * the orphan running forever — a durable lie rather than a compile error.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type ContainedOptions = ProcessReaper.SpawnerOptions & ProcessReaper.Options\n\n/** The reaper half of {@link ContainedOptions}. */\nconst reaping = (options?: ContainedOptions): ProcessReaper.Options => ({\n ownerPid: options?.ownerPid,\n system: options?.system\n})\n\n/**\n * Provides the default Node implementations for the whole closed Host surface.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layer: Layer.Layer<NodeHost, JjError> = Layer.mergeAll(\n ProcessConfinement.layer(),\n platform,\n Layer.provide(NodeChildProcessSpawner.layer, platform),\n httpClient,\n NodeJj.layer\n)\n\n/**\n * Provides the Node host with `Jj` bound to one absolute repository root.\n *\n * @category layers\n * @since 1.0.0\n */\nexport const layerAt = (repositoryRoot: string): Layer.Layer<NodeHost, JjError> =>\n Layer.mergeAll(\n ProcessConfinement.layer(),\n platform,\n Layer.provide(NodeChildProcessSpawner.layer, platform),\n httpClient,\n NodeJj.layerAt(absoluteRoot(repositoryRoot))\n )\n\n/**\n * Provides the Node host with process containment turned on.\n *\n * The difference from {@link layer} is what happens to a spawned process when\n * its run stops. Under {@link layer} a child is signalled when its scope\n * closes and then waited for, forever if it ignores `SIGTERM`, and a host that\n * dies without closing its scopes abandons every child it started. This layer\n * gives each child an escalation deadline and records it in the\n * `ProcessLedger`, then sweeps the records a previous incarnation of the same\n * host left behind before it hands the host over\n * ({@link ProcessReaper.reap}).\n *\n * jj is contained here too: `layerContained` builds the `Jj` service over the\n * same spawner rather than letting it start its own children, so a `jj`\n * invocation a crashed host left running is a record the next incarnation\n * reaps like any other.\n *\n * The ledger is a requirement rather than a default because the durable half\n * of containment is only as good as the journal underneath it:\n * `ProcessLedger.layer` inherits a crashed incarnation's processes,\n * `ProcessLedger.layerMemory` contains this incarnation and nothing more, and\n * the choice belongs to the program that knows which it has.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layerContained = (\n options?: ContainedOptions\n): Layer.Layer<NodeHost, JjError, ProcessLedger.ProcessLedger> => {\n const spawner = Layer.provide(\n ProcessReaper.layerSpawner({ graceMs: options?.graceMs }),\n Layer.provide(NodeChildProcessSpawner.layer, platform)\n )\n return Layer.mergeAll(\n ProcessConfinement.layer(),\n platform,\n httpClient,\n // jj goes through the CONTAINED spawner here, not around it. `NodeJj.layer`\n // spawns its own children, which is right for a host that has no spawner\n // to offer, but under containment it would mean a `jj` that leads no\n // recorded process group, appears in no ledger, and survives the\n // incarnation that started it.\n Layer.provideMerge(NodeJj.layerSpawner, spawner)\n ).pipe(Layer.provideMerge(ProcessReaper.layer(reaping(options))))\n}\n\n/**\n * Provides the contained Node host with `Jj` bound to one absolute repository\n * root.\n *\n * @category layers\n * @since 1.0.0\n */\nexport const layerContainedAt = (\n repositoryRoot: string,\n options?: ContainedOptions\n): Layer.Layer<NodeHost, JjError, ProcessLedger.ProcessLedger> => {\n const spawner = Layer.provide(\n ProcessReaper.layerSpawner({ graceMs: options?.graceMs }),\n Layer.provide(NodeChildProcessSpawner.layer, platform)\n )\n return Layer.mergeAll(\n ProcessConfinement.layer(),\n platform,\n httpClient,\n Layer.provideMerge(NodeJj.layerSpawnerAt(absoluteRoot(repositoryRoot)), spawner)\n ).pipe(Layer.provideMerge(ProcessReaper.layer(reaping(options))))\n}\n"]}
|
|
1
|
+
{"version":3,"file":"NodeHost.js","sourceRoot":"","sources":["../../src/NodeHost.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Aggregate Node.js Host bundle.\n *\n * This module defines the `NodeHost` service union and a single `layer` that\n * provides the closed Host surface backed by Node: `@effect/platform-node`'s\n * filesystem, child-process spawner, Undici `HttpClient`, native `Path`,\n * and the Node `Jj` adapter from its own package. Use the layer when a Node\n * program wants every host capability from one place; use the individual\n * modules when a program should only be able to reach part of the host. The\n * bundle also supplies native `ProcessConfinement` for the kernel spawner.\n *\n * There is no Node HTTP module either: outgoing requests are Effect's\n * `HttpClient`, and `@effect/platform-node` already ships the Undici-backed\n * implementation. Undici follows no redirect unless a redirect interceptor is\n * installed, so every hop stays visible to `@smthrs/kernel`'s decorator.\n *\n * There is no Node shell module: running a command is Effect's\n * `ChildProcessSpawner`, and `@effect/platform-node` already ships the\n * implementation.\n *\n * @since 0.1.0\n */\n\nimport * as NodeChildProcessSpawner from \"@effect/platform-node/NodeChildProcessSpawner\"\nimport * as NodeCrypto from \"@effect/platform-node/NodeCrypto\"\nimport * as NodeFileSystem from \"@effect/platform-node/NodeFileSystem\"\nimport * as NodeHttpClient from \"@effect/platform-node/NodeHttpClient\"\nimport * as NodePath from \"@effect/platform-node/NodePath\"\nimport type { Jj, JjError } from \"@smthrs/jj\"\nimport * as NodeJj from \"@smthrs/jj/node/NodeJj\"\nimport type { HostServiceIds } from \"@smthrs/kernel/HostServices\"\nimport type * as KernelProcessConfinement from \"@smthrs/kernel/ProcessConfinement\"\nimport type * as ProcessLedger from \"@smthrs/kernel/ProcessLedger\"\nimport type { FileSystem } from \"effect/FileSystem\"\nimport type { HttpClient } from \"effect/http/HttpClient\"\nimport * as Layer from \"effect/Layer\"\nimport type * as Path from \"effect/Path\"\nimport type { ChildProcessSpawner } from \"effect/process/ChildProcessSpawner\"\nimport * as Schema from \"effect/Schema\"\nimport { isAbsolute } from \"node:path\"\nimport * as AtomicFileSystem from \"./AtomicFileSystem.ts\"\nimport * as EgressHttpClient from \"./EgressHttpClient.ts\"\nimport * as ProcessConfinement from \"./ProcessConfinement.ts\"\nimport * as ProcessReaper from \"./ProcessReaper.ts\"\n\n/**\n * The Node platform modules Effect ships, re-exported so a program that wants\n * only part of the host has one place to reach for them. `NodeJj` belongs to\n * `@smthrs/jj`; import it from there.\n *\n * `NodeCrypto` is here for a different reason than the rest. `Crypto` is not a\n * Host service — it carries no host authority the kernel could attenuate, so\n * it is not in {@link NodeHost} and not in the closed list — but every durable\n * composition needs one, and a program that already depends on this package\n * for its host should not have to add a second dependency for the digest.\n *\n * @category re-exports\n * @since 0.1.0\n */\nexport {\n AtomicFileSystem,\n EgressHttpClient,\n NodeChildProcessSpawner,\n NodeCrypto,\n NodeFileSystem,\n NodeHttpClient,\n ProcessReaper\n}\n\n/**\n * The `HttpClient` every bundle below installs: Undici through the egress\n * proxy this process's environment names, and a direct Undici pool when it\n * names none.\n *\n * `NodeHttpClient.layerUndici` is the direct pool unconditionally. It is still\n * re-exported above for a program composing its own services, but a bundle\n * that spans a whole host has to work inside a sandbox whose only way out is a\n * proxy, so the bundles read the environment. See {@link EgressHttpClient}.\n */\nconst httpClient = EgressHttpClient.layer(process.env)\n\n/**\n * The union of host services provided by the Node host layer.\n *\n * @category models\n * @since 0.1.0\n */\nexport type NodeHost =\n | FileSystem\n | Path.Path\n | ChildProcessSpawner\n | Jj\n | HttpClient\n | KernelProcessConfinement.ProcessConfinement\n\n/**\n * Invalid repository-root configuration, refused before layer construction.\n * @category errors\n * @since 1.0.0-rc.0\n */\nexport class NodeHostError extends Schema.TaggedError<NodeHostError>()(\"@smthrs/platform-node/NodeHostError\", {\n code: Schema.Literal(\"invalid_repository_root\"),\n message: Schema.String\n}) {\n override readonly name = \"NodeHostError\"\n}\n\nconst absoluteRoot = (root: string): string => {\n if (isAbsolute(root)) return root\n throw new NodeHostError({\n code: \"invalid_repository_root\",\n message: `NodeHost requires an absolute repository root, got ${\n JSON.stringify(Array.from(root).slice(0, 64).join(\"\"))\n }`\n })\n}\n\n/**\n * Stable implementation identities for the raw bundle's five Host slots.\n * Contained POSIX factories replace its spawner with {@link ProcessReaper.layerSpawner}.\n * @category models\n * @since 1.0.0-rc.0\n */\nexport const implementationIds: Readonly<Record<(typeof HostServiceIds)[number], string>> = {\n \"effect/FileSystem\": \"@smthrs/platform-node/AtomicFileSystem\",\n \"effect/Path\": \"@effect/platform-node/NodePath\",\n \"effect/process/ChildProcessSpawner\": \"@effect/platform-node/NodeChildProcessSpawner\",\n \"@smthrs/jj/Jj\": \"@smthrs/jj/node/NodeJj\",\n \"effect/HttpClient\": \"@smthrs/platform-node/EgressHttpClient\"\n}\n\n/** The two services `NodeChildProcessSpawner` resolves paths and files with. */\nconst platform = Layer.mergeAll(AtomicFileSystem.layer, NodePath.layer)\n\n/**\n * What a caller may configure about a contained Node host.\n *\n * `platform` is deliberately absent. `ContainedSpawner.Options` declares it so a\n * caller that supplies its own spawner can describe one, but this native host\n * detaches by `process.platform` whatever a record claims. A caller-supplied\n * `\"win32\"` on a POSIX host would therefore\n * record `pgid: null` for a child that really does lead a group, and\n * {@link ProcessReaper.reap} would retire that record as `no-group` and leave\n * the orphan running forever — a durable lie rather than a compile error.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type ContainedOptions = ProcessReaper.SpawnerOptions & ProcessReaper.Options\n\n/** The reaper half of {@link ContainedOptions}. */\nconst reaping = (options?: ContainedOptions): ProcessReaper.Options => ({\n ownerPid: options?.ownerPid,\n system: options?.system\n})\n\n/**\n * Provides the default Node implementations for the whole closed Host surface.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layer: Layer.Layer<NodeHost, JjError> = Layer.mergeAll(\n ProcessConfinement.layer(),\n platform,\n Layer.provide(NodeChildProcessSpawner.layer, platform),\n httpClient,\n NodeJj.layer\n)\n\n/**\n * Provides the Node host with `Jj` bound to one absolute repository root.\n *\n * @category layers\n * @since 1.0.0\n */\nexport const layerAt = (repositoryRoot: string): Layer.Layer<NodeHost, JjError> =>\n Layer.mergeAll(\n ProcessConfinement.layer(),\n platform,\n Layer.provide(NodeChildProcessSpawner.layer, platform),\n httpClient,\n NodeJj.layerAt(absoluteRoot(repositoryRoot))\n )\n\n/**\n * Provides the Node host with process containment turned on.\n *\n * The difference from {@link layer} is what happens to a spawned process when\n * its run stops. Under {@link layer} a child is signalled when its scope\n * closes and then waited for, forever if it ignores `SIGTERM`, and a host that\n * dies without closing its scopes abandons every child it started. This layer\n * gives each child an escalation deadline and records it in the\n * `ProcessLedger`, then sweeps the records a previous incarnation of the same\n * host left behind before it hands the host over\n * ({@link ProcessReaper.reap}).\n *\n * jj is contained here too: `layerContained` builds the `Jj` service over the\n * same spawner rather than letting it start its own children, so a `jj`\n * invocation a crashed host left running is a record the next incarnation\n * reaps like any other.\n *\n * The ledger is a requirement rather than a default because the durable half\n * of containment is only as good as the journal underneath it:\n * `ProcessLedger.layer` inherits a crashed incarnation's processes,\n * `ProcessLedger.layerMemory` contains this incarnation and nothing more, and\n * the choice belongs to the program that knows which it has.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layerContained = (\n options?: ContainedOptions\n): Layer.Layer<NodeHost, JjError, ProcessLedger.ProcessLedger> => {\n const spawner = Layer.provide(\n ProcessReaper.layerSpawner({ graceMs: options?.graceMs }),\n Layer.provide(NodeChildProcessSpawner.layer, platform)\n )\n return Layer.mergeAll(\n ProcessConfinement.layer(),\n platform,\n httpClient,\n // jj goes through the CONTAINED spawner here, not around it. `NodeJj.layer`\n // spawns its own children, which is right for a host that has no spawner\n // to offer, but under containment it would mean a `jj` that leads no\n // recorded process group, appears in no ledger, and survives the\n // incarnation that started it.\n Layer.provideMerge(NodeJj.layerSpawner, spawner)\n ).pipe(Layer.provideMerge(ProcessReaper.layer(reaping(options))))\n}\n\n/**\n * Provides the contained Node host with `Jj` bound to one absolute repository\n * root.\n *\n * @category layers\n * @since 1.0.0\n */\nexport const layerContainedAt = (\n repositoryRoot: string,\n options?: ContainedOptions\n): Layer.Layer<NodeHost, JjError, ProcessLedger.ProcessLedger> => {\n const spawner = Layer.provide(\n ProcessReaper.layerSpawner({ graceMs: options?.graceMs }),\n Layer.provide(NodeChildProcessSpawner.layer, platform)\n )\n return Layer.mergeAll(\n ProcessConfinement.layer(),\n platform,\n httpClient,\n Layer.provideMerge(NodeJj.layerSpawnerAt(absoluteRoot(repositoryRoot)), spawner)\n ).pipe(Layer.provideMerge(ProcessReaper.layer(reaping(options))))\n}\n"]}
|
|
@@ -26,7 +26,7 @@ import * as KernelProcessConfinement from "@smthrs/kernel/ProcessConfinement";
|
|
|
26
26
|
import * as Effect from "effect/Effect";
|
|
27
27
|
import * as Layer from "effect/Layer";
|
|
28
28
|
import * as PlatformError from "effect/PlatformError";
|
|
29
|
-
import * as ChildProcess from "effect/
|
|
29
|
+
import * as ChildProcess from "effect/process/ChildProcess";
|
|
30
30
|
import * as NodeFs from "node:fs";
|
|
31
31
|
import * as NodeOs from "node:os";
|
|
32
32
|
import * as NodePath from "node:path";
|