rivetkit 2.0.42 → 2.1.0-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/{tsup/config-CLnylLYY.d.ts → browser/client.d.ts} +2127 -1910
- package/dist/browser/client.js +5182 -0
- package/dist/browser/client.js.map +1 -0
- package/dist/browser/inspector/client.d.ts +130 -0
- package/dist/browser/inspector/client.js +2854 -0
- package/dist/browser/inspector/client.js.map +1 -0
- package/dist/browser/v3-DnYObHH3.d.ts +279 -0
- package/dist/schemas/actor-inspector/v2.ts +796 -0
- package/dist/schemas/actor-inspector/v3.ts +899 -0
- package/dist/schemas/actor-persist/v4.ts +406 -0
- package/dist/schemas/client-protocol/v3.ts +554 -0
- package/dist/schemas/persist/v1.ts +781 -0
- package/dist/schemas/transport/v1.ts +697 -0
- package/dist/tsup/actor/errors.cjs +27 -3
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +37 -1
- package/dist/tsup/actor/errors.d.ts +37 -1
- package/dist/tsup/actor/errors.js +26 -1
- package/dist/tsup/{actor-router-consts-DzI2szci.d.cts → actor-router-consts-D29T1Z-K.d.cts} +1 -1
- package/dist/tsup/{actor-router-consts-DzI2szci.d.ts → actor-router-consts-D29T1Z-K.d.ts} +1 -1
- package/dist/tsup/chunk-424PT5DM.js +23 -0
- package/dist/tsup/chunk-424PT5DM.js.map +1 -0
- package/dist/tsup/{chunk-JDAD2YFA.js → chunk-5ESWDTHJ.js} +148 -273
- package/dist/tsup/chunk-5ESWDTHJ.js.map +1 -0
- package/dist/tsup/{chunk-FJ3KTN4V.js → chunk-6LIBPELE.js} +119 -11
- package/dist/tsup/chunk-6LIBPELE.js.map +1 -0
- package/dist/tsup/chunk-6LJAZ5R4.cjs +96 -0
- package/dist/tsup/chunk-6LJAZ5R4.cjs.map +1 -0
- package/dist/tsup/{chunk-LFVF5SCU.js → chunk-7HTNH26M.js} +126 -1
- package/dist/tsup/chunk-7HTNH26M.js.map +1 -0
- package/dist/tsup/chunk-7K4CYDGD.js +630 -0
- package/dist/tsup/chunk-7K4CYDGD.js.map +1 -0
- package/dist/tsup/{chunk-XXGJCOL6.js → chunk-A6YIZWTK.js} +2 -2
- package/dist/tsup/chunk-AIYEYMX5.cjs +630 -0
- package/dist/tsup/chunk-AIYEYMX5.cjs.map +1 -0
- package/dist/tsup/{chunk-Q6W7RJJP.js → chunk-DIGBC2VI.js} +211 -2316
- package/dist/tsup/chunk-DIGBC2VI.js.map +1 -0
- package/dist/tsup/{chunk-RZW2DNND.cjs → chunk-F6JYU5IK.cjs} +1957 -1039
- package/dist/tsup/chunk-F6JYU5IK.cjs.map +1 -0
- package/dist/tsup/chunk-HAZL2EPK.cjs +534 -0
- package/dist/tsup/chunk-HAZL2EPK.cjs.map +1 -0
- package/dist/tsup/chunk-HDQ2JUQT.cjs +23 -0
- package/dist/tsup/chunk-HDQ2JUQT.cjs.map +1 -0
- package/dist/tsup/chunk-HIDX4C5Y.cjs +1036 -0
- package/dist/tsup/chunk-HIDX4C5Y.cjs.map +1 -0
- package/dist/tsup/chunk-IVG73YCW.js +534 -0
- package/dist/tsup/chunk-IVG73YCW.js.map +1 -0
- package/dist/tsup/chunk-KJSYAUOM.js +96 -0
- package/dist/tsup/chunk-KJSYAUOM.js.map +1 -0
- package/dist/tsup/{chunk-2XQS746M.cjs → chunk-L47L3ZWJ.cjs} +127 -2
- package/dist/tsup/chunk-L47L3ZWJ.cjs.map +1 -0
- package/dist/tsup/{chunk-H4TB4X25.cjs → chunk-LW6KLR7A.cjs} +126 -18
- package/dist/tsup/chunk-LW6KLR7A.cjs.map +1 -0
- package/dist/tsup/chunk-LXUQ667X.js +2006 -0
- package/dist/tsup/chunk-LXUQ667X.js.map +1 -0
- package/dist/tsup/{chunk-GMAVRZSF.js → chunk-M2T62AZQ.js} +1790 -872
- package/dist/tsup/chunk-M2T62AZQ.js.map +1 -0
- package/dist/tsup/chunk-MZ37VV3P.js +5974 -0
- package/dist/tsup/chunk-MZ37VV3P.js.map +1 -0
- package/dist/tsup/chunk-N4KRDJ56.js +72 -0
- package/dist/tsup/chunk-N4KRDJ56.js.map +1 -0
- package/dist/tsup/chunk-NIYZDWMW.cjs +2006 -0
- package/dist/tsup/chunk-NIYZDWMW.cjs.map +1 -0
- package/dist/tsup/chunk-OMEPCQK2.js +649 -0
- package/dist/tsup/chunk-OMEPCQK2.js.map +1 -0
- package/dist/tsup/chunk-SR3KQE7Q.cjs +72 -0
- package/dist/tsup/chunk-SR3KQE7Q.cjs.map +1 -0
- package/dist/tsup/chunk-SSEP6DHP.cjs +2657 -0
- package/dist/tsup/chunk-SSEP6DHP.cjs.map +1 -0
- package/dist/tsup/chunk-T5YCUGVS.js +1036 -0
- package/dist/tsup/chunk-T5YCUGVS.js.map +1 -0
- package/dist/tsup/{chunk-EJVBH5VF.cjs → chunk-TPGXWFQT.cjs} +3 -3
- package/dist/tsup/{chunk-EJVBH5VF.cjs.map → chunk-TPGXWFQT.cjs.map} +1 -1
- package/dist/tsup/{chunk-X35U3YNX.cjs → chunk-TYLXNCA5.cjs} +214 -339
- package/dist/tsup/chunk-TYLXNCA5.cjs.map +1 -0
- package/dist/tsup/chunk-VKVNIQRQ.js +257 -0
- package/dist/tsup/chunk-VKVNIQRQ.js.map +1 -0
- package/dist/tsup/chunk-XWBAQO5H.cjs +649 -0
- package/dist/tsup/chunk-XWBAQO5H.cjs.map +1 -0
- package/dist/tsup/chunk-YQ4LDVD6.cjs +5974 -0
- package/dist/tsup/chunk-YQ4LDVD6.cjs.map +1 -0
- package/dist/tsup/chunk-ZFY5J2EP.cjs +257 -0
- package/dist/tsup/chunk-ZFY5J2EP.cjs.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -10
- package/dist/tsup/client/mod.cjs.map +1 -1
- package/dist/tsup/client/mod.d.cts +11 -5
- package/dist/tsup/client/mod.d.ts +11 -5
- package/dist/tsup/client/mod.js +8 -8
- package/dist/tsup/common/log.cjs +4 -4
- package/dist/tsup/common/log.d.cts +2 -2
- package/dist/tsup/common/log.d.ts +2 -2
- package/dist/tsup/common/log.js +3 -2
- package/dist/tsup/common/websocket.cjs +5 -5
- package/dist/tsup/common/websocket.js +4 -3
- package/dist/tsup/config-BFqid9Gr.d.ts +2574 -0
- package/dist/tsup/config-BiNoIHRs.d.cts +80 -0
- package/dist/tsup/config-BiNoIHRs.d.ts +80 -0
- package/dist/tsup/{config-CZB2-W8x.d.cts → config-CAZphOS1.d.cts} +681 -355
- package/dist/tsup/db/drizzle/mod.cjs +49 -0
- package/dist/tsup/db/drizzle/mod.cjs.map +1 -0
- package/dist/tsup/db/drizzle/mod.d.cts +17 -0
- package/dist/tsup/db/drizzle/mod.d.ts +17 -0
- package/dist/tsup/db/drizzle/mod.js +49 -0
- package/dist/tsup/db/drizzle/mod.js.map +1 -0
- package/dist/tsup/db/mod.cjs +9 -0
- package/dist/tsup/db/mod.cjs.map +1 -0
- package/dist/tsup/db/mod.d.cts +9 -0
- package/dist/tsup/db/mod.d.ts +9 -0
- package/dist/tsup/db/mod.js +9 -0
- package/dist/tsup/db/mod.js.map +1 -0
- package/dist/tsup/{driver-D0QX9M11.d.ts → driver-Bxv62E2p.d.ts} +2 -2
- package/dist/tsup/{driver-q-zqG7fc.d.cts → driver-DYXwJR5D.d.cts} +2 -2
- package/dist/tsup/driver-helpers/mod.cjs +12 -6
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +12 -5
- package/dist/tsup/driver-helpers/mod.d.ts +12 -5
- package/dist/tsup/driver-helpers/mod.js +12 -5
- package/dist/tsup/driver-test-suite/mod.cjs +1370 -116
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +10 -4
- package/dist/tsup/driver-test-suite/mod.d.ts +10 -4
- package/dist/tsup/driver-test-suite/mod.js +2093 -838
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +29 -3
- package/dist/tsup/inspector/mod.cjs.map +1 -1
- package/dist/tsup/inspector/mod.d.cts +124 -3
- package/dist/tsup/inspector/mod.d.ts +124 -3
- package/dist/tsup/inspector/mod.js +72 -45
- package/dist/tsup/keys-CydblqMh.d.cts +13 -0
- package/dist/tsup/keys-CydblqMh.d.ts +13 -0
- package/dist/tsup/mod.cjs +16 -10
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +26 -14
- package/dist/tsup/mod.d.ts +26 -14
- package/dist/tsup/mod.js +20 -13
- package/dist/tsup/serve-test-suite/mod.cjs +1165 -83
- package/dist/tsup/serve-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/serve-test-suite/mod.js +1114 -29
- package/dist/tsup/serve-test-suite/mod.js.map +1 -1
- package/dist/tsup/test/mod.cjs +84 -11
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +10 -5
- package/dist/tsup/test/mod.d.ts +10 -5
- package/dist/tsup/test/mod.js +85 -11
- package/dist/tsup/test/mod.js.map +1 -1
- package/dist/tsup/utils.cjs +10 -4
- package/dist/tsup/utils.cjs.map +1 -1
- package/dist/tsup/utils.d.cts +72 -2
- package/dist/tsup/utils.d.ts +72 -2
- package/dist/tsup/utils.js +9 -2
- package/dist/tsup/v3-DnYObHH3.d.cts +279 -0
- package/dist/tsup/v3-DnYObHH3.d.ts +279 -0
- package/dist/tsup/workflow/mod.cjs +16 -0
- package/dist/tsup/workflow/mod.cjs.map +1 -0
- package/dist/tsup/workflow/mod.d.cts +83 -0
- package/dist/tsup/workflow/mod.d.ts +83 -0
- package/dist/tsup/workflow/mod.js +16 -0
- package/dist/tsup/workflow/mod.js.map +1 -0
- package/package.json +62 -5
- package/src/actor/config.ts +478 -68
- package/src/actor/conn/mod.ts +68 -16
- package/src/actor/conn/state-manager.ts +2 -2
- package/src/actor/contexts/action.ts +20 -12
- package/src/actor/contexts/base/actor.ts +137 -7
- package/src/actor/contexts/base/conn-init.ts +27 -7
- package/src/actor/contexts/base/conn.ts +27 -18
- package/src/actor/contexts/before-action-response.ts +9 -2
- package/src/actor/contexts/before-connect.ts +7 -2
- package/src/actor/contexts/connect.ts +9 -2
- package/src/actor/contexts/create-conn-state.ts +7 -2
- package/src/actor/contexts/create-vars.ts +16 -3
- package/src/actor/contexts/create.ts +16 -3
- package/src/actor/contexts/destroy.ts +9 -3
- package/src/actor/contexts/disconnect.ts +10 -4
- package/src/actor/contexts/index.ts +4 -3
- package/src/actor/contexts/request.ts +23 -6
- package/src/actor/contexts/run.ts +47 -0
- package/src/actor/contexts/sleep.ts +9 -3
- package/src/actor/contexts/state-change.ts +9 -3
- package/src/actor/contexts/wake.ts +9 -3
- package/src/actor/contexts/websocket.ts +23 -6
- package/src/actor/database.ts +8 -18
- package/src/actor/definition.ts +20 -6
- package/src/actor/driver.ts +32 -3
- package/src/actor/errors.ts +127 -0
- package/src/actor/instance/connection-manager.ts +183 -80
- package/src/actor/instance/event-manager.ts +26 -15
- package/src/actor/instance/keys.ts +117 -0
- package/src/actor/instance/mod.ts +784 -174
- package/src/actor/instance/queue-manager.ts +603 -0
- package/src/actor/instance/queue.ts +287 -0
- package/src/actor/instance/schedule-manager.ts +49 -7
- package/src/actor/instance/state-manager.ts +35 -11
- package/src/actor/instance/traces-driver.ts +128 -0
- package/src/actor/mod.ts +26 -2
- package/src/actor/protocol/old.ts +28 -13
- package/src/actor/protocol/serde.ts +1 -1
- package/src/actor/router-endpoints.ts +177 -21
- package/src/actor/router-websocket-endpoints.ts +18 -29
- package/src/actor/router.ts +177 -0
- package/src/actor/schema.ts +291 -0
- package/src/actor/utils.ts +40 -0
- package/src/client/actor-common.ts +1 -1
- package/src/client/actor-conn.ts +100 -33
- package/src/client/actor-handle.ts +61 -33
- package/src/client/client.ts +2 -4
- package/src/client/config.ts +1 -1
- package/src/client/mod.browser.ts +2 -0
- package/src/client/mod.ts +1 -4
- package/src/client/queue.ts +146 -0
- package/src/client/utils.ts +1 -1
- package/src/common/log.ts +1 -1
- package/src/common/utils.ts +3 -3
- package/src/db/config.ts +100 -0
- package/src/db/drizzle/mod.ts +226 -0
- package/src/db/drizzle/sqlite-core.ts +22 -0
- package/src/db/mod.ts +125 -0
- package/src/db/shared.ts +92 -0
- package/src/db/sqlite-vfs.ts +12 -0
- package/src/driver-helpers/mod.ts +1 -0
- package/src/driver-test-suite/mod.ts +69 -43
- package/src/driver-test-suite/tests/access-control.ts +218 -0
- package/src/driver-test-suite/tests/actor-db-raw.ts +73 -0
- package/src/driver-test-suite/tests/actor-db.ts +394 -0
- package/src/driver-test-suite/tests/actor-inspector.ts +259 -358
- package/src/driver-test-suite/tests/actor-kv.ts +41 -20
- package/src/driver-test-suite/tests/actor-queue.ts +324 -0
- package/src/driver-test-suite/tests/actor-run.ts +181 -0
- package/src/driver-test-suite/tests/actor-schedule.ts +5 -2
- package/src/driver-test-suite/tests/actor-sleep.ts +3 -3
- package/src/driver-test-suite/tests/actor-stateless.ts +70 -0
- package/src/driver-test-suite/tests/actor-workflow.ts +108 -0
- package/src/driver-test-suite/tests/manager-driver.ts +11 -0
- package/src/driver-test-suite/tests/raw-http-request-properties.ts +1 -1
- package/src/driver-test-suite/tests/raw-websocket.ts +12 -12
- package/src/drivers/default.ts +7 -2
- package/src/drivers/engine/actor-driver.ts +45 -37
- package/src/drivers/engine/config.ts +1 -1
- package/src/drivers/file-system/actor.ts +20 -2
- package/src/drivers/file-system/global-state.ts +569 -258
- package/src/drivers/file-system/kv-limits.ts +70 -0
- package/src/drivers/file-system/manager.ts +22 -6
- package/src/drivers/file-system/mod.ts +39 -16
- package/src/drivers/file-system/sqlite-runtime.ts +210 -0
- package/src/inspector/actor-inspector.ts +224 -102
- package/src/inspector/config.ts +1 -1
- package/src/inspector/handler.ts +102 -20
- package/src/inspector/mod.browser.ts +8 -0
- package/src/inspector/mod.ts +2 -0
- package/src/inspector/serve-ui.ts +40 -0
- package/src/inspector/transport.ts +18 -0
- package/src/inspector/utils.ts +5 -39
- package/src/manager/gateway.ts +1 -1
- package/src/manager/protocol/mod.ts +1 -1
- package/src/manager/protocol/query.ts +1 -1
- package/src/manager/router-schema.ts +1 -1
- package/src/manager/router.ts +38 -12
- package/src/manager-api/actors.ts +1 -1
- package/src/manager-api/common.ts +1 -1
- package/src/registry/config/driver.ts +1 -1
- package/src/registry/config/index.ts +212 -43
- package/src/registry/config/legacy-runner.ts +1 -1
- package/src/registry/config/runner.ts +1 -1
- package/src/registry/config/serverless.ts +1 -1
- package/src/registry/index.ts +7 -5
- package/src/remote-manager-driver/api-utils.ts +1 -1
- package/src/schemas/actor-inspector/mod.ts +1 -1
- package/src/schemas/actor-inspector/versioned.ts +195 -8
- package/src/schemas/actor-persist/versioned.ts +87 -7
- package/src/schemas/client-protocol/mod.ts +1 -1
- package/src/schemas/client-protocol/versioned.ts +127 -11
- package/src/schemas/client-protocol-zod/mod.ts +16 -1
- package/src/schemas/persist/mod.ts +1 -0
- package/src/schemas/transport/mod.ts +1 -0
- package/src/serde.ts +1 -1
- package/src/serve-test-suite/mod.ts +10 -9
- package/src/test/mod.ts +15 -56
- package/src/utils/endpoint-parser.test.ts +1 -1
- package/src/utils/endpoint-parser.ts +1 -1
- package/src/utils/env-vars.ts +12 -1
- package/src/utils/node.ts +15 -2
- package/src/utils.test.ts +34 -0
- package/src/utils.ts +140 -6
- package/src/workflow/constants.ts +2 -0
- package/src/workflow/context.ts +532 -0
- package/src/workflow/driver.ts +191 -0
- package/src/workflow/inspector.ts +268 -0
- package/src/workflow/mod.ts +122 -0
- package/dist/tsup/chunk-2IJTYN6K.cjs +0 -278
- package/dist/tsup/chunk-2IJTYN6K.cjs.map +0 -1
- package/dist/tsup/chunk-2XQS746M.cjs.map +0 -1
- package/dist/tsup/chunk-3VP5CSHV.cjs +0 -114
- package/dist/tsup/chunk-3VP5CSHV.cjs.map +0 -1
- package/dist/tsup/chunk-AQFSQMBG.js +0 -114
- package/dist/tsup/chunk-AQFSQMBG.js.map +0 -1
- package/dist/tsup/chunk-E6ZE2YEA.js +0 -664
- package/dist/tsup/chunk-E6ZE2YEA.js.map +0 -1
- package/dist/tsup/chunk-FJ3KTN4V.js.map +0 -1
- package/dist/tsup/chunk-GBENOENJ.cjs +0 -8
- package/dist/tsup/chunk-GBENOENJ.cjs.map +0 -1
- package/dist/tsup/chunk-GD7UXGOE.cjs +0 -4762
- package/dist/tsup/chunk-GD7UXGOE.cjs.map +0 -1
- package/dist/tsup/chunk-GMAVRZSF.js.map +0 -1
- package/dist/tsup/chunk-H4TB4X25.cjs.map +0 -1
- package/dist/tsup/chunk-JDAD2YFA.js.map +0 -1
- package/dist/tsup/chunk-KCOVZOPS.js +0 -1946
- package/dist/tsup/chunk-KCOVZOPS.js.map +0 -1
- package/dist/tsup/chunk-KDFWJKMJ.cjs +0 -664
- package/dist/tsup/chunk-KDFWJKMJ.cjs.map +0 -1
- package/dist/tsup/chunk-LFVF5SCU.js.map +0 -1
- package/dist/tsup/chunk-Q6W7RJJP.js.map +0 -1
- package/dist/tsup/chunk-RUW5CZ5Z.cjs +0 -1949
- package/dist/tsup/chunk-RUW5CZ5Z.cjs.map +0 -1
- package/dist/tsup/chunk-RZW2DNND.cjs.map +0 -1
- package/dist/tsup/chunk-TCOEBUUE.js +0 -278
- package/dist/tsup/chunk-TCOEBUUE.js.map +0 -1
- package/dist/tsup/chunk-X35U3YNX.cjs.map +0 -1
- package/dist/tsup/keys-Chhy4ylv.d.cts +0 -8
- package/dist/tsup/keys-Chhy4ylv.d.ts +0 -8
- package/dist/tsup/v1-Gq4avTK3.d.cts +0 -240
- package/dist/tsup/v1-Gq4avTK3.d.ts +0 -240
- /package/dist/tsup/{chunk-XXGJCOL6.js.map → chunk-A6YIZWTK.js.map} +0 -0
|
@@ -1,1946 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createClientWithDriver,
|
|
3
|
-
lookupInRegistry
|
|
4
|
-
} from "./chunk-Q6W7RJJP.js";
|
|
5
|
-
import {
|
|
6
|
-
CONN_DRIVER_SYMBOL,
|
|
7
|
-
PATH_CONNECT,
|
|
8
|
-
PATH_INSPECTOR_CONNECT,
|
|
9
|
-
PATH_WEBSOCKET_PREFIX,
|
|
10
|
-
getInitialActorKvState,
|
|
11
|
-
handleAction,
|
|
12
|
-
handleRawRequest,
|
|
13
|
-
handleRouteError,
|
|
14
|
-
handleRouteNotFound,
|
|
15
|
-
loggerMiddleware,
|
|
16
|
-
loggerWithoutContext,
|
|
17
|
-
parseWebSocketProtocols,
|
|
18
|
-
routeWebSocket
|
|
19
|
-
} from "./chunk-GMAVRZSF.js";
|
|
20
|
-
import {
|
|
21
|
-
VERSION,
|
|
22
|
-
arrayBuffersEqual,
|
|
23
|
-
bufferToArrayBuffer,
|
|
24
|
-
getLogger,
|
|
25
|
-
noopNext,
|
|
26
|
-
promiseWithResolvers,
|
|
27
|
-
setLongTimeout,
|
|
28
|
-
stringifyError
|
|
29
|
-
} from "./chunk-FJ3KTN4V.js";
|
|
30
|
-
import {
|
|
31
|
-
ActorDuplicateKey,
|
|
32
|
-
ActorStopping
|
|
33
|
-
} from "./chunk-LFVF5SCU.js";
|
|
34
|
-
|
|
35
|
-
// src/actor/router.ts
|
|
36
|
-
import { Hono } from "hono";
|
|
37
|
-
function createActorRouter(config4, actorDriver, getUpgradeWebSocket, isTest) {
|
|
38
|
-
const router = new Hono({
|
|
39
|
-
strict: false
|
|
40
|
-
});
|
|
41
|
-
router.use("*", loggerMiddleware(loggerWithoutContext()));
|
|
42
|
-
router.use("*", async (c, next) => {
|
|
43
|
-
const actor = await actorDriver.loadActor(c.env.actorId);
|
|
44
|
-
actor.beginHonoHttpRequest();
|
|
45
|
-
try {
|
|
46
|
-
await next();
|
|
47
|
-
} finally {
|
|
48
|
-
actor.endHonoHttpRequest();
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
router.get("/", (c) => {
|
|
52
|
-
return c.text(
|
|
53
|
-
"This is an RivetKit actor.\n\nLearn more at https://rivetkit.org"
|
|
54
|
-
);
|
|
55
|
-
});
|
|
56
|
-
router.get("/health", (c) => {
|
|
57
|
-
return c.text("ok");
|
|
58
|
-
});
|
|
59
|
-
router.get("/metadata", async (c) => {
|
|
60
|
-
return c.json({
|
|
61
|
-
runtime: "rivetkit",
|
|
62
|
-
version: VERSION
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
if (isTest) {
|
|
66
|
-
router.post("/.test/force-disconnect", async (c) => {
|
|
67
|
-
var _a;
|
|
68
|
-
const connId = c.req.query("conn");
|
|
69
|
-
if (!connId) {
|
|
70
|
-
return c.text("Missing conn query parameter", 400);
|
|
71
|
-
}
|
|
72
|
-
const actor = await actorDriver.loadActor(c.env.actorId);
|
|
73
|
-
const conn = actor.connectionManager.getConnForId(connId);
|
|
74
|
-
if (!conn) {
|
|
75
|
-
return c.text(`Connection not found: ${connId}`, 404);
|
|
76
|
-
}
|
|
77
|
-
if ((_a = conn[CONN_DRIVER_SYMBOL]) == null ? void 0 : _a.terminate) {
|
|
78
|
-
conn[CONN_DRIVER_SYMBOL].terminate(actor, conn);
|
|
79
|
-
}
|
|
80
|
-
return c.json({ success: true });
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
if (getUpgradeWebSocket) {
|
|
84
|
-
router.on(
|
|
85
|
-
"GET",
|
|
86
|
-
[PATH_CONNECT, `${PATH_WEBSOCKET_PREFIX}*`, PATH_INSPECTOR_CONNECT],
|
|
87
|
-
async (c) => {
|
|
88
|
-
const upgradeWebSocket = getUpgradeWebSocket();
|
|
89
|
-
if (upgradeWebSocket) {
|
|
90
|
-
return upgradeWebSocket(async (c2) => {
|
|
91
|
-
const protocols = c2.req.header(
|
|
92
|
-
"sec-websocket-protocol"
|
|
93
|
-
);
|
|
94
|
-
const { encoding, connParams } = parseWebSocketProtocols(protocols);
|
|
95
|
-
return await routeWebSocket(
|
|
96
|
-
c2.req.raw,
|
|
97
|
-
c2.req.path,
|
|
98
|
-
c2.req.header(),
|
|
99
|
-
config4,
|
|
100
|
-
actorDriver,
|
|
101
|
-
c2.env.actorId,
|
|
102
|
-
encoding,
|
|
103
|
-
connParams,
|
|
104
|
-
void 0,
|
|
105
|
-
void 0,
|
|
106
|
-
false,
|
|
107
|
-
false
|
|
108
|
-
);
|
|
109
|
-
})(c, noopNext());
|
|
110
|
-
} else {
|
|
111
|
-
return c.text(
|
|
112
|
-
"WebSockets are not enabled for this driver.",
|
|
113
|
-
400
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
router.post("/action/:action", async (c) => {
|
|
120
|
-
const actionName = c.req.param("action");
|
|
121
|
-
return handleAction(c, config4, actorDriver, actionName, c.env.actorId);
|
|
122
|
-
});
|
|
123
|
-
router.all("/request/*", async (c) => {
|
|
124
|
-
const url = new URL(c.req.url);
|
|
125
|
-
const originalPath = url.pathname.replace(/^\/request/, "") || "/";
|
|
126
|
-
const correctedUrl = new URL(originalPath + url.search, url.origin);
|
|
127
|
-
const correctedRequest = new Request(correctedUrl, {
|
|
128
|
-
method: c.req.method,
|
|
129
|
-
headers: c.req.raw.headers,
|
|
130
|
-
body: c.req.raw.body,
|
|
131
|
-
duplex: "half"
|
|
132
|
-
});
|
|
133
|
-
loggerWithoutContext().debug({
|
|
134
|
-
msg: "rewriting http url",
|
|
135
|
-
from: c.req.url,
|
|
136
|
-
to: correctedRequest.url
|
|
137
|
-
});
|
|
138
|
-
return await handleRawRequest(
|
|
139
|
-
c,
|
|
140
|
-
correctedRequest,
|
|
141
|
-
actorDriver,
|
|
142
|
-
c.env.actorId
|
|
143
|
-
);
|
|
144
|
-
});
|
|
145
|
-
router.notFound(handleRouteNotFound);
|
|
146
|
-
router.onError(handleRouteError);
|
|
147
|
-
return router;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// src/common/inline-websocket-adapter.ts
|
|
151
|
-
import { WSContext } from "hono/ws";
|
|
152
|
-
import { VirtualWebSocket } from "@rivetkit/virtual-websocket";
|
|
153
|
-
function logger() {
|
|
154
|
-
return getLogger("inline-websocket-adapter");
|
|
155
|
-
}
|
|
156
|
-
var InlineWebSocketAdapter = class {
|
|
157
|
-
#handler;
|
|
158
|
-
#wsContext;
|
|
159
|
-
#readyState = 0;
|
|
160
|
-
#clientWs;
|
|
161
|
-
#actorWs;
|
|
162
|
-
constructor(handler) {
|
|
163
|
-
this.#handler = handler;
|
|
164
|
-
this.#clientWs = new VirtualWebSocket({
|
|
165
|
-
getReadyState: () => this.#readyState,
|
|
166
|
-
onSend: (data) => {
|
|
167
|
-
try {
|
|
168
|
-
this.#handler.onMessage({ data }, this.#wsContext);
|
|
169
|
-
this.#actorWs.triggerMessage(data);
|
|
170
|
-
} catch (err) {
|
|
171
|
-
this.#handleError(err);
|
|
172
|
-
this.#close(1011, "Internal error processing message");
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
|
-
onClose: (code, reason) => this.#close(code, reason)
|
|
176
|
-
});
|
|
177
|
-
this.#actorWs = new VirtualWebSocket({
|
|
178
|
-
getReadyState: () => this.#readyState,
|
|
179
|
-
onSend: (data) => this.#clientWs.triggerMessage(data),
|
|
180
|
-
onClose: (code, reason) => this.#close(code, reason)
|
|
181
|
-
});
|
|
182
|
-
this.#wsContext = new WSContext({
|
|
183
|
-
raw: this.#actorWs,
|
|
184
|
-
send: (data) => {
|
|
185
|
-
logger().debug({ msg: "WSContext.send called" });
|
|
186
|
-
this.#clientWs.triggerMessage(data);
|
|
187
|
-
},
|
|
188
|
-
close: (code, reason) => {
|
|
189
|
-
logger().debug({ msg: "WSContext.close called", code, reason });
|
|
190
|
-
this.#close(code || 1e3, reason || "");
|
|
191
|
-
},
|
|
192
|
-
readyState: 1
|
|
193
|
-
});
|
|
194
|
-
setTimeout(() => {
|
|
195
|
-
this.#initialize();
|
|
196
|
-
}, 0);
|
|
197
|
-
}
|
|
198
|
-
/** Get the client-side WebSocket (for proxy/client code) */
|
|
199
|
-
get clientWebSocket() {
|
|
200
|
-
return this.#clientWs;
|
|
201
|
-
}
|
|
202
|
-
/** Get the actor-side WebSocket (passed to actor via wsContext.raw) */
|
|
203
|
-
get actorWebSocket() {
|
|
204
|
-
return this.#actorWs;
|
|
205
|
-
}
|
|
206
|
-
async #initialize() {
|
|
207
|
-
try {
|
|
208
|
-
logger().debug({ msg: "websocket initializing" });
|
|
209
|
-
this.#readyState = 1;
|
|
210
|
-
logger().debug({ msg: "calling handler.onOpen with WSContext" });
|
|
211
|
-
this.#handler.onOpen(void 0, this.#wsContext);
|
|
212
|
-
this.#clientWs.triggerOpen();
|
|
213
|
-
this.#actorWs.triggerOpen();
|
|
214
|
-
} catch (err) {
|
|
215
|
-
this.#handleError(err);
|
|
216
|
-
this.#close(1011, "Internal error during initialization");
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
#handleError(err) {
|
|
220
|
-
logger().error({
|
|
221
|
-
msg: "error in websocket",
|
|
222
|
-
error: err,
|
|
223
|
-
errorMessage: err instanceof Error ? err.message : String(err),
|
|
224
|
-
stack: err instanceof Error ? err.stack : void 0
|
|
225
|
-
});
|
|
226
|
-
try {
|
|
227
|
-
this.#handler.onError(err, this.#wsContext);
|
|
228
|
-
} catch (handlerErr) {
|
|
229
|
-
logger().error({ msg: "error in onError handler", error: handlerErr });
|
|
230
|
-
}
|
|
231
|
-
this.#clientWs.triggerError(err);
|
|
232
|
-
this.#actorWs.triggerError(err);
|
|
233
|
-
}
|
|
234
|
-
#close(code, reason) {
|
|
235
|
-
if (this.#readyState === 3 || this.#readyState === 2) {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
logger().debug({ msg: "closing websocket", code, reason });
|
|
239
|
-
this.#readyState = 2;
|
|
240
|
-
try {
|
|
241
|
-
this.#handler.onClose({ code, reason, wasClean: true }, this.#wsContext);
|
|
242
|
-
} catch (err) {
|
|
243
|
-
logger().error({ msg: "error closing websocket", error: err });
|
|
244
|
-
} finally {
|
|
245
|
-
this.#readyState = 3;
|
|
246
|
-
this.#clientWs.triggerClose(code, reason);
|
|
247
|
-
this.#actorWs.triggerClose(code, reason);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
function createInlineWebSocket(handler) {
|
|
252
|
-
const adapter = new InlineWebSocketAdapter(handler);
|
|
253
|
-
return adapter.clientWebSocket;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// src/utils/node.ts
|
|
257
|
-
import { createRequire } from "module";
|
|
258
|
-
var nodeCrypto;
|
|
259
|
-
var nodeFsSync;
|
|
260
|
-
var nodeFs;
|
|
261
|
-
var nodePath;
|
|
262
|
-
var nodeOs;
|
|
263
|
-
var nodeChildProcess;
|
|
264
|
-
var nodeStream;
|
|
265
|
-
var hasImportedDependencies = false;
|
|
266
|
-
function getRequireFn() {
|
|
267
|
-
return createRequire(import.meta.url);
|
|
268
|
-
}
|
|
269
|
-
function importNodeDependencies() {
|
|
270
|
-
if (hasImportedDependencies) return;
|
|
271
|
-
try {
|
|
272
|
-
const requireFn = getRequireFn();
|
|
273
|
-
nodeCrypto = requireFn(
|
|
274
|
-
/* webpackIgnore: true */
|
|
275
|
-
"node:crypto"
|
|
276
|
-
);
|
|
277
|
-
nodeFsSync = requireFn(
|
|
278
|
-
/* webpackIgnore: true */
|
|
279
|
-
"node:fs"
|
|
280
|
-
);
|
|
281
|
-
nodeFs = requireFn(
|
|
282
|
-
/* webpackIgnore: true */
|
|
283
|
-
"node:fs/promises"
|
|
284
|
-
);
|
|
285
|
-
nodePath = requireFn(
|
|
286
|
-
/* webpackIgnore: true */
|
|
287
|
-
"node:path"
|
|
288
|
-
);
|
|
289
|
-
nodeOs = requireFn(
|
|
290
|
-
/* webpackIgnore: true */
|
|
291
|
-
"node:os"
|
|
292
|
-
);
|
|
293
|
-
nodeChildProcess = requireFn(
|
|
294
|
-
/* webpackIgnore: true */
|
|
295
|
-
"node:child_process"
|
|
296
|
-
);
|
|
297
|
-
nodeStream = requireFn(
|
|
298
|
-
/* webpackIgnore: true */
|
|
299
|
-
"node:stream/promises"
|
|
300
|
-
);
|
|
301
|
-
hasImportedDependencies = true;
|
|
302
|
-
} catch (err) {
|
|
303
|
-
console.warn(
|
|
304
|
-
"Node.js modules not available, file system driver will not work",
|
|
305
|
-
err
|
|
306
|
-
);
|
|
307
|
-
throw err;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
function getNodeCrypto() {
|
|
311
|
-
if (!nodeCrypto) {
|
|
312
|
-
throw new Error(
|
|
313
|
-
"Node crypto module not loaded. Ensure importNodeDependencies() has been called."
|
|
314
|
-
);
|
|
315
|
-
}
|
|
316
|
-
return nodeCrypto;
|
|
317
|
-
}
|
|
318
|
-
function getNodeFsSync() {
|
|
319
|
-
if (!nodeFsSync) {
|
|
320
|
-
throw new Error(
|
|
321
|
-
"Node fs module not loaded. Ensure importNodeDependencies() has been called."
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
|
-
return nodeFsSync;
|
|
325
|
-
}
|
|
326
|
-
function getNodeFs() {
|
|
327
|
-
if (!nodeFs) {
|
|
328
|
-
throw new Error(
|
|
329
|
-
"Node fs/promises module not loaded. Ensure importNodeDependencies() has been called."
|
|
330
|
-
);
|
|
331
|
-
}
|
|
332
|
-
return nodeFs;
|
|
333
|
-
}
|
|
334
|
-
function getNodePath() {
|
|
335
|
-
if (!nodePath) {
|
|
336
|
-
throw new Error(
|
|
337
|
-
"Node path module not loaded. Ensure importNodeDependencies() has been called."
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
return nodePath;
|
|
341
|
-
}
|
|
342
|
-
function getNodeOs() {
|
|
343
|
-
if (!nodeOs) {
|
|
344
|
-
throw new Error(
|
|
345
|
-
"Node os module not loaded. Ensure importNodeDependencies() has been called."
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
|
-
return nodeOs;
|
|
349
|
-
}
|
|
350
|
-
function getNodeChildProcess() {
|
|
351
|
-
if (!nodeChildProcess) {
|
|
352
|
-
throw new Error(
|
|
353
|
-
"Node child_process module not loaded. Ensure importNodeDependencies() has been called."
|
|
354
|
-
);
|
|
355
|
-
}
|
|
356
|
-
return nodeChildProcess;
|
|
357
|
-
}
|
|
358
|
-
function getNodeStream() {
|
|
359
|
-
if (!nodeStream) {
|
|
360
|
-
throw new Error(
|
|
361
|
-
"Node stream/promises module not loaded. Ensure importNodeDependencies() has been called."
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
return nodeStream;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// src/drivers/file-system/actor.ts
|
|
368
|
-
var FileSystemActorDriver = class {
|
|
369
|
-
#config;
|
|
370
|
-
#managerDriver;
|
|
371
|
-
#inlineClient;
|
|
372
|
-
#state;
|
|
373
|
-
constructor(config4, managerDriver, inlineClient, state) {
|
|
374
|
-
this.#config = config4;
|
|
375
|
-
this.#managerDriver = managerDriver;
|
|
376
|
-
this.#inlineClient = inlineClient;
|
|
377
|
-
this.#state = state;
|
|
378
|
-
}
|
|
379
|
-
async loadActor(actorId) {
|
|
380
|
-
return this.#state.startActor(
|
|
381
|
-
this.#config,
|
|
382
|
-
this.#inlineClient,
|
|
383
|
-
this,
|
|
384
|
-
actorId
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Get the current storage directory path
|
|
389
|
-
*/
|
|
390
|
-
get storagePath() {
|
|
391
|
-
return this.#state.storagePath;
|
|
392
|
-
}
|
|
393
|
-
getContext(_actorId) {
|
|
394
|
-
return {};
|
|
395
|
-
}
|
|
396
|
-
async kvBatchPut(actorId, entries) {
|
|
397
|
-
await this.#state.kvBatchPut(actorId, entries);
|
|
398
|
-
}
|
|
399
|
-
async kvBatchGet(actorId, keys) {
|
|
400
|
-
return await this.#state.kvBatchGet(actorId, keys);
|
|
401
|
-
}
|
|
402
|
-
async kvBatchDelete(actorId, keys) {
|
|
403
|
-
await this.#state.kvBatchDelete(actorId, keys);
|
|
404
|
-
}
|
|
405
|
-
async kvListPrefix(actorId, prefix) {
|
|
406
|
-
return await this.#state.kvListPrefix(actorId, prefix);
|
|
407
|
-
}
|
|
408
|
-
async setAlarm(actor, timestamp) {
|
|
409
|
-
await this.#state.setActorAlarm(actor.id, timestamp);
|
|
410
|
-
}
|
|
411
|
-
getDatabase(actorId) {
|
|
412
|
-
return this.#state.createDatabase(actorId);
|
|
413
|
-
}
|
|
414
|
-
startSleep(actorId) {
|
|
415
|
-
this.#state.sleepActor(actorId);
|
|
416
|
-
}
|
|
417
|
-
async startDestroy(actorId) {
|
|
418
|
-
await this.#state.destroyActor(actorId);
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
|
-
|
|
422
|
-
// src/drivers/file-system/global-state.ts
|
|
423
|
-
import invariant from "invariant";
|
|
424
|
-
|
|
425
|
-
// src/schemas/file-system-driver/versioned.ts
|
|
426
|
-
import { createVersionedDataHandler } from "vbare";
|
|
427
|
-
|
|
428
|
-
// dist/schemas/file-system-driver/v1.ts
|
|
429
|
-
import * as bare from "@rivetkit/bare-ts";
|
|
430
|
-
var config = /* @__PURE__ */ bare.Config({});
|
|
431
|
-
function read0(bc) {
|
|
432
|
-
const len = bare.readUintSafe(bc);
|
|
433
|
-
if (len === 0) {
|
|
434
|
-
return [];
|
|
435
|
-
}
|
|
436
|
-
const result = [bare.readString(bc)];
|
|
437
|
-
for (let i = 1; i < len; i++) {
|
|
438
|
-
result[i] = bare.readString(bc);
|
|
439
|
-
}
|
|
440
|
-
return result;
|
|
441
|
-
}
|
|
442
|
-
function write0(bc, x) {
|
|
443
|
-
bare.writeUintSafe(bc, x.length);
|
|
444
|
-
for (let i = 0; i < x.length; i++) {
|
|
445
|
-
bare.writeString(bc, x[i]);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
function readActorState(bc) {
|
|
449
|
-
return {
|
|
450
|
-
actorId: bare.readString(bc),
|
|
451
|
-
name: bare.readString(bc),
|
|
452
|
-
key: read0(bc),
|
|
453
|
-
persistedData: bare.readData(bc),
|
|
454
|
-
createdAt: bare.readU64(bc)
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
function writeActorState(bc, x) {
|
|
458
|
-
bare.writeString(bc, x.actorId);
|
|
459
|
-
bare.writeString(bc, x.name);
|
|
460
|
-
write0(bc, x.key);
|
|
461
|
-
bare.writeData(bc, x.persistedData);
|
|
462
|
-
bare.writeU64(bc, x.createdAt);
|
|
463
|
-
}
|
|
464
|
-
function encodeActorState(x) {
|
|
465
|
-
const bc = new bare.ByteCursor(
|
|
466
|
-
new Uint8Array(config.initialBufferLength),
|
|
467
|
-
config
|
|
468
|
-
);
|
|
469
|
-
writeActorState(bc, x);
|
|
470
|
-
return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
|
|
471
|
-
}
|
|
472
|
-
function decodeActorState(bytes) {
|
|
473
|
-
const bc = new bare.ByteCursor(bytes, config);
|
|
474
|
-
const result = readActorState(bc);
|
|
475
|
-
if (bc.offset < bc.view.byteLength) {
|
|
476
|
-
throw new bare.BareError(bc.offset, "remaining bytes");
|
|
477
|
-
}
|
|
478
|
-
return result;
|
|
479
|
-
}
|
|
480
|
-
function readActorAlarm(bc) {
|
|
481
|
-
return {
|
|
482
|
-
actorId: bare.readString(bc),
|
|
483
|
-
timestamp: bare.readUint(bc)
|
|
484
|
-
};
|
|
485
|
-
}
|
|
486
|
-
function writeActorAlarm(bc, x) {
|
|
487
|
-
bare.writeString(bc, x.actorId);
|
|
488
|
-
bare.writeUint(bc, x.timestamp);
|
|
489
|
-
}
|
|
490
|
-
function encodeActorAlarm(x) {
|
|
491
|
-
const bc = new bare.ByteCursor(
|
|
492
|
-
new Uint8Array(config.initialBufferLength),
|
|
493
|
-
config
|
|
494
|
-
);
|
|
495
|
-
writeActorAlarm(bc, x);
|
|
496
|
-
return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
|
|
497
|
-
}
|
|
498
|
-
function decodeActorAlarm(bytes) {
|
|
499
|
-
const bc = new bare.ByteCursor(bytes, config);
|
|
500
|
-
const result = readActorAlarm(bc);
|
|
501
|
-
if (bc.offset < bc.view.byteLength) {
|
|
502
|
-
throw new bare.BareError(bc.offset, "remaining bytes");
|
|
503
|
-
}
|
|
504
|
-
return result;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
// dist/schemas/file-system-driver/v2.ts
|
|
508
|
-
import * as bare2 from "@rivetkit/bare-ts";
|
|
509
|
-
var config2 = /* @__PURE__ */ bare2.Config({});
|
|
510
|
-
function readActorKvEntry(bc) {
|
|
511
|
-
return {
|
|
512
|
-
key: bare2.readData(bc),
|
|
513
|
-
value: bare2.readData(bc)
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
function writeActorKvEntry(bc, x) {
|
|
517
|
-
bare2.writeData(bc, x.key);
|
|
518
|
-
bare2.writeData(bc, x.value);
|
|
519
|
-
}
|
|
520
|
-
function read02(bc) {
|
|
521
|
-
const len = bare2.readUintSafe(bc);
|
|
522
|
-
if (len === 0) {
|
|
523
|
-
return [];
|
|
524
|
-
}
|
|
525
|
-
const result = [bare2.readString(bc)];
|
|
526
|
-
for (let i = 1; i < len; i++) {
|
|
527
|
-
result[i] = bare2.readString(bc);
|
|
528
|
-
}
|
|
529
|
-
return result;
|
|
530
|
-
}
|
|
531
|
-
function write02(bc, x) {
|
|
532
|
-
bare2.writeUintSafe(bc, x.length);
|
|
533
|
-
for (let i = 0; i < x.length; i++) {
|
|
534
|
-
bare2.writeString(bc, x[i]);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
function read1(bc) {
|
|
538
|
-
const len = bare2.readUintSafe(bc);
|
|
539
|
-
if (len === 0) {
|
|
540
|
-
return [];
|
|
541
|
-
}
|
|
542
|
-
const result = [readActorKvEntry(bc)];
|
|
543
|
-
for (let i = 1; i < len; i++) {
|
|
544
|
-
result[i] = readActorKvEntry(bc);
|
|
545
|
-
}
|
|
546
|
-
return result;
|
|
547
|
-
}
|
|
548
|
-
function write1(bc, x) {
|
|
549
|
-
bare2.writeUintSafe(bc, x.length);
|
|
550
|
-
for (let i = 0; i < x.length; i++) {
|
|
551
|
-
writeActorKvEntry(bc, x[i]);
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
function readActorState2(bc) {
|
|
555
|
-
return {
|
|
556
|
-
actorId: bare2.readString(bc),
|
|
557
|
-
name: bare2.readString(bc),
|
|
558
|
-
key: read02(bc),
|
|
559
|
-
kvStorage: read1(bc),
|
|
560
|
-
createdAt: bare2.readU64(bc)
|
|
561
|
-
};
|
|
562
|
-
}
|
|
563
|
-
function writeActorState2(bc, x) {
|
|
564
|
-
bare2.writeString(bc, x.actorId);
|
|
565
|
-
bare2.writeString(bc, x.name);
|
|
566
|
-
write02(bc, x.key);
|
|
567
|
-
write1(bc, x.kvStorage);
|
|
568
|
-
bare2.writeU64(bc, x.createdAt);
|
|
569
|
-
}
|
|
570
|
-
function encodeActorState2(x) {
|
|
571
|
-
const bc = new bare2.ByteCursor(
|
|
572
|
-
new Uint8Array(config2.initialBufferLength),
|
|
573
|
-
config2
|
|
574
|
-
);
|
|
575
|
-
writeActorState2(bc, x);
|
|
576
|
-
return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
|
|
577
|
-
}
|
|
578
|
-
function decodeActorState2(bytes) {
|
|
579
|
-
const bc = new bare2.ByteCursor(bytes, config2);
|
|
580
|
-
const result = readActorState2(bc);
|
|
581
|
-
if (bc.offset < bc.view.byteLength) {
|
|
582
|
-
throw new bare2.BareError(bc.offset, "remaining bytes");
|
|
583
|
-
}
|
|
584
|
-
return result;
|
|
585
|
-
}
|
|
586
|
-
function readActorAlarm2(bc) {
|
|
587
|
-
return {
|
|
588
|
-
actorId: bare2.readString(bc),
|
|
589
|
-
timestamp: bare2.readUint(bc)
|
|
590
|
-
};
|
|
591
|
-
}
|
|
592
|
-
function writeActorAlarm2(bc, x) {
|
|
593
|
-
bare2.writeString(bc, x.actorId);
|
|
594
|
-
bare2.writeUint(bc, x.timestamp);
|
|
595
|
-
}
|
|
596
|
-
function encodeActorAlarm2(x) {
|
|
597
|
-
const bc = new bare2.ByteCursor(
|
|
598
|
-
new Uint8Array(config2.initialBufferLength),
|
|
599
|
-
config2
|
|
600
|
-
);
|
|
601
|
-
writeActorAlarm2(bc, x);
|
|
602
|
-
return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
|
|
603
|
-
}
|
|
604
|
-
function decodeActorAlarm2(bytes) {
|
|
605
|
-
const bc = new bare2.ByteCursor(bytes, config2);
|
|
606
|
-
const result = readActorAlarm2(bc);
|
|
607
|
-
if (bc.offset < bc.view.byteLength) {
|
|
608
|
-
throw new bare2.BareError(bc.offset, "remaining bytes");
|
|
609
|
-
}
|
|
610
|
-
return result;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
// dist/schemas/file-system-driver/v3.ts
|
|
614
|
-
import * as bare3 from "@rivetkit/bare-ts";
|
|
615
|
-
var config3 = /* @__PURE__ */ bare3.Config({});
|
|
616
|
-
function readActorKvEntry2(bc) {
|
|
617
|
-
return {
|
|
618
|
-
key: bare3.readData(bc),
|
|
619
|
-
value: bare3.readData(bc)
|
|
620
|
-
};
|
|
621
|
-
}
|
|
622
|
-
function writeActorKvEntry2(bc, x) {
|
|
623
|
-
bare3.writeData(bc, x.key);
|
|
624
|
-
bare3.writeData(bc, x.value);
|
|
625
|
-
}
|
|
626
|
-
function read03(bc) {
|
|
627
|
-
const len = bare3.readUintSafe(bc);
|
|
628
|
-
if (len === 0) {
|
|
629
|
-
return [];
|
|
630
|
-
}
|
|
631
|
-
const result = [bare3.readString(bc)];
|
|
632
|
-
for (let i = 1; i < len; i++) {
|
|
633
|
-
result[i] = bare3.readString(bc);
|
|
634
|
-
}
|
|
635
|
-
return result;
|
|
636
|
-
}
|
|
637
|
-
function write03(bc, x) {
|
|
638
|
-
bare3.writeUintSafe(bc, x.length);
|
|
639
|
-
for (let i = 0; i < x.length; i++) {
|
|
640
|
-
bare3.writeString(bc, x[i]);
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
function read12(bc) {
|
|
644
|
-
const len = bare3.readUintSafe(bc);
|
|
645
|
-
if (len === 0) {
|
|
646
|
-
return [];
|
|
647
|
-
}
|
|
648
|
-
const result = [readActorKvEntry2(bc)];
|
|
649
|
-
for (let i = 1; i < len; i++) {
|
|
650
|
-
result[i] = readActorKvEntry2(bc);
|
|
651
|
-
}
|
|
652
|
-
return result;
|
|
653
|
-
}
|
|
654
|
-
function write12(bc, x) {
|
|
655
|
-
bare3.writeUintSafe(bc, x.length);
|
|
656
|
-
for (let i = 0; i < x.length; i++) {
|
|
657
|
-
writeActorKvEntry2(bc, x[i]);
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
function read2(bc) {
|
|
661
|
-
return bare3.readBool(bc) ? bare3.readU64(bc) : null;
|
|
662
|
-
}
|
|
663
|
-
function write2(bc, x) {
|
|
664
|
-
bare3.writeBool(bc, x !== null);
|
|
665
|
-
if (x !== null) {
|
|
666
|
-
bare3.writeU64(bc, x);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
function readActorState3(bc) {
|
|
670
|
-
return {
|
|
671
|
-
actorId: bare3.readString(bc),
|
|
672
|
-
name: bare3.readString(bc),
|
|
673
|
-
key: read03(bc),
|
|
674
|
-
kvStorage: read12(bc),
|
|
675
|
-
createdAt: bare3.readU64(bc),
|
|
676
|
-
startTs: read2(bc),
|
|
677
|
-
connectableTs: read2(bc),
|
|
678
|
-
sleepTs: read2(bc),
|
|
679
|
-
destroyTs: read2(bc)
|
|
680
|
-
};
|
|
681
|
-
}
|
|
682
|
-
function writeActorState3(bc, x) {
|
|
683
|
-
bare3.writeString(bc, x.actorId);
|
|
684
|
-
bare3.writeString(bc, x.name);
|
|
685
|
-
write03(bc, x.key);
|
|
686
|
-
write12(bc, x.kvStorage);
|
|
687
|
-
bare3.writeU64(bc, x.createdAt);
|
|
688
|
-
write2(bc, x.startTs);
|
|
689
|
-
write2(bc, x.connectableTs);
|
|
690
|
-
write2(bc, x.sleepTs);
|
|
691
|
-
write2(bc, x.destroyTs);
|
|
692
|
-
}
|
|
693
|
-
function encodeActorState3(x) {
|
|
694
|
-
const bc = new bare3.ByteCursor(
|
|
695
|
-
new Uint8Array(config3.initialBufferLength),
|
|
696
|
-
config3
|
|
697
|
-
);
|
|
698
|
-
writeActorState3(bc, x);
|
|
699
|
-
return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
|
|
700
|
-
}
|
|
701
|
-
function decodeActorState3(bytes) {
|
|
702
|
-
const bc = new bare3.ByteCursor(bytes, config3);
|
|
703
|
-
const result = readActorState3(bc);
|
|
704
|
-
if (bc.offset < bc.view.byteLength) {
|
|
705
|
-
throw new bare3.BareError(bc.offset, "remaining bytes");
|
|
706
|
-
}
|
|
707
|
-
return result;
|
|
708
|
-
}
|
|
709
|
-
function readActorAlarm3(bc) {
|
|
710
|
-
return {
|
|
711
|
-
actorId: bare3.readString(bc),
|
|
712
|
-
timestamp: bare3.readUint(bc)
|
|
713
|
-
};
|
|
714
|
-
}
|
|
715
|
-
function writeActorAlarm3(bc, x) {
|
|
716
|
-
bare3.writeString(bc, x.actorId);
|
|
717
|
-
bare3.writeUint(bc, x.timestamp);
|
|
718
|
-
}
|
|
719
|
-
function encodeActorAlarm3(x) {
|
|
720
|
-
const bc = new bare3.ByteCursor(
|
|
721
|
-
new Uint8Array(config3.initialBufferLength),
|
|
722
|
-
config3
|
|
723
|
-
);
|
|
724
|
-
writeActorAlarm3(bc, x);
|
|
725
|
-
return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
|
|
726
|
-
}
|
|
727
|
-
function decodeActorAlarm3(bytes) {
|
|
728
|
-
const bc = new bare3.ByteCursor(bytes, config3);
|
|
729
|
-
const result = readActorAlarm3(bc);
|
|
730
|
-
if (bc.offset < bc.view.byteLength) {
|
|
731
|
-
throw new bare3.BareError(bc.offset, "remaining bytes");
|
|
732
|
-
}
|
|
733
|
-
return result;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
// src/schemas/file-system-driver/versioned.ts
|
|
737
|
-
var CURRENT_VERSION = 3;
|
|
738
|
-
var v1ToV2 = (v1State) => {
|
|
739
|
-
const kvStorage = [];
|
|
740
|
-
if (v1State.persistedData) {
|
|
741
|
-
const key = new Uint8Array([1]);
|
|
742
|
-
kvStorage.push({
|
|
743
|
-
key: bufferToArrayBuffer(key),
|
|
744
|
-
value: v1State.persistedData
|
|
745
|
-
});
|
|
746
|
-
}
|
|
747
|
-
return {
|
|
748
|
-
actorId: v1State.actorId,
|
|
749
|
-
name: v1State.name,
|
|
750
|
-
key: v1State.key,
|
|
751
|
-
kvStorage,
|
|
752
|
-
createdAt: v1State.createdAt
|
|
753
|
-
};
|
|
754
|
-
};
|
|
755
|
-
var v2ToV3 = (v2State) => {
|
|
756
|
-
return {
|
|
757
|
-
actorId: v2State.actorId,
|
|
758
|
-
name: v2State.name,
|
|
759
|
-
key: v2State.key,
|
|
760
|
-
kvStorage: v2State.kvStorage,
|
|
761
|
-
createdAt: v2State.createdAt,
|
|
762
|
-
startTs: null,
|
|
763
|
-
connectableTs: null,
|
|
764
|
-
sleepTs: null,
|
|
765
|
-
destroyTs: null
|
|
766
|
-
};
|
|
767
|
-
};
|
|
768
|
-
var v3ToV2 = (v3State) => {
|
|
769
|
-
return {
|
|
770
|
-
actorId: v3State.actorId,
|
|
771
|
-
name: v3State.name,
|
|
772
|
-
key: v3State.key,
|
|
773
|
-
kvStorage: v3State.kvStorage,
|
|
774
|
-
createdAt: v3State.createdAt
|
|
775
|
-
};
|
|
776
|
-
};
|
|
777
|
-
var v2ToV1 = (v2State) => {
|
|
778
|
-
const persistDataEntry = v2State.kvStorage.find((entry) => {
|
|
779
|
-
const key = new Uint8Array(entry.key);
|
|
780
|
-
return key.length === 1 && key[0] === 1;
|
|
781
|
-
});
|
|
782
|
-
return {
|
|
783
|
-
actorId: v2State.actorId,
|
|
784
|
-
name: v2State.name,
|
|
785
|
-
key: v2State.key,
|
|
786
|
-
persistedData: (persistDataEntry == null ? void 0 : persistDataEntry.value) || new ArrayBuffer(0),
|
|
787
|
-
createdAt: v2State.createdAt
|
|
788
|
-
};
|
|
789
|
-
};
|
|
790
|
-
var ACTOR_STATE_VERSIONED = createVersionedDataHandler({
|
|
791
|
-
deserializeVersion: (bytes, version) => {
|
|
792
|
-
switch (version) {
|
|
793
|
-
case 1:
|
|
794
|
-
return decodeActorState(bytes);
|
|
795
|
-
case 2:
|
|
796
|
-
return decodeActorState2(bytes);
|
|
797
|
-
case 3:
|
|
798
|
-
return decodeActorState3(bytes);
|
|
799
|
-
default:
|
|
800
|
-
throw new Error(`Unknown version ${version}`);
|
|
801
|
-
}
|
|
802
|
-
},
|
|
803
|
-
serializeVersion: (data, version) => {
|
|
804
|
-
switch (version) {
|
|
805
|
-
case 1:
|
|
806
|
-
return encodeActorState(data);
|
|
807
|
-
case 2:
|
|
808
|
-
return encodeActorState2(data);
|
|
809
|
-
case 3:
|
|
810
|
-
return encodeActorState3(data);
|
|
811
|
-
default:
|
|
812
|
-
throw new Error(`Unknown version ${version}`);
|
|
813
|
-
}
|
|
814
|
-
},
|
|
815
|
-
deserializeConverters: () => [v1ToV2, v2ToV3],
|
|
816
|
-
serializeConverters: () => [v3ToV2, v2ToV1]
|
|
817
|
-
});
|
|
818
|
-
var ACTOR_ALARM_VERSIONED = createVersionedDataHandler({
|
|
819
|
-
deserializeVersion: (bytes, version) => {
|
|
820
|
-
switch (version) {
|
|
821
|
-
case 1:
|
|
822
|
-
return decodeActorAlarm(bytes);
|
|
823
|
-
case 2:
|
|
824
|
-
return decodeActorAlarm2(bytes);
|
|
825
|
-
case 3:
|
|
826
|
-
return decodeActorAlarm3(bytes);
|
|
827
|
-
default:
|
|
828
|
-
throw new Error(`Unknown version ${version}`);
|
|
829
|
-
}
|
|
830
|
-
},
|
|
831
|
-
serializeVersion: (data, version) => {
|
|
832
|
-
switch (version) {
|
|
833
|
-
case 1:
|
|
834
|
-
return encodeActorAlarm(data);
|
|
835
|
-
case 2:
|
|
836
|
-
return encodeActorAlarm2(data);
|
|
837
|
-
case 3:
|
|
838
|
-
return encodeActorAlarm3(data);
|
|
839
|
-
default:
|
|
840
|
-
throw new Error(`Unknown version ${version}`);
|
|
841
|
-
}
|
|
842
|
-
},
|
|
843
|
-
deserializeConverters: () => [],
|
|
844
|
-
serializeConverters: () => []
|
|
845
|
-
});
|
|
846
|
-
|
|
847
|
-
// src/drivers/file-system/log.ts
|
|
848
|
-
function logger2() {
|
|
849
|
-
return getLogger("driver-fs");
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
// src/drivers/file-system/utils.ts
|
|
853
|
-
function generateActorId(name, key) {
|
|
854
|
-
const jsonString = JSON.stringify([name, key]);
|
|
855
|
-
const crypto2 = getNodeCrypto();
|
|
856
|
-
const hash = crypto2.createHash("sha256").update(jsonString).digest("hex").substring(0, 16);
|
|
857
|
-
return hash;
|
|
858
|
-
}
|
|
859
|
-
function createHashForPath(dirPath) {
|
|
860
|
-
const path = getNodePath();
|
|
861
|
-
const normalizedPath = path.normalize(dirPath);
|
|
862
|
-
const lastComponent = path.basename(normalizedPath);
|
|
863
|
-
const crypto2 = getNodeCrypto();
|
|
864
|
-
const hash = crypto2.createHash("sha256").update(normalizedPath).digest("hex").substring(0, 8);
|
|
865
|
-
return `${lastComponent}-${hash}`;
|
|
866
|
-
}
|
|
867
|
-
function getStoragePath() {
|
|
868
|
-
const dataPath = getDataPath("rivetkit");
|
|
869
|
-
const dirHash = createHashForPath(process.cwd());
|
|
870
|
-
const path = getNodePath();
|
|
871
|
-
return path.join(dataPath, dirHash);
|
|
872
|
-
}
|
|
873
|
-
async function pathExists(path) {
|
|
874
|
-
try {
|
|
875
|
-
const fs = getNodeFs();
|
|
876
|
-
await fs.access(path);
|
|
877
|
-
return true;
|
|
878
|
-
} catch {
|
|
879
|
-
return false;
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
async function ensureDirectoryExists(directoryPath) {
|
|
883
|
-
if (!await pathExists(directoryPath)) {
|
|
884
|
-
const fs = getNodeFs();
|
|
885
|
-
await fs.mkdir(directoryPath, { recursive: true });
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
function ensureDirectoryExistsSync(directoryPath) {
|
|
889
|
-
const fsSync = getNodeFsSync();
|
|
890
|
-
if (!fsSync.existsSync(directoryPath)) {
|
|
891
|
-
fsSync.mkdirSync(directoryPath, { recursive: true });
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
function getDataPath(appName) {
|
|
895
|
-
const platform = process.platform;
|
|
896
|
-
const os = getNodeOs();
|
|
897
|
-
const homeDir = os.homedir();
|
|
898
|
-
const path = getNodePath();
|
|
899
|
-
switch (platform) {
|
|
900
|
-
case "win32":
|
|
901
|
-
return path.join(
|
|
902
|
-
process.env.APPDATA || path.join(homeDir, "AppData", "Roaming"),
|
|
903
|
-
appName
|
|
904
|
-
);
|
|
905
|
-
case "darwin":
|
|
906
|
-
return path.join(
|
|
907
|
-
homeDir,
|
|
908
|
-
"Library",
|
|
909
|
-
"Application Support",
|
|
910
|
-
appName
|
|
911
|
-
);
|
|
912
|
-
default:
|
|
913
|
-
return path.join(
|
|
914
|
-
process.env.XDG_DATA_HOME || path.join(homeDir, ".local", "share"),
|
|
915
|
-
appName
|
|
916
|
-
);
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
// src/drivers/file-system/global-state.ts
|
|
921
|
-
var FileSystemGlobalState = class {
|
|
922
|
-
#storagePath;
|
|
923
|
-
#stateDir;
|
|
924
|
-
#dbsDir;
|
|
925
|
-
#alarmsDir;
|
|
926
|
-
#persist;
|
|
927
|
-
// IMPORTANT: Never delete from this map. Doing so will result in race
|
|
928
|
-
// conditions since the actor generation will cease to be tracked
|
|
929
|
-
// correctly. Always increment generation if a new actor is created.
|
|
930
|
-
#actors = /* @__PURE__ */ new Map();
|
|
931
|
-
#actorCountOnStartup = 0;
|
|
932
|
-
#runnerParams;
|
|
933
|
-
get persist() {
|
|
934
|
-
return this.#persist;
|
|
935
|
-
}
|
|
936
|
-
get storagePath() {
|
|
937
|
-
return this.#storagePath;
|
|
938
|
-
}
|
|
939
|
-
get actorCountOnStartup() {
|
|
940
|
-
return this.#actorCountOnStartup;
|
|
941
|
-
}
|
|
942
|
-
constructor(persist = true, customPath) {
|
|
943
|
-
this.#persist = persist;
|
|
944
|
-
this.#storagePath = persist ? customPath ?? getStoragePath() : "/tmp";
|
|
945
|
-
const path = getNodePath();
|
|
946
|
-
this.#stateDir = path.join(this.#storagePath, "state");
|
|
947
|
-
this.#dbsDir = path.join(this.#storagePath, "databases");
|
|
948
|
-
this.#alarmsDir = path.join(this.#storagePath, "alarms");
|
|
949
|
-
if (this.#persist) {
|
|
950
|
-
ensureDirectoryExistsSync(this.#stateDir);
|
|
951
|
-
ensureDirectoryExistsSync(this.#dbsDir);
|
|
952
|
-
ensureDirectoryExistsSync(this.#alarmsDir);
|
|
953
|
-
try {
|
|
954
|
-
const fsSync = getNodeFsSync();
|
|
955
|
-
const actorIds = fsSync.readdirSync(this.#stateDir);
|
|
956
|
-
this.#actorCountOnStartup = actorIds.length;
|
|
957
|
-
} catch (error) {
|
|
958
|
-
logger2().error({ msg: "failed to count actors", error });
|
|
959
|
-
}
|
|
960
|
-
logger2().debug({
|
|
961
|
-
msg: "file system driver ready",
|
|
962
|
-
dir: this.#storagePath,
|
|
963
|
-
actorCount: this.#actorCountOnStartup
|
|
964
|
-
});
|
|
965
|
-
try {
|
|
966
|
-
this.#cleanupTempFilesSync();
|
|
967
|
-
} catch (err) {
|
|
968
|
-
logger2().error({
|
|
969
|
-
msg: "failed to cleanup temp files",
|
|
970
|
-
error: err
|
|
971
|
-
});
|
|
972
|
-
}
|
|
973
|
-
} else {
|
|
974
|
-
logger2().debug({ msg: "memory driver ready" });
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
getActorStatePath(actorId) {
|
|
978
|
-
return getNodePath().join(this.#stateDir, actorId);
|
|
979
|
-
}
|
|
980
|
-
getActorDbPath(actorId) {
|
|
981
|
-
return getNodePath().join(this.#dbsDir, `${actorId}.db`);
|
|
982
|
-
}
|
|
983
|
-
getActorAlarmPath(actorId) {
|
|
984
|
-
return getNodePath().join(this.#alarmsDir, actorId);
|
|
985
|
-
}
|
|
986
|
-
async *getActorsIterator(params) {
|
|
987
|
-
let actorIds = Array.from(this.#actors.keys()).sort();
|
|
988
|
-
const fsSync = getNodeFsSync();
|
|
989
|
-
if (fsSync.existsSync(this.#stateDir)) {
|
|
990
|
-
actorIds = fsSync.readdirSync(this.#stateDir).filter((id) => !id.includes(".tmp")).sort();
|
|
991
|
-
}
|
|
992
|
-
const startIndex = params.cursor ? actorIds.indexOf(params.cursor) + 1 : 0;
|
|
993
|
-
for (let i = startIndex; i < actorIds.length; i++) {
|
|
994
|
-
const actorId = actorIds[i];
|
|
995
|
-
if (!actorId) {
|
|
996
|
-
continue;
|
|
997
|
-
}
|
|
998
|
-
try {
|
|
999
|
-
const state = await this.loadActorStateOrError(actorId);
|
|
1000
|
-
yield state;
|
|
1001
|
-
} catch (error) {
|
|
1002
|
-
logger2().error({
|
|
1003
|
-
msg: "failed to load actor state",
|
|
1004
|
-
actorId,
|
|
1005
|
-
error
|
|
1006
|
-
});
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
/**
|
|
1011
|
-
* Ensures an entry exists for this actor.
|
|
1012
|
-
*
|
|
1013
|
-
* Used for #createActor and #loadActor.
|
|
1014
|
-
*/
|
|
1015
|
-
#upsertEntry(actorId) {
|
|
1016
|
-
let entry = this.#actors.get(actorId);
|
|
1017
|
-
if (entry) {
|
|
1018
|
-
return entry;
|
|
1019
|
-
}
|
|
1020
|
-
entry = {
|
|
1021
|
-
id: actorId,
|
|
1022
|
-
lifecycleState: 0 /* NONEXISTENT */,
|
|
1023
|
-
generation: crypto.randomUUID()
|
|
1024
|
-
};
|
|
1025
|
-
this.#actors.set(actorId, entry);
|
|
1026
|
-
return entry;
|
|
1027
|
-
}
|
|
1028
|
-
/**
|
|
1029
|
-
* Creates a new actor and writes to file system.
|
|
1030
|
-
*/
|
|
1031
|
-
async createActor(actorId, name, key, input) {
|
|
1032
|
-
const entry = this.#upsertEntry(actorId);
|
|
1033
|
-
if (entry.state) {
|
|
1034
|
-
throw new ActorDuplicateKey(name, key);
|
|
1035
|
-
}
|
|
1036
|
-
if (this.isActorStopping(actorId)) {
|
|
1037
|
-
throw new Error(`Actor ${actorId} is stopping`);
|
|
1038
|
-
}
|
|
1039
|
-
if (entry.lifecycleState === 4 /* DESTROYED */) {
|
|
1040
|
-
entry.lifecycleState = 0 /* NONEXISTENT */;
|
|
1041
|
-
entry.generation = crypto.randomUUID();
|
|
1042
|
-
}
|
|
1043
|
-
const kvStorage = [];
|
|
1044
|
-
const initialKvState = getInitialActorKvState(input);
|
|
1045
|
-
for (const [key2, value] of initialKvState) {
|
|
1046
|
-
kvStorage.push({
|
|
1047
|
-
key: bufferToArrayBuffer(key2),
|
|
1048
|
-
value: bufferToArrayBuffer(value)
|
|
1049
|
-
});
|
|
1050
|
-
}
|
|
1051
|
-
entry.state = {
|
|
1052
|
-
actorId,
|
|
1053
|
-
name,
|
|
1054
|
-
key,
|
|
1055
|
-
createdAt: BigInt(Date.now()),
|
|
1056
|
-
kvStorage,
|
|
1057
|
-
startTs: null,
|
|
1058
|
-
connectableTs: null,
|
|
1059
|
-
sleepTs: null,
|
|
1060
|
-
destroyTs: null
|
|
1061
|
-
};
|
|
1062
|
-
entry.lifecycleState = 1 /* AWAKE */;
|
|
1063
|
-
await this.writeActor(actorId, entry.generation, entry.state);
|
|
1064
|
-
return entry;
|
|
1065
|
-
}
|
|
1066
|
-
/**
|
|
1067
|
-
* Loads the actor from disk or returns the existing actor entry. This will return an entry even if the actor does not actually exist.
|
|
1068
|
-
*/
|
|
1069
|
-
async loadActor(actorId) {
|
|
1070
|
-
const entry = this.#upsertEntry(actorId);
|
|
1071
|
-
if (entry.lifecycleState === 4 /* DESTROYED */) {
|
|
1072
|
-
return entry;
|
|
1073
|
-
}
|
|
1074
|
-
if (entry.state) {
|
|
1075
|
-
return entry;
|
|
1076
|
-
}
|
|
1077
|
-
if (!this.#persist) {
|
|
1078
|
-
return entry;
|
|
1079
|
-
}
|
|
1080
|
-
if (entry.loadPromise) {
|
|
1081
|
-
await entry.loadPromise;
|
|
1082
|
-
return entry;
|
|
1083
|
-
}
|
|
1084
|
-
entry.loadPromise = this.loadActorState(entry);
|
|
1085
|
-
return entry.loadPromise;
|
|
1086
|
-
}
|
|
1087
|
-
async loadActorState(entry) {
|
|
1088
|
-
const stateFilePath = this.getActorStatePath(entry.id);
|
|
1089
|
-
try {
|
|
1090
|
-
const fs = getNodeFs();
|
|
1091
|
-
const stateData = await fs.readFile(stateFilePath);
|
|
1092
|
-
entry.state = ACTOR_STATE_VERSIONED.deserializeWithEmbeddedVersion(
|
|
1093
|
-
new Uint8Array(stateData)
|
|
1094
|
-
);
|
|
1095
|
-
return entry;
|
|
1096
|
-
} catch (innerError) {
|
|
1097
|
-
if (innerError.code === "ENOENT") {
|
|
1098
|
-
entry.loadPromise = void 0;
|
|
1099
|
-
return entry;
|
|
1100
|
-
}
|
|
1101
|
-
const error = new Error(
|
|
1102
|
-
`Failed to load actor state: ${innerError}`
|
|
1103
|
-
);
|
|
1104
|
-
throw error;
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
|
-
async loadOrCreateActor(actorId, name, key, input) {
|
|
1108
|
-
const entry = await this.loadActor(actorId);
|
|
1109
|
-
if (!entry.state) {
|
|
1110
|
-
if (this.isActorStopping(actorId)) {
|
|
1111
|
-
throw new Error(`Actor ${actorId} stopping`);
|
|
1112
|
-
}
|
|
1113
|
-
if (entry.lifecycleState === 4 /* DESTROYED */) {
|
|
1114
|
-
entry.lifecycleState = 0 /* NONEXISTENT */;
|
|
1115
|
-
entry.generation = crypto.randomUUID();
|
|
1116
|
-
}
|
|
1117
|
-
const kvStorage = [];
|
|
1118
|
-
const initialKvState = getInitialActorKvState(input);
|
|
1119
|
-
for (const [key2, value] of initialKvState) {
|
|
1120
|
-
kvStorage.push({
|
|
1121
|
-
key: bufferToArrayBuffer(key2),
|
|
1122
|
-
value: bufferToArrayBuffer(value)
|
|
1123
|
-
});
|
|
1124
|
-
}
|
|
1125
|
-
entry.state = {
|
|
1126
|
-
actorId,
|
|
1127
|
-
name,
|
|
1128
|
-
key,
|
|
1129
|
-
createdAt: BigInt(Date.now()),
|
|
1130
|
-
kvStorage,
|
|
1131
|
-
startTs: null,
|
|
1132
|
-
connectableTs: null,
|
|
1133
|
-
sleepTs: null,
|
|
1134
|
-
destroyTs: null
|
|
1135
|
-
};
|
|
1136
|
-
await this.writeActor(actorId, entry.generation, entry.state);
|
|
1137
|
-
}
|
|
1138
|
-
return entry;
|
|
1139
|
-
}
|
|
1140
|
-
async sleepActor(actorId) {
|
|
1141
|
-
var _a;
|
|
1142
|
-
invariant(
|
|
1143
|
-
this.#persist,
|
|
1144
|
-
"cannot sleep actor with memory driver, must use file system driver"
|
|
1145
|
-
);
|
|
1146
|
-
const actor = this.#upsertEntry(actorId);
|
|
1147
|
-
invariant(actor, `tried to sleep ${actorId}, does not exist`);
|
|
1148
|
-
if (this.isActorStopping(actorId)) {
|
|
1149
|
-
return;
|
|
1150
|
-
}
|
|
1151
|
-
actor.lifecycleState = 2 /* STARTING_SLEEP */;
|
|
1152
|
-
if (actor.loadPromise) await actor.loadPromise.catch();
|
|
1153
|
-
if ((_a = actor.startPromise) == null ? void 0 : _a.promise)
|
|
1154
|
-
await actor.startPromise.promise.catch();
|
|
1155
|
-
if (actor.state) {
|
|
1156
|
-
actor.state = {
|
|
1157
|
-
...actor.state,
|
|
1158
|
-
sleepTs: BigInt(Date.now())
|
|
1159
|
-
};
|
|
1160
|
-
await this.writeActor(actorId, actor.generation, actor.state);
|
|
1161
|
-
}
|
|
1162
|
-
invariant(actor.actor, "actor should be loaded");
|
|
1163
|
-
await actor.actor.onStop("sleep");
|
|
1164
|
-
this.#actors.delete(actorId);
|
|
1165
|
-
}
|
|
1166
|
-
async destroyActor(actorId) {
|
|
1167
|
-
var _a;
|
|
1168
|
-
const actor = this.#upsertEntry(actorId);
|
|
1169
|
-
if (this.isActorStopping(actorId)) {
|
|
1170
|
-
return;
|
|
1171
|
-
}
|
|
1172
|
-
actor.lifecycleState = 3 /* STARTING_DESTROY */;
|
|
1173
|
-
if (actor.loadPromise) await actor.loadPromise.catch();
|
|
1174
|
-
if ((_a = actor.startPromise) == null ? void 0 : _a.promise)
|
|
1175
|
-
await actor.startPromise.promise.catch();
|
|
1176
|
-
if (actor.state) {
|
|
1177
|
-
actor.state = {
|
|
1178
|
-
...actor.state,
|
|
1179
|
-
destroyTs: BigInt(Date.now())
|
|
1180
|
-
};
|
|
1181
|
-
await this.writeActor(actorId, actor.generation, actor.state);
|
|
1182
|
-
}
|
|
1183
|
-
if (actor.actor) {
|
|
1184
|
-
await actor.actor.onStop("destroy");
|
|
1185
|
-
}
|
|
1186
|
-
if (actor.alarmTimeout) {
|
|
1187
|
-
actor.alarmTimeout.abort();
|
|
1188
|
-
}
|
|
1189
|
-
if (this.#persist) {
|
|
1190
|
-
const fs = getNodeFs();
|
|
1191
|
-
await Promise.all([
|
|
1192
|
-
// Delete actor state file
|
|
1193
|
-
(async () => {
|
|
1194
|
-
try {
|
|
1195
|
-
await fs.unlink(this.getActorStatePath(actorId));
|
|
1196
|
-
} catch (err) {
|
|
1197
|
-
if ((err == null ? void 0 : err.code) !== "ENOENT") {
|
|
1198
|
-
logger2().error({
|
|
1199
|
-
msg: "failed to delete actor state file",
|
|
1200
|
-
actorId,
|
|
1201
|
-
error: stringifyError(err)
|
|
1202
|
-
});
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
})(),
|
|
1206
|
-
// Delete actor database file
|
|
1207
|
-
(async () => {
|
|
1208
|
-
try {
|
|
1209
|
-
await fs.unlink(this.getActorDbPath(actorId));
|
|
1210
|
-
} catch (err) {
|
|
1211
|
-
if ((err == null ? void 0 : err.code) !== "ENOENT") {
|
|
1212
|
-
logger2().error({
|
|
1213
|
-
msg: "failed to delete actor database file",
|
|
1214
|
-
actorId,
|
|
1215
|
-
error: stringifyError(err)
|
|
1216
|
-
});
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
})(),
|
|
1220
|
-
// Delete actor alarm file
|
|
1221
|
-
(async () => {
|
|
1222
|
-
try {
|
|
1223
|
-
await fs.unlink(this.getActorAlarmPath(actorId));
|
|
1224
|
-
} catch (err) {
|
|
1225
|
-
if ((err == null ? void 0 : err.code) !== "ENOENT") {
|
|
1226
|
-
logger2().error({
|
|
1227
|
-
msg: "failed to delete actor alarm file",
|
|
1228
|
-
actorId,
|
|
1229
|
-
error: stringifyError(err)
|
|
1230
|
-
});
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
})()
|
|
1234
|
-
]);
|
|
1235
|
-
}
|
|
1236
|
-
actor.state = void 0;
|
|
1237
|
-
actor.loadPromise = void 0;
|
|
1238
|
-
actor.actor = void 0;
|
|
1239
|
-
actor.startPromise = void 0;
|
|
1240
|
-
actor.alarmTimeout = void 0;
|
|
1241
|
-
actor.alarmTimeout = void 0;
|
|
1242
|
-
actor.pendingWriteResolver = void 0;
|
|
1243
|
-
actor.lifecycleState = 4 /* DESTROYED */;
|
|
1244
|
-
}
|
|
1245
|
-
/**
|
|
1246
|
-
* Save actor state to disk.
|
|
1247
|
-
*/
|
|
1248
|
-
async writeActor(actorId, generation, state) {
|
|
1249
|
-
if (!this.#persist) {
|
|
1250
|
-
return;
|
|
1251
|
-
}
|
|
1252
|
-
const entry = this.#actors.get(actorId);
|
|
1253
|
-
invariant(entry, "actor entry does not exist");
|
|
1254
|
-
await this.#performWrite(actorId, generation, state);
|
|
1255
|
-
}
|
|
1256
|
-
isGenerationCurrentAndNotDestroyed(actorId, generation) {
|
|
1257
|
-
const entry = this.#upsertEntry(actorId);
|
|
1258
|
-
if (!entry) return false;
|
|
1259
|
-
return entry.generation === generation && entry.lifecycleState !== 3 /* STARTING_DESTROY */;
|
|
1260
|
-
}
|
|
1261
|
-
isActorStopping(actorId) {
|
|
1262
|
-
const entry = this.#upsertEntry(actorId);
|
|
1263
|
-
if (!entry) return false;
|
|
1264
|
-
return entry.lifecycleState === 2 /* STARTING_SLEEP */ || entry.lifecycleState === 3 /* STARTING_DESTROY */;
|
|
1265
|
-
}
|
|
1266
|
-
async setActorAlarm(actorId, timestamp) {
|
|
1267
|
-
const entry = this.#actors.get(actorId);
|
|
1268
|
-
invariant(entry, "actor entry does not exist");
|
|
1269
|
-
const writeGeneration = entry.generation;
|
|
1270
|
-
if (this.isActorStopping(actorId)) {
|
|
1271
|
-
logger2().info("skipping set alarm since actor stopping");
|
|
1272
|
-
return;
|
|
1273
|
-
}
|
|
1274
|
-
if (this.#persist) {
|
|
1275
|
-
const alarmPath = this.getActorAlarmPath(actorId);
|
|
1276
|
-
const crypto2 = getNodeCrypto();
|
|
1277
|
-
const tempPath = `${alarmPath}.tmp.${crypto2.randomUUID()}`;
|
|
1278
|
-
try {
|
|
1279
|
-
const path = getNodePath();
|
|
1280
|
-
await ensureDirectoryExists(path.dirname(alarmPath));
|
|
1281
|
-
const alarmData = {
|
|
1282
|
-
actorId,
|
|
1283
|
-
timestamp: BigInt(timestamp)
|
|
1284
|
-
};
|
|
1285
|
-
const data = ACTOR_ALARM_VERSIONED.serializeWithEmbeddedVersion(
|
|
1286
|
-
alarmData,
|
|
1287
|
-
CURRENT_VERSION
|
|
1288
|
-
);
|
|
1289
|
-
const fs = getNodeFs();
|
|
1290
|
-
await fs.writeFile(tempPath, data);
|
|
1291
|
-
if (!this.isGenerationCurrentAndNotDestroyed(
|
|
1292
|
-
actorId,
|
|
1293
|
-
writeGeneration
|
|
1294
|
-
)) {
|
|
1295
|
-
logger2().debug(
|
|
1296
|
-
"skipping writing alarm since actor destroying or new generation"
|
|
1297
|
-
);
|
|
1298
|
-
return;
|
|
1299
|
-
}
|
|
1300
|
-
await fs.rename(tempPath, alarmPath);
|
|
1301
|
-
} catch (error) {
|
|
1302
|
-
try {
|
|
1303
|
-
const fs = getNodeFs();
|
|
1304
|
-
await fs.unlink(tempPath);
|
|
1305
|
-
} catch {
|
|
1306
|
-
}
|
|
1307
|
-
logger2().error({
|
|
1308
|
-
msg: "failed to write alarm",
|
|
1309
|
-
actorId,
|
|
1310
|
-
error
|
|
1311
|
-
});
|
|
1312
|
-
throw new Error(`Failed to write alarm: ${error}`);
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
this.#scheduleAlarmTimeout(actorId, timestamp);
|
|
1316
|
-
}
|
|
1317
|
-
/**
|
|
1318
|
-
* Perform the actual write operation with atomic writes
|
|
1319
|
-
*/
|
|
1320
|
-
async #performWrite(actorId, generation, state) {
|
|
1321
|
-
const dataPath = this.getActorStatePath(actorId);
|
|
1322
|
-
const crypto2 = getNodeCrypto();
|
|
1323
|
-
const tempPath = `${dataPath}.tmp.${crypto2.randomUUID()}`;
|
|
1324
|
-
try {
|
|
1325
|
-
const path = getNodePath();
|
|
1326
|
-
await ensureDirectoryExists(path.dirname(dataPath));
|
|
1327
|
-
const bareState = {
|
|
1328
|
-
actorId: state.actorId,
|
|
1329
|
-
name: state.name,
|
|
1330
|
-
key: state.key,
|
|
1331
|
-
createdAt: state.createdAt,
|
|
1332
|
-
kvStorage: state.kvStorage,
|
|
1333
|
-
startTs: state.startTs,
|
|
1334
|
-
connectableTs: state.connectableTs,
|
|
1335
|
-
sleepTs: state.sleepTs,
|
|
1336
|
-
destroyTs: state.destroyTs
|
|
1337
|
-
};
|
|
1338
|
-
const serializedState = ACTOR_STATE_VERSIONED.serializeWithEmbeddedVersion(
|
|
1339
|
-
bareState,
|
|
1340
|
-
CURRENT_VERSION
|
|
1341
|
-
);
|
|
1342
|
-
const fs = getNodeFs();
|
|
1343
|
-
await fs.writeFile(tempPath, serializedState);
|
|
1344
|
-
if (!this.isGenerationCurrentAndNotDestroyed(actorId, generation)) {
|
|
1345
|
-
logger2().debug(
|
|
1346
|
-
"skipping writing alarm since actor destroying or new generation"
|
|
1347
|
-
);
|
|
1348
|
-
return;
|
|
1349
|
-
}
|
|
1350
|
-
await fs.rename(tempPath, dataPath);
|
|
1351
|
-
} catch (error) {
|
|
1352
|
-
try {
|
|
1353
|
-
const fs = getNodeFs();
|
|
1354
|
-
await fs.unlink(tempPath);
|
|
1355
|
-
} catch {
|
|
1356
|
-
}
|
|
1357
|
-
logger2().error({
|
|
1358
|
-
msg: "failed to save actor state",
|
|
1359
|
-
actorId,
|
|
1360
|
-
error
|
|
1361
|
-
});
|
|
1362
|
-
throw new Error(`Failed to save actor state: ${error}`);
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
/**
|
|
1366
|
-
* Call this method after the actor driver has been initiated.
|
|
1367
|
-
*
|
|
1368
|
-
* This will trigger all initial alarms from the file system.
|
|
1369
|
-
*
|
|
1370
|
-
* This needs to be sync since DriverConfig.actor is sync
|
|
1371
|
-
*/
|
|
1372
|
-
onRunnerStart(config4, inlineClient, actorDriver) {
|
|
1373
|
-
if (this.#runnerParams) {
|
|
1374
|
-
return;
|
|
1375
|
-
}
|
|
1376
|
-
this.#runnerParams = {
|
|
1377
|
-
config: config4,
|
|
1378
|
-
inlineClient,
|
|
1379
|
-
actorDriver
|
|
1380
|
-
};
|
|
1381
|
-
try {
|
|
1382
|
-
this.#loadAlarmsSync();
|
|
1383
|
-
} catch (err) {
|
|
1384
|
-
logger2().error({
|
|
1385
|
-
msg: "failed to load alarms on startup",
|
|
1386
|
-
error: err
|
|
1387
|
-
});
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
async startActor(config4, inlineClient, actorDriver, actorId) {
|
|
1391
|
-
var _a;
|
|
1392
|
-
const entry = await this.loadActor(actorId);
|
|
1393
|
-
if (!entry.state) {
|
|
1394
|
-
throw new Error(
|
|
1395
|
-
`Actor does not exist and cannot be started: "${actorId}"`
|
|
1396
|
-
);
|
|
1397
|
-
}
|
|
1398
|
-
if (entry.startPromise) {
|
|
1399
|
-
await entry.startPromise.promise;
|
|
1400
|
-
invariant(entry.actor, "actor should have loaded");
|
|
1401
|
-
return entry.actor;
|
|
1402
|
-
}
|
|
1403
|
-
if (entry.actor) {
|
|
1404
|
-
return entry.actor;
|
|
1405
|
-
}
|
|
1406
|
-
entry.startPromise = promiseWithResolvers();
|
|
1407
|
-
try {
|
|
1408
|
-
const definition = lookupInRegistry(
|
|
1409
|
-
config4,
|
|
1410
|
-
entry.state.name
|
|
1411
|
-
);
|
|
1412
|
-
entry.actor = definition.instantiate();
|
|
1413
|
-
await entry.actor.start(
|
|
1414
|
-
actorDriver,
|
|
1415
|
-
inlineClient,
|
|
1416
|
-
actorId,
|
|
1417
|
-
entry.state.name,
|
|
1418
|
-
entry.state.key,
|
|
1419
|
-
"unknown"
|
|
1420
|
-
);
|
|
1421
|
-
const now = BigInt(Date.now());
|
|
1422
|
-
entry.state = {
|
|
1423
|
-
...entry.state,
|
|
1424
|
-
startTs: now,
|
|
1425
|
-
connectableTs: now,
|
|
1426
|
-
sleepTs: null
|
|
1427
|
-
// Clear sleep timestamp when actor wakes up
|
|
1428
|
-
};
|
|
1429
|
-
await this.writeActor(actorId, entry.generation, entry.state);
|
|
1430
|
-
entry.startPromise.resolve();
|
|
1431
|
-
entry.startPromise = void 0;
|
|
1432
|
-
return entry.actor;
|
|
1433
|
-
} catch (innerError) {
|
|
1434
|
-
const error = new Error(
|
|
1435
|
-
`Failed to start actor ${actorId}: ${innerError}`,
|
|
1436
|
-
{ cause: innerError }
|
|
1437
|
-
);
|
|
1438
|
-
(_a = entry.startPromise) == null ? void 0 : _a.reject(error);
|
|
1439
|
-
entry.startPromise = void 0;
|
|
1440
|
-
throw error;
|
|
1441
|
-
}
|
|
1442
|
-
}
|
|
1443
|
-
async loadActorStateOrError(actorId) {
|
|
1444
|
-
const state = (await this.loadActor(actorId)).state;
|
|
1445
|
-
if (!state) throw new Error(`Actor does not exist: ${actorId}`);
|
|
1446
|
-
return state;
|
|
1447
|
-
}
|
|
1448
|
-
getActorOrError(actorId) {
|
|
1449
|
-
const entry = this.#actors.get(actorId);
|
|
1450
|
-
if (!entry) throw new Error(`No entry for actor: ${actorId}`);
|
|
1451
|
-
return entry;
|
|
1452
|
-
}
|
|
1453
|
-
async createDatabase(actorId) {
|
|
1454
|
-
return this.getActorDbPath(actorId);
|
|
1455
|
-
}
|
|
1456
|
-
/**
|
|
1457
|
-
* Load all persisted alarms from disk and schedule their timers.
|
|
1458
|
-
*/
|
|
1459
|
-
#loadAlarmsSync() {
|
|
1460
|
-
try {
|
|
1461
|
-
const fsSync = getNodeFsSync();
|
|
1462
|
-
const files = fsSync.existsSync(this.#alarmsDir) ? fsSync.readdirSync(this.#alarmsDir) : [];
|
|
1463
|
-
for (const file of files) {
|
|
1464
|
-
if (file.includes(".tmp.")) continue;
|
|
1465
|
-
const path = getNodePath();
|
|
1466
|
-
const fullPath = path.join(this.#alarmsDir, file);
|
|
1467
|
-
try {
|
|
1468
|
-
const buf = fsSync.readFileSync(fullPath);
|
|
1469
|
-
const alarmData = ACTOR_ALARM_VERSIONED.deserializeWithEmbeddedVersion(
|
|
1470
|
-
new Uint8Array(buf)
|
|
1471
|
-
);
|
|
1472
|
-
const timestamp = Number(alarmData.timestamp);
|
|
1473
|
-
if (Number.isFinite(timestamp)) {
|
|
1474
|
-
this.#scheduleAlarmTimeout(
|
|
1475
|
-
alarmData.actorId,
|
|
1476
|
-
timestamp
|
|
1477
|
-
);
|
|
1478
|
-
} else {
|
|
1479
|
-
logger2().debug({
|
|
1480
|
-
msg: "invalid alarm file contents",
|
|
1481
|
-
file
|
|
1482
|
-
});
|
|
1483
|
-
}
|
|
1484
|
-
} catch (err) {
|
|
1485
|
-
logger2().error({
|
|
1486
|
-
msg: "failed to read alarm file",
|
|
1487
|
-
file,
|
|
1488
|
-
error: stringifyError(err)
|
|
1489
|
-
});
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
|
-
} catch (err) {
|
|
1493
|
-
logger2().error({
|
|
1494
|
-
msg: "failed to list alarms directory",
|
|
1495
|
-
error: err
|
|
1496
|
-
});
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
/**
|
|
1500
|
-
* Schedule an alarm timer for an actor without writing to disk.
|
|
1501
|
-
*/
|
|
1502
|
-
#scheduleAlarmTimeout(actorId, timestamp) {
|
|
1503
|
-
var _a;
|
|
1504
|
-
const entry = this.#upsertEntry(actorId);
|
|
1505
|
-
if (entry.alarmTimestamp !== void 0 && timestamp >= entry.alarmTimestamp) {
|
|
1506
|
-
logger2().debug({
|
|
1507
|
-
msg: "skipping alarm schedule (later than existing)",
|
|
1508
|
-
actorId,
|
|
1509
|
-
timestamp,
|
|
1510
|
-
current: entry.alarmTimestamp
|
|
1511
|
-
});
|
|
1512
|
-
return;
|
|
1513
|
-
}
|
|
1514
|
-
logger2().debug({ msg: "scheduling alarm", actorId, timestamp });
|
|
1515
|
-
(_a = entry.alarmTimeout) == null ? void 0 : _a.abort();
|
|
1516
|
-
entry.alarmTimestamp = timestamp;
|
|
1517
|
-
const delay = Math.max(0, timestamp - Date.now());
|
|
1518
|
-
entry.alarmTimeout = setLongTimeout(async () => {
|
|
1519
|
-
entry.alarmTimestamp = void 0;
|
|
1520
|
-
if (this.#persist) {
|
|
1521
|
-
try {
|
|
1522
|
-
const fs = getNodeFs();
|
|
1523
|
-
await fs.unlink(this.getActorAlarmPath(actorId));
|
|
1524
|
-
} catch (err) {
|
|
1525
|
-
if ((err == null ? void 0 : err.code) !== "ENOENT") {
|
|
1526
|
-
logger2().debug({
|
|
1527
|
-
msg: "failed to remove alarm file",
|
|
1528
|
-
actorId,
|
|
1529
|
-
error: stringifyError(err)
|
|
1530
|
-
});
|
|
1531
|
-
}
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
try {
|
|
1535
|
-
logger2().debug({ msg: "triggering alarm", actorId, timestamp });
|
|
1536
|
-
const loaded = await this.loadActor(actorId);
|
|
1537
|
-
if (!loaded.state)
|
|
1538
|
-
throw new Error(`Actor does not exist: ${actorId}`);
|
|
1539
|
-
const runnerParams = this.#runnerParams;
|
|
1540
|
-
invariant(runnerParams, "missing runner params");
|
|
1541
|
-
if (!loaded.actor) {
|
|
1542
|
-
await this.startActor(
|
|
1543
|
-
runnerParams.config,
|
|
1544
|
-
runnerParams.inlineClient,
|
|
1545
|
-
runnerParams.actorDriver,
|
|
1546
|
-
actorId
|
|
1547
|
-
);
|
|
1548
|
-
}
|
|
1549
|
-
invariant(loaded.actor, "actor should be loaded after wake");
|
|
1550
|
-
await loaded.actor.onAlarm();
|
|
1551
|
-
} catch (err) {
|
|
1552
|
-
logger2().error({
|
|
1553
|
-
msg: "failed to handle alarm",
|
|
1554
|
-
actorId,
|
|
1555
|
-
error: stringifyError(err)
|
|
1556
|
-
});
|
|
1557
|
-
}
|
|
1558
|
-
}, delay);
|
|
1559
|
-
}
|
|
1560
|
-
/**
|
|
1561
|
-
* Cleanup stale temp files on startup (synchronous)
|
|
1562
|
-
*/
|
|
1563
|
-
#cleanupTempFilesSync() {
|
|
1564
|
-
try {
|
|
1565
|
-
const fsSync = getNodeFsSync();
|
|
1566
|
-
const files = fsSync.readdirSync(this.#stateDir);
|
|
1567
|
-
const tempFiles = files.filter((f) => f.includes(".tmp."));
|
|
1568
|
-
const oneHourAgo = Date.now() - 36e5;
|
|
1569
|
-
for (const tempFile of tempFiles) {
|
|
1570
|
-
try {
|
|
1571
|
-
const path = getNodePath();
|
|
1572
|
-
const fullPath = path.join(this.#stateDir, tempFile);
|
|
1573
|
-
const stat = fsSync.statSync(fullPath);
|
|
1574
|
-
if (stat.mtimeMs < oneHourAgo) {
|
|
1575
|
-
fsSync.unlinkSync(fullPath);
|
|
1576
|
-
logger2().info({
|
|
1577
|
-
msg: "cleaned up stale temp file",
|
|
1578
|
-
file: tempFile
|
|
1579
|
-
});
|
|
1580
|
-
}
|
|
1581
|
-
} catch (err) {
|
|
1582
|
-
logger2().debug({
|
|
1583
|
-
msg: "failed to cleanup temp file",
|
|
1584
|
-
file: tempFile,
|
|
1585
|
-
error: err
|
|
1586
|
-
});
|
|
1587
|
-
}
|
|
1588
|
-
}
|
|
1589
|
-
} catch (err) {
|
|
1590
|
-
logger2().error({
|
|
1591
|
-
msg: "failed to read actors directory for cleanup",
|
|
1592
|
-
error: err
|
|
1593
|
-
});
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
/**
|
|
1597
|
-
* Batch put KV entries for an actor.
|
|
1598
|
-
*/
|
|
1599
|
-
async kvBatchPut(actorId, entries) {
|
|
1600
|
-
const entry = await this.loadActor(actorId);
|
|
1601
|
-
if (!entry.state) {
|
|
1602
|
-
if (this.isActorStopping(actorId)) {
|
|
1603
|
-
return;
|
|
1604
|
-
} else {
|
|
1605
|
-
throw new Error(`Actor ${actorId} state not loaded`);
|
|
1606
|
-
}
|
|
1607
|
-
}
|
|
1608
|
-
const newKvStorage = [...entry.state.kvStorage];
|
|
1609
|
-
for (const [key, value] of entries) {
|
|
1610
|
-
const existingIndex = newKvStorage.findIndex(
|
|
1611
|
-
(e) => arrayBuffersEqual(e.key, bufferToArrayBuffer(key))
|
|
1612
|
-
);
|
|
1613
|
-
if (existingIndex >= 0) {
|
|
1614
|
-
newKvStorage[existingIndex] = {
|
|
1615
|
-
key: bufferToArrayBuffer(key),
|
|
1616
|
-
value: bufferToArrayBuffer(value)
|
|
1617
|
-
};
|
|
1618
|
-
} else {
|
|
1619
|
-
newKvStorage.push({
|
|
1620
|
-
key: bufferToArrayBuffer(key),
|
|
1621
|
-
value: bufferToArrayBuffer(value)
|
|
1622
|
-
});
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
|
-
entry.state = {
|
|
1626
|
-
...entry.state,
|
|
1627
|
-
kvStorage: newKvStorage
|
|
1628
|
-
};
|
|
1629
|
-
await this.writeActor(actorId, entry.generation, entry.state);
|
|
1630
|
-
}
|
|
1631
|
-
/**
|
|
1632
|
-
* Batch get KV entries for an actor.
|
|
1633
|
-
*/
|
|
1634
|
-
async kvBatchGet(actorId, keys) {
|
|
1635
|
-
const entry = await this.loadActor(actorId);
|
|
1636
|
-
if (!entry.state) {
|
|
1637
|
-
if (this.isActorStopping(actorId)) {
|
|
1638
|
-
throw new Error(`Actor ${actorId} is stopping`);
|
|
1639
|
-
} else {
|
|
1640
|
-
throw new Error(`Actor ${actorId} state not loaded`);
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
const results = [];
|
|
1644
|
-
for (const key of keys) {
|
|
1645
|
-
const foundEntry = entry.state.kvStorage.find(
|
|
1646
|
-
(e) => arrayBuffersEqual(e.key, bufferToArrayBuffer(key))
|
|
1647
|
-
);
|
|
1648
|
-
if (foundEntry) {
|
|
1649
|
-
results.push(new Uint8Array(foundEntry.value));
|
|
1650
|
-
} else {
|
|
1651
|
-
results.push(null);
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1654
|
-
return results;
|
|
1655
|
-
}
|
|
1656
|
-
/**
|
|
1657
|
-
* Batch delete KV entries for an actor.
|
|
1658
|
-
*/
|
|
1659
|
-
async kvBatchDelete(actorId, keys) {
|
|
1660
|
-
const entry = await this.loadActor(actorId);
|
|
1661
|
-
if (!entry.state) {
|
|
1662
|
-
if (this.isActorStopping(actorId)) {
|
|
1663
|
-
return;
|
|
1664
|
-
} else {
|
|
1665
|
-
throw new Error(`Actor ${actorId} state not loaded`);
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
const newKvStorage = [...entry.state.kvStorage];
|
|
1669
|
-
for (const key of keys) {
|
|
1670
|
-
const indexToDelete = newKvStorage.findIndex(
|
|
1671
|
-
(e) => arrayBuffersEqual(e.key, bufferToArrayBuffer(key))
|
|
1672
|
-
);
|
|
1673
|
-
if (indexToDelete >= 0) {
|
|
1674
|
-
newKvStorage.splice(indexToDelete, 1);
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
entry.state = {
|
|
1678
|
-
...entry.state,
|
|
1679
|
-
kvStorage: newKvStorage
|
|
1680
|
-
};
|
|
1681
|
-
await this.writeActor(actorId, entry.generation, entry.state);
|
|
1682
|
-
}
|
|
1683
|
-
/**
|
|
1684
|
-
* List KV entries with a given prefix for an actor.
|
|
1685
|
-
*/
|
|
1686
|
-
async kvListPrefix(actorId, prefix) {
|
|
1687
|
-
const entry = await this.loadActor(actorId);
|
|
1688
|
-
if (!entry.state) {
|
|
1689
|
-
if (this.isActorStopping(actorId)) {
|
|
1690
|
-
throw new Error(`Actor ${actorId} is destroying`);
|
|
1691
|
-
} else {
|
|
1692
|
-
throw new Error(`Actor ${actorId} state not loaded`);
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
const results = [];
|
|
1696
|
-
for (const kvEntry of entry.state.kvStorage) {
|
|
1697
|
-
const keyBytes = new Uint8Array(kvEntry.key);
|
|
1698
|
-
if (keyBytes.length >= prefix.length) {
|
|
1699
|
-
let hasPrefix = true;
|
|
1700
|
-
for (let i = 0; i < prefix.length; i++) {
|
|
1701
|
-
if (keyBytes[i] !== prefix[i]) {
|
|
1702
|
-
hasPrefix = false;
|
|
1703
|
-
break;
|
|
1704
|
-
}
|
|
1705
|
-
}
|
|
1706
|
-
if (hasPrefix) {
|
|
1707
|
-
results.push([keyBytes, new Uint8Array(kvEntry.value)]);
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
return results;
|
|
1712
|
-
}
|
|
1713
|
-
};
|
|
1714
|
-
|
|
1715
|
-
// src/drivers/file-system/manager.ts
|
|
1716
|
-
import invariant2 from "invariant";
|
|
1717
|
-
var FileSystemManagerDriver = class {
|
|
1718
|
-
#config;
|
|
1719
|
-
#state;
|
|
1720
|
-
#driverConfig;
|
|
1721
|
-
#getUpgradeWebSocket;
|
|
1722
|
-
#actorDriver;
|
|
1723
|
-
#actorRouter;
|
|
1724
|
-
constructor(config4, state, driverConfig) {
|
|
1725
|
-
this.#config = config4;
|
|
1726
|
-
this.#state = state;
|
|
1727
|
-
this.#driverConfig = driverConfig;
|
|
1728
|
-
const inlineClient = createClientWithDriver(this);
|
|
1729
|
-
this.#actorDriver = this.#driverConfig.actor(
|
|
1730
|
-
config4,
|
|
1731
|
-
this,
|
|
1732
|
-
inlineClient
|
|
1733
|
-
);
|
|
1734
|
-
this.#actorRouter = createActorRouter(
|
|
1735
|
-
this.#config,
|
|
1736
|
-
this.#actorDriver,
|
|
1737
|
-
void 0,
|
|
1738
|
-
config4.test.enabled
|
|
1739
|
-
);
|
|
1740
|
-
}
|
|
1741
|
-
async sendRequest(actorId, actorRequest) {
|
|
1742
|
-
return await this.#actorRouter.fetch(actorRequest, {
|
|
1743
|
-
actorId
|
|
1744
|
-
});
|
|
1745
|
-
}
|
|
1746
|
-
async openWebSocket(path, actorId, encoding, params) {
|
|
1747
|
-
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
1748
|
-
const fakeUrl = `http://inline-actor${normalizedPath}`;
|
|
1749
|
-
const fakeRequest = new Request(fakeUrl, {
|
|
1750
|
-
method: "GET"
|
|
1751
|
-
});
|
|
1752
|
-
const pathOnly = normalizedPath.split("?")[0];
|
|
1753
|
-
const wsHandler = await routeWebSocket(
|
|
1754
|
-
fakeRequest,
|
|
1755
|
-
pathOnly,
|
|
1756
|
-
{},
|
|
1757
|
-
this.#config,
|
|
1758
|
-
this.#actorDriver,
|
|
1759
|
-
actorId,
|
|
1760
|
-
encoding,
|
|
1761
|
-
params,
|
|
1762
|
-
void 0,
|
|
1763
|
-
void 0,
|
|
1764
|
-
false,
|
|
1765
|
-
false
|
|
1766
|
-
);
|
|
1767
|
-
return createInlineWebSocket(wsHandler);
|
|
1768
|
-
}
|
|
1769
|
-
async proxyRequest(c, actorRequest, actorId) {
|
|
1770
|
-
return await this.#actorRouter.fetch(actorRequest, {
|
|
1771
|
-
actorId
|
|
1772
|
-
});
|
|
1773
|
-
}
|
|
1774
|
-
async proxyWebSocket(c, path, actorId, encoding, params) {
|
|
1775
|
-
var _a;
|
|
1776
|
-
const upgradeWebSocket = (_a = this.#getUpgradeWebSocket) == null ? void 0 : _a.call(this);
|
|
1777
|
-
invariant2(upgradeWebSocket, "missing getUpgradeWebSocket");
|
|
1778
|
-
const pathOnly = path.split("?")[0];
|
|
1779
|
-
const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
|
|
1780
|
-
const wsHandler = await routeWebSocket(
|
|
1781
|
-
// TODO: Create new request with new path
|
|
1782
|
-
c.req.raw,
|
|
1783
|
-
normalizedPath,
|
|
1784
|
-
c.req.header(),
|
|
1785
|
-
this.#config,
|
|
1786
|
-
this.#actorDriver,
|
|
1787
|
-
actorId,
|
|
1788
|
-
encoding,
|
|
1789
|
-
params,
|
|
1790
|
-
void 0,
|
|
1791
|
-
void 0,
|
|
1792
|
-
false,
|
|
1793
|
-
false
|
|
1794
|
-
);
|
|
1795
|
-
return upgradeWebSocket(() => wsHandler)(c, noopNext());
|
|
1796
|
-
}
|
|
1797
|
-
async buildGatewayUrl(actorId) {
|
|
1798
|
-
const port = this.#config.managerPort ?? 6420;
|
|
1799
|
-
return `http://127.0.0.1:${port}/gateway/${encodeURIComponent(actorId)}`;
|
|
1800
|
-
}
|
|
1801
|
-
async getForId({
|
|
1802
|
-
actorId
|
|
1803
|
-
}) {
|
|
1804
|
-
const actor = await this.#state.loadActor(actorId);
|
|
1805
|
-
if (!actor.state) {
|
|
1806
|
-
return void 0;
|
|
1807
|
-
}
|
|
1808
|
-
if (this.#state.isActorStopping(actorId)) {
|
|
1809
|
-
throw new ActorStopping(actorId);
|
|
1810
|
-
}
|
|
1811
|
-
return actorStateToOutput(actor.state);
|
|
1812
|
-
}
|
|
1813
|
-
async getWithKey({
|
|
1814
|
-
name,
|
|
1815
|
-
key
|
|
1816
|
-
}) {
|
|
1817
|
-
const actorId = generateActorId(name, key);
|
|
1818
|
-
const actor = await this.#state.loadActor(actorId);
|
|
1819
|
-
if (actor.state) {
|
|
1820
|
-
return actorStateToOutput(actor.state);
|
|
1821
|
-
}
|
|
1822
|
-
return void 0;
|
|
1823
|
-
}
|
|
1824
|
-
async getOrCreateWithKey(input) {
|
|
1825
|
-
const actorId = generateActorId(input.name, input.key);
|
|
1826
|
-
await this.#state.loadOrCreateActor(
|
|
1827
|
-
actorId,
|
|
1828
|
-
input.name,
|
|
1829
|
-
input.key,
|
|
1830
|
-
input.input
|
|
1831
|
-
);
|
|
1832
|
-
await this.#actorDriver.loadActor(actorId);
|
|
1833
|
-
const state = await this.#state.loadActorStateOrError(actorId);
|
|
1834
|
-
return actorStateToOutput(state);
|
|
1835
|
-
}
|
|
1836
|
-
async createActor({ name, key, input }) {
|
|
1837
|
-
const actorId = generateActorId(name, key);
|
|
1838
|
-
await this.#state.createActor(actorId, name, key, input);
|
|
1839
|
-
await this.#actorDriver.loadActor(actorId);
|
|
1840
|
-
const state = await this.#state.loadActorStateOrError(actorId);
|
|
1841
|
-
return actorStateToOutput(state);
|
|
1842
|
-
}
|
|
1843
|
-
async listActors({ name }) {
|
|
1844
|
-
const actors = [];
|
|
1845
|
-
const itr = this.#state.getActorsIterator({});
|
|
1846
|
-
for await (const actor of itr) {
|
|
1847
|
-
if (actor.name === name) {
|
|
1848
|
-
actors.push(actorStateToOutput(actor));
|
|
1849
|
-
}
|
|
1850
|
-
}
|
|
1851
|
-
actors.sort((a, b) => {
|
|
1852
|
-
const aTs = a.createTs ?? 0;
|
|
1853
|
-
const bTs = b.createTs ?? 0;
|
|
1854
|
-
return bTs - aTs;
|
|
1855
|
-
});
|
|
1856
|
-
return actors;
|
|
1857
|
-
}
|
|
1858
|
-
async kvGet(actorId, key) {
|
|
1859
|
-
const response = await this.#state.kvBatchGet(actorId, [key]);
|
|
1860
|
-
return response[0] !== null ? new TextDecoder().decode(response[0]) : null;
|
|
1861
|
-
}
|
|
1862
|
-
displayInformation() {
|
|
1863
|
-
return {
|
|
1864
|
-
properties: {
|
|
1865
|
-
...this.#state.persist ? { Data: this.#state.storagePath } : {},
|
|
1866
|
-
Instances: this.#state.actorCountOnStartup.toString()
|
|
1867
|
-
}
|
|
1868
|
-
};
|
|
1869
|
-
}
|
|
1870
|
-
extraStartupLog() {
|
|
1871
|
-
return {
|
|
1872
|
-
instances: this.#state.actorCountOnStartup,
|
|
1873
|
-
data: this.#state.storagePath
|
|
1874
|
-
};
|
|
1875
|
-
}
|
|
1876
|
-
setGetUpgradeWebSocket(getUpgradeWebSocket) {
|
|
1877
|
-
this.#getUpgradeWebSocket = getUpgradeWebSocket;
|
|
1878
|
-
}
|
|
1879
|
-
};
|
|
1880
|
-
function actorStateToOutput(state) {
|
|
1881
|
-
return {
|
|
1882
|
-
actorId: state.actorId,
|
|
1883
|
-
name: state.name,
|
|
1884
|
-
key: state.key,
|
|
1885
|
-
createTs: Number(state.createdAt),
|
|
1886
|
-
startTs: state.startTs !== null ? Number(state.startTs) : null,
|
|
1887
|
-
connectableTs: state.connectableTs !== null ? Number(state.connectableTs) : null,
|
|
1888
|
-
sleepTs: state.sleepTs !== null ? Number(state.sleepTs) : null,
|
|
1889
|
-
destroyTs: state.destroyTs !== null ? Number(state.destroyTs) : null
|
|
1890
|
-
};
|
|
1891
|
-
}
|
|
1892
|
-
|
|
1893
|
-
// src/drivers/file-system/mod.ts
|
|
1894
|
-
function createFileSystemOrMemoryDriver(persist = true, customPath) {
|
|
1895
|
-
importNodeDependencies();
|
|
1896
|
-
const state = new FileSystemGlobalState(persist, customPath);
|
|
1897
|
-
const driverConfig = {
|
|
1898
|
-
name: persist ? "file-system" : "memory",
|
|
1899
|
-
displayName: persist ? "File System" : "Memory",
|
|
1900
|
-
manager: (config4) => new FileSystemManagerDriver(
|
|
1901
|
-
config4,
|
|
1902
|
-
state,
|
|
1903
|
-
driverConfig
|
|
1904
|
-
),
|
|
1905
|
-
actor: (config4, managerDriver, inlineClient) => {
|
|
1906
|
-
const actorDriver = new FileSystemActorDriver(
|
|
1907
|
-
config4,
|
|
1908
|
-
managerDriver,
|
|
1909
|
-
inlineClient,
|
|
1910
|
-
state
|
|
1911
|
-
);
|
|
1912
|
-
state.onRunnerStart(
|
|
1913
|
-
config4,
|
|
1914
|
-
inlineClient,
|
|
1915
|
-
actorDriver
|
|
1916
|
-
);
|
|
1917
|
-
return actorDriver;
|
|
1918
|
-
},
|
|
1919
|
-
autoStartActorDriver: true
|
|
1920
|
-
};
|
|
1921
|
-
return driverConfig;
|
|
1922
|
-
}
|
|
1923
|
-
function createFileSystemDriver(opts) {
|
|
1924
|
-
return createFileSystemOrMemoryDriver(true, opts == null ? void 0 : opts.path);
|
|
1925
|
-
}
|
|
1926
|
-
function createMemoryDriver() {
|
|
1927
|
-
return createFileSystemOrMemoryDriver(false);
|
|
1928
|
-
}
|
|
1929
|
-
|
|
1930
|
-
export {
|
|
1931
|
-
createActorRouter,
|
|
1932
|
-
InlineWebSocketAdapter,
|
|
1933
|
-
importNodeDependencies,
|
|
1934
|
-
getNodeCrypto,
|
|
1935
|
-
getNodeFsSync,
|
|
1936
|
-
getNodeFs,
|
|
1937
|
-
getNodePath,
|
|
1938
|
-
getNodeChildProcess,
|
|
1939
|
-
getNodeStream,
|
|
1940
|
-
getStoragePath,
|
|
1941
|
-
ensureDirectoryExists,
|
|
1942
|
-
createFileSystemOrMemoryDriver,
|
|
1943
|
-
createFileSystemDriver,
|
|
1944
|
-
createMemoryDriver
|
|
1945
|
-
};
|
|
1946
|
-
//# sourceMappingURL=chunk-KCOVZOPS.js.map
|