rivetkit 2.1.4 → 2.1.6-rc.1
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/dist/browser/client.d.ts +593 -588
- package/dist/browser/client.js +215 -35
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/inspector/client.js +109 -10
- package/dist/browser/inspector/client.js.map +1 -1
- package/dist/inspector.tar.gz +0 -0
- package/dist/tsup/actor/errors.cjs +2 -2
- package/dist/tsup/actor/errors.js +1 -1
- package/dist/tsup/{actor-router-consts-D29T1Z-K.d.cts → actor-router-consts-DU-1IdQj.d.cts} +1 -1
- package/dist/tsup/{actor-router-consts-D29T1Z-K.d.ts → actor-router-consts-DU-1IdQj.d.ts} +1 -1
- package/dist/tsup/chunk-2ELYUO6C.cjs +112 -0
- package/dist/tsup/chunk-2ELYUO6C.cjs.map +1 -0
- package/dist/tsup/chunk-2LY7RW3Y.cjs +2316 -0
- package/dist/tsup/chunk-2LY7RW3Y.cjs.map +1 -0
- package/dist/tsup/{chunk-L47L3ZWJ.cjs → chunk-6G7ZNM27.cjs} +11 -6
- package/dist/tsup/chunk-6G7ZNM27.cjs.map +1 -0
- package/dist/tsup/{chunk-LK36OGGO.cjs → chunk-A4KEUCB6.cjs} +84 -34
- package/dist/tsup/chunk-A4KEUCB6.cjs.map +1 -0
- package/dist/tsup/{chunk-7HTNH26M.js → chunk-AKUJ5OTO.js} +11 -6
- package/dist/tsup/chunk-AKUJ5OTO.js.map +1 -0
- package/dist/tsup/{chunk-ANKZ2FS6.js → chunk-C22JYHVT.js} +77 -27
- package/dist/tsup/chunk-C22JYHVT.js.map +1 -0
- package/dist/tsup/chunk-C4EB42ET.js +1459 -0
- package/dist/tsup/chunk-C4EB42ET.js.map +1 -0
- package/dist/tsup/chunk-CGGGBIDP.cjs +1459 -0
- package/dist/tsup/chunk-CGGGBIDP.cjs.map +1 -0
- package/dist/tsup/chunk-CMQPDBBR.cjs +1486 -0
- package/dist/tsup/chunk-CMQPDBBR.cjs.map +1 -0
- package/dist/tsup/{chunk-AQD4CBZ2.cjs → chunk-DH6UINWA.cjs} +4 -4
- package/dist/tsup/{chunk-AQD4CBZ2.cjs.map → chunk-DH6UINWA.cjs.map} +1 -1
- package/dist/tsup/chunk-DK46YYCJ.js +1486 -0
- package/dist/tsup/chunk-DK46YYCJ.js.map +1 -0
- package/dist/tsup/chunk-EGWXXBZV.js +2316 -0
- package/dist/tsup/chunk-EGWXXBZV.js.map +1 -0
- package/dist/tsup/{chunk-HBYEYBIC.js → chunk-EONWXYMN.js} +2 -2
- package/dist/tsup/{chunk-N4KRDJ56.js → chunk-GFGRBYO2.js} +35 -6
- package/dist/tsup/chunk-GFGRBYO2.js.map +1 -0
- package/dist/tsup/{chunk-TEUL4UYN.cjs → chunk-GUHXWPGB.cjs} +1515 -1479
- package/dist/tsup/chunk-GUHXWPGB.cjs.map +1 -0
- package/dist/tsup/{chunk-3B6PCYJB.cjs → chunk-HNE2AK6C.cjs} +2375 -3713
- package/dist/tsup/chunk-HNE2AK6C.cjs.map +1 -0
- package/dist/tsup/{chunk-5UEFNG7P.js → chunk-I5I6OALK.js} +2 -2
- package/dist/tsup/chunk-IHQAF2HV.cjs +23 -0
- package/dist/tsup/chunk-IHQAF2HV.cjs.map +1 -0
- package/dist/tsup/{chunk-UWAGLDT6.cjs → chunk-JJNZQDUN.cjs} +667 -2517
- package/dist/tsup/chunk-JJNZQDUN.cjs.map +1 -0
- package/dist/tsup/{chunk-M6H4XIF4.js → chunk-JJSPHLJN.js} +219 -287
- package/dist/tsup/chunk-JJSPHLJN.js.map +1 -0
- package/dist/tsup/chunk-JRKPV5NJ.js +481 -0
- package/dist/tsup/chunk-JRKPV5NJ.js.map +1 -0
- package/dist/tsup/{chunk-VKVNIQRQ.js → chunk-K7MVU5SI.js} +36 -41
- package/dist/tsup/chunk-K7MVU5SI.js.map +1 -0
- package/dist/tsup/{chunk-KJSYAUOM.js → chunk-MLK3GY6P.js} +43 -27
- package/dist/tsup/chunk-MLK3GY6P.js.map +1 -0
- package/dist/tsup/{chunk-4KSHPFXF.cjs → chunk-MPLMTJY5.cjs} +123 -23
- package/dist/tsup/chunk-MPLMTJY5.cjs.map +1 -0
- package/dist/tsup/{chunk-UDMRZR6A.js → chunk-PQWI44WD.js} +1755 -3093
- package/dist/tsup/chunk-PQWI44WD.js.map +1 -0
- package/dist/tsup/{chunk-SR3KQE7Q.cjs → chunk-SQFCIDCG.cjs} +35 -6
- package/dist/tsup/chunk-SQFCIDCG.cjs.map +1 -0
- package/dist/tsup/{chunk-3GTO6H3E.js → chunk-SVHJSM2E.js} +110 -24
- package/dist/tsup/chunk-SVHJSM2E.js.map +1 -0
- package/dist/tsup/chunk-T5KYKM6R.js +49 -0
- package/dist/tsup/chunk-T5KYKM6R.js.map +1 -0
- package/dist/tsup/{chunk-GXRVSSVD.cjs → chunk-TJ7DKW6F.cjs} +123 -37
- package/dist/tsup/chunk-TJ7DKW6F.cjs.map +1 -0
- package/dist/tsup/chunk-UQZRMTM3.js +23 -0
- package/dist/tsup/chunk-UQZRMTM3.js.map +1 -0
- package/dist/tsup/{chunk-QPADHLDU.cjs → chunk-V3JSZR5P.cjs} +3 -3
- package/dist/tsup/{chunk-QPADHLDU.cjs.map → chunk-V3JSZR5P.cjs.map} +1 -1
- package/dist/tsup/{chunk-HKOSZKKZ.cjs → chunk-VBR35EQF.cjs} +271 -339
- package/dist/tsup/chunk-VBR35EQF.cjs.map +1 -0
- package/dist/tsup/{chunk-DZXDUGLL.js → chunk-VWYO36X4.js} +117 -17
- package/dist/tsup/chunk-VWYO36X4.js.map +1 -0
- package/dist/tsup/{chunk-I6PL6QIY.js → chunk-WW27B6DM.js} +1452 -1416
- package/dist/tsup/chunk-WW27B6DM.js.map +1 -0
- package/dist/tsup/chunk-YAE3MEJM.cjs +49 -0
- package/dist/tsup/chunk-YAE3MEJM.cjs.map +1 -0
- package/dist/tsup/{chunk-KTWY3K6Z.js → chunk-YGYGANCA.js} +473 -2323
- package/dist/tsup/chunk-YGYGANCA.js.map +1 -0
- package/dist/tsup/chunk-YZJWZBY5.cjs +481 -0
- package/dist/tsup/chunk-YZJWZBY5.cjs.map +1 -0
- package/dist/tsup/{chunk-ZFY5J2EP.cjs → chunk-ZZLJ5TSM.cjs} +39 -44
- package/dist/tsup/chunk-ZZLJ5TSM.cjs.map +1 -0
- package/dist/tsup/client/mod.cjs +10 -7
- package/dist/tsup/client/mod.cjs.map +1 -1
- package/dist/tsup/client/mod.d.cts +6 -6
- package/dist/tsup/client/mod.d.ts +6 -6
- package/dist/tsup/client/mod.js +11 -8
- package/dist/tsup/common/log.cjs +3 -3
- package/dist/tsup/common/log.js +2 -2
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{config-Qj-zLJPc.d.ts → config-C2Wwnc69.d.ts} +142 -208
- package/dist/tsup/{config-BiNoIHRs.d.ts → config-DROwzBLT.d.cts} +82 -6
- package/dist/tsup/{config-BiNoIHRs.d.cts → config-DROwzBLT.d.ts} +82 -6
- package/dist/tsup/{config-iPj5l1bL.d.cts → config-ehT-_3BB.d.cts} +142 -208
- package/dist/tsup/{context-DzvH1PBK.d.cts → context-DGMJuAyc.d.ts} +16 -3
- package/dist/tsup/{context-CQCMuHND.d.ts → context-Dpp2RJbW.d.cts} +16 -3
- package/dist/tsup/db/drizzle/mod.cjs +3 -3
- package/dist/tsup/db/drizzle/mod.d.cts +1 -1
- package/dist/tsup/db/drizzle/mod.d.ts +1 -1
- package/dist/tsup/db/drizzle/mod.js +2 -2
- package/dist/tsup/db/mod.cjs +3 -3
- package/dist/tsup/db/mod.d.cts +1 -1
- package/dist/tsup/db/mod.d.ts +1 -1
- package/dist/tsup/db/mod.js +2 -2
- package/dist/tsup/{driver-Jo8v-kbU.d.ts → driver-CYZP9QYo.d.ts} +1 -1
- package/dist/tsup/{driver-iV8J-WMv.d.cts → driver-CoTFpipv.d.cts} +1 -1
- package/dist/tsup/driver-helpers/mod.cjs +7 -5
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +17 -18
- package/dist/tsup/driver-helpers/mod.d.ts +17 -18
- package/dist/tsup/driver-helpers/mod.js +11 -9
- package/dist/tsup/driver-test-suite/mod.cjs +1275 -228
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +6 -5
- package/dist/tsup/driver-test-suite/mod.d.ts +6 -5
- package/dist/tsup/driver-test-suite/mod.js +1581 -534
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +4 -4
- package/dist/tsup/inspector/mod.js +3 -3
- package/dist/tsup/mod.cjs +15 -9
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +9 -9
- package/dist/tsup/mod.d.ts +9 -9
- package/dist/tsup/mod.js +19 -13
- package/dist/tsup/sandbox/client.cjs +28 -0
- package/dist/tsup/sandbox/client.cjs.map +1 -0
- package/dist/tsup/sandbox/client.d.cts +88 -0
- package/dist/tsup/sandbox/client.d.ts +88 -0
- package/dist/tsup/sandbox/client.js +28 -0
- package/dist/tsup/sandbox/client.js.map +1 -0
- package/dist/tsup/sandbox/index.cjs +761 -0
- package/dist/tsup/sandbox/index.cjs.map +1 -0
- package/dist/tsup/sandbox/index.d.cts +120 -0
- package/dist/tsup/sandbox/index.d.ts +120 -0
- package/dist/tsup/sandbox/index.js +761 -0
- package/dist/tsup/sandbox/index.js.map +1 -0
- package/dist/tsup/sandbox/providers/computesdk.cjs +3 -0
- package/dist/tsup/sandbox/providers/computesdk.cjs.map +1 -0
- package/dist/tsup/sandbox/providers/computesdk.d.cts +7 -0
- package/dist/tsup/sandbox/providers/computesdk.d.ts +7 -0
- package/dist/tsup/sandbox/providers/computesdk.js +3 -0
- package/dist/tsup/sandbox/providers/computesdk.js.map +1 -0
- package/dist/tsup/sandbox/providers/daytona.cjs +3 -0
- package/dist/tsup/sandbox/providers/daytona.cjs.map +1 -0
- package/dist/tsup/sandbox/providers/daytona.d.cts +1 -0
- package/dist/tsup/sandbox/providers/daytona.d.ts +1 -0
- package/dist/tsup/sandbox/providers/daytona.js +3 -0
- package/dist/tsup/sandbox/providers/daytona.js.map +1 -0
- package/dist/tsup/sandbox/providers/docker.cjs +3 -0
- package/dist/tsup/sandbox/providers/docker.cjs.map +1 -0
- package/dist/tsup/sandbox/providers/docker.d.cts +1 -0
- package/dist/tsup/sandbox/providers/docker.d.ts +1 -0
- package/dist/tsup/sandbox/providers/docker.js +3 -0
- package/dist/tsup/sandbox/providers/docker.js.map +1 -0
- package/dist/tsup/sandbox/providers/e2b.cjs +3 -0
- package/dist/tsup/sandbox/providers/e2b.cjs.map +1 -0
- package/dist/tsup/sandbox/providers/e2b.d.cts +1 -0
- package/dist/tsup/sandbox/providers/e2b.d.ts +1 -0
- package/dist/tsup/sandbox/providers/e2b.js +3 -0
- package/dist/tsup/sandbox/providers/e2b.js.map +1 -0
- package/dist/tsup/sandbox/providers/local.cjs +3 -0
- package/dist/tsup/sandbox/providers/local.cjs.map +1 -0
- package/dist/tsup/sandbox/providers/local.d.cts +1 -0
- package/dist/tsup/sandbox/providers/local.d.ts +1 -0
- package/dist/tsup/sandbox/providers/local.js +3 -0
- package/dist/tsup/sandbox/providers/local.js.map +1 -0
- package/dist/tsup/sandbox/providers/modal.cjs +3 -0
- package/dist/tsup/sandbox/providers/modal.cjs.map +1 -0
- package/dist/tsup/sandbox/providers/modal.d.cts +1 -0
- package/dist/tsup/sandbox/providers/modal.d.ts +1 -0
- package/dist/tsup/sandbox/providers/modal.js +3 -0
- package/dist/tsup/sandbox/providers/modal.js.map +1 -0
- package/dist/tsup/sandbox/providers/vercel.cjs +3 -0
- package/dist/tsup/sandbox/providers/vercel.cjs.map +1 -0
- package/dist/tsup/sandbox/providers/vercel.d.cts +1 -0
- package/dist/tsup/sandbox/providers/vercel.d.ts +1 -0
- package/dist/tsup/sandbox/providers/vercel.js +3 -0
- package/dist/tsup/sandbox/providers/vercel.js.map +1 -0
- package/dist/tsup/serve-test-suite/mod.cjs +451 -327
- package/dist/tsup/serve-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/serve-test-suite/mod.js +362 -238
- package/dist/tsup/serve-test-suite/mod.js.map +1 -1
- package/dist/tsup/test/mod.cjs +17 -14
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +4 -4
- package/dist/tsup/test/mod.d.ts +4 -4
- package/dist/tsup/test/mod.js +14 -11
- package/dist/tsup/test/mod.js.map +1 -1
- package/dist/tsup/utils.cjs +3 -3
- package/dist/tsup/utils.js +2 -2
- package/dist/tsup/workflow/mod.cjs +6 -6
- package/dist/tsup/workflow/mod.d.cts +13 -9
- package/dist/tsup/workflow/mod.d.ts +13 -9
- package/dist/tsup/workflow/mod.js +5 -5
- package/package.json +113 -14
- package/src/actor/config.ts +94 -88
- package/src/actor/conn/drivers/websocket.ts +2 -1
- package/src/actor/contexts/base/actor.ts +27 -4
- package/src/actor/database.ts +6 -1
- package/src/actor/driver.ts +27 -8
- package/src/actor/errors.ts +10 -5
- package/src/actor/instance/connection-manager.ts +4 -3
- package/src/actor/instance/kv.ts +52 -9
- package/src/actor/instance/mod.ts +135 -84
- package/src/actor/instance/queue-manager.ts +2 -5
- package/src/actor/instance/queue.ts +31 -29
- package/src/actor/instance/state-manager.ts +7 -1
- package/src/actor/instance/traces-driver.ts +34 -36
- package/src/actor/metrics.ts +137 -0
- package/src/actor/protocol/old.ts +9 -12
- package/src/actor/router-websocket-endpoints.ts +12 -6
- package/src/actor/router.ts +46 -9
- package/src/actor/schema.ts +14 -22
- package/src/client/actor-common.ts +65 -0
- package/src/client/actor-conn.ts +71 -9
- package/src/client/actor-handle.ts +22 -5
- package/src/client/client.ts +32 -6
- package/src/client/config.ts +18 -21
- package/src/client/mod.ts +1 -0
- package/src/client/queue.ts +8 -6
- package/src/common/inline-websocket-adapter.ts +8 -2
- package/src/common/router.ts +1 -4
- package/src/common/utils.ts +2 -5
- package/src/db/config.ts +10 -5
- package/src/db/drizzle/mod.ts +51 -41
- package/src/db/mod.ts +54 -29
- package/src/db/shared.ts +42 -8
- package/src/driver-helpers/mod.ts +2 -1
- package/src/driver-helpers/sqlite-pool.ts +42 -0
- package/src/driver-helpers/utils.ts +0 -20
- package/src/driver-test-suite/mod.ts +11 -1
- package/src/driver-test-suite/tests/access-control.ts +19 -12
- package/src/driver-test-suite/tests/action-features.ts +20 -8
- package/src/driver-test-suite/tests/actor-conn.ts +94 -8
- package/src/driver-test-suite/tests/actor-db-kv-stats.ts +282 -0
- package/src/driver-test-suite/tests/actor-db-raw.ts +6 -2
- package/src/driver-test-suite/tests/actor-db.ts +101 -31
- package/src/driver-test-suite/tests/actor-inspector.ts +174 -32
- package/src/driver-test-suite/tests/actor-kv.ts +79 -33
- package/src/driver-test-suite/tests/actor-lifecycle.ts +4 -12
- package/src/driver-test-suite/tests/actor-queue.ts +125 -17
- package/src/driver-test-suite/tests/actor-run.ts +59 -55
- package/src/driver-test-suite/tests/actor-sandbox.ts +78 -0
- package/src/driver-test-suite/tests/actor-schedule.ts +1 -4
- package/src/driver-test-suite/tests/actor-sleep.ts +111 -0
- package/src/driver-test-suite/tests/actor-workflow.ts +387 -3
- package/src/driver-test-suite/tests/conn-error-serialization.ts +3 -1
- package/src/driver-test-suite/tests/raw-websocket.ts +5 -1
- package/src/drivers/default.ts +1 -3
- package/src/drivers/engine/actor-driver.ts +94 -21
- package/src/drivers/engine/config.ts +4 -12
- package/src/drivers/engine/mod.ts +1 -5
- package/src/drivers/file-system/actor.ts +43 -8
- package/src/drivers/file-system/global-state.ts +180 -64
- package/src/drivers/file-system/kv-limits.ts +1 -1
- package/src/drivers/file-system/sqlite-runtime.ts +13 -4
- package/src/engine-process/mod.ts +5 -1
- package/src/inspector/actor-inspector.ts +47 -21
- package/src/inspector/config.ts +1 -4
- package/src/inspector/mod.browser.ts +2 -2
- package/src/inspector/mod.ts +4 -1
- package/src/inspector/serve-ui.ts +0 -1
- package/src/inspector/workflow-history-json.ts +309 -0
- package/src/manager/gateway.ts +6 -2
- package/src/manager/router.ts +3 -3
- package/src/registry/config/index.ts +65 -12
- package/src/registry/config/runner.ts +19 -4
- package/src/registry/index.ts +42 -89
- package/src/sandbox/actor/db.ts +36 -0
- package/src/sandbox/actor/index.ts +476 -0
- package/src/sandbox/actor/session.ts +350 -0
- package/src/sandbox/actor.test.ts +36 -0
- package/src/sandbox/client.test.ts +484 -0
- package/src/sandbox/client.ts +707 -0
- package/src/sandbox/config.ts +151 -0
- package/src/sandbox/index.ts +41 -0
- package/src/sandbox/providers/computesdk.ts +1 -0
- package/src/sandbox/providers/daytona.ts +1 -0
- package/src/sandbox/providers/docker.ts +1 -0
- package/src/sandbox/providers/e2b.ts +1 -0
- package/src/sandbox/providers/local.ts +1 -0
- package/src/sandbox/providers/modal.ts +1 -0
- package/src/sandbox/providers/vercel.ts +1 -0
- package/src/sandbox/session-persist-driver.ts +180 -0
- package/src/sandbox/types.ts +138 -0
- package/src/serverless/configure.ts +5 -3
- package/src/serverless/router.test.ts +17 -9
- package/src/serverless/router.ts +20 -13
- package/src/test/mod.ts +3 -4
- package/src/utils/endpoint-parser.test.ts +6 -2
- package/src/utils/endpoint-parser.ts +6 -2
- package/src/utils/env-vars.ts +0 -2
- package/src/utils/node.ts +1 -1
- package/src/utils/serve.ts +10 -5
- package/src/utils.ts +6 -1
- package/src/workflow/constants.ts +1 -2
- package/src/workflow/context.ts +42 -9
- package/src/workflow/driver.ts +57 -23
- package/src/workflow/inspector.ts +7 -13
- package/src/workflow/mod.ts +91 -4
- package/dist/tsup/chunk-3B6PCYJB.cjs.map +0 -1
- package/dist/tsup/chunk-3GTO6H3E.js.map +0 -1
- package/dist/tsup/chunk-4KSHPFXF.cjs.map +0 -1
- package/dist/tsup/chunk-6LJAZ5R4.cjs +0 -96
- package/dist/tsup/chunk-6LJAZ5R4.cjs.map +0 -1
- package/dist/tsup/chunk-7HTNH26M.js.map +0 -1
- package/dist/tsup/chunk-ANKZ2FS6.js.map +0 -1
- package/dist/tsup/chunk-DZXDUGLL.js.map +0 -1
- package/dist/tsup/chunk-GXRVSSVD.cjs.map +0 -1
- package/dist/tsup/chunk-H5TSEPN4.cjs +0 -645
- package/dist/tsup/chunk-H5TSEPN4.cjs.map +0 -1
- package/dist/tsup/chunk-HKOSZKKZ.cjs.map +0 -1
- package/dist/tsup/chunk-I6PL6QIY.js.map +0 -1
- package/dist/tsup/chunk-KJSYAUOM.js.map +0 -1
- package/dist/tsup/chunk-KTWY3K6Z.js.map +0 -1
- package/dist/tsup/chunk-L47L3ZWJ.cjs.map +0 -1
- package/dist/tsup/chunk-LK36OGGO.cjs.map +0 -1
- package/dist/tsup/chunk-M6H4XIF4.js.map +0 -1
- package/dist/tsup/chunk-N4KRDJ56.js.map +0 -1
- package/dist/tsup/chunk-SR3KQE7Q.cjs.map +0 -1
- package/dist/tsup/chunk-TEFYRRAK.js +0 -645
- package/dist/tsup/chunk-TEFYRRAK.js.map +0 -1
- package/dist/tsup/chunk-TEUL4UYN.cjs.map +0 -1
- package/dist/tsup/chunk-UDMRZR6A.js.map +0 -1
- package/dist/tsup/chunk-UWAGLDT6.cjs.map +0 -1
- package/dist/tsup/chunk-VKVNIQRQ.js.map +0 -1
- package/dist/tsup/chunk-ZFY5J2EP.cjs.map +0 -1
- package/src/db/sqlite-vfs.ts +0 -12
- /package/dist/tsup/{chunk-HBYEYBIC.js.map → chunk-EONWXYMN.js.map} +0 -0
- /package/dist/tsup/{chunk-5UEFNG7P.js.map → chunk-I5I6OALK.js.map} +0 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } var _class;// src/sandbox/client.ts
|
|
2
|
+
var API_PREFIX = "/v1";
|
|
3
|
+
async function uploadFile(sandboxUrl, path, data) {
|
|
4
|
+
const response = await fetchSandbox(
|
|
5
|
+
buildUrl(sandboxUrl, `${API_PREFIX}/fs/file`, { path }),
|
|
6
|
+
{
|
|
7
|
+
method: "PUT",
|
|
8
|
+
headers: {
|
|
9
|
+
"Content-Type": "application/octet-stream"
|
|
10
|
+
},
|
|
11
|
+
body: data
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
await assertOk(response, "upload file");
|
|
15
|
+
}
|
|
16
|
+
async function downloadFile(sandboxUrl, path) {
|
|
17
|
+
const response = await fetchSandbox(
|
|
18
|
+
buildUrl(sandboxUrl, `${API_PREFIX}/fs/file`, { path }),
|
|
19
|
+
{
|
|
20
|
+
method: "GET"
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
await assertOk(response, "download file");
|
|
24
|
+
return await response.arrayBuffer();
|
|
25
|
+
}
|
|
26
|
+
async function uploadBatch(sandboxUrl, destinationPath, tarData) {
|
|
27
|
+
const response = await fetchSandbox(
|
|
28
|
+
buildUrl(sandboxUrl, `${API_PREFIX}/fs/upload-batch`, {
|
|
29
|
+
path: destinationPath
|
|
30
|
+
}),
|
|
31
|
+
{
|
|
32
|
+
method: "POST",
|
|
33
|
+
headers: {
|
|
34
|
+
"Content-Type": "application/x-tar"
|
|
35
|
+
},
|
|
36
|
+
body: tarData
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
await assertOk(response, "upload batch");
|
|
40
|
+
return await response.json();
|
|
41
|
+
}
|
|
42
|
+
async function listFiles(sandboxUrl, path) {
|
|
43
|
+
const response = await fetchSandbox(
|
|
44
|
+
buildUrl(sandboxUrl, `${API_PREFIX}/fs/entries`, { path }),
|
|
45
|
+
{
|
|
46
|
+
method: "GET"
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
await assertOk(response, "list files");
|
|
50
|
+
return await response.json();
|
|
51
|
+
}
|
|
52
|
+
async function statFile(sandboxUrl, path) {
|
|
53
|
+
const response = await fetchSandbox(
|
|
54
|
+
buildUrl(sandboxUrl, `${API_PREFIX}/fs/stat`, { path }),
|
|
55
|
+
{
|
|
56
|
+
method: "GET"
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
await assertOk(response, "stat file");
|
|
60
|
+
return await response.json();
|
|
61
|
+
}
|
|
62
|
+
async function deleteFile(sandboxUrl, path) {
|
|
63
|
+
const response = await fetchSandbox(
|
|
64
|
+
buildUrl(sandboxUrl, `${API_PREFIX}/fs/entry`, { path }),
|
|
65
|
+
{
|
|
66
|
+
method: "DELETE"
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
await assertOk(response, "delete file");
|
|
70
|
+
}
|
|
71
|
+
async function mkdirFs(sandboxUrl, path) {
|
|
72
|
+
const response = await fetchSandbox(
|
|
73
|
+
buildUrl(sandboxUrl, `${API_PREFIX}/fs/mkdir`, { path }),
|
|
74
|
+
{
|
|
75
|
+
method: "POST"
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
await assertOk(response, "mkdir");
|
|
79
|
+
}
|
|
80
|
+
async function moveFile(sandboxUrl, from, to, overwrite = false) {
|
|
81
|
+
const response = await fetchSandbox(
|
|
82
|
+
buildUrl(sandboxUrl, `${API_PREFIX}/fs/move`),
|
|
83
|
+
{
|
|
84
|
+
method: "POST",
|
|
85
|
+
headers: {
|
|
86
|
+
"Content-Type": "application/json"
|
|
87
|
+
},
|
|
88
|
+
body: JSON.stringify({
|
|
89
|
+
from,
|
|
90
|
+
to,
|
|
91
|
+
overwrite
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
await assertOk(response, "move file");
|
|
96
|
+
}
|
|
97
|
+
function buildTerminalWebSocketUrl(sandboxUrl, processId) {
|
|
98
|
+
const url = new URL(
|
|
99
|
+
buildUrl(
|
|
100
|
+
sandboxUrl,
|
|
101
|
+
`${API_PREFIX}/processes/${encodeURIComponent(processId)}/terminal/ws`
|
|
102
|
+
)
|
|
103
|
+
);
|
|
104
|
+
if (url.protocol === "http:") {
|
|
105
|
+
url.protocol = "ws:";
|
|
106
|
+
} else if (url.protocol === "https:") {
|
|
107
|
+
url.protocol = "wss:";
|
|
108
|
+
}
|
|
109
|
+
return url.toString();
|
|
110
|
+
}
|
|
111
|
+
function connectTerminal(sandboxUrl, processId, options = {}) {
|
|
112
|
+
const WebSocketCtor = _nullishCoalesce(options.WebSocket, () => ( getWebSocketCtor()));
|
|
113
|
+
const socket = new WebSocketCtor(
|
|
114
|
+
buildTerminalWebSocketUrl(sandboxUrl, processId),
|
|
115
|
+
options.protocols
|
|
116
|
+
);
|
|
117
|
+
socket.binaryType = "arraybuffer";
|
|
118
|
+
return new DirectTerminalSession(socket);
|
|
119
|
+
}
|
|
120
|
+
async function followProcessLogs(sandboxUrl, processId, listener, options = {}) {
|
|
121
|
+
const abortController = new AbortController();
|
|
122
|
+
const response = await fetchSandbox(
|
|
123
|
+
buildUrl(
|
|
124
|
+
sandboxUrl,
|
|
125
|
+
`${API_PREFIX}/processes/${encodeURIComponent(processId)}/logs`,
|
|
126
|
+
{
|
|
127
|
+
follow: true,
|
|
128
|
+
stream: options.stream,
|
|
129
|
+
tail: options.tail,
|
|
130
|
+
since: options.since
|
|
131
|
+
}
|
|
132
|
+
),
|
|
133
|
+
{
|
|
134
|
+
method: "GET",
|
|
135
|
+
headers: {
|
|
136
|
+
Accept: "text/event-stream"
|
|
137
|
+
},
|
|
138
|
+
signal: abortController.signal
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
await assertOk(response, "follow process logs");
|
|
142
|
+
if (!response.body) {
|
|
143
|
+
abortController.abort();
|
|
144
|
+
throw new Error("SSE stream is not readable in this environment.");
|
|
145
|
+
}
|
|
146
|
+
const closed = consumeProcessLogSse(
|
|
147
|
+
response.body,
|
|
148
|
+
listener,
|
|
149
|
+
abortController.signal
|
|
150
|
+
);
|
|
151
|
+
return {
|
|
152
|
+
close: () => abortController.abort(),
|
|
153
|
+
closed
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
async function assertOk(response, operation) {
|
|
157
|
+
if (!response.ok) {
|
|
158
|
+
const body = await response.text().catch(() => "");
|
|
159
|
+
throw new Error(
|
|
160
|
+
`Sandbox ${operation} failed (${response.status}): ${body}`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
var DirectTerminalSession = (_class = class {
|
|
165
|
+
|
|
166
|
+
__init() {this.dataListeners = /* @__PURE__ */ new Set()}
|
|
167
|
+
__init2() {this.exitListeners = /* @__PURE__ */ new Set()}
|
|
168
|
+
__init3() {this.errorListeners = /* @__PURE__ */ new Set()}
|
|
169
|
+
__init4() {this.closeListeners = /* @__PURE__ */ new Set()}
|
|
170
|
+
__init5() {this.closeSignalSent = false}
|
|
171
|
+
constructor(socket) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);
|
|
172
|
+
this.socket = socket;
|
|
173
|
+
this.socket.addEventListener("message", (event) => {
|
|
174
|
+
void this.handleMessage(event.data);
|
|
175
|
+
});
|
|
176
|
+
this.socket.addEventListener("error", () => {
|
|
177
|
+
this.emitError(new Error("Terminal websocket connection failed."));
|
|
178
|
+
});
|
|
179
|
+
this.socket.addEventListener("close", () => {
|
|
180
|
+
for (const listener of this.closeListeners) {
|
|
181
|
+
listener();
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
onData(listener) {
|
|
186
|
+
this.dataListeners.add(listener);
|
|
187
|
+
return () => this.dataListeners.delete(listener);
|
|
188
|
+
}
|
|
189
|
+
onExit(listener) {
|
|
190
|
+
this.exitListeners.add(listener);
|
|
191
|
+
return () => this.exitListeners.delete(listener);
|
|
192
|
+
}
|
|
193
|
+
onError(listener) {
|
|
194
|
+
this.errorListeners.add(listener);
|
|
195
|
+
return () => this.errorListeners.delete(listener);
|
|
196
|
+
}
|
|
197
|
+
onClose(listener) {
|
|
198
|
+
this.closeListeners.add(listener);
|
|
199
|
+
return () => this.closeListeners.delete(listener);
|
|
200
|
+
}
|
|
201
|
+
sendInput(data) {
|
|
202
|
+
const payload = encodeTerminalInput(data);
|
|
203
|
+
this.sendFrame({
|
|
204
|
+
type: "input",
|
|
205
|
+
data: payload.data,
|
|
206
|
+
encoding: payload.encoding
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
resize(cols, rows) {
|
|
210
|
+
this.sendFrame({
|
|
211
|
+
type: "resize",
|
|
212
|
+
cols,
|
|
213
|
+
rows
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
close() {
|
|
217
|
+
if (this.socket.readyState === 0) {
|
|
218
|
+
this.socket.addEventListener(
|
|
219
|
+
"open",
|
|
220
|
+
() => {
|
|
221
|
+
this.close();
|
|
222
|
+
},
|
|
223
|
+
{ once: true }
|
|
224
|
+
);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (this.socket.readyState === 1) {
|
|
228
|
+
if (!this.closeSignalSent) {
|
|
229
|
+
this.closeSignalSent = true;
|
|
230
|
+
this.sendFrame({ type: "close" });
|
|
231
|
+
}
|
|
232
|
+
this.socket.close();
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (this.socket.readyState !== 3) {
|
|
236
|
+
this.socket.close();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
async handleMessage(data) {
|
|
240
|
+
try {
|
|
241
|
+
if (typeof data === "string") {
|
|
242
|
+
const frame = parseTerminalServerFrame(data);
|
|
243
|
+
if (!frame) {
|
|
244
|
+
this.emitError(
|
|
245
|
+
new Error("Received invalid terminal control frame.")
|
|
246
|
+
);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
if (frame.type === "exit") {
|
|
250
|
+
for (const listener of this.exitListeners) {
|
|
251
|
+
listener({ exitCode: _nullishCoalesce(frame.exitCode, () => ( null)) });
|
|
252
|
+
}
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (frame.type === "error") {
|
|
256
|
+
this.emitError(new Error(frame.message));
|
|
257
|
+
}
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const bytes = await decodeTerminalBytes(data);
|
|
261
|
+
if (!bytes) {
|
|
262
|
+
this.emitError(
|
|
263
|
+
new Error("Received unsupported terminal message payload.")
|
|
264
|
+
);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
for (const listener of this.dataListeners) {
|
|
268
|
+
listener(bytes);
|
|
269
|
+
}
|
|
270
|
+
} catch (error) {
|
|
271
|
+
this.emitError(
|
|
272
|
+
error instanceof Error ? error : new Error(String(error))
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
sendFrame(frame) {
|
|
277
|
+
if (this.socket.readyState !== 1) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
this.socket.send(JSON.stringify(frame));
|
|
281
|
+
}
|
|
282
|
+
emitError(error) {
|
|
283
|
+
for (const listener of this.errorListeners) {
|
|
284
|
+
listener(error);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}, _class);
|
|
288
|
+
async function fetchSandbox(input, init) {
|
|
289
|
+
const requestInit = { ...init };
|
|
290
|
+
requestInit.body = init.body;
|
|
291
|
+
if (isReadableStream(init.body)) {
|
|
292
|
+
requestInit.duplex = "half";
|
|
293
|
+
}
|
|
294
|
+
return await getFetch()(input, requestInit);
|
|
295
|
+
}
|
|
296
|
+
function getFetch() {
|
|
297
|
+
if (!globalThis.fetch) {
|
|
298
|
+
throw new Error(
|
|
299
|
+
"Fetch API is not available; provide a global fetch implementation."
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
return globalThis.fetch.bind(globalThis);
|
|
303
|
+
}
|
|
304
|
+
function getWebSocketCtor() {
|
|
305
|
+
if (!globalThis.WebSocket) {
|
|
306
|
+
throw new Error(
|
|
307
|
+
"WebSocket API is not available; provide a WebSocket implementation."
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
return globalThis.WebSocket;
|
|
311
|
+
}
|
|
312
|
+
function buildUrl(sandboxUrl, pathname, query) {
|
|
313
|
+
const url = new URL(sandboxUrl);
|
|
314
|
+
const basePath = url.pathname.replace(/\/+$/, "");
|
|
315
|
+
const suffix = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
316
|
+
url.pathname = `${basePath}${suffix}`.replace(/\/{2,}/g, "/");
|
|
317
|
+
if (query) {
|
|
318
|
+
for (const [key, value] of Object.entries(query)) {
|
|
319
|
+
if (value === void 0) {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
url.searchParams.set(key, String(value));
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return url.toString();
|
|
326
|
+
}
|
|
327
|
+
function parseTerminalServerFrame(payload) {
|
|
328
|
+
try {
|
|
329
|
+
const parsed = JSON.parse(payload);
|
|
330
|
+
if (typeof parsed.type !== "string") {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
if (parsed.type === "ready" && typeof parsed.processId === "string") {
|
|
334
|
+
return {
|
|
335
|
+
type: "ready",
|
|
336
|
+
processId: parsed.processId
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
if (parsed.type === "exit" && (parsed.exitCode === void 0 || parsed.exitCode === null || typeof parsed.exitCode === "number")) {
|
|
340
|
+
return {
|
|
341
|
+
type: "exit",
|
|
342
|
+
exitCode: _nullishCoalesce(parsed.exitCode, () => ( null))
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
if (parsed.type === "error" && typeof parsed.message === "string") {
|
|
346
|
+
return {
|
|
347
|
+
type: "error",
|
|
348
|
+
message: parsed.message
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
} catch (e) {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
function encodeTerminalInput(data) {
|
|
357
|
+
if (typeof data === "string") {
|
|
358
|
+
return { data };
|
|
359
|
+
}
|
|
360
|
+
return {
|
|
361
|
+
data: bytesToBase64(encodeTerminalBytes(data)),
|
|
362
|
+
encoding: "base64"
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
function encodeTerminalBytes(data) {
|
|
366
|
+
if (data instanceof ArrayBuffer) {
|
|
367
|
+
return new Uint8Array(data);
|
|
368
|
+
}
|
|
369
|
+
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength).slice();
|
|
370
|
+
}
|
|
371
|
+
async function decodeTerminalBytes(data) {
|
|
372
|
+
if (data instanceof ArrayBuffer) {
|
|
373
|
+
return new Uint8Array(data);
|
|
374
|
+
}
|
|
375
|
+
if (ArrayBuffer.isView(data)) {
|
|
376
|
+
return new Uint8Array(
|
|
377
|
+
data.buffer,
|
|
378
|
+
data.byteOffset,
|
|
379
|
+
data.byteLength
|
|
380
|
+
).slice();
|
|
381
|
+
}
|
|
382
|
+
if (typeof Blob !== "undefined" && data instanceof Blob) {
|
|
383
|
+
return new Uint8Array(await data.arrayBuffer());
|
|
384
|
+
}
|
|
385
|
+
return null;
|
|
386
|
+
}
|
|
387
|
+
function bytesToBase64(bytes) {
|
|
388
|
+
const bufferCtor = globalThis.Buffer;
|
|
389
|
+
if (bufferCtor) {
|
|
390
|
+
return bufferCtor.from(bytes).toString("base64");
|
|
391
|
+
}
|
|
392
|
+
let binary = "";
|
|
393
|
+
const chunkSize = 32768;
|
|
394
|
+
for (let index = 0; index < bytes.length; index += chunkSize) {
|
|
395
|
+
const chunk = bytes.subarray(index, index + chunkSize);
|
|
396
|
+
binary += String.fromCharCode(...chunk);
|
|
397
|
+
}
|
|
398
|
+
if (typeof btoa !== "function") {
|
|
399
|
+
throw new Error("No base64 encoder is available in this environment.");
|
|
400
|
+
}
|
|
401
|
+
return btoa(binary);
|
|
402
|
+
}
|
|
403
|
+
async function consumeProcessLogSse(body, listener, signal) {
|
|
404
|
+
const reader = body.getReader();
|
|
405
|
+
const decoder = new TextDecoder();
|
|
406
|
+
let buffer = "";
|
|
407
|
+
try {
|
|
408
|
+
while (!signal.aborted) {
|
|
409
|
+
const { done, value } = await reader.read();
|
|
410
|
+
if (done) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
buffer += decoder.decode(value, { stream: true }).replace(/\r\n/g, "\n");
|
|
414
|
+
let separatorIndex = buffer.indexOf("\n\n");
|
|
415
|
+
while (separatorIndex !== -1) {
|
|
416
|
+
const chunk = buffer.slice(0, separatorIndex);
|
|
417
|
+
buffer = buffer.slice(separatorIndex + 2);
|
|
418
|
+
const entry = parseProcessLogSseChunk(chunk);
|
|
419
|
+
if (entry) {
|
|
420
|
+
listener(entry);
|
|
421
|
+
}
|
|
422
|
+
separatorIndex = buffer.indexOf("\n\n");
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
} catch (error) {
|
|
426
|
+
if (signal.aborted || isAbortError(error)) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
throw error;
|
|
430
|
+
} finally {
|
|
431
|
+
reader.releaseLock();
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
function parseProcessLogSseChunk(chunk) {
|
|
435
|
+
if (!chunk.trim()) {
|
|
436
|
+
return null;
|
|
437
|
+
}
|
|
438
|
+
let eventName = "message";
|
|
439
|
+
const dataLines = [];
|
|
440
|
+
for (const line of chunk.split("\n")) {
|
|
441
|
+
if (!line || line.startsWith(":")) {
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
if (line.startsWith("event:")) {
|
|
445
|
+
eventName = line.slice(6).trim();
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
if (line.startsWith("data:")) {
|
|
449
|
+
dataLines.push(line.slice(5).trimStart());
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
if (eventName !== "log") {
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
const data = dataLines.join("\n");
|
|
456
|
+
if (!data.trim()) {
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
459
|
+
return JSON.parse(data);
|
|
460
|
+
}
|
|
461
|
+
function isAbortError(error) {
|
|
462
|
+
return error instanceof Error && error.name === "AbortError";
|
|
463
|
+
}
|
|
464
|
+
function isReadableStream(value) {
|
|
465
|
+
return typeof ReadableStream !== "undefined" && value instanceof ReadableStream;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
exports.uploadFile = uploadFile; exports.downloadFile = downloadFile; exports.uploadBatch = uploadBatch; exports.listFiles = listFiles; exports.statFile = statFile; exports.deleteFile = deleteFile; exports.mkdirFs = mkdirFs; exports.moveFile = moveFile; exports.buildTerminalWebSocketUrl = buildTerminalWebSocketUrl; exports.connectTerminal = connectTerminal; exports.followProcessLogs = followProcessLogs;
|
|
481
|
+
//# sourceMappingURL=chunk-YZJWZBY5.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/rivet/rivet/rivetkit-typescript/packages/rivetkit/dist/tsup/chunk-YZJWZBY5.cjs","../../src/sandbox/client.ts"],"names":[],"mappings":"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AAIY,EAAA;AACL,IAAA;AACf,EAAA;AACO,EAAA;AACc,IAAA;AACV,IAAA;AACX,EAAA;AACD;AAES;AACY,EAAA;AACG,IAAA;AACvB,EAAA;AACsB,EAAA;AACvB;AAEe;AACM,EAAA;AACG,IAAA;AACvB,EAAA;AACuB,EAAA;AACX,IAAA;AACL,MAAA;AACA,MAAA;AACA,MAAA;AACE,IAAA;AACT,EAAA;AACoB,EAAA;AACG,IAAA;AACvB,EAAA;AACO,EAAA;AACR;AAEuB;AAErB,EAAA;AAMe,EAAA;AACG,IAAA;AACnB,EAAA;AAEa,EAAA;AACK,EAAA;AACE,EAAA;AACC,IAAA;AACH,IAAA;AAClB,EAAA;AACoB,EAAA;AACH,IAAA;AACjB,EAAA;AACkB,EAAA;AACnB;AAEe;AAKM,EAAA;AACA,EAAA;AACP,EAAA;AACT,EAAA;AACY,IAAA;AACM,MAAA;AACV,MAAA;AACT,QAAA;AACD,MAAA;AAEE,MAAA;AAEE,MAAA;AACG,MAAA;AACQ,QAAA;AACE,QAAA;AACF,QAAA;AACH,QAAA;AACI,UAAA;AACf,QAAA;AACiB,QAAA;AAClB,MAAA;AACD,IAAA;AACe,EAAA;AACO,IAAA;AACrB,MAAA;AACD,IAAA;AACM,IAAA;AACL,EAAA;AACkB,IAAA;AACpB,EAAA;AACD;AAES;AACW,EAAA;AACX,IAAA;AACR,EAAA;AAEgB,EAAA;AACa,EAAA;AACV,EAAA;AACA,IAAA;AACjB,MAAA;AACD,IAAA;AACoB,IAAA;AACF,MAAA;AACjB,MAAA;AACD,IAAA;AACoB,IAAA;AACC,MAAA;AACrB,IAAA;AACD,EAAA;AAEkB,EAAA;AACV,IAAA;AACR,EAAA;AAEuB,EAAA;AACL,EAAA;AACV,IAAA;AACR,EAAA;AAEsB,EAAA;AACvB;AAEsB;AACG,EAAA;AACzB;AAE0B;AAEjB,EAAA;AAGT;ADhP0B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/rivet/rivet/rivetkit-typescript/packages/rivetkit/dist/tsup/chunk-YZJWZBY5.cjs","sourcesContent":[null,"/**\n * Client-side helpers for direct operations against a sandbox-agent server.\n *\n * The sandbox actor proxies all sandbox-agent SDK methods as Rivet Actor\n * actions, which use JSON-based RPC serialization. This works well for\n * structured data (sessions, processes, MCP config), but three categories of\n * operations do not fit through JSON actions:\n *\n * 1. Binary filesystem I/O (readFsFile, writeFsFile, uploadFsBatch): raw\n * binary payloads would require base64 encoding with ~33% size overhead.\n * 2. WebSocket terminals (connectProcessTerminal,\n * connectProcessTerminalWebSocket): bidirectional binary streams cannot be\n * serialized through request-response JSON.\n * 3. SSE log streaming (followProcessLogs): continuous event streams with\n * callbacks cannot be proxied through one-shot JSON actions.\n *\n * These helpers let the client talk directly to the sandbox-agent HTTP API,\n * bypassing the actor's JSON action layer. The sandbox URL is obtained via\n * the actor's `getSandboxUrl` action. Sandbox providers already secure the\n * connection between client and sandbox, so no additional authentication is\n * needed on these direct endpoints.\n */\n\nconst API_PREFIX = \"/v1\";\n\ntype FetchBody =\n\t| Blob\n\t| ArrayBuffer\n\t| Uint8Array\n\t| ReadableStream\n\t| string;\n\ntype TerminalInput = string | ArrayBuffer | ArrayBufferView;\ntype WebSocketConstructor = typeof WebSocket;\ntype ProcessLogStream = \"stdout\" | \"stderr\" | \"combined\" | \"pty\";\n\nexport interface FsEntry {\n\tentryType: \"file\" | \"directory\";\n\tmodified?: string | null;\n\tname: string;\n\tpath: string;\n\tsize: number;\n}\n\nexport interface FsStat {\n\tentryType: \"file\" | \"directory\";\n\tmodified?: string | null;\n\tpath: string;\n\tsize: number;\n}\n\nexport interface UploadBatchResponse {\n\tpaths: string[];\n\ttruncated: boolean;\n}\n\nexport interface ProcessLogEntry {\n\tdata: string;\n\tencoding: string;\n\tsequence: number;\n\tstream: ProcessLogStream;\n\ttimestampMs: number;\n}\n\nexport interface FollowProcessLogsOptions {\n\tstream?: ProcessLogStream;\n\ttail?: number;\n\tsince?: number;\n}\n\nexport interface TerminalExitStatus {\n\texitCode: number | null;\n}\n\nexport interface TerminalConnectOptions {\n\tprotocols?: string | string[];\n\tWebSocket?: WebSocketConstructor;\n}\n\nexport interface TerminalSession {\n\tonData(listener: (data: Uint8Array) => void): () => void;\n\tonExit(listener: (status: TerminalExitStatus) => void): () => void;\n\tonError(listener: (error: Error) => void): () => void;\n\tonClose(listener: () => void): () => void;\n\tsendInput(data: TerminalInput): void;\n\tresize(cols: number, rows: number): void;\n\tclose(): void;\n\tsocket: WebSocket;\n}\n\nexport async function uploadFile(\n\tsandboxUrl: string,\n\tpath: string,\n\tdata: FetchBody,\n): Promise<void> {\n\tconst response = await fetchSandbox(\n\t\tbuildUrl(sandboxUrl, `${API_PREFIX}/fs/file`, { path }),\n\t\t{\n\t\t\tmethod: \"PUT\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/octet-stream\",\n\t\t\t},\n\t\t\tbody: data,\n\t\t},\n\t);\n\tawait assertOk(response, \"upload file\");\n}\n\nexport async function downloadFile(\n\tsandboxUrl: string,\n\tpath: string,\n): Promise<ArrayBuffer> {\n\tconst response = await fetchSandbox(\n\t\tbuildUrl(sandboxUrl, `${API_PREFIX}/fs/file`, { path }),\n\t\t{\n\t\t\tmethod: \"GET\",\n\t\t},\n\t);\n\tawait assertOk(response, \"download file\");\n\treturn await response.arrayBuffer();\n}\n\nexport async function uploadBatch(\n\tsandboxUrl: string,\n\tdestinationPath: string,\n\ttarData: Blob | ArrayBuffer | Uint8Array,\n): Promise<UploadBatchResponse> {\n\tconst response = await fetchSandbox(\n\t\tbuildUrl(sandboxUrl, `${API_PREFIX}/fs/upload-batch`, {\n\t\t\tpath: destinationPath,\n\t\t}),\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-tar\",\n\t\t\t},\n\t\t\tbody: tarData,\n\t\t},\n\t);\n\tawait assertOk(response, \"upload batch\");\n\treturn (await response.json()) as UploadBatchResponse;\n}\n\nexport async function listFiles(\n\tsandboxUrl: string,\n\tpath: string,\n): Promise<FsEntry[]> {\n\tconst response = await fetchSandbox(\n\t\tbuildUrl(sandboxUrl, `${API_PREFIX}/fs/entries`, { path }),\n\t\t{\n\t\t\tmethod: \"GET\",\n\t\t},\n\t);\n\tawait assertOk(response, \"list files\");\n\treturn (await response.json()) as FsEntry[];\n}\n\nexport async function statFile(\n\tsandboxUrl: string,\n\tpath: string,\n): Promise<FsStat> {\n\tconst response = await fetchSandbox(\n\t\tbuildUrl(sandboxUrl, `${API_PREFIX}/fs/stat`, { path }),\n\t\t{\n\t\t\tmethod: \"GET\",\n\t\t},\n\t);\n\tawait assertOk(response, \"stat file\");\n\treturn (await response.json()) as FsStat;\n}\n\nexport async function deleteFile(\n\tsandboxUrl: string,\n\tpath: string,\n): Promise<void> {\n\tconst response = await fetchSandbox(\n\t\tbuildUrl(sandboxUrl, `${API_PREFIX}/fs/entry`, { path }),\n\t\t{\n\t\t\tmethod: \"DELETE\",\n\t\t},\n\t);\n\tawait assertOk(response, \"delete file\");\n}\n\nexport async function mkdirFs(\n\tsandboxUrl: string,\n\tpath: string,\n): Promise<void> {\n\tconst response = await fetchSandbox(\n\t\tbuildUrl(sandboxUrl, `${API_PREFIX}/fs/mkdir`, { path }),\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t},\n\t);\n\tawait assertOk(response, \"mkdir\");\n}\n\nexport async function moveFile(\n\tsandboxUrl: string,\n\tfrom: string,\n\tto: string,\n\toverwrite = false,\n): Promise<void> {\n\tconst response = await fetchSandbox(\n\t\tbuildUrl(sandboxUrl, `${API_PREFIX}/fs/move`),\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tfrom,\n\t\t\t\tto,\n\t\t\t\toverwrite,\n\t\t\t}),\n\t\t},\n\t);\n\tawait assertOk(response, \"move file\");\n}\n\nexport function buildTerminalWebSocketUrl(\n\tsandboxUrl: string,\n\tprocessId: string,\n): string {\n\tconst url = new URL(\n\t\tbuildUrl(\n\t\t\tsandboxUrl,\n\t\t\t`${API_PREFIX}/processes/${encodeURIComponent(processId)}/terminal/ws`,\n\t\t),\n\t);\n\tif (url.protocol === \"http:\") {\n\t\turl.protocol = \"ws:\";\n\t} else if (url.protocol === \"https:\") {\n\t\turl.protocol = \"wss:\";\n\t}\n\treturn url.toString();\n}\n\nexport function connectTerminal(\n\tsandboxUrl: string,\n\tprocessId: string,\n\toptions: TerminalConnectOptions = {},\n): TerminalSession {\n\tconst WebSocketCtor = options.WebSocket ?? getWebSocketCtor();\n\tconst socket = new WebSocketCtor(\n\t\tbuildTerminalWebSocketUrl(sandboxUrl, processId),\n\t\toptions.protocols,\n\t);\n\tsocket.binaryType = \"arraybuffer\";\n\treturn new DirectTerminalSession(socket);\n}\n\nexport async function followProcessLogs(\n\tsandboxUrl: string,\n\tprocessId: string,\n\tlistener: (entry: ProcessLogEntry) => void,\n\toptions: FollowProcessLogsOptions = {},\n): Promise<{ close: () => void; closed: Promise<void> }> {\n\tconst abortController = new AbortController();\n\tconst response = await fetchSandbox(\n\t\tbuildUrl(\n\t\t\tsandboxUrl,\n\t\t\t`${API_PREFIX}/processes/${encodeURIComponent(processId)}/logs`,\n\t\t\t{\n\t\t\t\tfollow: true,\n\t\t\t\tstream: options.stream,\n\t\t\t\ttail: options.tail,\n\t\t\t\tsince: options.since,\n\t\t\t},\n\t\t),\n\t\t{\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {\n\t\t\t\tAccept: \"text/event-stream\",\n\t\t\t},\n\t\t\tsignal: abortController.signal,\n\t\t},\n\t);\n\tawait assertOk(response, \"follow process logs\");\n\tif (!response.body) {\n\t\tabortController.abort();\n\t\tthrow new Error(\"SSE stream is not readable in this environment.\");\n\t}\n\n\tconst closed = consumeProcessLogSse(\n\t\tresponse.body,\n\t\tlistener,\n\t\tabortController.signal,\n\t);\n\treturn {\n\t\tclose: () => abortController.abort(),\n\t\tclosed,\n\t};\n}\n\nasync function assertOk(response: Response, operation: string): Promise<void> {\n\tif (!response.ok) {\n\t\tconst body = await response.text().catch(() => \"\");\n\t\tthrow new Error(\n\t\t\t`Sandbox ${operation} failed (${response.status}): ${body}`,\n\t\t);\n\t}\n}\n\nclass DirectTerminalSession implements TerminalSession {\n\treadonly socket: WebSocket;\n\n\tprivate readonly dataListeners = new Set<(data: Uint8Array) => void>();\n\tprivate readonly exitListeners = new Set<\n\t\t(status: TerminalExitStatus) => void\n\t>();\n\tprivate readonly errorListeners = new Set<(error: Error) => void>();\n\tprivate readonly closeListeners = new Set<() => void>();\n\tprivate closeSignalSent = false;\n\n\tconstructor(socket: WebSocket) {\n\t\tthis.socket = socket;\n\t\tthis.socket.addEventListener(\"message\", (event) => {\n\t\t\tvoid this.handleMessage(event.data);\n\t\t});\n\t\tthis.socket.addEventListener(\"error\", () => {\n\t\t\tthis.emitError(new Error(\"Terminal websocket connection failed.\"));\n\t\t});\n\t\tthis.socket.addEventListener(\"close\", () => {\n\t\t\tfor (const listener of this.closeListeners) {\n\t\t\t\tlistener();\n\t\t\t}\n\t\t});\n\t}\n\n\tonData(listener: (data: Uint8Array) => void): () => void {\n\t\tthis.dataListeners.add(listener);\n\t\treturn () => this.dataListeners.delete(listener);\n\t}\n\n\tonExit(listener: (status: TerminalExitStatus) => void): () => void {\n\t\tthis.exitListeners.add(listener);\n\t\treturn () => this.exitListeners.delete(listener);\n\t}\n\n\tonError(listener: (error: Error) => void): () => void {\n\t\tthis.errorListeners.add(listener);\n\t\treturn () => this.errorListeners.delete(listener);\n\t}\n\n\tonClose(listener: () => void): () => void {\n\t\tthis.closeListeners.add(listener);\n\t\treturn () => this.closeListeners.delete(listener);\n\t}\n\n\tsendInput(data: TerminalInput): void {\n\t\tconst payload = encodeTerminalInput(data);\n\t\tthis.sendFrame({\n\t\t\ttype: \"input\",\n\t\t\tdata: payload.data,\n\t\t\tencoding: payload.encoding,\n\t\t});\n\t}\n\n\tresize(cols: number, rows: number): void {\n\t\tthis.sendFrame({\n\t\t\ttype: \"resize\",\n\t\t\tcols,\n\t\t\trows,\n\t\t});\n\t}\n\n\tclose(): void {\n\t\tif (this.socket.readyState === 0) {\n\t\t\tthis.socket.addEventListener(\n\t\t\t\t\"open\",\n\t\t\t\t() => {\n\t\t\t\t\tthis.close();\n\t\t\t\t},\n\t\t\t\t{ once: true },\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.socket.readyState === 1) {\n\t\t\tif (!this.closeSignalSent) {\n\t\t\t\tthis.closeSignalSent = true;\n\t\t\t\tthis.sendFrame({ type: \"close\" });\n\t\t\t}\n\t\t\tthis.socket.close();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.socket.readyState !== 3) {\n\t\t\tthis.socket.close();\n\t\t}\n\t}\n\n\tprivate async handleMessage(data: unknown): Promise<void> {\n\t\ttry {\n\t\t\tif (typeof data === \"string\") {\n\t\t\t\tconst frame = parseTerminalServerFrame(data);\n\t\t\t\tif (!frame) {\n\t\t\t\t\tthis.emitError(\n\t\t\t\t\t\tnew Error(\"Received invalid terminal control frame.\"),\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (frame.type === \"exit\") {\n\t\t\t\t\tfor (const listener of this.exitListeners) {\n\t\t\t\t\t\tlistener({ exitCode: frame.exitCode ?? null });\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (frame.type === \"error\") {\n\t\t\t\t\tthis.emitError(new Error(frame.message));\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst bytes = await decodeTerminalBytes(data);\n\t\t\tif (!bytes) {\n\t\t\t\tthis.emitError(\n\t\t\t\t\tnew Error(\"Received unsupported terminal message payload.\"),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (const listener of this.dataListeners) {\n\t\t\t\tlistener(bytes);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.emitError(\n\t\t\t\terror instanceof Error ? error : new Error(String(error)),\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate sendFrame(frame: {\n\t\ttype: \"input\";\n\t\tdata: string;\n\t\tencoding?: string;\n\t} | {\n\t\ttype: \"resize\";\n\t\tcols: number;\n\t\trows: number;\n\t} | {\n\t\ttype: \"close\";\n\t}): void {\n\t\tif (this.socket.readyState !== 1) {\n\t\t\treturn;\n\t\t}\n\t\tthis.socket.send(JSON.stringify(frame));\n\t}\n\n\tprivate emitError(error: Error): void {\n\t\tfor (const listener of this.errorListeners) {\n\t\t\tlistener(error);\n\t\t}\n\t}\n}\n\nasync function fetchSandbox(\n\tinput: string,\n\tinit: RequestInit & { body?: FetchBody },\n): Promise<Response> {\n\tconst requestInit = { ...init } as RequestInit & {\n\t\tbody?: unknown;\n\t\tduplex?: \"half\";\n\t};\n\trequestInit.body = init.body;\n\tif (isReadableStream(init.body)) {\n\t\trequestInit.duplex = \"half\";\n\t}\n\treturn await getFetch()(input, requestInit);\n}\n\nfunction getFetch(): typeof fetch {\n\tif (!globalThis.fetch) {\n\t\tthrow new Error(\n\t\t\t\"Fetch API is not available; provide a global fetch implementation.\",\n\t\t);\n\t}\n\treturn globalThis.fetch.bind(globalThis);\n}\n\nfunction getWebSocketCtor(): WebSocketConstructor {\n\tif (!globalThis.WebSocket) {\n\t\tthrow new Error(\n\t\t\t\"WebSocket API is not available; provide a WebSocket implementation.\",\n\t\t);\n\t}\n\treturn globalThis.WebSocket;\n}\n\nfunction buildUrl(\n\tsandboxUrl: string,\n\tpathname: string,\n\tquery?: Record<string, string | number | boolean | undefined>,\n): string {\n\tconst url = new URL(sandboxUrl);\n\tconst basePath = url.pathname.replace(/\\/+$/, \"\");\n\tconst suffix = pathname.startsWith(\"/\") ? pathname : `/${pathname}`;\n\turl.pathname = `${basePath}${suffix}`.replace(/\\/{2,}/g, \"/\");\n\tif (query) {\n\t\tfor (const [key, value] of Object.entries(query)) {\n\t\t\tif (value === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\turl.searchParams.set(key, String(value));\n\t\t}\n\t}\n\treturn url.toString();\n}\n\nfunction parseTerminalServerFrame(payload: string):\n\t| {\n\t\t\ttype: \"ready\";\n\t\t\tprocessId: string;\n\t }\n\t| {\n\t\t\ttype: \"exit\";\n\t\t\texitCode?: number | null;\n\t }\n\t| {\n\t\t\ttype: \"error\";\n\t\t\tmessage: string;\n\t }\n\t| null {\n\ttry {\n\t\tconst parsed = JSON.parse(payload) as Record<string, unknown>;\n\t\tif (typeof parsed.type !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\t\tif (\n\t\t\tparsed.type === \"ready\" &&\n\t\t\ttypeof parsed.processId === \"string\"\n\t\t) {\n\t\t\treturn {\n\t\t\t\ttype: \"ready\",\n\t\t\t\tprocessId: parsed.processId,\n\t\t\t};\n\t\t}\n\t\tif (\n\t\t\tparsed.type === \"exit\" &&\n\t\t\t(parsed.exitCode === undefined ||\n\t\t\t\tparsed.exitCode === null ||\n\t\t\t\ttypeof parsed.exitCode === \"number\")\n\t\t) {\n\t\t\treturn {\n\t\t\t\ttype: \"exit\",\n\t\t\t\texitCode: (parsed.exitCode as number | null | undefined) ?? null,\n\t\t\t};\n\t\t}\n\t\tif (\n\t\t\tparsed.type === \"error\" &&\n\t\t\ttypeof parsed.message === \"string\"\n\t\t) {\n\t\t\treturn {\n\t\t\t\ttype: \"error\",\n\t\t\t\tmessage: parsed.message,\n\t\t\t};\n\t\t}\n\t} catch {\n\t\treturn null;\n\t}\n\treturn null;\n}\n\nfunction encodeTerminalInput(data: TerminalInput): {\n\tdata: string;\n\tencoding?: string;\n} {\n\tif (typeof data === \"string\") {\n\t\treturn { data };\n\t}\n\treturn {\n\t\tdata: bytesToBase64(encodeTerminalBytes(data)),\n\t\tencoding: \"base64\",\n\t};\n}\n\nfunction encodeTerminalBytes(data: ArrayBuffer | ArrayBufferView): Uint8Array {\n\tif (data instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(data);\n\t}\n\treturn new Uint8Array(data.buffer, data.byteOffset, data.byteLength).slice();\n}\n\nasync function decodeTerminalBytes(data: unknown): Promise<Uint8Array | null> {\n\tif (data instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(data);\n\t}\n\tif (ArrayBuffer.isView(data)) {\n\t\treturn new Uint8Array(\n\t\t\tdata.buffer,\n\t\t\tdata.byteOffset,\n\t\t\tdata.byteLength,\n\t\t).slice();\n\t}\n\tif (typeof Blob !== \"undefined\" && data instanceof Blob) {\n\t\treturn new Uint8Array(await data.arrayBuffer());\n\t}\n\treturn null;\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n\tconst bufferCtor = (\n\t\tglobalThis as typeof globalThis & {\n\t\t\tBuffer?: {\n\t\t\t\tfrom(data: Uint8Array): { toString(encoding: \"base64\"): string };\n\t\t\t};\n\t\t}\n\t).Buffer;\n\tif (bufferCtor) {\n\t\treturn bufferCtor.from(bytes).toString(\"base64\");\n\t}\n\n\tlet binary = \"\";\n\tconst chunkSize = 0x8000;\n\tfor (let index = 0; index < bytes.length; index += chunkSize) {\n\t\tconst chunk = bytes.subarray(index, index + chunkSize);\n\t\tbinary += String.fromCharCode(...chunk);\n\t}\n\tif (typeof btoa !== \"function\") {\n\t\tthrow new Error(\"No base64 encoder is available in this environment.\");\n\t}\n\treturn btoa(binary);\n}\n\nasync function consumeProcessLogSse(\n\tbody: ReadableStream<Uint8Array>,\n\tlistener: (entry: ProcessLogEntry) => void,\n\tsignal: AbortSignal,\n): Promise<void> {\n\tconst reader = body.getReader();\n\tconst decoder = new TextDecoder();\n\tlet buffer = \"\";\n\ttry {\n\t\twhile (!signal.aborted) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tbuffer += decoder\n\t\t\t\t.decode(value, { stream: true })\n\t\t\t\t.replace(/\\r\\n/g, \"\\n\");\n\t\t\tlet separatorIndex = buffer.indexOf(\"\\n\\n\");\n\t\t\twhile (separatorIndex !== -1) {\n\t\t\t\tconst chunk = buffer.slice(0, separatorIndex);\n\t\t\t\tbuffer = buffer.slice(separatorIndex + 2);\n\t\t\t\tconst entry = parseProcessLogSseChunk(chunk);\n\t\t\t\tif (entry) {\n\t\t\t\t\tlistener(entry);\n\t\t\t\t}\n\t\t\t\tseparatorIndex = buffer.indexOf(\"\\n\\n\");\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tif (signal.aborted || isAbortError(error)) {\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t} finally {\n\t\treader.releaseLock();\n\t}\n}\n\nfunction parseProcessLogSseChunk(chunk: string): ProcessLogEntry | null {\n\tif (!chunk.trim()) {\n\t\treturn null;\n\t}\n\n\tlet eventName = \"message\";\n\tconst dataLines: string[] = [];\n\tfor (const line of chunk.split(\"\\n\")) {\n\t\tif (!line || line.startsWith(\":\")) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\"event:\")) {\n\t\t\teventName = line.slice(6).trim();\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\"data:\")) {\n\t\t\tdataLines.push(line.slice(5).trimStart());\n\t\t}\n\t}\n\n\tif (eventName !== \"log\") {\n\t\treturn null;\n\t}\n\n\tconst data = dataLines.join(\"\\n\");\n\tif (!data.trim()) {\n\t\treturn null;\n\t}\n\n\treturn JSON.parse(data) as ProcessLogEntry;\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && error.name === \"AbortError\";\n}\n\nfunction isReadableStream(value: unknown): value is ReadableStream {\n\treturn (\n\t\ttypeof ReadableStream !== \"undefined\" &&\n\t\tvalue instanceof ReadableStream\n\t);\n}\n"]}
|