@smthrs/gateway 0.34.0 → 1.0.0-rc.3
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 +198 -0
- package/LICENSE +1 -1
- package/README.md +92 -0
- package/dist/cjs/Diagnosis.d.ts +275 -0
- package/dist/cjs/Diagnosis.d.ts.map +1 -0
- package/dist/cjs/Diagnosis.js +476 -0
- package/dist/cjs/Diagnosis.js.map +7 -0
- package/dist/cjs/EngineTrace.d.ts +76 -0
- package/dist/cjs/EngineTrace.d.ts.map +1 -0
- package/dist/cjs/EngineTrace.js +501 -0
- package/dist/cjs/EngineTrace.js.map +7 -0
- package/dist/cjs/GatewayError.d.ts +54 -0
- package/dist/cjs/GatewayError.d.ts.map +1 -0
- package/dist/cjs/GatewayError.js +51 -0
- package/dist/cjs/GatewayError.js.map +7 -0
- package/dist/cjs/GatewayProjection.d.ts +480 -0
- package/dist/cjs/GatewayProjection.d.ts.map +1 -0
- package/dist/cjs/GatewayProjection.js +462 -0
- package/dist/cjs/GatewayProjection.js.map +7 -0
- package/dist/cjs/GatewayRpcs.d.ts +1886 -0
- package/dist/cjs/GatewayRpcs.d.ts.map +1 -0
- package/dist/cjs/GatewayRpcs.js +121 -0
- package/dist/cjs/GatewayRpcs.js.map +7 -0
- package/dist/cjs/GatewaySchema.d.ts +3274 -0
- package/dist/cjs/GatewaySchema.d.ts.map +1 -0
- package/dist/cjs/GatewaySchema.js +141 -0
- package/dist/cjs/GatewaySchema.js.map +7 -0
- package/dist/cjs/GatewayServer.d.ts +427 -0
- package/dist/cjs/GatewayServer.d.ts.map +1 -0
- package/dist/cjs/GatewayServer.js +428 -0
- package/dist/cjs/GatewayServer.js.map +7 -0
- package/dist/cjs/HostBranchPresence.d.ts +12 -0
- package/dist/cjs/HostBranchPresence.d.ts.map +1 -0
- package/dist/cjs/HostBranchPresence.js +82 -0
- package/dist/cjs/HostBranchPresence.js.map +7 -0
- package/dist/cjs/Projections.d.ts +209 -0
- package/dist/cjs/Projections.d.ts.map +1 -0
- package/dist/cjs/Projections.js +906 -0
- package/dist/cjs/Projections.js.map +7 -0
- package/dist/cjs/RunDevTools.d.ts +181 -0
- package/dist/cjs/RunDevTools.d.ts.map +1 -0
- package/dist/cjs/RunDevTools.js +195 -0
- package/dist/cjs/RunDevTools.js.map +7 -0
- package/dist/cjs/RunHistory.d.ts +185 -0
- package/dist/cjs/RunHistory.d.ts.map +1 -0
- package/dist/cjs/RunHistory.js +68 -0
- package/dist/cjs/RunHistory.js.map +7 -0
- package/dist/cjs/RunTrace.d.ts +753 -0
- package/dist/cjs/RunTrace.d.ts.map +1 -0
- package/dist/cjs/RunTrace.js +1593 -0
- package/dist/cjs/RunTrace.js.map +7 -0
- package/dist/cjs/RuntimeBridge.d.ts +1386 -0
- package/dist/cjs/RuntimeBridge.d.ts.map +1 -0
- package/dist/cjs/RuntimeBridge.js +598 -0
- package/dist/cjs/RuntimeBridge.js.map +7 -0
- package/dist/cjs/bun/BunGateway.d.ts +20 -0
- package/dist/cjs/bun/BunGateway.d.ts.map +1 -0
- package/dist/cjs/bun/BunGateway.js +62 -0
- package/dist/cjs/bun/BunGateway.js.map +7 -0
- package/dist/cjs/index.d.ts +65 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +59 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/NativeGateway.d.ts +176 -0
- package/dist/cjs/internal/NativeGateway.d.ts.map +1 -0
- package/dist/cjs/internal/NativeGateway.js +187 -0
- package/dist/cjs/internal/NativeGateway.js.map +7 -0
- package/dist/cjs/internal/actionRenderings.d.ts +2 -0
- package/dist/cjs/internal/actionRenderings.d.ts.map +1 -0
- package/dist/cjs/internal/actionRenderings.js +224 -0
- package/dist/cjs/internal/actionRenderings.js.map +7 -0
- package/dist/cjs/internal/callEvents.d.ts +97 -0
- package/dist/cjs/internal/callEvents.d.ts.map +1 -0
- package/dist/cjs/internal/callEvents.js +169 -0
- package/dist/cjs/internal/callEvents.js.map +7 -0
- package/dist/cjs/internal/digestIndex.d.ts +31 -0
- package/dist/cjs/internal/digestIndex.d.ts.map +1 -0
- package/dist/cjs/internal/digestIndex.js +105 -0
- package/dist/cjs/internal/digestIndex.js.map +7 -0
- package/dist/cjs/internal/digestMemory.d.ts +19 -0
- package/dist/cjs/internal/digestMemory.d.ts.map +1 -0
- package/dist/cjs/internal/digestMemory.js +33 -0
- package/dist/cjs/internal/digestMemory.js.map +7 -0
- package/dist/cjs/internal/inspectLabels.d.ts +8 -0
- package/dist/cjs/internal/inspectLabels.d.ts.map +1 -0
- package/dist/cjs/internal/inspectLabels.js +29 -0
- package/dist/cjs/internal/inspectLabels.js.map +7 -0
- package/dist/cjs/internal/nativeResolution.d.ts +41 -0
- package/dist/cjs/internal/nativeResolution.d.ts.map +1 -0
- package/dist/cjs/internal/nativeResolution.js +62 -0
- package/dist/cjs/internal/nativeResolution.js.map +7 -0
- package/dist/cjs/internal/nodeEvents.d.ts +47 -0
- package/dist/cjs/internal/nodeEvents.d.ts.map +1 -0
- package/dist/cjs/internal/nodeEvents.js +60 -0
- package/dist/cjs/internal/nodeEvents.js.map +7 -0
- package/dist/cjs/node/NodeGateway.d.ts +16 -0
- package/dist/cjs/node/NodeGateway.d.ts.map +1 -0
- package/dist/cjs/node/NodeGateway.js +48 -0
- package/dist/cjs/node/NodeGateway.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/Diagnosis.d.ts +275 -0
- package/dist/esm/Diagnosis.d.ts.map +1 -0
- package/dist/esm/Diagnosis.js +697 -0
- package/dist/esm/Diagnosis.js.map +1 -0
- package/dist/esm/EngineTrace.d.ts +76 -0
- package/dist/esm/EngineTrace.d.ts.map +1 -0
- package/dist/esm/EngineTrace.js +548 -0
- package/dist/esm/EngineTrace.js.map +1 -0
- package/dist/esm/GatewayError.d.ts +54 -0
- package/dist/esm/GatewayError.d.ts.map +1 -0
- package/dist/esm/GatewayError.js +60 -0
- package/dist/esm/GatewayError.js.map +1 -0
- package/dist/esm/GatewayProjection.d.ts +480 -0
- package/dist/esm/GatewayProjection.d.ts.map +1 -0
- package/dist/esm/GatewayProjection.js +792 -0
- package/dist/esm/GatewayProjection.js.map +1 -0
- package/dist/esm/GatewayRpcs.d.ts +1886 -0
- package/dist/esm/GatewayRpcs.d.ts.map +1 -0
- package/dist/esm/GatewayRpcs.js +145 -0
- package/dist/esm/GatewayRpcs.js.map +1 -0
- package/dist/esm/GatewaySchema.d.ts +3274 -0
- package/dist/esm/GatewaySchema.d.ts.map +1 -0
- package/dist/esm/GatewaySchema.js +244 -0
- package/dist/esm/GatewaySchema.js.map +1 -0
- package/dist/esm/GatewayServer.d.ts +427 -0
- package/dist/esm/GatewayServer.d.ts.map +1 -0
- package/dist/esm/GatewayServer.js +725 -0
- package/dist/esm/GatewayServer.js.map +1 -0
- package/dist/esm/HostBranchPresence.d.ts +12 -0
- package/dist/esm/HostBranchPresence.d.ts.map +1 -0
- package/dist/esm/HostBranchPresence.js +54 -0
- package/dist/esm/HostBranchPresence.js.map +1 -0
- package/dist/esm/Projections.d.ts +209 -0
- package/dist/esm/Projections.d.ts.map +1 -0
- package/dist/esm/Projections.js +1254 -0
- package/dist/esm/Projections.js.map +1 -0
- package/dist/esm/RunDevTools.d.ts +181 -0
- package/dist/esm/RunDevTools.d.ts.map +1 -0
- package/dist/esm/RunDevTools.js +281 -0
- package/dist/esm/RunDevTools.js.map +1 -0
- package/dist/esm/RunHistory.d.ts +185 -0
- package/dist/esm/RunHistory.d.ts.map +1 -0
- package/dist/esm/RunHistory.js +109 -0
- package/dist/esm/RunHistory.js.map +1 -0
- package/dist/esm/RunTrace.d.ts +753 -0
- package/dist/esm/RunTrace.d.ts.map +1 -0
- package/dist/esm/RunTrace.js +2105 -0
- package/dist/esm/RunTrace.js.map +1 -0
- package/dist/esm/RuntimeBridge.d.ts +1386 -0
- package/dist/esm/RuntimeBridge.d.ts.map +1 -0
- package/dist/esm/RuntimeBridge.js +659 -0
- package/dist/esm/RuntimeBridge.js.map +1 -0
- package/dist/esm/bun/BunGateway.d.ts +20 -0
- package/dist/esm/bun/BunGateway.d.ts.map +1 -0
- package/dist/esm/bun/BunGateway.js +32 -0
- package/dist/esm/bun/BunGateway.js.map +1 -0
- package/dist/esm/index.d.ts +65 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +65 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/NativeGateway.d.ts +176 -0
- package/dist/esm/internal/NativeGateway.d.ts.map +1 -0
- package/dist/esm/internal/NativeGateway.js +268 -0
- package/dist/esm/internal/NativeGateway.js.map +1 -0
- package/dist/esm/internal/actionRenderings.d.ts +2 -0
- package/dist/esm/internal/actionRenderings.d.ts.map +1 -0
- package/dist/esm/internal/actionRenderings.js +202 -0
- package/dist/esm/internal/actionRenderings.js.map +1 -0
- package/dist/esm/internal/callEvents.d.ts +97 -0
- package/dist/esm/internal/callEvents.d.ts.map +1 -0
- package/dist/esm/internal/callEvents.js +206 -0
- package/dist/esm/internal/callEvents.js.map +1 -0
- package/dist/esm/internal/digestIndex.d.ts +31 -0
- package/dist/esm/internal/digestIndex.d.ts.map +1 -0
- package/dist/esm/internal/digestIndex.js +87 -0
- package/dist/esm/internal/digestIndex.js.map +1 -0
- package/dist/esm/internal/digestMemory.d.ts +19 -0
- package/dist/esm/internal/digestMemory.d.ts.map +1 -0
- package/dist/esm/internal/digestMemory.js +23 -0
- package/dist/esm/internal/digestMemory.js.map +1 -0
- package/dist/esm/internal/inspectLabels.d.ts +8 -0
- package/dist/esm/internal/inspectLabels.d.ts.map +1 -0
- package/dist/esm/internal/inspectLabels.js +12 -0
- package/dist/esm/internal/inspectLabels.js.map +1 -0
- package/dist/esm/internal/nativeResolution.d.ts +41 -0
- package/dist/esm/internal/nativeResolution.d.ts.map +1 -0
- package/dist/esm/internal/nativeResolution.js +78 -0
- package/dist/esm/internal/nativeResolution.js.map +1 -0
- package/dist/esm/internal/nodeEvents.d.ts +47 -0
- package/dist/esm/internal/nodeEvents.d.ts.map +1 -0
- package/dist/esm/internal/nodeEvents.js +60 -0
- package/dist/esm/internal/nodeEvents.js.map +1 -0
- package/dist/esm/node/NodeGateway.d.ts +16 -0
- package/dist/esm/node/NodeGateway.d.ts.map +1 -0
- package/dist/esm/node/NodeGateway.js +13 -0
- package/dist/esm/node/NodeGateway.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-2GCOZTTW.js +48 -0
- package/dist/vendor/chunk-37CUR3PO.js +81 -0
- package/dist/vendor/chunk-3ARKKENZ.js +45 -0
- package/dist/vendor/chunk-3NV2UDBI.js +7 -0
- package/dist/vendor/chunk-3OSW7CT7.js +143 -0
- package/dist/vendor/chunk-62R63L74.js +62 -0
- package/dist/vendor/chunk-6AQLBC2I.js +118 -0
- package/dist/vendor/chunk-6C5H7S6B.js +18 -0
- package/dist/vendor/chunk-6DY5RBZD.js +85 -0
- package/dist/vendor/chunk-6UPBD47P.js +53 -0
- package/dist/vendor/chunk-AVVVN75Z.js +96 -0
- package/dist/vendor/chunk-B4DHEMBB.js +14 -0
- package/dist/vendor/chunk-BCK3NJOX.js +15 -0
- package/dist/vendor/chunk-BFBIHJ6X.js +0 -0
- package/dist/vendor/chunk-CES4OUM4.js +63 -0
- package/dist/vendor/chunk-D64L6YND.js +59 -0
- package/dist/vendor/chunk-DS2R6WOM.js +18 -0
- package/dist/vendor/chunk-DX4Z23DM.js +65 -0
- package/dist/vendor/chunk-DZ2VOUDP.js +564 -0
- package/dist/vendor/chunk-FOXN6JPJ.js +61 -0
- package/dist/vendor/chunk-FPQF7CR5.js +55 -0
- package/dist/vendor/chunk-FUTCTCEG.js +20 -0
- package/dist/vendor/chunk-GUPAV2YZ.js +18 -0
- package/dist/vendor/chunk-H2Z2Y4QH.js +70 -0
- package/dist/vendor/chunk-HAEDVSSM.js +129 -0
- package/dist/vendor/chunk-HY7BBL3K.js +93 -0
- package/dist/vendor/chunk-IFTTT6D5.js +31 -0
- package/dist/vendor/chunk-KQDSNB7M.js +26 -0
- package/dist/vendor/chunk-LIHLXXGQ.js +26 -0
- package/dist/vendor/chunk-LKCGQEE5.js +28 -0
- package/dist/vendor/chunk-MH2J3BYB.js +0 -0
- package/dist/vendor/chunk-ML2NAFH2.js +131 -0
- package/dist/vendor/chunk-MLFIZ5O2.js +0 -0
- package/dist/vendor/chunk-MLKGABMK.js +9 -0
- package/dist/vendor/chunk-MSCLEMYX.js +71 -0
- package/dist/vendor/chunk-OBWXQKVP.js +57 -0
- package/dist/vendor/chunk-QR557K66.js +20 -0
- package/dist/vendor/chunk-R4QUY7DH.js +18 -0
- package/dist/vendor/chunk-RGECXXJS.js +18 -0
- package/dist/vendor/chunk-TFY7W6D4.js +36 -0
- package/dist/vendor/chunk-TGPIVY4A.js +104 -0
- package/dist/vendor/chunk-TGXCX6W3.js +398 -0
- package/dist/vendor/chunk-TOHSFXMV.js +437 -0
- package/dist/vendor/chunk-UHIDPUFF.js +34 -0
- package/dist/vendor/chunk-ULT6CWUI.js +109 -0
- package/dist/vendor/chunk-UXBGYQR3.js +18 -0
- package/dist/vendor/chunk-V6LUGQ7O.js +21 -0
- package/dist/vendor/chunk-W4OASVX6.js +92 -0
- package/dist/vendor/chunk-WAII54GA.js +18 -0
- package/dist/vendor/chunk-WECQDT36.js +426 -0
- package/dist/vendor/chunk-WHKMOC7Z.js +28 -0
- package/dist/vendor/chunk-WVFOZ2UL.js +40 -0
- package/dist/vendor/chunk-X73E2UPI.js +18 -0
- package/dist/vendor/chunk-XCYARUII.js +63 -0
- package/dist/vendor/chunk-XFEVTDVD.js +34 -0
- package/dist/vendor/chunk-XFZZYSJ4.js +22 -0
- package/dist/vendor/chunk-XJWJXLXJ.js +18 -0
- package/dist/vendor/chunk-XY3Q62EO.js +18 -0
- package/dist/vendor/chunk-YDASSC75.js +394 -0
- package/dist/vendor/chunk-Z6C7SO5Z.js +507 -0
- package/dist/vendor/chunk-Z7QNPJEB.js +229 -0
- package/dist/vendor/chunk-Z7QPP4YH.js +249 -0
- package/dist/vendor/chunk-ZCHYLHJH.js +86 -0
- package/dist/vendor/chunk-ZIQVYVMA.js +22 -0
- package/dist/vendor/chunk-ZPIG2CUA.js +34 -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 +158 -0
- package/docs/api.md +601 -0
- package/docs/concepts/projections.md +250 -0
- package/docs/concepts/subscriptions.md +204 -0
- package/docs/concepts/trust-boundary.md +256 -0
- package/docs/guides/diagnose-a-run.md +115 -0
- package/docs/guides/follow-a-run.md +150 -0
- package/docs/guides/host-the-gateway.md +153 -0
- package/docs/guides/read-a-projection.md +138 -0
- package/docs/guides/serve-beyond-loopback.md +166 -0
- package/docs/guides/submit-an-approval.md +187 -0
- package/docs/guides/testing.md +148 -0
- package/docs/installation.md +89 -0
- package/docs/quickstart.md +200 -0
- package/docs/troubleshooting.md +355 -0
- package/package.json +264 -32
- package/src/Diagnosis.ts +892 -0
- package/src/EngineTrace.ts +605 -0
- package/src/GatewayError.ts +71 -0
- package/src/GatewayProjection.ts +948 -0
- package/src/GatewayRpcs.ts +179 -0
- package/src/GatewaySchema.ts +516 -0
- package/src/GatewayServer.ts +932 -0
- package/src/HostBranchPresence.ts +72 -0
- package/src/Projections.ts +1735 -0
- package/src/RunDevTools.ts +394 -0
- package/src/RunHistory.ts +174 -0
- package/src/RunTrace.ts +2793 -0
- package/src/RuntimeBridge.ts +835 -0
- package/src/bun/BunGateway.ts +52 -0
- package/src/index.ts +77 -0
- package/src/internal/NativeGateway.ts +360 -0
- package/src/internal/actionRenderings.ts +201 -0
- package/src/internal/callEvents.ts +257 -0
- package/src/internal/digestIndex.ts +134 -0
- package/src/internal/digestMemory.ts +27 -0
- package/src/internal/inspectLabels.ts +13 -0
- package/src/internal/nativeResolution.ts +103 -0
- package/src/internal/nodeEvents.ts +100 -0
- package/src/node/NodeGateway.ts +30 -0
- package/openapi.yaml +0 -29182
- package/src/README.md +0 -39
- package/src/api/README.md +0 -23
- package/src/api/apiCollectionNames.js +0 -10
- package/src/api/index.d.ts +0 -126
- package/src/api/index.js +0 -14
- package/src/api/normalizeApiRow.js +0 -36
- package/src/api/serializeAccountRow.js +0 -10
- package/src/api/serializeApprovalRow.js +0 -53
- package/src/api/serializeComparisonScoreRow.js +0 -18
- package/src/api/serializeCronRow.js +0 -30
- package/src/api/serializeDocRow.js +0 -20
- package/src/api/serializeMemoryFactRow.js +0 -21
- package/src/api/serializePromptRow.js +0 -10
- package/src/api/serializeRunEventRow.js +0 -28
- package/src/api/serializeRunRow.js +0 -61
- package/src/api/serializeScoreDetailRow.js +0 -25
- package/src/api/serializeScoreRow.js +0 -26
- package/src/api/serializeTicketRow.js +0 -20
- package/src/api/serializeWorkflowRow.js +0 -10
- package/src/auth/scopes.d.ts +0 -19
- package/src/auth/scopes.js +0 -164
- package/src/index.d.ts +0 -316
- package/src/index.js +0 -108
- package/src/rpc/gatewayRpcTypes.ts +0 -183
- package/src/rpc/index.d.ts +0 -221
- package/src/rpc/index.js +0 -2431
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Read a projection over HTTP"
|
|
3
|
+
description: "Call Projection.Snapshot for each of the eight selectors, decode the rows with the schema the selector names, and keep the cursor the snapshot answers with."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 2
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
`Projection.Snapshot` answers every row a selector currently projects, plus the
|
|
9
|
+
cursor they were read at. It is the request/response half of the read path, and
|
|
10
|
+
it is what a relay in front of a gateway uses, because a stream belongs on a
|
|
11
|
+
socket rather than in a buffered response.
|
|
12
|
+
|
|
13
|
+
## Pick a selector
|
|
14
|
+
|
|
15
|
+
Each selector is a tagged struct. Build one as a value, never as a string:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import * as GatewaySchema from "@smthrs/gateway/GatewaySchema"
|
|
19
|
+
|
|
20
|
+
const everyRun: GatewaySchema.ProjectionSelector = { _tag: "workspace-runs" }
|
|
21
|
+
const oneRun: GatewaySchema.ProjectionSelector = { _tag: "run-summary", runId }
|
|
22
|
+
const itsEvents: GatewaySchema.ProjectionSelector = { _tag: "run-events", runId }
|
|
23
|
+
const itsTranscript: GatewaySchema.ProjectionSelector = { _tag: "transcript", runId }
|
|
24
|
+
const itsCalls: GatewaySchema.ProjectionSelector = { _tag: "run-tree", runId }
|
|
25
|
+
const itsGates: GatewaySchema.ProjectionSelector = { _tag: "approvals", runId }
|
|
26
|
+
const theInbox: GatewaySchema.ProjectionSelector = { _tag: "approvals" }
|
|
27
|
+
const oneOutput: GatewaySchema.ProjectionSelector = { _tag: "node-output", runId, nodeId: "call-1" }
|
|
28
|
+
const itsDurations: GatewaySchema.ProjectionSelector = { _tag: "flow-durations", flowId }
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`approvals` is the one selector whose `runId` is optional, and the two forms
|
|
32
|
+
answer different questions. With a run it lists that run's gates including the
|
|
33
|
+
decided ones, which is what a run card renders: a gate a human already answered
|
|
34
|
+
still belongs on the card that asked. Without one it lists the workspace's
|
|
35
|
+
pending gates, which is the approvals inbox.
|
|
36
|
+
|
|
37
|
+
## Read it in process
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { Projections } from "@smthrs/gateway/Projections"
|
|
41
|
+
import { Effect } from "effect"
|
|
42
|
+
|
|
43
|
+
const rows = Effect.gen(function*() {
|
|
44
|
+
const projections = yield* Projections
|
|
45
|
+
const snapshot = yield* projections.snapshot({ _tag: "run-tree", runId })
|
|
46
|
+
return snapshot.rows
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The effect fails with a `GatewayError`. `run_not_found` means the control plane
|
|
51
|
+
does not have that run, and it is answered identically for every run-scoped
|
|
52
|
+
selector: reading a run's events alone cannot tell an unknown run from a run
|
|
53
|
+
with no events.
|
|
54
|
+
|
|
55
|
+
## Read it over the wire
|
|
56
|
+
|
|
57
|
+
The mount speaks RPC over newline-delimited JSON. One request is one line:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
curl -s http://127.0.0.1:3000/projections \
|
|
61
|
+
-H 'content-type: application/json' \
|
|
62
|
+
--data-binary '{"_tag":"Request","id":1,"tag":"Projection.Snapshot","payload":{"selector":{"_tag":"run-tree","runId":"run-1"}},"headers":[]}
|
|
63
|
+
'
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
{"_tag":"Exit","requestId":1,"exit":{"_tag":"Success","value":{"selector":{"_tag":"run-tree","runId":"run-1"},"cursor":{...},"rows":[...]}}}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
A failure arrives as the same envelope with a `Failure` exit carrying the typed
|
|
71
|
+
`GatewayError`. A refusal answered by the ingress guard instead, before the
|
|
72
|
+
mount saw the request, is a plain JSON body under an HTTP status: see
|
|
73
|
+
[the trust boundary](../concepts/trust-boundary.md#ingress-runs-before-the-transport-parses-anything).
|
|
74
|
+
|
|
75
|
+
If the gateway was bound with a credential, send it:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
curl -s http://127.0.0.1:3000/projections \
|
|
79
|
+
-H "authorization: Bearer $SMITHERS_TOKEN" \
|
|
80
|
+
-H 'content-type: application/json' \
|
|
81
|
+
--data-binary '{"_tag":"Request","id":1,"tag":"Projection.Snapshot","payload":{"selector":{"_tag":"workspace-runs"}},"headers":[]}
|
|
82
|
+
'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Decode the rows, do not cast them
|
|
86
|
+
|
|
87
|
+
`GatewaySchema.rowSchemaFor` maps a selector to the schema its rows decode
|
|
88
|
+
under, so a client that already has the selector does not need a switch of its
|
|
89
|
+
own:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import * as GatewaySchema from "@smthrs/gateway/GatewaySchema"
|
|
93
|
+
import { Schema } from "effect"
|
|
94
|
+
|
|
95
|
+
const decodeRows = (selector: GatewaySchema.ProjectionSelector, rows: unknown) =>
|
|
96
|
+
Schema.decodeUnknownSync(Schema.Array(GatewaySchema.rowSchemaFor(selector)))(rows)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
| Selector | Row schema |
|
|
100
|
+
| ------------------------------- | ----------------------------------- |
|
|
101
|
+
| `workspace-runs`, `run-summary` | `GatewayProjection.RunSummaryRow` |
|
|
102
|
+
| `run-events` | `ControlSchema.ControlEvent` |
|
|
103
|
+
| `transcript` | `GatewayProjection.TranscriptRow` |
|
|
104
|
+
| `run-tree` | `GatewayProjection.RunTreeRow` |
|
|
105
|
+
| `approvals` | `GatewayProjection.ApprovalRow` |
|
|
106
|
+
| `node-output` | `GatewayProjection.NodeOutputRow` |
|
|
107
|
+
| `flow-durations` | `GatewayProjection.FlowDurationRow` |
|
|
108
|
+
|
|
109
|
+
`GatewaySchema.ProjectionSnapshot` decodes the whole answer, selector and
|
|
110
|
+
cursor included, and it is a union correlated on the selector: a snapshot whose
|
|
111
|
+
rows do not belong to its selector does not decode at all.
|
|
112
|
+
|
|
113
|
+
## Keep the cursor
|
|
114
|
+
|
|
115
|
+
Every snapshot carries the cursor its rows were read at. It is not decoration:
|
|
116
|
+
it is the position a subscription resumes from without a second snapshot, and
|
|
117
|
+
the read that produced the rows produced it, so the two cannot disagree. See
|
|
118
|
+
[Follow a run over a WebSocket](./follow-a-run.md).
|
|
119
|
+
|
|
120
|
+
A workspace cursor is always `value` 0 with a `null` run, and cannot resume
|
|
121
|
+
anything. That is a fact about control journal partitioning, not a gap: see
|
|
122
|
+
[Subscriptions and cursors](../concepts/subscriptions.md#workspace-subscriptions-do-not-resume).
|
|
123
|
+
|
|
124
|
+
## Fold rows yourself
|
|
125
|
+
|
|
126
|
+
The folds are exported, so a client that already holds a run summary and its
|
|
127
|
+
events can compute the same rows without a gateway at all:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import * as GatewayProjection from "@smthrs/gateway/GatewayProjection"
|
|
131
|
+
|
|
132
|
+
const tree = GatewayProjection.runTree(run, events)
|
|
133
|
+
const gates = GatewayProjection.approvals(events)
|
|
134
|
+
const lines = GatewayProjection.transcript(events)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
This is the same code path the served projection uses, which is what makes an
|
|
138
|
+
offline reader and a served reader agree.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Serve beyond loopback"
|
|
3
|
+
description: "Bind a gateway on a network address: the two opt-ins the policy requires, the credential every mount then enforces, and the request limits worth setting at the same time."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 5
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
A loopback gateway needs no credential. Its ingress still accepts only a
|
|
9
|
+
loopback `Host` and, when present, a loopback browser `Origin`; Origin-less CLI
|
|
10
|
+
requests keep working. Anything reachable from another machine needs two
|
|
11
|
+
opt-ins, and the policy refuses the bind rather than serving without them.
|
|
12
|
+
|
|
13
|
+
## The two rules
|
|
14
|
+
|
|
15
|
+
1. **A non-loopback host requires an explicit `listen` opt-in.**
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
Refusing non-loopback gateway bind 0.0.0.0 without an explicit --listen opt-in
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
2. **A non-loopback bind requires a bearer credential.**
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
Refusing non-loopback gateway bind 0.0.0.0 without a bearer credential
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`NodeGateway.isLoopbackHost` accepts `127.0.0.1`, `::1`, and `localhost`.
|
|
28
|
+
Every other host, a LAN address and a public one alike, is treated as reachable
|
|
29
|
+
from elsewhere.
|
|
30
|
+
|
|
31
|
+
Both refusals are `bind_failed` `GatewayError` values, answered before anything
|
|
32
|
+
binds.
|
|
33
|
+
|
|
34
|
+
## Bind it
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import * as NodeGateway from "@smthrs/gateway/node/NodeGateway"
|
|
38
|
+
|
|
39
|
+
const gateway = NodeGateway.layer(health, {
|
|
40
|
+
host: "0.0.0.0",
|
|
41
|
+
port: 7331,
|
|
42
|
+
listen: true,
|
|
43
|
+
credential: process.env.SMITHERS_TOKEN,
|
|
44
|
+
allowedHosts: ["gateway.example.com"],
|
|
45
|
+
// Optional, and worth setting behind a relay that cuts idle tunnels sooner
|
|
46
|
+
// than 600 seconds.
|
|
47
|
+
heartbeatMillis: 10_000,
|
|
48
|
+
// Optional. One MiB by default.
|
|
49
|
+
maxRequestBodyBytes: 256 * 1024
|
|
50
|
+
})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
From the command line, bind the machine's concrete LAN address so that address
|
|
54
|
+
is also admitted by the Host policy (replace this example with your address):
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
export SMITHERS_TOKEN="<the bearer token from your secret manager>"
|
|
58
|
+
smthrs serve --host 192.168.1.10 --port 3000 --listen
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The server reads the bearer from `SMITHERS_TOKEN`, which keeps it out of the
|
|
62
|
+
long-lived process's argv. See
|
|
63
|
+
[Serve the workspace gateway](/pkg/cli/guides/serve-the-workspace-gateway).
|
|
64
|
+
|
|
65
|
+
## What the credential then covers
|
|
66
|
+
|
|
67
|
+
One credential authenticates every mount and binds one principal,
|
|
68
|
+
`{ id: "gateway", kind: "bearer" }`. This authenticator has no per-user or
|
|
69
|
+
per-run identity. Approval authority is separately configured on the owning
|
|
70
|
+
Control runtime: by default the bearer cannot approve or deny. To delegate,
|
|
71
|
+
provide `ApprovalAuthority` with that exact identity and allowed target kinds
|
|
72
|
+
and scopes. Delegation applies to everyone holding the shared credential; it
|
|
73
|
+
does not distinguish a human from an agent. See
|
|
74
|
+
[the approval contract](/pkg/control/guides/approvals/#who-may-decide).
|
|
75
|
+
|
|
76
|
+
The loopback Host/Origin restriction belongs to the credential-less local
|
|
77
|
+
mode. A bearer-protected non-loopback gateway accepts the network hostname it
|
|
78
|
+
was deployed under and relies on the configured credential instead.
|
|
79
|
+
|
|
80
|
+
Clients send it as a bearer token:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
curl -s https://gateway.example.com/projections \
|
|
84
|
+
-H "authorization: Bearer $SMITHERS_TOKEN" \
|
|
85
|
+
-H 'content-type: application/json' \
|
|
86
|
+
--data-binary '{"_tag":"Request","id":1,"tag":"Projection.Snapshot","payload":{"selector":{"_tag":"workspace-runs"}},"headers":[]}
|
|
87
|
+
'
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
A WebSocket client sends the same header on the upgrade request. A browser's
|
|
91
|
+
`WebSocket` cannot set headers on an upgrade, so it exchanges the credential for
|
|
92
|
+
a single-use ticket first and presents that on the upgrade instead:
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
const { ticket } = await (await fetch("https://gateway.example.com/auth/ticket", {
|
|
96
|
+
method: "POST",
|
|
97
|
+
headers: { authorization: `Bearer ${token}` }
|
|
98
|
+
})).json()
|
|
99
|
+
const socket = new WebSocket(`wss://gateway.example.com/rpc/ws?ticket=${ticket}`)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The ticket opens one socket within thirty seconds and is refused on replay.
|
|
103
|
+
The socket runs as the credential the ticket was issued against.
|
|
104
|
+
|
|
105
|
+
## Hand out less than the credential
|
|
106
|
+
|
|
107
|
+
`smthrs token mint --scope read:runs --ttl 1h` mints a token under
|
|
108
|
+
`SMITHERS_TOKEN` that this gateway accepts for the procedures the scope names
|
|
109
|
+
and nothing else, until it expires. `--run <id>` or `--flow <id>` confines it
|
|
110
|
+
further. The scopes are `read:runs`, `write:runs`, and `approve:runs`; a token
|
|
111
|
+
stamps `gateway/scoped`, so an `approve:runs` token decides only where the host
|
|
112
|
+
delegates to that identity. Rotating `SMITHERS_TOKEN` revokes every token
|
|
113
|
+
minted under it. See [the trust boundary](../concepts/trust-boundary.md#scoped-expiring-tokens).
|
|
114
|
+
|
|
115
|
+
`/health` stays unauthenticated even here. It answers identity and nothing
|
|
116
|
+
else: no token, no run, no path.
|
|
117
|
+
|
|
118
|
+
## Two refusals that look alike and are not
|
|
119
|
+
|
|
120
|
+
`POST /rpc` is not edge-authenticated. It authenticates in band and answers
|
|
121
|
+
`@smthrs/control`'s typed `Unauthorized`, so a caller sees a control error
|
|
122
|
+
rather than a transport error, exactly as it would against a control server
|
|
123
|
+
hosting the same procedures. `/rpc/ws`, `/projections`, `/sync`, and both other
|
|
124
|
+
sockets are checked at the edge and answer 401 with a `unauthorized`
|
|
125
|
+
`GatewayError` body.
|
|
126
|
+
|
|
127
|
+
Why the two differ, and why it matters to a client's error handling, is in
|
|
128
|
+
[the trust boundary](../concepts/trust-boundary.md#edge-authentication-and-where-it-deliberately-stops).
|
|
129
|
+
|
|
130
|
+
## Bound the requests while you are here
|
|
131
|
+
|
|
132
|
+
For a wildcard bind, set `allowedHosts: ["gateway.example.com"]` on
|
|
133
|
+
`NodeGateway.ServerOptions` to admit the hostname clients use. These entries
|
|
134
|
+
contain no ports or wildcards. A concrete bind host and the loopback names are
|
|
135
|
+
also accepted. The Host and Origin checks apply before bearer authentication;
|
|
136
|
+
a browser's Origin must match the requested authority, including its port.
|
|
137
|
+
|
|
138
|
+
This server binds plain HTTP. For network access, terminate TLS at a trusted
|
|
139
|
+
proxy or use an encrypted tunnel so the bearer token is not sent in cleartext.
|
|
140
|
+
|
|
141
|
+
An HTTP RPC body is capped at `GatewayServer.defaultMaxRequestBodyBytes`, one
|
|
142
|
+
MiB. A declared `content-length` over the limit is refused without reading the
|
|
143
|
+
body; a body that declares no length, or declares less than it sends, is
|
|
144
|
+
measured as it is read. Declared overflow is 413 `request_too_large`; the Node
|
|
145
|
+
host hard-closes a streaming overflow rather than draining attacker-controlled
|
|
146
|
+
bytes, so that client may see a connection reset. A body the server could not
|
|
147
|
+
read for another reason is 400 `malformed_request`.
|
|
148
|
+
|
|
149
|
+
`maxRequestBodyBytes` and `heartbeatMillis` are checked the same way and must
|
|
150
|
+
both be positive safe integers. A body limit of zero would refuse every request
|
|
151
|
+
and a cadence of zero would spin, so a composition that asks for either is
|
|
152
|
+
refused with `bind_failed` before it binds rather than after it is serving.
|
|
153
|
+
|
|
154
|
+
## Check the policy without composing anything
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
const refusal = NodeGateway.bindRefusal(options)
|
|
158
|
+
if (refusal !== undefined) {
|
|
159
|
+
// refusal.code === "bind_failed", refusal.message names the rule that refused
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`bindRefusal` is the same value `listenOptions` fails with and `layer` fails
|
|
164
|
+
through. Operating system listen failures, such as an address already in use,
|
|
165
|
+
are mapped to the same sanitized `bind_failed` shape, so a host has one failure
|
|
166
|
+
contract to handle rather than two.
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Submit an approval from a client"
|
|
3
|
+
description: "Read a pending gate, submit Approval.Submit with independent approval authority, and handle its typed refusals."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 4
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
`Approval.Submit` is the one mutation this package declares. Every other
|
|
9
|
+
mutation a client makes is [`@smthrs/control`](/api/control) `ControlRpcs`,
|
|
10
|
+
mounted unchanged on `/rpc`, so there is exactly one wire definition of `Plan`,
|
|
11
|
+
`Run`, `Approve`, `Deny`, `Cancel`, `Signal`, `Steer`, `Resume`, `List`, and
|
|
12
|
+
`Watch`.
|
|
13
|
+
|
|
14
|
+
This one exists because a decision is a composite act a client cannot
|
|
15
|
+
assemble safely on its own: the grant has to be recorded and the parked run
|
|
16
|
+
delegated to resume, atomically. Control owns that as a single domain command.
|
|
17
|
+
The gateway is a transport adapter over it and composes no second mutation.
|
|
18
|
+
|
|
19
|
+
## Read the gate
|
|
20
|
+
|
|
21
|
+
The payload a decision needs is published by the `approvals` projection. Do not
|
|
22
|
+
build it:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { Projections } from "@smthrs/gateway/Projections"
|
|
26
|
+
import { Effect } from "effect"
|
|
27
|
+
|
|
28
|
+
const pending = Effect.gen(function*() {
|
|
29
|
+
const projections = yield* Projections
|
|
30
|
+
// No runId: the workspace inbox, which lists only gates a human still owes
|
|
31
|
+
// an answer to.
|
|
32
|
+
const snapshot = yield* projections.snapshot({ _tag: "approvals" })
|
|
33
|
+
return snapshot.rows
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Each `GatewayProjection.ApprovalRow` carries:
|
|
38
|
+
|
|
39
|
+
| Field | Holds |
|
|
40
|
+
| ------------- | --------------------------------------------------------------------- |
|
|
41
|
+
| `runId` | the run parked on this gate |
|
|
42
|
+
| `waitRunId` | the execution holding the wait, when it is held below `runId` |
|
|
43
|
+
| `requestId` | the gate's own id |
|
|
44
|
+
| `title` | the question, as the run asked it |
|
|
45
|
+
| `request` | the whole journaled request payload, for rendering |
|
|
46
|
+
| `payload` | the `ControlSchema.ApprovalPayload` a decision submits back unchanged |
|
|
47
|
+
| `requestedAt` | when the gate opened |
|
|
48
|
+
| `status` | `pending`, `approved`, or `denied` |
|
|
49
|
+
|
|
50
|
+
`payload` is the point. It is the exact `ApprovalTarget.Node` envelope the run
|
|
51
|
+
published, carrying the target, the grant scope, and the idempotency key. A
|
|
52
|
+
client submits it back byte for byte, so no client reconstructs authority for
|
|
53
|
+
itself.
|
|
54
|
+
|
|
55
|
+
### Gates held by a nested execution
|
|
56
|
+
|
|
57
|
+
A flow that calls another flow parks the CHILD execution. A `HumanTask` in a
|
|
58
|
+
nested flow therefore parks a run an operator has never heard of, while the run
|
|
59
|
+
they did open sits at `waiting-approval` with nothing of its own to decide.
|
|
60
|
+
|
|
61
|
+
The control plane rolls those waits up: `ControlSchema.RunSummary.pendingWaits`
|
|
62
|
+
lists every open human wait in a run's tree, and the run's status rolls up with
|
|
63
|
+
them, so the ordinary `status: "waiting-approval"` filter finds the root. The
|
|
64
|
+
`approvals` projection turns each into a pending row of that root run.
|
|
65
|
+
`waitRunId` names the execution actually holding it; the workspace inbox lists
|
|
66
|
+
one question once, from the outermost run that carries it.
|
|
67
|
+
|
|
68
|
+
Such a row asks a QUESTION rather than for a grant, and its `request` says
|
|
69
|
+
what kind of answer:
|
|
70
|
+
|
|
71
|
+
| `request` field | Holds |
|
|
72
|
+
| --------------- | ------------------------------------------------------------- |
|
|
73
|
+
| `kind` | `ask`, `confirm`, `select`, or `json` |
|
|
74
|
+
| `prompt` | the question, which is also the row's `title` |
|
|
75
|
+
| `name` | the wait point's own name, which `Signal` addresses |
|
|
76
|
+
| `attempt` | which attempt of a re-asked question this is, counting from 1 |
|
|
77
|
+
| `maxAttempts` | the attempt budget the task declared |
|
|
78
|
+
| `options` | the choices, on a `select` |
|
|
79
|
+
| `token` | the durable wait address, for a client that prefers it |
|
|
80
|
+
|
|
81
|
+
## Submit the decision
|
|
82
|
+
|
|
83
|
+
`GatewayRpcs.SubmitApprovalInput` is that payload plus one field:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"_tag": "Request",
|
|
88
|
+
"id": 1,
|
|
89
|
+
"tag": "Approval.Submit",
|
|
90
|
+
"payload": {
|
|
91
|
+
"target": {
|
|
92
|
+
"_tag": "Node",
|
|
93
|
+
"runId": "run-1",
|
|
94
|
+
"requestId": "gate",
|
|
95
|
+
"digest": "gate-digest",
|
|
96
|
+
"envelope": { "capabilities": ["model:call"], "flows": ["ask"], "budget": {} }
|
|
97
|
+
},
|
|
98
|
+
"scope": "run",
|
|
99
|
+
"idempotencyKey": "approve:gate",
|
|
100
|
+
"decision": "approve"
|
|
101
|
+
},
|
|
102
|
+
"headers": []
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Post it to `/projections`, or send it on `/projections/ws`. `decision` is
|
|
107
|
+
`"approve"` or `"deny"`; everything else is the row's `payload` spread in
|
|
108
|
+
place.
|
|
109
|
+
|
|
110
|
+
### Answering a question
|
|
111
|
+
|
|
112
|
+
A gate that asks a question needs the value, not the word: add `answer`.
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"target": {
|
|
117
|
+
"_tag": "Node",
|
|
118
|
+
"runId": "run-3",
|
|
119
|
+
"requestId": "coding-clarification#1",
|
|
120
|
+
"digest": "<the row's wait token>",
|
|
121
|
+
"envelope": { "capabilities": [], "flows": [], "budget": {} }
|
|
122
|
+
},
|
|
123
|
+
"scope": "once",
|
|
124
|
+
"idempotencyKey": "answer:run-3:coding-clarification#1",
|
|
125
|
+
"decision": "approve",
|
|
126
|
+
"answer": "the scheduler owns it"
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Shape the answer for the question's `kind`: prose for `ask`, a boolean for
|
|
131
|
+
`confirm`, one of `options` for `select`, and the decoded JSON value for
|
|
132
|
+
`json`. The mount routes it to `Control.signal`, addressed to `target.runId`
|
|
133
|
+
and naming `target.requestId`, and the control plane finds the execution
|
|
134
|
+
holding that wait. A denial carries no answer: it refuses the question rather
|
|
135
|
+
than answering it, and an unanswered question re-parks or times out on the
|
|
136
|
+
task's own budget.
|
|
137
|
+
|
|
138
|
+
The answer is `GatewayRpcs.SubmitApprovalOutput`: one field, `decision`, the
|
|
139
|
+
`ControlSchema.Receipt` that is the receipt for the grant or the refusal. There
|
|
140
|
+
is no second call. Approving a parked node delegates its durable resume in the
|
|
141
|
+
same command, and denying it records the refusal the same way.
|
|
142
|
+
|
|
143
|
+
## Who the decision is journaled as
|
|
144
|
+
|
|
145
|
+
The handler reads the principal the shared `ControlAuth` middleware
|
|
146
|
+
authenticated and passes it through, exactly as `ControlServer` stamps it on
|
|
147
|
+
`Approve` and `Deny`. This mount is the same decision under a different
|
|
148
|
+
payload, so it is answerable to the same operator. A decision journaled under
|
|
149
|
+
the composition's default operator would name the wrong one.
|
|
150
|
+
|
|
151
|
+
Authentication is not approval authority. Control checks its host-owned
|
|
152
|
+
`ApprovalAuthority` before mutation or receipt replay, and again at resolution.
|
|
153
|
+
A shared bearer authenticates `gateway/bearer`, which is not an approver by
|
|
154
|
+
default. The host must explicitly delegate that identity and the requested
|
|
155
|
+
scope, or an authorized local operator must decide the gate. Both `/rpc` and
|
|
156
|
+
`/projections`, over HTTP and WebSocket, enforce the same policy. Supplying a
|
|
157
|
+
principal in the payload cannot override the authenticated actor.
|
|
158
|
+
|
|
159
|
+
## The failures
|
|
160
|
+
|
|
161
|
+
`Approval.Submit` answers with exactly the union `Control.approve`,
|
|
162
|
+
`Control.deny`, and, for an answer, `Control.signal` declare, because the
|
|
163
|
+
handler adds no failure of its own. A member none of them raises would be a
|
|
164
|
+
recovery branch no client's code could ever reach.
|
|
165
|
+
|
|
166
|
+
| Failure | Means | What to do |
|
|
167
|
+
| -------------------- | --------------------------------------------------------- | ------------------------------------------------------------ |
|
|
168
|
+
| `Unauthorized` | the caller lacks approval authority for this target/scope | ask an authorized operator; do not keep retrying unchanged |
|
|
169
|
+
| `PlanDigestMismatch` | the plan changed since the gate was published | re-read the gate and show the new plan before deciding again |
|
|
170
|
+
| `EnvelopeMismatch` | the capability envelope is not the one that was approved | re-read the gate; do not widen the envelope client-side |
|
|
171
|
+
| `AlreadyResolved` | someone already decided this gate | refresh the row; the decision stands |
|
|
172
|
+
| `PlanNotFound` | the plan the target names is gone | re-plan |
|
|
173
|
+
| `RunNotFound` | the run the target names is gone | drop the gate from the inbox |
|
|
174
|
+
| `InvalidInput` | the payload is not a decidable approval payload | submit the row's `payload` unchanged |
|
|
175
|
+
| `PersistenceError` | the control plane could not write the decision | retry with the same `idempotencyKey` |
|
|
176
|
+
| `Unavailable` | the control plane is not serving this operation | retry later |
|
|
177
|
+
| `NoMatchingWait` | the question was answered after the run moved on | re-read the inbox; somebody answered it, or it timed out |
|
|
178
|
+
|
|
179
|
+
Retrying is safe. The payload carries an `idempotencyKey`, so a second
|
|
180
|
+
submission of the same decision lands one effect.
|
|
181
|
+
|
|
182
|
+
## From the command line
|
|
183
|
+
|
|
184
|
+
The same decision from a terminal is [`smthrs approvals approve`](/cli/approvals) and
|
|
185
|
+
`smthrs approvals deny`, which take the same payload the projection
|
|
186
|
+
publishes. For the domain semantics behind both, see
|
|
187
|
+
[Approvals](/pkg/control/guides/approvals).
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Test against a real gateway"
|
|
3
|
+
description: "Stand a gateway up over a real SQLite control plane on an ephemeral port, write the events a projection folds, and control the supervision port from a test."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 7
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Test a gateway client against one real stack: a durable journal, a durable run
|
|
9
|
+
store, the SQL control runtime, `ControlLive`, the served projections, the sync
|
|
10
|
+
read path, and the assembled HTTP surface bound to an ephemeral loopback port.
|
|
11
|
+
Stub nothing below the control plane.
|
|
12
|
+
|
|
13
|
+
The behaviours worth pinning are an approval projected out of a parked run, a
|
|
14
|
+
cancellation's attribution, and a child run's visibility. Those are exactly the
|
|
15
|
+
places a mocked control plane agrees with your assertion and disagrees with the
|
|
16
|
+
gateway a real workspace serves.
|
|
17
|
+
|
|
18
|
+
## Compose the stack
|
|
19
|
+
|
|
20
|
+
The stack reaches below this package's own dependencies. Add the packages
|
|
21
|
+
that supply storage, the selected SQLite driver, and the control runtime's ports:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm add -D \
|
|
25
|
+
@smthrs/database@1.0.0-rc.0 \
|
|
26
|
+
@smthrs/journal@1.0.0-rc.0 \
|
|
27
|
+
@smthrs/notifications@1.0.0-rc.0 \
|
|
28
|
+
@smthrs/registry@1.0.0-rc.0 \
|
|
29
|
+
effect@4.0.0-rc.115 \
|
|
30
|
+
@effect/sql-sqlite-node@4.0.0-rc.115
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import * as NodeCrypto from "@effect/platform-node/NodeCrypto"
|
|
35
|
+
import * as ControlExecutor from "@smthrs/control/ControlExecutor"
|
|
36
|
+
import * as ControlLive from "@smthrs/control/ControlLive"
|
|
37
|
+
import * as SqlControlRuntime from "@smthrs/control/SqlControlRuntime"
|
|
38
|
+
import * as DurableWriter from "@smthrs/database/DurableWriter"
|
|
39
|
+
import * as NodeDatabase from "@smthrs/database/node/NodeDatabase"
|
|
40
|
+
import * as Projections from "@smthrs/gateway/Projections"
|
|
41
|
+
import { Migrations, SqlJournal } from "@smthrs/journal"
|
|
42
|
+
import { NotificationQueue } from "@smthrs/notifications"
|
|
43
|
+
import { Registry } from "@smthrs/registry"
|
|
44
|
+
import { Migrations as RunStoreMigrations, RunStore } from "@smthrs/run-store"
|
|
45
|
+
import * as RunCatalog from "@smthrs/sync/RunCatalog"
|
|
46
|
+
import * as SyncAuth from "@smthrs/sync/SyncAuth"
|
|
47
|
+
import * as SyncServer from "@smthrs/sync/SyncServer"
|
|
48
|
+
import * as WorkspaceShare from "@smthrs/sync/WorkspaceShare"
|
|
49
|
+
import { Layer } from "effect"
|
|
50
|
+
|
|
51
|
+
const storage = (filename: string) =>
|
|
52
|
+
Layer.mergeAll(SqlJournal.layer({ capacity: 1024, overflow: "reject" }), RunStore.layer).pipe(
|
|
53
|
+
Layer.provideMerge(
|
|
54
|
+
Layer.provideMerge(
|
|
55
|
+
Layer.merge(Migrations.layer, RunStoreMigrations.layer),
|
|
56
|
+
Layer.provideMerge(DurableWriter.layer(), NodeDatabase.layer({ filename }))
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
export const stack = (filename: string) =>
|
|
62
|
+
Layer.mergeAll(
|
|
63
|
+
// A short cadence, so a keepalive assertion does not wait 30 seconds.
|
|
64
|
+
Projections.layerWith({ heartbeatMillis: 50 }),
|
|
65
|
+
SyncServer.layer,
|
|
66
|
+
SyncAuth.layer
|
|
67
|
+
).pipe(
|
|
68
|
+
Layer.provideMerge(Layer.merge(RunCatalog.layerNoop, WorkspaceShare.layerNoop)),
|
|
69
|
+
Layer.provideMerge(ControlLive.layer),
|
|
70
|
+
Layer.provideMerge(
|
|
71
|
+
Layer.mergeAll(
|
|
72
|
+
SqlControlRuntime.layer({}).pipe(Layer.orDie),
|
|
73
|
+
NotificationQueue.layer,
|
|
74
|
+
ControlExecutor.layer(ControlExecutor.makeNoop()),
|
|
75
|
+
Registry.layerNoop()
|
|
76
|
+
)
|
|
77
|
+
),
|
|
78
|
+
Layer.provideMerge(Layer.merge(storage(filename), NodeCrypto.layer))
|
|
79
|
+
)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
A worked version of this helper, with the temporary-file lifecycle around it,
|
|
83
|
+
is [`GatewayStack.ts`](https://github.com/smithersai/smithers/blob/main/packages/smithers/gateway/test/GatewayStack.ts)
|
|
84
|
+
in the package source.
|
|
85
|
+
|
|
86
|
+
## Bind an ephemeral port and read it back
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import * as NodeGateway from "@smthrs/gateway/node/NodeGateway"
|
|
90
|
+
import { Effect, Layer } from "effect"
|
|
91
|
+
import { HttpServer } from "effect/unstable/http"
|
|
92
|
+
|
|
93
|
+
const served = NodeGateway.layer(health, { host: "127.0.0.1", port: 0 }).pipe(Layer.provideMerge(stack(filename)))
|
|
94
|
+
|
|
95
|
+
const baseUrl = Effect.map(HttpServer.HttpServer, (server) => {
|
|
96
|
+
if (server.address._tag !== "InetAddressV4" && server.address._tag !== "InetAddressV6") {
|
|
97
|
+
throw new Error("expected a TCP gateway")
|
|
98
|
+
}
|
|
99
|
+
return `http://127.0.0.1:${server.address.port}`
|
|
100
|
+
})
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Port 0 lets the operating system pick, and the layer retains the concrete
|
|
104
|
+
`HttpServer`, so a test reads the address it actually got rather than racing
|
|
105
|
+
for a fixed port.
|
|
106
|
+
|
|
107
|
+
## Give a run something to project
|
|
108
|
+
|
|
109
|
+
Write events through the journal's durable channel, not its lossy one:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import * as Journal from "@smthrs/journal/Journal"
|
|
113
|
+
import * as JournalEvent from "@smthrs/journal/JournalEvent"
|
|
114
|
+
import { Effect } from "effect"
|
|
115
|
+
|
|
116
|
+
const emit = (runId: string, eventType: string, payload: unknown, sourceSeq: number) =>
|
|
117
|
+
Effect.flatMap(Journal.Journal, (journal) =>
|
|
118
|
+
journal.emitDurableUnfenced(
|
|
119
|
+
new JournalEvent.Input({
|
|
120
|
+
runId: JournalEvent.RunId.make(runId),
|
|
121
|
+
sourceId: JournalEvent.SourceId.make("gateway-test"),
|
|
122
|
+
sourceSeq: JournalEvent.SourceSeq.make(sourceSeq),
|
|
123
|
+
eventType,
|
|
124
|
+
payload: JSON.parse(JSON.stringify(payload))
|
|
125
|
+
})
|
|
126
|
+
))
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`emitLossy` returns once the optimistic queue accepts an entry, so a projection
|
|
130
|
+
read straight afterwards can legitimately miss it, and a suite built on that
|
|
131
|
+
races its own fixture. Give each event a monotonic `sourceSeq`, or two
|
|
132
|
+
identical fixture events will not both admit.
|
|
133
|
+
|
|
134
|
+
## Fold without a stack at all
|
|
135
|
+
|
|
136
|
+
A test that only cares about a fold does not need any of the above. The folds
|
|
137
|
+
are pure functions of a run summary and its events:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import * as GatewayProjection from "@smthrs/gateway/GatewayProjection"
|
|
141
|
+
|
|
142
|
+
const rows = GatewayProjection.runTree(run, events)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
This is the same code the served projection runs, so a fold test and an
|
|
146
|
+
end-to-end test cannot disagree about what a row means. Reach for the full
|
|
147
|
+
stack when what you are pinning is the _serving_: a status the run row owns, a
|
|
148
|
+
cursor, a refusal, or an HTTP status.
|