@smthrs/platform-bun 0.0.0-stage → 1.0.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +73 -0
- package/LICENSE +21 -0
- package/README.md +113 -2
- package/dist/cjs/BunFileSystem.d.ts +44 -0
- package/dist/cjs/BunFileSystem.d.ts.map +1 -0
- package/dist/cjs/BunFileSystem.js +38 -0
- package/dist/cjs/BunFileSystem.js.map +7 -0
- package/dist/cjs/BunHost.d.ts +205 -0
- package/dist/cjs/BunHost.d.ts.map +1 -0
- package/dist/cjs/BunHost.js +147 -0
- package/dist/cjs/BunHost.js.map +7 -0
- package/dist/cjs/index.d.ts +26 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +37 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/BunFileSystem.d.ts +44 -0
- package/dist/esm/BunFileSystem.d.ts.map +1 -0
- package/dist/esm/BunFileSystem.js +35 -0
- package/dist/esm/BunFileSystem.js.map +1 -0
- package/dist/esm/BunHost.d.ts +205 -0
- package/dist/esm/BunHost.d.ts.map +1 -0
- package/dist/esm/BunHost.js +242 -0
- package/dist/esm/BunHost.js.map +1 -0
- package/dist/esm/index.d.ts +26 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +26 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/vendor/adapters.json +2707 -0
- package/dist/vendor/bun/BunChildProcessSpawner.d.ts +7 -0
- package/dist/vendor/bun/BunChildProcessSpawner.js +14 -0
- package/dist/vendor/bun/BunClusterHttp.d.ts +83 -0
- package/dist/vendor/bun/BunClusterHttp.js +39 -0
- package/dist/vendor/bun/BunClusterSocket.d.ts +65 -0
- package/dist/vendor/bun/BunClusterSocket.js +22 -0
- package/dist/vendor/bun/BunCrypto.d.ts +10 -0
- package/dist/vendor/bun/BunCrypto.js +8 -0
- package/dist/vendor/bun/BunFileSystem.d.ts +10 -0
- package/dist/vendor/bun/BunFileSystem.js +9 -0
- package/dist/vendor/bun/BunHttpClient.d.ts +9 -0
- package/dist/vendor/bun/BunHttpClient.js +1 -0
- package/dist/vendor/bun/BunHttpPlatform.d.ts +10 -0
- package/dist/vendor/bun/BunHttpPlatform.js +11 -0
- package/dist/vendor/bun/BunHttpServer.d.ts +142 -0
- package/dist/vendor/bun/BunHttpServer.js +38 -0
- package/dist/vendor/bun/BunHttpServerRequest.d.ts +18 -0
- package/dist/vendor/bun/BunHttpServerRequest.js +7 -0
- package/dist/vendor/bun/BunMultipart.d.ts +31 -0
- package/dist/vendor/bun/BunMultipart.js +12 -0
- package/dist/vendor/bun/BunPath.d.ts +24 -0
- package/dist/vendor/bun/BunPath.js +12 -0
- package/dist/vendor/bun/BunRedis.d.ts +49 -0
- package/dist/vendor/bun/BunRedis.js +11 -0
- package/dist/vendor/bun/BunRuntime.d.ts +85 -0
- package/dist/vendor/bun/BunRuntime.js +8 -0
- package/dist/vendor/bun/BunServices.d.ts +34 -0
- package/dist/vendor/bun/BunServices.js +23 -0
- package/dist/vendor/bun/BunSink.d.ts +8 -0
- package/dist/vendor/bun/BunSink.js +12 -0
- package/dist/vendor/bun/BunSocket.d.ts +40 -0
- package/dist/vendor/bun/BunSocket.js +29 -0
- package/dist/vendor/bun/BunSocketServer.d.ts +8 -0
- package/dist/vendor/bun/BunSocketServer.js +21 -0
- package/dist/vendor/bun/BunStdio.d.ts +11 -0
- package/dist/vendor/bun/BunStdio.js +10 -0
- package/dist/vendor/bun/BunStream.d.ts +19 -0
- package/dist/vendor/bun/BunStream.js +30 -0
- package/dist/vendor/bun/BunTerminal.d.ts +21 -0
- package/dist/vendor/bun/BunTerminal.js +10 -0
- package/dist/vendor/bun/BunWorker.d.ts +20 -0
- package/dist/vendor/bun/BunWorker.js +9 -0
- package/dist/vendor/bun/BunWorkerRunner.d.ts +12 -0
- package/dist/vendor/bun/BunWorkerRunner.js +7 -0
- package/dist/vendor/bun/LICENSE +21 -0
- package/dist/vendor/bun/index.d.ts +92 -0
- package/dist/vendor/bun/index.js +107 -0
- package/dist/vendor/chunk-2KZ2IFIZ.js +71 -0
- package/dist/vendor/chunk-2Y7WC4KU.js +109 -0
- package/dist/vendor/chunk-3GR5VZ2M.js +118 -0
- package/dist/vendor/chunk-3QW2PNUY.js +7 -0
- package/dist/vendor/chunk-42QKY6T6.js +40 -0
- package/dist/vendor/chunk-54RLBMTZ.js +61 -0
- package/dist/vendor/chunk-5U3MC37H.js +63 -0
- package/dist/vendor/chunk-5ZMHBXIK.js +55 -0
- package/dist/vendor/chunk-64Q2B7BA.js +34 -0
- package/dist/vendor/chunk-6CRG556Y.js +15 -0
- package/dist/vendor/chunk-6HWHSZL3.js +34 -0
- package/dist/vendor/chunk-6J25AYCI.js +93 -0
- package/dist/vendor/chunk-6ME2W7TF.js +28 -0
- package/dist/vendor/chunk-6TZ7LQAC.js +18 -0
- package/dist/vendor/chunk-B3FZ67QU.js +59 -0
- package/dist/vendor/chunk-BBLQEPNJ.js +22 -0
- package/dist/vendor/chunk-BKTBUBQY.js +437 -0
- package/dist/vendor/chunk-CIB6JB2Y.js +63 -0
- package/dist/vendor/chunk-DS7GF46S.js +34 -0
- package/dist/vendor/chunk-DVOAHXPG.js +104 -0
- package/dist/vendor/chunk-DWSHTSVX.js +229 -0
- package/dist/vendor/chunk-EGBNVEEW.js +14 -0
- package/dist/vendor/chunk-EHDTBBPL.js +45 -0
- package/dist/vendor/chunk-EZWY45HP.js +18 -0
- package/dist/vendor/chunk-F7VENFF4.js +507 -0
- package/dist/vendor/chunk-GXCHI7BM.js +131 -0
- package/dist/vendor/chunk-HX4AXITW.js +65 -0
- package/dist/vendor/chunk-IIJ52ZU6.js +20 -0
- package/dist/vendor/chunk-IR7WG7SA.js +564 -0
- package/dist/vendor/chunk-J7A4CZDO.js +92 -0
- package/dist/vendor/chunk-JG5TTWPT.js +85 -0
- package/dist/vendor/chunk-JJ24ARBQ.js +394 -0
- package/dist/vendor/chunk-JUVIPOOR.js +18 -0
- package/dist/vendor/chunk-KCLEGTEN.js +86 -0
- package/dist/vendor/chunk-KOZMM5PZ.js +426 -0
- package/dist/vendor/chunk-KUUXSID7.js +18 -0
- package/dist/vendor/chunk-KWOY4JDR.js +398 -0
- package/dist/vendor/chunk-LEUPYT3Q.js +36 -0
- package/dist/vendor/chunk-LJVI2DIF.js +57 -0
- package/dist/vendor/chunk-M32LDTW7.js +18 -0
- package/dist/vendor/chunk-M7CLUILA.js +0 -0
- package/dist/vendor/chunk-MBSKBQ5D.js +21 -0
- package/dist/vendor/chunk-MLKGABMK.js +9 -0
- package/dist/vendor/chunk-MMEGG3WE.js +96 -0
- package/dist/vendor/chunk-MSWDMTAF.js +18 -0
- package/dist/vendor/chunk-NBVRTDTV.js +129 -0
- package/dist/vendor/chunk-NBYGGMAE.js +70 -0
- package/dist/vendor/chunk-NLMT7VBU.js +18 -0
- package/dist/vendor/chunk-OXNGN5H7.js +81 -0
- package/dist/vendor/chunk-RBKBXDZW.js +18 -0
- package/dist/vendor/chunk-RNBBYWS2.js +26 -0
- package/dist/vendor/chunk-SFHVFMSR.js +18 -0
- package/dist/vendor/chunk-TFIKFFSC.js +26 -0
- package/dist/vendor/chunk-TXKLEBBL.js +143 -0
- package/dist/vendor/chunk-U6OWSZD2.js +62 -0
- package/dist/vendor/chunk-UFH5UUZK.js +48 -0
- package/dist/vendor/chunk-UJAEC4DS.js +20 -0
- package/dist/vendor/chunk-VZBDV3TV.js +18 -0
- package/dist/vendor/chunk-WGN4AMSX.js +0 -0
- package/dist/vendor/chunk-WIYD3THC.js +31 -0
- package/dist/vendor/chunk-XDKNKFBW.js +22 -0
- package/dist/vendor/chunk-XH4U3JSV.js +249 -0
- package/dist/vendor/chunk-XWPHMSXO.js +28 -0
- package/dist/vendor/chunk-Y35ZAO5U.js +53 -0
- package/dist/vendor/chunk-ZJMRMY57.js +0 -0
- package/dist/vendor/cjs/bun/BunChildProcessSpawner.d.ts +7 -0
- package/dist/vendor/cjs/bun/BunChildProcessSpawner.js +1 -0
- package/dist/vendor/cjs/bun/BunClusterHttp.d.ts +83 -0
- package/dist/vendor/cjs/bun/BunClusterHttp.js +1 -0
- package/dist/vendor/cjs/bun/BunClusterSocket.d.ts +65 -0
- package/dist/vendor/cjs/bun/BunClusterSocket.js +1 -0
- package/dist/vendor/cjs/bun/BunCrypto.d.ts +10 -0
- package/dist/vendor/cjs/bun/BunCrypto.js +1 -0
- package/dist/vendor/cjs/bun/BunFileSystem.d.ts +10 -0
- package/dist/vendor/cjs/bun/BunFileSystem.js +1 -0
- package/dist/vendor/cjs/bun/BunHttpClient.d.ts +9 -0
- package/dist/vendor/cjs/bun/BunHttpClient.js +1 -0
- package/dist/vendor/cjs/bun/BunHttpPlatform.d.ts +10 -0
- package/dist/vendor/cjs/bun/BunHttpPlatform.js +1 -0
- package/dist/vendor/cjs/bun/BunHttpServer.d.ts +142 -0
- package/dist/vendor/cjs/bun/BunHttpServer.js +1 -0
- package/dist/vendor/cjs/bun/BunHttpServerRequest.d.ts +18 -0
- package/dist/vendor/cjs/bun/BunHttpServerRequest.js +1 -0
- package/dist/vendor/cjs/bun/BunMultipart.d.ts +31 -0
- package/dist/vendor/cjs/bun/BunMultipart.js +1 -0
- package/dist/vendor/cjs/bun/BunPath.d.ts +24 -0
- package/dist/vendor/cjs/bun/BunPath.js +1 -0
- package/dist/vendor/cjs/bun/BunRedis.d.ts +49 -0
- package/dist/vendor/cjs/bun/BunRedis.js +1 -0
- package/dist/vendor/cjs/bun/BunRuntime.d.ts +85 -0
- package/dist/vendor/cjs/bun/BunRuntime.js +1 -0
- package/dist/vendor/cjs/bun/BunServices.d.ts +34 -0
- package/dist/vendor/cjs/bun/BunServices.js +1 -0
- package/dist/vendor/cjs/bun/BunSink.d.ts +8 -0
- package/dist/vendor/cjs/bun/BunSink.js +1 -0
- package/dist/vendor/cjs/bun/BunSocket.d.ts +40 -0
- package/dist/vendor/cjs/bun/BunSocket.js +1 -0
- package/dist/vendor/cjs/bun/BunSocketServer.d.ts +8 -0
- package/dist/vendor/cjs/bun/BunSocketServer.js +1 -0
- package/dist/vendor/cjs/bun/BunStdio.d.ts +11 -0
- package/dist/vendor/cjs/bun/BunStdio.js +1 -0
- package/dist/vendor/cjs/bun/BunStream.d.ts +19 -0
- package/dist/vendor/cjs/bun/BunStream.js +1 -0
- package/dist/vendor/cjs/bun/BunTerminal.d.ts +21 -0
- package/dist/vendor/cjs/bun/BunTerminal.js +1 -0
- package/dist/vendor/cjs/bun/BunWorker.d.ts +20 -0
- package/dist/vendor/cjs/bun/BunWorker.js +1 -0
- package/dist/vendor/cjs/bun/BunWorkerRunner.d.ts +12 -0
- package/dist/vendor/cjs/bun/BunWorkerRunner.js +1 -0
- package/dist/vendor/cjs/bun/index.d.ts +92 -0
- package/dist/vendor/cjs/bun/index.js +1 -0
- package/dist/vendor/cjs/node/NodeChildProcessSpawner.d.ts +7 -0
- package/dist/vendor/cjs/node/NodeChildProcessSpawner.js +1 -0
- package/dist/vendor/cjs/node/NodeClusterHttp.d.ts +63 -0
- package/dist/vendor/cjs/node/NodeClusterHttp.js +1 -0
- package/dist/vendor/cjs/node/NodeClusterSocket.d.ts +79 -0
- package/dist/vendor/cjs/node/NodeClusterSocket.js +1 -0
- package/dist/vendor/cjs/node/NodeCrypto.d.ts +10 -0
- package/dist/vendor/cjs/node/NodeCrypto.js +1 -0
- package/dist/vendor/cjs/node/NodeFileSystem.d.ts +10 -0
- package/dist/vendor/cjs/node/NodeFileSystem.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpClient.d.ts +179 -0
- package/dist/vendor/cjs/node/NodeHttpClient.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpIncomingMessage.d.ts +62 -0
- package/dist/vendor/cjs/node/NodeHttpIncomingMessage.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpPlatform.d.ts +36 -0
- package/dist/vendor/cjs/node/NodeHttpPlatform.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpServer.d.ts +120 -0
- package/dist/vendor/cjs/node/NodeHttpServer.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpServerRequest.d.ts +29 -0
- package/dist/vendor/cjs/node/NodeHttpServerRequest.js +1 -0
- package/dist/vendor/cjs/node/NodeMultipart.d.ts +46 -0
- package/dist/vendor/cjs/node/NodeMultipart.js +1 -0
- package/dist/vendor/cjs/node/NodeMultipartParser.d.ts +97 -0
- package/dist/vendor/cjs/node/NodeMultipartParser.js +1 -0
- package/dist/vendor/cjs/node/NodePath.d.ts +27 -0
- package/dist/vendor/cjs/node/NodePath.js +1 -0
- package/dist/vendor/cjs/node/NodeRedis.d.ts +74 -0
- package/dist/vendor/cjs/node/NodeRedis.js +1 -0
- package/dist/vendor/cjs/node/NodeRuntime.d.ts +85 -0
- package/dist/vendor/cjs/node/NodeRuntime.js +1 -0
- package/dist/vendor/cjs/node/NodeServices.d.ts +34 -0
- package/dist/vendor/cjs/node/NodeServices.js +1 -0
- package/dist/vendor/cjs/node/NodeSink.d.ts +8 -0
- package/dist/vendor/cjs/node/NodeSink.js +1 -0
- package/dist/vendor/cjs/node/NodeSocket.d.ts +38 -0
- package/dist/vendor/cjs/node/NodeSocket.js +1 -0
- package/dist/vendor/cjs/node/NodeSocketServer.d.ts +8 -0
- package/dist/vendor/cjs/node/NodeSocketServer.js +1 -0
- package/dist/vendor/cjs/node/NodeStdio.d.ts +11 -0
- package/dist/vendor/cjs/node/NodeStdio.js +1 -0
- package/dist/vendor/cjs/node/NodeStream.d.ts +8 -0
- package/dist/vendor/cjs/node/NodeStream.js +1 -0
- package/dist/vendor/cjs/node/NodeTerminal.d.ts +21 -0
- package/dist/vendor/cjs/node/NodeTerminal.js +1 -0
- package/dist/vendor/cjs/node/NodeWorker.d.ts +22 -0
- package/dist/vendor/cjs/node/NodeWorker.js +1 -0
- package/dist/vendor/cjs/node/NodeWorkerRunner.d.ts +12 -0
- package/dist/vendor/cjs/node/NodeWorkerRunner.js +1 -0
- package/dist/vendor/cjs/node/Undici.d.ts +28 -0
- package/dist/vendor/cjs/node/Undici.js +1 -0
- package/dist/vendor/cjs/node/index.d.ts +100 -0
- package/dist/vendor/cjs/node/index.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.d.ts +57 -0
- package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeClusterSocket.d.ts +22 -0
- package/dist/vendor/cjs/node-shared/NodeClusterSocket.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeCrypto.d.ts +27 -0
- package/dist/vendor/cjs/node-shared/NodeCrypto.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeFileSystem.d.ts +11 -0
- package/dist/vendor/cjs/node-shared/NodeFileSystem.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeHttpCompression.d.ts +36 -0
- package/dist/vendor/cjs/node-shared/NodeHttpCompression.js +1 -0
- package/dist/vendor/cjs/node-shared/NodePath.d.ts +27 -0
- package/dist/vendor/cjs/node-shared/NodePath.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeRuntime.d.ts +47 -0
- package/dist/vendor/cjs/node-shared/NodeRuntime.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeSink.d.ts +69 -0
- package/dist/vendor/cjs/node-shared/NodeSink.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeSocket.d.ts +134 -0
- package/dist/vendor/cjs/node-shared/NodeSocket.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeSocketServer.d.ts +80 -0
- package/dist/vendor/cjs/node-shared/NodeSocketServer.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeStdio.d.ts +12 -0
- package/dist/vendor/cjs/node-shared/NodeStdio.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeStream.d.ts +179 -0
- package/dist/vendor/cjs/node-shared/NodeStream.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeTerminal.d.ts +22 -0
- package/dist/vendor/cjs/node-shared/NodeTerminal.js +1 -0
- package/dist/vendor/cjs/node-shared/index.d.ts +56 -0
- package/dist/vendor/cjs/node-shared/index.js +1 -0
- package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
- package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.js +1 -0
- package/dist/vendor/cjs/node-shared/internal/utils.d.ts +2 -0
- package/dist/vendor/cjs/node-shared/internal/utils.js +1 -0
- package/dist/vendor/cjs/package.json +1 -0
- package/dist/vendor/cjs/platform-bun.d.ts +92 -0
- package/dist/vendor/cjs/platform-bun.js +1 -0
- package/dist/vendor/cjs/platform-node-shared.d.ts +56 -0
- package/dist/vendor/cjs/platform-node-shared.js +1 -0
- package/dist/vendor/cjs/platform-node.d.ts +100 -0
- package/dist/vendor/cjs/platform-node.js +1 -0
- package/dist/vendor/node/LICENSE +21 -0
- package/dist/vendor/node/NodeChildProcessSpawner.d.ts +7 -0
- package/dist/vendor/node/NodeChildProcessSpawner.js +14 -0
- package/dist/vendor/node/NodeClusterHttp.d.ts +63 -0
- package/dist/vendor/node/NodeClusterHttp.js +43 -0
- package/dist/vendor/node/NodeClusterSocket.d.ts +79 -0
- package/dist/vendor/node/NodeClusterSocket.js +30 -0
- package/dist/vendor/node/NodeCrypto.d.ts +10 -0
- package/dist/vendor/node/NodeCrypto.js +8 -0
- package/dist/vendor/node/NodeFileSystem.d.ts +10 -0
- package/dist/vendor/node/NodeFileSystem.js +9 -0
- package/dist/vendor/node/NodeHttpClient.d.ts +179 -0
- package/dist/vendor/node/NodeHttpClient.js +46 -0
- package/dist/vendor/node/NodeHttpIncomingMessage.d.ts +62 -0
- package/dist/vendor/node/NodeHttpIncomingMessage.js +10 -0
- package/dist/vendor/node/NodeHttpPlatform.d.ts +36 -0
- package/dist/vendor/node/NodeHttpPlatform.js +16 -0
- package/dist/vendor/node/NodeHttpServer.d.ts +120 -0
- package/dist/vendor/node/NodeHttpServer.js +46 -0
- package/dist/vendor/node/NodeHttpServerRequest.d.ts +29 -0
- package/dist/vendor/node/NodeHttpServerRequest.js +9 -0
- package/dist/vendor/node/NodeMultipart.d.ts +46 -0
- package/dist/vendor/node/NodeMultipart.js +15 -0
- package/dist/vendor/node/NodeMultipartParser.d.ts +97 -0
- package/dist/vendor/node/NodeMultipartParser.js +11 -0
- package/dist/vendor/node/NodePath.d.ts +27 -0
- package/dist/vendor/node/NodePath.js +12 -0
- package/dist/vendor/node/NodeRedis.d.ts +74 -0
- package/dist/vendor/node/NodeRedis.js +11 -0
- package/dist/vendor/node/NodeRuntime.d.ts +85 -0
- package/dist/vendor/node/NodeRuntime.js +8 -0
- package/dist/vendor/node/NodeServices.d.ts +34 -0
- package/dist/vendor/node/NodeServices.js +23 -0
- package/dist/vendor/node/NodeSink.d.ts +8 -0
- package/dist/vendor/node/NodeSink.js +12 -0
- package/dist/vendor/node/NodeSocket.d.ts +38 -0
- package/dist/vendor/node/NodeSocket.js +31 -0
- package/dist/vendor/node/NodeSocketServer.d.ts +8 -0
- package/dist/vendor/node/NodeSocketServer.js +21 -0
- package/dist/vendor/node/NodeStdio.d.ts +11 -0
- package/dist/vendor/node/NodeStdio.js +10 -0
- package/dist/vendor/node/NodeStream.d.ts +8 -0
- package/dist/vendor/node/NodeStream.js +27 -0
- package/dist/vendor/node/NodeTerminal.d.ts +21 -0
- package/dist/vendor/node/NodeTerminal.js +10 -0
- package/dist/vendor/node/NodeWorker.d.ts +22 -0
- package/dist/vendor/node/NodeWorker.js +9 -0
- package/dist/vendor/node/NodeWorkerRunner.d.ts +12 -0
- package/dist/vendor/node/NodeWorkerRunner.js +7 -0
- package/dist/vendor/node/Undici.d.ts +28 -0
- package/dist/vendor/node/Undici.js +9 -0
- package/dist/vendor/node/index.d.ts +100 -0
- package/dist/vendor/node/index.js +115 -0
- package/dist/vendor/node-shared/LICENSE +21 -0
- package/dist/vendor/node-shared/NodeChildProcessSpawner.d.ts +57 -0
- package/dist/vendor/node-shared/NodeChildProcessSpawner.js +13 -0
- package/dist/vendor/node-shared/NodeClusterSocket.d.ts +22 -0
- package/dist/vendor/node-shared/NodeClusterSocket.js +11 -0
- package/dist/vendor/node-shared/NodeCrypto.d.ts +27 -0
- package/dist/vendor/node-shared/NodeCrypto.js +9 -0
- package/dist/vendor/node-shared/NodeFileSystem.d.ts +11 -0
- package/dist/vendor/node-shared/NodeFileSystem.js +8 -0
- package/dist/vendor/node-shared/NodeHttpCompression.d.ts +36 -0
- package/dist/vendor/node-shared/NodeHttpCompression.js +13 -0
- package/dist/vendor/node-shared/NodePath.d.ts +27 -0
- package/dist/vendor/node-shared/NodePath.js +11 -0
- package/dist/vendor/node-shared/NodeRuntime.d.ts +47 -0
- package/dist/vendor/node-shared/NodeRuntime.js +7 -0
- package/dist/vendor/node-shared/NodeSink.d.ts +69 -0
- package/dist/vendor/node-shared/NodeSink.js +11 -0
- package/dist/vendor/node-shared/NodeSocket.d.ts +134 -0
- package/dist/vendor/node-shared/NodeSocket.js +23 -0
- package/dist/vendor/node-shared/NodeSocketServer.d.ts +80 -0
- package/dist/vendor/node-shared/NodeSocketServer.js +20 -0
- package/dist/vendor/node-shared/NodeStdio.d.ts +12 -0
- package/dist/vendor/node-shared/NodeStdio.js +9 -0
- package/dist/vendor/node-shared/NodeStream.d.ts +179 -0
- package/dist/vendor/node-shared/NodeStream.js +26 -0
- package/dist/vendor/node-shared/NodeTerminal.d.ts +22 -0
- package/dist/vendor/node-shared/NodeTerminal.js +9 -0
- package/dist/vendor/node-shared/index.d.ts +56 -0
- package/dist/vendor/node-shared/index.js +58 -0
- package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
- package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.js +7 -0
- package/dist/vendor/node-shared/internal/utils.d.ts +2 -0
- package/dist/vendor/node-shared/internal/utils.js +7 -0
- package/dist/vendor/platform-bun.d.ts +92 -0
- package/dist/vendor/platform-bun.js +107 -0
- package/dist/vendor/platform-node-shared.d.ts +56 -0
- package/dist/vendor/platform-node-shared.js +58 -0
- package/dist/vendor/platform-node.d.ts +100 -0
- package/dist/vendor/platform-node.js +115 -0
- package/docs/README.md +132 -0
- package/docs/api.md +265 -0
- package/docs/concepts/host-surface.md +152 -0
- package/docs/concepts/runtime-parity.md +80 -0
- package/docs/guides/bind-a-repository-root.md +109 -0
- package/docs/guides/configure-the-filesystem-helper.md +109 -0
- package/docs/guides/contain-child-processes.md +176 -0
- package/docs/installation.md +128 -0
- package/docs/quickstart.md +159 -0
- package/docs/troubleshooting.md +178 -0
- package/package.json +146 -3
- package/src/BunFileSystem.ts +47 -0
- package/src/BunHost.ts +338 -0
- package/src/index.ts +27 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "The Host surface on Bun"
|
|
3
|
+
description: "The five service slots a Smithers program reaches the world through, what fills each one on Bun, why the bundle adds no shell and no HTTP wrapper, and how to take one service without the other four."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 1
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Smithers programs do not call `node:fs`, `Bun.spawn`, or a global `fetch`.
|
|
9
|
+
Everything that touches the outside world enters through a closed list of five
|
|
10
|
+
Effect service tags, and a host bundle is the thing that fills them:
|
|
11
|
+
|
|
12
|
+
| Slot | Tag |
|
|
13
|
+
| --------------- | --------------------------------------------- |
|
|
14
|
+
| Filesystem | `effect/FileSystem` |
|
|
15
|
+
| Path | `effect/Path` |
|
|
16
|
+
| Child processes | `effect/unstable/process/ChildProcessSpawner` |
|
|
17
|
+
| Version control | `Jj`, from [`@smthrs/jj`](/api/jj) |
|
|
18
|
+
| Network | `effect/unstable/http/HttpClient` |
|
|
19
|
+
|
|
20
|
+
The list is closed for one reason, owned by
|
|
21
|
+
[`@smthrs/kernel`](/api/kernel): a service that is not on it cannot be
|
|
22
|
+
attenuated, denied, or audited, so it must not exist.
|
|
23
|
+
|
|
24
|
+
Closing the list does not make the platform implementations part of a step's
|
|
25
|
+
identity. [`@smthrs/plan`](/api/plan)'s step key digests only the `layers` its
|
|
26
|
+
caller passes it, so "which platform implementations were in scope" is an
|
|
27
|
+
explicit input a caller supplies, not something this bundle contributes. The
|
|
28
|
+
identity table below is data to pass; nothing reads it for you.
|
|
29
|
+
|
|
30
|
+
`BunHost.layer` provides all five, and `BunHost` is the type union of them:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
export type BunHost = FileSystem | Path.Path | ChildProcessSpawner | Jj | HttpClient
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## What fills each slot, and whose code it is
|
|
37
|
+
|
|
38
|
+
`BunHost.implementationIds` is this mapping as data, so a swapped
|
|
39
|
+
implementation is a visible change to a public value rather than a comment
|
|
40
|
+
that drifted:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { BunHost } from "@smthrs/platform-bun"
|
|
44
|
+
|
|
45
|
+
BunHost.implementationIds
|
|
46
|
+
// {
|
|
47
|
+
// "effect/FileSystem": "@smthrs/platform-node/AtomicFileSystem",
|
|
48
|
+
// "effect/Path": "@effect/platform-bun/BunPath",
|
|
49
|
+
// "effect/process/ChildProcessSpawner": "@effect/platform-bun/BunChildProcessSpawner",
|
|
50
|
+
// "@smthrs/jj/Jj": "@smthrs/jj/bun/BunJj",
|
|
51
|
+
// "effect/HttpClient": "@smthrs/platform-node/EgressHttpClient"
|
|
52
|
+
// }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Each value names the module actually behind the slot, not the specifier you
|
|
56
|
+
import it through. The filesystem entry says
|
|
57
|
+
`@smthrs/platform-node/AtomicFileSystem` because that is the implementation,
|
|
58
|
+
even though a Bun program reaches it through this package. Each key is the
|
|
59
|
+
slot's stable identity in the closed list, which is likewise not always the
|
|
60
|
+
specifier the tag comes from: the spawner key is
|
|
61
|
+
`effect/process/ChildProcessSpawner` while its tag is imported from
|
|
62
|
+
`effect/unstable/process/ChildProcessSpawner`.
|
|
63
|
+
|
|
64
|
+
Nothing digests these values today. [`@smthrs/plan`](/api/plan)'s step key
|
|
65
|
+
carries a `layers` component they are meant to feed, but no planner derives it
|
|
66
|
+
from a host bundle yet, so changing one invalidates no cached step.
|
|
67
|
+
|
|
68
|
+
## Three slots the bundle does not implement
|
|
69
|
+
|
|
70
|
+
**Path** is runtime independent. `effect/Path`'s own layer goes in the slot
|
|
71
|
+
unchanged, and the kernel keeps `Path` on the closed list as an explicit
|
|
72
|
+
pass-through decision rather than dropping it.
|
|
73
|
+
|
|
74
|
+
**Child processes** are Effect's. `@effect/platform-bun`'s
|
|
75
|
+
`BunChildProcessSpawner` is `@effect/platform-node-shared`'s spawner
|
|
76
|
+
re-exported, which means Bun and Node run literally the same module. There is
|
|
77
|
+
no Bun shell wrapper here and no runtime detection, because there is nothing
|
|
78
|
+
to choose between. See
|
|
79
|
+
[Runtime parity with Node](./runtime-parity.md) for what that means for your
|
|
80
|
+
program, and where the parity stops.
|
|
81
|
+
|
|
82
|
+
**The network** is Effect's `HttpClient`. There is no Smithers transport port
|
|
83
|
+
beneath it, because a raw port would be a second way to reach the network
|
|
84
|
+
whose contract never mentions permission. The bundle provides
|
|
85
|
+
`@smthrs/platform-node`'s egress client, with hostname-based proxy routing
|
|
86
|
+
and connection pinning for web tools.
|
|
87
|
+
|
|
88
|
+
## Redirects and connection pinning
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
const layerHttpClient: Layer.Layer<HttpClient> = EgressHttpClient.layer(process.env)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
A `302` therefore comes back to the caller as a `302`, with its `location`
|
|
95
|
+
header intact and the second origin never contacted. That is deliberate: a
|
|
96
|
+
client that follows a redirect on its own reaches a host the capability kernel
|
|
97
|
+
never authorized. Following a redirect is the kernel's guarded
|
|
98
|
+
`HttpClient.layer`, which rechecks the capability on every hop.
|
|
99
|
+
|
|
100
|
+
## Two slots the bundle composes from Smithers packages
|
|
101
|
+
|
|
102
|
+
**Version control** is `Jj`, the service whose methods make a step reversible:
|
|
103
|
+
snapshot, restore, diff, workspace lanes. It runs the `jj` command from
|
|
104
|
+
[Jujutsu](https://jj-vcs.github.io), a version-control system that works on a
|
|
105
|
+
Git repository, so the slot needs that binary on the host. Bun's adapter is
|
|
106
|
+
`@smthrs/jj/bun/BunJj`, which is the Node adapter under another name because
|
|
107
|
+
Bun implements the child-process API it uses. The adapter is imported from
|
|
108
|
+
[`@smthrs/jj`](/api/jj) and deliberately not re-exported here: it belongs to
|
|
109
|
+
that package.
|
|
110
|
+
|
|
111
|
+
**The filesystem** is `@smthrs/platform-node`'s `AtomicFileSystem`, byte for
|
|
112
|
+
byte the layer [`@smthrs/platform-node`](/api/platform-node) puts in its own
|
|
113
|
+
filesystem slot. It carries the kernel's atomic host extension, which is what
|
|
114
|
+
lets the kernel's guarded `FileSystem.layer` perform a guarded path operation
|
|
115
|
+
descriptor-relative and no-follow instead of failing closed. With the
|
|
116
|
+
extension, the operation runs against file descriptors, so a symlink swapped in
|
|
117
|
+
after authorization cannot redirect it somewhere else. Without a working one,
|
|
118
|
+
every guarded path operation is refused with a typed `PermissionDenied` rather
|
|
119
|
+
than falling back to a path-based call, because the fallback is the race the
|
|
120
|
+
extension exists to prevent.
|
|
121
|
+
|
|
122
|
+
That extension executes its syscalls in a `smithers-jj-export` subprocess
|
|
123
|
+
rather than in-process, which is why the host needs that helper. See
|
|
124
|
+
[Configure the filesystem helper](../guides/configure-the-filesystem-helper.md).
|
|
125
|
+
|
|
126
|
+
## Taking one service without the other four
|
|
127
|
+
|
|
128
|
+
`BunHost` re-exports the single-slot modules, so a program that should
|
|
129
|
+
reach only part of the host has one import to take it from:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
import { BunHost } from "@smthrs/platform-bun"
|
|
133
|
+
|
|
134
|
+
BunHost.AtomicFileSystem // the filesystem implementation, with its options
|
|
135
|
+
BunHost.BunFileSystem // the filesystem slot as this package spells it
|
|
136
|
+
BunHost.BunChildProcessSpawner
|
|
137
|
+
BunHost.layerHttpClient // the network slot, redirects stopped
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`@effect/platform-bun/BunHttpClient` is not re-exported: its `layer` follows
|
|
141
|
+
redirects, which is the escape the section above closes.
|
|
142
|
+
|
|
143
|
+
`AtomicFileSystem` is in that set for a specific reason: it owns the only
|
|
144
|
+
configuration escape hatch the filesystem slot has, and a Bun program whose
|
|
145
|
+
helper is elsewhere must be able to reach
|
|
146
|
+
`AtomicFileSystem.layerWith` without adding
|
|
147
|
+
[`@smthrs/platform-node`](/api/platform-node) as a second dependency.
|
|
148
|
+
|
|
149
|
+
Composing individual slots yourself means you own the closure. `BunHost.layer`
|
|
150
|
+
is the only thing that guarantees all five are present and consistent; a
|
|
151
|
+
hand-composed subset is a surface the kernel can still guard, but not one this
|
|
152
|
+
package pins.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Runtime parity with Node"
|
|
3
|
+
description: "Which adapters Bun and Node share, how contained hosts prepare a runtime supervisor, and which runtime and platform boundaries still need separate verification."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 2
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
The Bun bundle shares its host adapters with Node. A flow asks for the same
|
|
9
|
+
service tags on either runtime. Shared source does not make every runtime or
|
|
10
|
+
operating-system behavior identical, especially around native process pipes
|
|
11
|
+
and cleanup.
|
|
12
|
+
|
|
13
|
+
## Bun and Node run the same modules here
|
|
14
|
+
|
|
15
|
+
Three of the raw bundle's five slots use shared implementations:
|
|
16
|
+
|
|
17
|
+
- `@effect/platform-bun/BunChildProcessSpawner` is
|
|
18
|
+
`@effect/platform-node-shared`'s spawner re-exported. Spawning a child is one
|
|
19
|
+
module, so there is nothing for a detection branch to choose between.
|
|
20
|
+
- `@smthrs/jj/bun/BunJj` is `@smthrs/jj/node/NodeJj` re-exported, because Bun
|
|
21
|
+
implements the child-process API the argv-safe jj adapter uses. The two share
|
|
22
|
+
the same error classification and the same interruption finalizer by
|
|
23
|
+
construction, not by agreement.
|
|
24
|
+
- The filesystem slot is `@smthrs/platform-node`'s `AtomicFileSystem.layer`
|
|
25
|
+
itself, the same value [`@smthrs/platform-node`](/api/platform-node) puts in
|
|
26
|
+
its own slot.
|
|
27
|
+
|
|
28
|
+
`effect/Path` is runtime independent, and the network slot is the shared Undici egress client, including the same
|
|
29
|
+
connection-pinning and proxy policy on both runtimes.
|
|
30
|
+
|
|
31
|
+
Contained POSIX variants substitute `ProcessReaper.layerSpawner`. It combines
|
|
32
|
+
the shared native process adapter with a supervisor started by the current
|
|
33
|
+
Node or Bun runtime. Preparation records the supervisor before executing the
|
|
34
|
+
target. Compiled Bun executables and Node single-executable applications are
|
|
35
|
+
refused before activation because they do not supply the runtime eval entry
|
|
36
|
+
point. Windows retains the raw runtime spawner and remains unsupported best
|
|
37
|
+
effort for containment.
|
|
38
|
+
|
|
39
|
+
## Two consequences you can rely on
|
|
40
|
+
|
|
41
|
+
**The bundle runs unchanged under Node.** Nothing in it requires the Bun
|
|
42
|
+
runtime, so a program composed on `BunHost.layer` executes on Node 26.4.0 or later as well. That is not a compatibility shim; it is what "the same modules"
|
|
43
|
+
means. The package declares both floors in `engines`.
|
|
44
|
+
|
|
45
|
+
**Recorded durable behavior does not require a Bun-specific flow.** The same
|
|
46
|
+
service contracts and error adapters are available on Node. Replay still
|
|
47
|
+
depends on the flow's recorded inputs and implementations; shared source alone
|
|
48
|
+
does not prove that a new native command has identical behavior on both hosts.
|
|
49
|
+
|
|
50
|
+
## Node-only in the browser-bundle sense
|
|
51
|
+
|
|
52
|
+
The same property that makes the bundle portable between Bun and Node is what
|
|
53
|
+
stops it reaching a browser. Falling back to the `@effect/platform-node`
|
|
54
|
+
adapters means resolving `node:` built-ins, so a browser bundler asked to
|
|
55
|
+
resolve `@smthrs/platform-bun` stops at `node:fs`. That is the intended
|
|
56
|
+
resolution, not a packaging defect to work around with an alias.
|
|
57
|
+
|
|
58
|
+
It runs on Bun and it runs on Node. What it does not do is bundle for a page.
|
|
59
|
+
That is [`@smthrs/platform-browser`](/api/platform-browser), which fills the
|
|
60
|
+
same five slots from browser primitives.
|
|
61
|
+
|
|
62
|
+
## Where the parity stops
|
|
63
|
+
|
|
64
|
+
The package's `test` target runs conformance under Node with V8 coverage.
|
|
65
|
+
The `bunTest` target imports Vitest's JavaScript entry under Bun and asserts
|
|
66
|
+
`process.versions.bun` inside every worker. Both lanes exercise redirects,
|
|
67
|
+
process containment, and filesystem helpers. Node coverage reports use private
|
|
68
|
+
`0700` directories under the package's gitignored `coverage/` directory and are
|
|
69
|
+
removed when the runner exits. Bun coverage is disabled.
|
|
70
|
+
|
|
71
|
+
Verify process streams, cancellation, and cleanup on the runtime and operating
|
|
72
|
+
system you deploy. The contained handle's POSIX
|
|
73
|
+
`pid` identifies its supervisor; target status and supported cleanup boundaries
|
|
74
|
+
are described in [Contain and reap child processes](../guides/contain-child-processes.md).
|
|
75
|
+
|
|
76
|
+
The filesystem is the exception worth holding on to. Its no-follow extension
|
|
77
|
+
does not run in-process: it executes each guarded operation in a
|
|
78
|
+
`smithers-jj-export` subprocess, so the slot depends on that helper rather than
|
|
79
|
+
on anything either runtime ships. See
|
|
80
|
+
[Configure the filesystem helper](../guides/configure-the-filesystem-helper.md).
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Bind the host to a repository root"
|
|
3
|
+
description: "Use BunHost.layerAt and BunHost.layerContainedAt so the Jj slot runs against one absolute repository root instead of the process working directory, and handle the refusal they throw."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`BunHost.layer` binds the `Jj` slot to the process working directory. That is
|
|
7
|
+
the right default for a command-line tool a person runs inside a repository,
|
|
8
|
+
and the wrong one for a long-lived host: the working directory is ambient
|
|
9
|
+
state that some other part of the program can change, and a host that inherits
|
|
10
|
+
it commits version-control operations against whichever repository happened to
|
|
11
|
+
be current.
|
|
12
|
+
|
|
13
|
+
`BunHost.layerAt` binds the slot to one root you name.
|
|
14
|
+
|
|
15
|
+
## Bind the root
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { Jj } from "@smthrs/jj"
|
|
19
|
+
import { BunHost } from "@smthrs/platform-bun"
|
|
20
|
+
import * as Effect from "effect/Effect"
|
|
21
|
+
|
|
22
|
+
const program = Effect.gen(function*() {
|
|
23
|
+
const jj = yield* Jj
|
|
24
|
+
return yield* jj.status()
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
Effect.runPromise(
|
|
28
|
+
Effect.scoped(Effect.provide(program, BunHost.layerAt("/srv/repositories/app")))
|
|
29
|
+
)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The other four slots are identical to `BunHost.layer`. Only `Jj` changes: it
|
|
33
|
+
is built with `BunJj.layerAt(root)` instead of `BunJj.layer`.
|
|
34
|
+
|
|
35
|
+
`BunHost.layerContainedAt` is the same substitution on the contained bundle.
|
|
36
|
+
Use it whenever you want both properties, which is the usual case for a
|
|
37
|
+
supervisor:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
BunHost.layerContainedAt("/srv/repositories/app", { graceMs: 2_000 })
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Pass an absolute root
|
|
44
|
+
|
|
45
|
+
Both factories require an absolute path. A relative root, and the empty string,
|
|
46
|
+
are refused:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
BunHost.layerAt("repositories/app")
|
|
50
|
+
// throws BunHostError: BunHost.layerAt requires an absolute repository root,
|
|
51
|
+
// got "repositories/app"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Three properties of that refusal matter when you handle it.
|
|
55
|
+
|
|
56
|
+
**It throws rather than fails.** A factory is called while your program
|
|
57
|
+
composes its layers, where there is no fiber to fail into. A wrong root is a
|
|
58
|
+
composition mistake, not a runtime outcome, so it surfaces where the mistake
|
|
59
|
+
was written, before any layer exists.
|
|
60
|
+
|
|
61
|
+
**It is this package's error, not the adapter's.** The `Jj` adapter underneath
|
|
62
|
+
would also refuse, with a bare `TypeError` that names `NodeJj.layerAt`, carries
|
|
63
|
+
no code, and echoes the whole string. You composed `BunHost`, so you get
|
|
64
|
+
`BunHost.BunHostError`, whose message names the Bun factory that refused and
|
|
65
|
+
mentions no adapter.
|
|
66
|
+
|
|
67
|
+
**Branch on `code`, never on the message.** The message is for a person and its
|
|
68
|
+
wording is not a contract:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import { BunHost } from "@smthrs/platform-bun"
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
return BunHost.layerAt(configuredRoot)
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (error instanceof BunHost.BunHostError && error.code === "invalid_repository_root") {
|
|
77
|
+
throw new Error(`SMITHERS_REPOSITORY_ROOT must be an absolute path, got ${configuredRoot}`)
|
|
78
|
+
}
|
|
79
|
+
throw error
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`BunHost.BunHostErrorCode` is the union of codes a factory refuses with; today
|
|
84
|
+
`"invalid_repository_root"` is the only member.
|
|
85
|
+
|
|
86
|
+
## Roots that come from input
|
|
87
|
+
|
|
88
|
+
A root read from an environment variable, a request, or a configuration file is
|
|
89
|
+
untrusted text, and it lands in a log line the moment it is refused. The whole
|
|
90
|
+
message stays under 256 UTF-16 code units for a root of any content and any
|
|
91
|
+
length, so a hostile root cannot flood the line. A root is quoted in full when
|
|
92
|
+
it is 64 code points or fewer and its quoted form fits that bound. Otherwise
|
|
93
|
+
it is cut: the message carries a quoted excerpt of at most 64 code points,
|
|
94
|
+
then `... (N characters)` with the root's true length in code points.
|
|
95
|
+
|
|
96
|
+
The excerpt is passed through `JSON.stringify`, so a newline in the root
|
|
97
|
+
cannot break the line it lands on. Escaping widens some characters: a control
|
|
98
|
+
character becomes a six-character `\u0001`, so a root made of them is cut
|
|
99
|
+
well before 64 code points. The cut is counted in code points rather than
|
|
100
|
+
UTF-16 units and lands between escapes, so it never splits a surrogate pair
|
|
101
|
+
or an escape, and the excerpt is always one valid JSON string.
|
|
102
|
+
|
|
103
|
+
## Related
|
|
104
|
+
|
|
105
|
+
- [Contain and reap child processes](./contain-child-processes.md): what
|
|
106
|
+
`layerContainedAt` adds on top of the root binding, including why `jj` runs
|
|
107
|
+
through the contained spawner.
|
|
108
|
+
- [`@smthrs/jj`](/api/jj): the `Jj` contract itself, its failure codes, and
|
|
109
|
+
choosing which `jj` binary runs.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Configure the filesystem helper"
|
|
3
|
+
description: "Point the filesystem slot at a smithers-jj-export helper with BunFileSystem.layerWith, and tune the helper's concurrency, timeout, and byte limits."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The filesystem slot carries the kernel's atomic host extension, and that
|
|
7
|
+
extension does not run in-process. Each guarded path operation is executed by
|
|
8
|
+
the `smithers-jj-export` helper the adapter spawns, which is what makes the
|
|
9
|
+
operation descriptor-relative and no-follow: a symlink swapped in after
|
|
10
|
+
authorization cannot redirect it somewhere else.
|
|
11
|
+
|
|
12
|
+
The adapter uses the first of `executable`, `SMITHERS_WORKSPACE_JJ_EXPORT_BINARY`,
|
|
13
|
+
the package's `bin/<platform>-<arch>/smithers-jj-export`, a source checkout's
|
|
14
|
+
`target/release` or `target/debug` build, and
|
|
15
|
+
`/usr/local/bin/smithers-jj-export`. It never searches `PATH`.
|
|
16
|
+
|
|
17
|
+
## Build or name the helper
|
|
18
|
+
|
|
19
|
+
In a source checkout:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cargo build --locked --release -p smithers-ffi --bin smithers-jj-export
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Anywhere else, set the absolute path:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
export SMITHERS_WORKSPACE_JJ_EXPORT_BINARY=/opt/smithers/bin/smithers-jj-export
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Or pass it to the layer:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { BunFileSystem } from "@smthrs/platform-bun"
|
|
35
|
+
|
|
36
|
+
const fileSystem = BunFileSystem.layerWith({ executable: "/opt/smithers/bin/smithers-jj-export" })
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The executable is re-validated on every request rather than read once when the
|
|
40
|
+
layer is built, because the file a path names can be replaced while the host
|
|
41
|
+
runs.
|
|
42
|
+
|
|
43
|
+
## Use it as the whole host's filesystem slot
|
|
44
|
+
|
|
45
|
+
`BunHost.layer` builds its filesystem slot from `BunFileSystem.layer`, which
|
|
46
|
+
uses the default search. Merge your configured layer over the bundle so it
|
|
47
|
+
shadows that slot, and put it last: for a duplicate tag, the later layer in a
|
|
48
|
+
merge wins.
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { BunFileSystem, BunHost } from "@smthrs/platform-bun"
|
|
52
|
+
import * as Layer from "effect/Layer"
|
|
53
|
+
|
|
54
|
+
// The override comes second. Reversing the arguments silently keeps the
|
|
55
|
+
// default helper.
|
|
56
|
+
const host = Layer.merge(
|
|
57
|
+
BunHost.layer,
|
|
58
|
+
BunFileSystem.layerWith({ executable: "/opt/smithers/bin/smithers-jj-export" })
|
|
59
|
+
)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This replaces the `FileSystem` tag every consumer resolves, including the
|
|
63
|
+
kernel's guarded `FileSystem.layer`, which is where the helper actually runs.
|
|
64
|
+
The spawner inside the bundle keeps the default filesystem layer it was built
|
|
65
|
+
with for resolving executables and working directories; that path is unguarded
|
|
66
|
+
and does not use the helper.
|
|
67
|
+
|
|
68
|
+
Prefer this over hand-composing the five slots. Rebuilding them yourself means
|
|
69
|
+
rebuilding the `HttpClient` slot too, and its `redirect: "manual"` wiring is
|
|
70
|
+
internal, so a hand-composed bundle quietly gains redirect following.
|
|
71
|
+
|
|
72
|
+
`BunHost` also re-exports `AtomicFileSystem` itself, so you can reach the
|
|
73
|
+
implementation and its full option set without adding
|
|
74
|
+
[`@smthrs/platform-node`](/api/platform-node) as a second dependency:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
BunHost.AtomicFileSystem.layerWith({ executable, concurrency, timeoutMs })
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## The other options
|
|
81
|
+
|
|
82
|
+
`BunFileSystem.Options` is `AtomicFileSystem.Options`:
|
|
83
|
+
|
|
84
|
+
| Field | Meaning |
|
|
85
|
+
| ------------- | --------------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| `executable` | The absolute `smithers-jj-export` path. Default: the search above. Re-validated per request. |
|
|
87
|
+
| `concurrency` | How many helper processes may run at once. A contract, not a tuning knob: every operation is one process. |
|
|
88
|
+
| `timeoutMs` | How long one helper may run before it is killed and the operation fails closed. |
|
|
89
|
+
| `limits` | The byte ceilings the helper enforces on the values it moves. |
|
|
90
|
+
|
|
91
|
+
`concurrency` exists because an unbounded `Effect.forEach` over a directory
|
|
92
|
+
would start one helper per entry and pin every core. Raise it deliberately.
|
|
93
|
+
|
|
94
|
+
Everything except `executable` is snapshotted when the layer is built. The
|
|
95
|
+
options object stays yours, and a byte ceiling that changed under a running
|
|
96
|
+
host would not be a ceiling.
|
|
97
|
+
|
|
98
|
+
## Windows
|
|
99
|
+
|
|
100
|
+
The extension is unsupported on Windows. A guarded path operation there fails
|
|
101
|
+
closed.
|
|
102
|
+
|
|
103
|
+
## Related
|
|
104
|
+
|
|
105
|
+
- [The Host surface on Bun](../concepts/host-surface.md): why the filesystem
|
|
106
|
+
slot is the Node package's implementation, and what the extension buys under
|
|
107
|
+
the kernel's guard.
|
|
108
|
+
- [`@smthrs/platform-node`](/api/platform-node): the `AtomicFileSystem` adapter
|
|
109
|
+
itself, its full option set, and its refusal matrix.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Contain and reap child processes"
|
|
3
|
+
description: "Compose BunHost.layerContained with a ProcessLedger so each command has a supervised process group, a cleanup deadline, and a durable identity for restart reconciliation."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`BunHost.layer` provides the raw process service. A scope finalizer can signal
|
|
7
|
+
its target, but a target that exits first can leave descendants holding output
|
|
8
|
+
open. A crashed host runs no finalizers at all.
|
|
9
|
+
|
|
10
|
+
`BunHost.layerContained` combines a live process owner with a ledger for
|
|
11
|
+
cleanup that a later host must reconcile.
|
|
12
|
+
|
|
13
|
+
## What containment adds
|
|
14
|
+
|
|
15
|
+
**A live owner and deadline.** Every pipeline leg gets a prepared POSIX
|
|
16
|
+
supervisor. Its lifetime is independent of the native target, so cleanup can
|
|
17
|
+
stop the owned group even after the target exits. The default policy is
|
|
18
|
+
`SIGTERM`, then `SIGKILL` after `graceMs`; an explicit `killSignal` or
|
|
19
|
+
`forceKillAfter` is preserved. A private connection also initiates cleanup
|
|
20
|
+
when the host disappears.
|
|
21
|
+
|
|
22
|
+
**A durable record before execution.** The kernel records the prepared
|
|
23
|
+
supervisor's identity and the executable it runs before activation starts the
|
|
24
|
+
target. The record carries the owner pid and group, host identity, host
|
|
25
|
+
incarnation pid, and start time. Only verified cleanup retires it; failed or
|
|
26
|
+
unverified cleanup fails scope release and retains the record.
|
|
27
|
+
|
|
28
|
+
`commandDigest` names the program and never its arguments, because a
|
|
29
|
+
journal-backed ledger keeps every record permanently and arguments carry
|
|
30
|
+
credentials: `curl -u user:pass`, `mysql -phunter2`, `deploy --token hunter2`.
|
|
31
|
+
Nothing that reads a record needs more, since the reaper matches on pid and
|
|
32
|
+
process group. Keep credentials out of argv anyway, in the environment or on
|
|
33
|
+
stdin: while a child runs, its arguments are readable through `ps`.
|
|
34
|
+
|
|
35
|
+
**A sweep on the way up.** While the layer is built,
|
|
36
|
+
[`@smthrs/platform-node`](/api/platform-node)'s `ProcessReaper` reads the
|
|
37
|
+
records a previous incarnation of the same `hostId` left behind and signals the
|
|
38
|
+
groups they name after checking their identities. The lifecycle and reaper
|
|
39
|
+
live in the Node package and support ordinary Node and Bun runtimes.
|
|
40
|
+
|
|
41
|
+
On POSIX, a returned handle's `pid` identifies the supervisor; `exitCode` and
|
|
42
|
+
`isRunning` describe the target. Signal through `handle.kill`, not either
|
|
43
|
+
numeric pid. `detached: false` retains a supervisor but opts out of group
|
|
44
|
+
cleanup, signalling only the target. Explicit stopping while a grouped target
|
|
45
|
+
is still alive also attempts a revalidated positive-PID sweep of escaped
|
|
46
|
+
descendants. That extra sweep is best effort; natural exit does not promise
|
|
47
|
+
cleanup of deliberately escaped sessions. Windows remains unsupported best
|
|
48
|
+
effort. Node single-executable applications and compiled Bun executables are
|
|
49
|
+
refused before activation because the supervisor needs a runtime eval entry
|
|
50
|
+
point.
|
|
51
|
+
|
|
52
|
+
## Compose it
|
|
53
|
+
|
|
54
|
+
The ledger is a layer requirement rather than a built-in default, because only
|
|
55
|
+
your program knows whether it has a durable one:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import * as ProcessLedger from "@smthrs/kernel/ProcessLedger"
|
|
59
|
+
import { BunHost } from "@smthrs/platform-bun"
|
|
60
|
+
import * as Layer from "effect/Layer"
|
|
61
|
+
|
|
62
|
+
const host = BunHost.layerContainedAt("/srv/repositories/app", {
|
|
63
|
+
graceMs: 2_000,
|
|
64
|
+
ownerPid: process.pid
|
|
65
|
+
}).pipe(
|
|
66
|
+
Layer.provide(ProcessLedger.layerMemory({ hostId: "worker-a", ownerPid: process.pid }))
|
|
67
|
+
)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`ProcessLedger.layerMemory` records nothing durably. A host built on it still
|
|
71
|
+
contains the process groups it owns, including when the host connection closes,
|
|
72
|
+
but it inherits nothing from a previous incarnation, so the reaper has nothing
|
|
73
|
+
to sweep. Use it in tests and in short-lived programs.
|
|
74
|
+
|
|
75
|
+
`ProcessLedger.layer` writes through a [`@smthrs/journal`](/api/journal)
|
|
76
|
+
`Journal`, which is what makes the durable half real. Give two incarnations the
|
|
77
|
+
same `hostId` and the second inherits the first's unreleased records.
|
|
78
|
+
|
|
79
|
+
## The options both contained factories take
|
|
80
|
+
|
|
81
|
+
`BunHost.ContainedOptions` is the containment configuration plus the reaper's:
|
|
82
|
+
|
|
83
|
+
| Field | Meaning |
|
|
84
|
+
| ---------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
85
|
+
| `graceMs` | Milliseconds between the `SIGTERM` that asks a child to stop and the `SIGKILL` that makes it. Default 2000. |
|
|
86
|
+
| `ownerPid` | The pid this host must never signal a group for, so it cannot kill itself. Default `process.pid`. |
|
|
87
|
+
| `system` | The operating-system seam the reaper reads liveness and start times through. Default: chosen from `process.platform`. |
|
|
88
|
+
|
|
89
|
+
Each factory reads the options when you call it, not when the layer is built,
|
|
90
|
+
and splits them into the two halves so a field meant for one can never be read
|
|
91
|
+
by the other. Mutating the object you passed afterwards changes neither layer.
|
|
92
|
+
|
|
93
|
+
## Why there is no `platform` option
|
|
94
|
+
|
|
95
|
+
`ContainedSpawner.Options` has a `platform` field. `ContainedOptions` omits it,
|
|
96
|
+
deliberately.
|
|
97
|
+
|
|
98
|
+
The contained factories use `ProcessReaper.layerSpawner`, which reads the real
|
|
99
|
+
`process.platform`. The native process-group behavior and recorded identity
|
|
100
|
+
must agree: a caller cannot describe a Windows record for an owner that
|
|
101
|
+
actually leads a POSIX group. Casting `platform: "win32"` past the type does
|
|
102
|
+
not override the running platform.
|
|
103
|
+
|
|
104
|
+
For a smaller Bun composition, use `ProcessReaper.layerSpawner` with a ledger
|
|
105
|
+
and an underlying runtime spawner. It includes the prepared native adapter
|
|
106
|
+
whose pipe error listeners remain alive through cancellation. Keep the kernel
|
|
107
|
+
permission decorator above it to authorize the caller's command before
|
|
108
|
+
preparation.
|
|
109
|
+
|
|
110
|
+
## `jj` is contained too
|
|
111
|
+
|
|
112
|
+
Under `BunHost.layer`, the `Jj` slot spawns the jj CLI through
|
|
113
|
+
`node:child_process` directly. A jj child therefore leads no group the host
|
|
114
|
+
recorded, appears in no ledger, and outlives the host that ran it.
|
|
115
|
+
|
|
116
|
+
`layerContained` and `layerContainedAt` build `Jj` over the contained spawner
|
|
117
|
+
(`BunJj.layerSpawner` and `BunJj.layerSpawnerAt`) rather than around it, so a
|
|
118
|
+
`jj` invocation is a ledger record like any other child:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { Jj } from "@smthrs/jj"
|
|
122
|
+
import * as Effect from "effect/Effect"
|
|
123
|
+
|
|
124
|
+
// The ledger records the jj executable while status runs, and retires it when the
|
|
125
|
+
// invocation and its cleanup finish.
|
|
126
|
+
const status = Effect.flatMap(Jj, (jj) => jj.status()).pipe(
|
|
127
|
+
Effect.provide(host),
|
|
128
|
+
Effect.scoped
|
|
129
|
+
)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
That is the observable difference: the same call under `BunHost.layer` leaves
|
|
133
|
+
the ledger empty. The initial `jj --version` probe uses the selected runner
|
|
134
|
+
too, so a contained host records and retires it before exposing `Jj`. Probe
|
|
135
|
+
results are cached per resolved absolute executable path and runner, with a
|
|
136
|
+
separate cache for each spawner instance.
|
|
137
|
+
|
|
138
|
+
Every aggregate host waits up to 5000 ms for the startup probe, then interrupts
|
|
139
|
+
it and awaits process cleanup. The typed `JjError` has `method: "version"`,
|
|
140
|
+
`code: "unknown"`, `cause.code: "ETIMEDOUT"`, and the executable path in its
|
|
141
|
+
command and message. Cleanup can add the contained spawner's shutdown grace
|
|
142
|
+
period to the startup budget. Raw hosts close the probe's pipes and kill its
|
|
143
|
+
direct child; they do not add a ledger entry.
|
|
144
|
+
|
|
145
|
+
Override the budget per host layer through the shared Node and Bun adapter:
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
import * as NodeJj from "@smthrs/jj/node/NodeJj"
|
|
149
|
+
|
|
150
|
+
const boundedHost = host.pipe(
|
|
151
|
+
Layer.provide(Layer.succeed(NodeJj.StartupTimeoutMs)(1_500))
|
|
152
|
+
)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The budget is a positive, finite number of milliseconds, at most 2147483647.
|
|
156
|
+
Timeout and interruption allow a later construction to retry the probe.
|
|
157
|
+
|
|
158
|
+
## What the reaper refuses to kill
|
|
159
|
+
|
|
160
|
+
A record is not a licence to signal. `ProcessReaper.reap` re-checks each
|
|
161
|
+
inherited record and declines when the numbers do not clearly name an
|
|
162
|
+
abandoned process: the owning incarnation is still alive, the record names this
|
|
163
|
+
host's own group, the pid is gone, the pid exists but did not start when the
|
|
164
|
+
record says it did, the record predates the machine's boot, or the host could
|
|
165
|
+
not ask the question at all.
|
|
166
|
+
|
|
167
|
+
Four refusals leave the record inherited rather than retiring it:
|
|
168
|
+
`owner-alive`, `identity-unverified`, `own-group-unknown`, and `kill-failed`. A host that
|
|
169
|
+
could not ask, or that has no business signalling, must not be the one that
|
|
170
|
+
closes the question. A later incarnation that can ask gets the chance.
|
|
171
|
+
|
|
172
|
+
## Related
|
|
173
|
+
|
|
174
|
+
- [Bind the host to a repository root](./bind-a-repository-root.md): what
|
|
175
|
+
`layerContainedAt` adds beyond containment, and the refusal it throws.
|
|
176
|
+
- [Quickstart](../quickstart.md): a runnable version of the composition above.
|