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
package/src/client/client.ts
CHANGED
|
@@ -514,10 +514,8 @@ function createActorProxy<AD extends AnyActorDefinition>(
|
|
|
514
514
|
|
|
515
515
|
// Support for 'in' operator
|
|
516
516
|
has(target: ActorHandleRaw, prop: string | symbol) {
|
|
517
|
-
// All string properties are potentially action functions
|
|
518
|
-
if (typeof prop === "string")
|
|
519
|
-
return true;
|
|
520
|
-
}
|
|
517
|
+
// All string properties are potentially action functions.
|
|
518
|
+
if (typeof prop === "string") return true;
|
|
521
519
|
// For symbols, defer to the target's own has behavior
|
|
522
520
|
return Reflect.has(target, prop);
|
|
523
521
|
},
|
package/src/client/config.ts
CHANGED
package/src/client/mod.ts
CHANGED
|
@@ -8,10 +8,7 @@ import {
|
|
|
8
8
|
} from "./client";
|
|
9
9
|
import { ClientConfigSchema } from "./config";
|
|
10
10
|
|
|
11
|
-
export {
|
|
12
|
-
ActorDefinition,
|
|
13
|
-
type AnyActorDefinition,
|
|
14
|
-
} from "@/actor/definition";
|
|
11
|
+
export type { ActorDefinition, AnyActorDefinition } from "@/actor/definition";
|
|
15
12
|
export type { Encoding } from "@/actor/protocol/serde";
|
|
16
13
|
export {
|
|
17
14
|
ActorClientError,
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import * as cbor from "cbor-x";
|
|
2
|
+
import type { Encoding } from "@/actor/protocol/serde";
|
|
3
|
+
import { HEADER_CONN_PARAMS, HEADER_ENCODING } from "@/driver-helpers/mod";
|
|
4
|
+
import type * as protocol from "@/schemas/client-protocol/mod";
|
|
5
|
+
import {
|
|
6
|
+
CURRENT_VERSION as CLIENT_PROTOCOL_CURRENT_VERSION,
|
|
7
|
+
HTTP_QUEUE_SEND_REQUEST_VERSIONED,
|
|
8
|
+
HTTP_QUEUE_SEND_RESPONSE_VERSIONED,
|
|
9
|
+
} from "@/schemas/client-protocol/versioned";
|
|
10
|
+
import {
|
|
11
|
+
type HttpQueueSendRequest as HttpQueueSendRequestJson,
|
|
12
|
+
HttpQueueSendRequestSchema,
|
|
13
|
+
type HttpQueueSendResponse as HttpQueueSendResponseJson,
|
|
14
|
+
HttpQueueSendResponseSchema,
|
|
15
|
+
} from "@/schemas/client-protocol-zod/mod";
|
|
16
|
+
import { bufferToArrayBuffer } from "@/utils";
|
|
17
|
+
import { sendHttpRequest } from "./utils";
|
|
18
|
+
|
|
19
|
+
export interface QueueSender {
|
|
20
|
+
send(
|
|
21
|
+
name: string,
|
|
22
|
+
body: unknown,
|
|
23
|
+
options: QueueSendWaitOptions,
|
|
24
|
+
): Promise<QueueSendResult>;
|
|
25
|
+
send(
|
|
26
|
+
name: string,
|
|
27
|
+
body: unknown,
|
|
28
|
+
options?: QueueSendNoWaitOptions,
|
|
29
|
+
): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface QueueSendWaitOptions {
|
|
33
|
+
wait: true;
|
|
34
|
+
timeout?: number;
|
|
35
|
+
signal?: AbortSignal;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface QueueSendNoWaitOptions {
|
|
39
|
+
wait?: false;
|
|
40
|
+
timeout?: never;
|
|
41
|
+
signal?: AbortSignal;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type QueueSendOptions = QueueSendWaitOptions | QueueSendNoWaitOptions;
|
|
45
|
+
|
|
46
|
+
export interface QueueSendResult {
|
|
47
|
+
status: "completed" | "timedOut";
|
|
48
|
+
response?: unknown;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface QueueSenderOptions {
|
|
52
|
+
encoding: Encoding;
|
|
53
|
+
params: unknown;
|
|
54
|
+
customFetch: (request: Request) => Promise<Response>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function createQueueSender(senderOptions: QueueSenderOptions): QueueSender {
|
|
58
|
+
async function send(
|
|
59
|
+
name: string,
|
|
60
|
+
body: unknown,
|
|
61
|
+
options: QueueSendWaitOptions,
|
|
62
|
+
): Promise<QueueSendResult>;
|
|
63
|
+
async function send(
|
|
64
|
+
name: string,
|
|
65
|
+
body: unknown,
|
|
66
|
+
options?: QueueSendNoWaitOptions,
|
|
67
|
+
): Promise<void>;
|
|
68
|
+
async function send(
|
|
69
|
+
name: string,
|
|
70
|
+
body: unknown,
|
|
71
|
+
options?: QueueSendOptions,
|
|
72
|
+
): Promise<QueueSendResult | void> {
|
|
73
|
+
const wait = options?.wait ?? false;
|
|
74
|
+
const timeout = options?.timeout;
|
|
75
|
+
|
|
76
|
+
const result = await sendHttpRequest<
|
|
77
|
+
protocol.HttpQueueSendRequest,
|
|
78
|
+
protocol.HttpQueueSendResponse,
|
|
79
|
+
HttpQueueSendRequestJson,
|
|
80
|
+
HttpQueueSendResponseJson,
|
|
81
|
+
{ body: unknown; wait?: boolean; timeout?: number; name?: string },
|
|
82
|
+
QueueSendResult
|
|
83
|
+
>({
|
|
84
|
+
url: `http://actor/queue/${encodeURIComponent(name)}`,
|
|
85
|
+
method: "POST",
|
|
86
|
+
headers: {
|
|
87
|
+
[HEADER_ENCODING]: senderOptions.encoding,
|
|
88
|
+
...(senderOptions.params !== undefined
|
|
89
|
+
? {
|
|
90
|
+
[HEADER_CONN_PARAMS]: JSON.stringify(
|
|
91
|
+
senderOptions.params,
|
|
92
|
+
),
|
|
93
|
+
}
|
|
94
|
+
: {}),
|
|
95
|
+
},
|
|
96
|
+
body: { body, wait, timeout },
|
|
97
|
+
encoding: senderOptions.encoding,
|
|
98
|
+
customFetch: senderOptions.customFetch,
|
|
99
|
+
signal: options?.signal,
|
|
100
|
+
requestVersion: CLIENT_PROTOCOL_CURRENT_VERSION,
|
|
101
|
+
requestVersionedDataHandler: HTTP_QUEUE_SEND_REQUEST_VERSIONED,
|
|
102
|
+
responseVersion: CLIENT_PROTOCOL_CURRENT_VERSION,
|
|
103
|
+
responseVersionedDataHandler:
|
|
104
|
+
HTTP_QUEUE_SEND_RESPONSE_VERSIONED,
|
|
105
|
+
requestZodSchema: HttpQueueSendRequestSchema,
|
|
106
|
+
responseZodSchema: HttpQueueSendResponseSchema,
|
|
107
|
+
requestToJson: (value): HttpQueueSendRequestJson => ({
|
|
108
|
+
...value,
|
|
109
|
+
name,
|
|
110
|
+
}),
|
|
111
|
+
requestToBare: (value): protocol.HttpQueueSendRequest => ({
|
|
112
|
+
name: value.name ?? name,
|
|
113
|
+
body: bufferToArrayBuffer(cbor.encode(value.body)),
|
|
114
|
+
wait: value.wait ?? false,
|
|
115
|
+
timeout: value.timeout !== undefined ? BigInt(value.timeout) : null,
|
|
116
|
+
}),
|
|
117
|
+
responseFromJson: (json): QueueSendResult => {
|
|
118
|
+
if (json.response === undefined) {
|
|
119
|
+
return { status: json.status as "completed" | "timedOut" };
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
status: json.status as "completed" | "timedOut",
|
|
123
|
+
response: json.response,
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
responseFromBare: (bare): QueueSendResult => {
|
|
127
|
+
if (bare.response === null || bare.response === undefined) {
|
|
128
|
+
return { status: bare.status as "completed" | "timedOut" };
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
status: bare.status as "completed" | "timedOut",
|
|
132
|
+
response: cbor.decode(new Uint8Array(bare.response)),
|
|
133
|
+
};
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
if (wait) {
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
send,
|
|
145
|
+
};
|
|
146
|
+
}
|
package/src/client/utils.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as cbor from "cbor-x";
|
|
2
2
|
import invariant from "invariant";
|
|
3
3
|
import type { VersionedDataHandler } from "vbare";
|
|
4
|
-
import type { z } from "zod";
|
|
4
|
+
import type { z } from "zod/v4";
|
|
5
5
|
import type { Encoding } from "@/actor/protocol/serde";
|
|
6
6
|
import { assertUnreachable } from "@/common/utils";
|
|
7
7
|
import type { HttpResponseError } from "@/schemas/client-protocol/mod";
|
package/src/common/log.ts
CHANGED
package/src/common/utils.ts
CHANGED
|
@@ -253,7 +253,7 @@ export function deconstructError(
|
|
|
253
253
|
} else {
|
|
254
254
|
statusCode = 500;
|
|
255
255
|
public_ = false;
|
|
256
|
-
group = "
|
|
256
|
+
group = "rivetkit";
|
|
257
257
|
code = errors.INTERNAL_ERROR_CODE;
|
|
258
258
|
message = getErrorMessage(error);
|
|
259
259
|
|
|
@@ -270,7 +270,7 @@ export function deconstructError(
|
|
|
270
270
|
} else {
|
|
271
271
|
statusCode = 500;
|
|
272
272
|
public_ = false;
|
|
273
|
-
group = "
|
|
273
|
+
group = "rivetkit";
|
|
274
274
|
code = errors.INTERNAL_ERROR_CODE;
|
|
275
275
|
message = errors.INTERNAL_ERROR_DESCRIPTION;
|
|
276
276
|
metadata = {
|
|
@@ -335,5 +335,5 @@ function getErrorMessage(err: unknown): string {
|
|
|
335
335
|
|
|
336
336
|
/** Generates a `Next` handler to pass to middleware in order to be able to call arbitrary middleware. */
|
|
337
337
|
export function noopNext(): Next {
|
|
338
|
-
return async () => {};
|
|
338
|
+
return async () => { };
|
|
339
339
|
}
|
package/src/db/config.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { SqliteVfs } from "@rivetkit/sqlite-vfs";
|
|
2
|
+
|
|
3
|
+
export type AnyDatabaseProvider = DatabaseProvider<any> | undefined;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Context provided to database providers for creating database clients
|
|
7
|
+
*/
|
|
8
|
+
export interface DatabaseProviderContext {
|
|
9
|
+
/**
|
|
10
|
+
* Actor ID
|
|
11
|
+
*/
|
|
12
|
+
actorId: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Override the default raw database client (optional).
|
|
16
|
+
* If not provided, a KV-backed client will be constructed.
|
|
17
|
+
*/
|
|
18
|
+
overrideRawDatabaseClient?: () => Promise<RawDatabaseClient | undefined>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Override the default Drizzle database client (optional).
|
|
22
|
+
* If not provided, a KV-backed client will be constructed.
|
|
23
|
+
*/
|
|
24
|
+
overrideDrizzleDatabaseClient?: () => Promise<
|
|
25
|
+
DrizzleDatabaseClient | undefined
|
|
26
|
+
>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* KV operations for constructing KV-backed database clients
|
|
30
|
+
*/
|
|
31
|
+
kv: {
|
|
32
|
+
batchPut: (entries: [Uint8Array, Uint8Array][]) => Promise<void>;
|
|
33
|
+
batchGet: (keys: Uint8Array[]) => Promise<(Uint8Array | null)[]>;
|
|
34
|
+
batchDelete: (keys: Uint8Array[]) => Promise<void>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* SQLite VFS instance for creating KV-backed databases.
|
|
39
|
+
* This should be actor-scoped because @rivetkit/sqlite is not re-entrant per
|
|
40
|
+
* module instance.
|
|
41
|
+
*/
|
|
42
|
+
sqliteVfs?: SqliteVfs;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type DatabaseProvider<DB extends RawAccess> = {
|
|
46
|
+
/**
|
|
47
|
+
* Creates a new database client for the actor.
|
|
48
|
+
* The result is passed to the actor context as `c.db`.
|
|
49
|
+
* @experimental
|
|
50
|
+
*/
|
|
51
|
+
createClient: (ctx: DatabaseProviderContext) => Promise<DB>;
|
|
52
|
+
/**
|
|
53
|
+
* Runs before the actor has started.
|
|
54
|
+
* Use this to run migrations or other setup tasks.
|
|
55
|
+
* @experimental
|
|
56
|
+
*/
|
|
57
|
+
onMigrate: (client: DB) => void | Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Runs when the actor is being destroyed.
|
|
60
|
+
* Use this to clean up database connections and release resources.
|
|
61
|
+
* @experimental
|
|
62
|
+
*/
|
|
63
|
+
onDestroy?: (client: DB) => void | Promise<void>;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Raw database client with basic exec method
|
|
68
|
+
*/
|
|
69
|
+
export interface RawDatabaseClient {
|
|
70
|
+
exec: <TRow extends Record<string, unknown> = Record<string, unknown>>(
|
|
71
|
+
query: string,
|
|
72
|
+
...args: unknown[]
|
|
73
|
+
) => Promise<TRow[]> | TRow[];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Drizzle database client interface (will be extended by drizzle-orm types)
|
|
78
|
+
*/
|
|
79
|
+
export interface DrizzleDatabaseClient {
|
|
80
|
+
// This will be extended by BaseSQLiteDatabase from drizzle-orm
|
|
81
|
+
// For now, just a marker interface
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
type ExecuteFunction = <
|
|
85
|
+
TRow extends Record<string, unknown> = Record<string, unknown>,
|
|
86
|
+
>(
|
|
87
|
+
query: string,
|
|
88
|
+
...args: unknown[]
|
|
89
|
+
) => Promise<TRow[]>;
|
|
90
|
+
|
|
91
|
+
export type RawAccess = {
|
|
92
|
+
/**
|
|
93
|
+
* Executes a raw SQL query.
|
|
94
|
+
*/
|
|
95
|
+
execute: ExecuteFunction;
|
|
96
|
+
/**
|
|
97
|
+
* Closes the database connection and releases resources.
|
|
98
|
+
*/
|
|
99
|
+
close: () => Promise<void>;
|
|
100
|
+
};
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import type { Database } from "@rivetkit/sqlite-vfs";
|
|
2
|
+
import {
|
|
3
|
+
drizzle as proxyDrizzle,
|
|
4
|
+
type SqliteRemoteDatabase,
|
|
5
|
+
} from "drizzle-orm/sqlite-proxy";
|
|
6
|
+
import type { DatabaseProvider, RawAccess } from "../config";
|
|
7
|
+
import { AsyncMutex, createActorKvStore, toSqliteBindings } from "../shared";
|
|
8
|
+
|
|
9
|
+
export * from "./sqlite-core";
|
|
10
|
+
|
|
11
|
+
import { type Config, defineConfig as originalDefineConfig } from "drizzle-kit";
|
|
12
|
+
|
|
13
|
+
export function defineConfig(
|
|
14
|
+
config: Partial<Config & { driver: "durable-sqlite" }>,
|
|
15
|
+
): Config {
|
|
16
|
+
return originalDefineConfig({
|
|
17
|
+
dialect: "sqlite",
|
|
18
|
+
driver: "durable-sqlite",
|
|
19
|
+
...config,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface DatabaseFactoryConfig<
|
|
24
|
+
TSchema extends Record<string, unknown> = Record<string, never>,
|
|
25
|
+
> {
|
|
26
|
+
schema?: TSchema;
|
|
27
|
+
migrations?: any;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a sqlite-proxy async callback from a @rivetkit/sqlite Database
|
|
32
|
+
*/
|
|
33
|
+
function createProxyCallback(
|
|
34
|
+
waDb: Database,
|
|
35
|
+
mutex: AsyncMutex,
|
|
36
|
+
isClosed: () => boolean,
|
|
37
|
+
) {
|
|
38
|
+
return async (
|
|
39
|
+
sql: string,
|
|
40
|
+
params: any[],
|
|
41
|
+
method: "run" | "all" | "values" | "get",
|
|
42
|
+
): Promise<{ rows: any }> => {
|
|
43
|
+
return mutex.run(async () => {
|
|
44
|
+
if (isClosed()) {
|
|
45
|
+
throw new Error("database is closed");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (method === "run") {
|
|
49
|
+
await waDb.run(sql, toSqliteBindings(params));
|
|
50
|
+
return { rows: [] };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// For all/get/values, use parameterized query
|
|
54
|
+
const result = await waDb.query(sql, toSqliteBindings(params));
|
|
55
|
+
|
|
56
|
+
// drizzle's mapResultRow accesses rows by column index (positional arrays)
|
|
57
|
+
// so we return raw arrays for all methods
|
|
58
|
+
if (method === "get") {
|
|
59
|
+
return { rows: result.rows[0] };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { rows: result.rows };
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Run inline migrations via the @rivetkit/sqlite Database.
|
|
69
|
+
* Migrations use the same embedded format as drizzle-orm's durable-sqlite.
|
|
70
|
+
*/
|
|
71
|
+
async function runInlineMigrations(
|
|
72
|
+
waDb: Database,
|
|
73
|
+
mutex: AsyncMutex,
|
|
74
|
+
migrations: any,
|
|
75
|
+
): Promise<void> {
|
|
76
|
+
// Create migrations table
|
|
77
|
+
await mutex.run(() =>
|
|
78
|
+
waDb.exec(`
|
|
79
|
+
CREATE TABLE IF NOT EXISTS __drizzle_migrations (
|
|
80
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
81
|
+
hash TEXT NOT NULL,
|
|
82
|
+
created_at INTEGER
|
|
83
|
+
)
|
|
84
|
+
`),
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// Get the last applied migration
|
|
88
|
+
let lastCreatedAt = 0;
|
|
89
|
+
await mutex.run(() =>
|
|
90
|
+
waDb.exec(
|
|
91
|
+
"SELECT id, hash, created_at FROM __drizzle_migrations ORDER BY created_at DESC LIMIT 1",
|
|
92
|
+
(row) => {
|
|
93
|
+
lastCreatedAt = Number(row[2]) || 0;
|
|
94
|
+
},
|
|
95
|
+
),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// Apply pending migrations from journal entries
|
|
99
|
+
const journal = migrations.journal;
|
|
100
|
+
if (!journal?.entries) return;
|
|
101
|
+
|
|
102
|
+
for (const entry of journal.entries) {
|
|
103
|
+
if (entry.when <= lastCreatedAt) continue;
|
|
104
|
+
|
|
105
|
+
// Find the migration SQL from the migrations map
|
|
106
|
+
// The key format is "m" + zero-padded index (e.g. "m0000")
|
|
107
|
+
const migrationKey = `m${String(entry.idx).padStart(4, "0")}`;
|
|
108
|
+
const sql = migrations.migrations[migrationKey];
|
|
109
|
+
if (!sql) continue;
|
|
110
|
+
|
|
111
|
+
// Execute migration SQL
|
|
112
|
+
await mutex.run(() => waDb.exec(sql));
|
|
113
|
+
|
|
114
|
+
// Record migration
|
|
115
|
+
await mutex.run(() =>
|
|
116
|
+
waDb.run(
|
|
117
|
+
"INSERT INTO __drizzle_migrations (hash, created_at) VALUES (?, ?)",
|
|
118
|
+
[entry.tag, entry.when],
|
|
119
|
+
),
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function db<
|
|
125
|
+
TSchema extends Record<string, unknown> = Record<string, never>,
|
|
126
|
+
>(
|
|
127
|
+
config?: DatabaseFactoryConfig<TSchema>,
|
|
128
|
+
): DatabaseProvider<SqliteRemoteDatabase<TSchema> & RawAccess> {
|
|
129
|
+
// Store the @rivetkit/sqlite Database instance alongside the drizzle client
|
|
130
|
+
let waDbInstance: Database | null = null;
|
|
131
|
+
const mutex = new AsyncMutex();
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
createClient: async (ctx) => {
|
|
135
|
+
// Construct KV-backed client using actor driver's KV operations
|
|
136
|
+
if (!ctx.sqliteVfs) {
|
|
137
|
+
throw new Error(
|
|
138
|
+
"SqliteVfs instance not provided in context. The driver must provide a sqliteVfs instance.",
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const kvStore = createActorKvStore(ctx.kv);
|
|
143
|
+
const waDb = await ctx.sqliteVfs.open(ctx.actorId, kvStore);
|
|
144
|
+
waDbInstance = waDb;
|
|
145
|
+
let closed = false;
|
|
146
|
+
const ensureOpen = () => {
|
|
147
|
+
if (closed) {
|
|
148
|
+
throw new Error("database is closed");
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// Create the async proxy callback
|
|
153
|
+
const callback = createProxyCallback(waDb, mutex, () => closed);
|
|
154
|
+
|
|
155
|
+
// Create the drizzle instance using sqlite-proxy
|
|
156
|
+
const client = proxyDrizzle<TSchema>(callback, config);
|
|
157
|
+
|
|
158
|
+
return Object.assign(client, {
|
|
159
|
+
execute: async <
|
|
160
|
+
TRow extends Record<string, unknown> = Record<string, unknown>,
|
|
161
|
+
>(
|
|
162
|
+
query: string,
|
|
163
|
+
...args: unknown[]
|
|
164
|
+
): Promise<TRow[]> => {
|
|
165
|
+
return mutex.run(async () => {
|
|
166
|
+
ensureOpen();
|
|
167
|
+
|
|
168
|
+
if (args.length > 0) {
|
|
169
|
+
const result = await waDb.query(
|
|
170
|
+
query,
|
|
171
|
+
toSqliteBindings(args),
|
|
172
|
+
);
|
|
173
|
+
return result.rows.map((row: unknown[]) => {
|
|
174
|
+
const obj: Record<string, unknown> = {};
|
|
175
|
+
for (let i = 0; i < result.columns.length; i++) {
|
|
176
|
+
obj[result.columns[i]] = row[i];
|
|
177
|
+
}
|
|
178
|
+
return obj;
|
|
179
|
+
}) as TRow[];
|
|
180
|
+
}
|
|
181
|
+
// Use exec for non-parameterized queries since
|
|
182
|
+
// @rivetkit/sqlite's query() can crash on some statements.
|
|
183
|
+
const results: Record<string, unknown>[] = [];
|
|
184
|
+
let columnNames: string[] | null = null;
|
|
185
|
+
await waDb.exec(
|
|
186
|
+
query,
|
|
187
|
+
(row: unknown[], columns: string[]) => {
|
|
188
|
+
if (!columnNames) {
|
|
189
|
+
columnNames = columns;
|
|
190
|
+
}
|
|
191
|
+
const obj: Record<string, unknown> = {};
|
|
192
|
+
for (let i = 0; i < row.length; i++) {
|
|
193
|
+
obj[columnNames[i]] = row[i];
|
|
194
|
+
}
|
|
195
|
+
results.push(obj);
|
|
196
|
+
},
|
|
197
|
+
);
|
|
198
|
+
return results as TRow[];
|
|
199
|
+
});
|
|
200
|
+
},
|
|
201
|
+
close: async () => {
|
|
202
|
+
await mutex.run(async () => {
|
|
203
|
+
if (closed) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
closed = true;
|
|
207
|
+
await waDb.close();
|
|
208
|
+
waDbInstance = null;
|
|
209
|
+
});
|
|
210
|
+
},
|
|
211
|
+
} satisfies RawAccess);
|
|
212
|
+
},
|
|
213
|
+
onMigrate: async (_client) => {
|
|
214
|
+
if (config?.migrations && waDbInstance) {
|
|
215
|
+
await runInlineMigrations(
|
|
216
|
+
waDbInstance,
|
|
217
|
+
mutex,
|
|
218
|
+
config.migrations,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
onDestroy: async (client) => {
|
|
223
|
+
await client.close();
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export * from "drizzle-orm/sqlite-core";
|
|
2
|
+
export {
|
|
3
|
+
blob,
|
|
4
|
+
check,
|
|
5
|
+
extractUsedTable,
|
|
6
|
+
foreignKey,
|
|
7
|
+
getTableConfig,
|
|
8
|
+
getViewConfig,
|
|
9
|
+
index,
|
|
10
|
+
integer,
|
|
11
|
+
numeric,
|
|
12
|
+
primaryKey,
|
|
13
|
+
real,
|
|
14
|
+
sqliteTable,
|
|
15
|
+
sqliteTableCreator,
|
|
16
|
+
sqliteView,
|
|
17
|
+
text,
|
|
18
|
+
unique,
|
|
19
|
+
uniqueIndex,
|
|
20
|
+
uniqueKeyName,
|
|
21
|
+
view,
|
|
22
|
+
} from "drizzle-orm/sqlite-core";
|
package/src/db/mod.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { DatabaseProvider, RawAccess } from "./config";
|
|
2
|
+
import { AsyncMutex, createActorKvStore, toSqliteBindings } from "./shared";
|
|
3
|
+
|
|
4
|
+
export type { RawAccess } from "./config";
|
|
5
|
+
|
|
6
|
+
interface DatabaseFactoryConfig {
|
|
7
|
+
onMigrate?: (db: RawAccess) => Promise<void> | void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function db({
|
|
11
|
+
onMigrate,
|
|
12
|
+
}: DatabaseFactoryConfig = {}): DatabaseProvider<RawAccess> {
|
|
13
|
+
return {
|
|
14
|
+
createClient: async (ctx) => {
|
|
15
|
+
// Check if override is provided
|
|
16
|
+
const override = ctx.overrideRawDatabaseClient
|
|
17
|
+
? await ctx.overrideRawDatabaseClient()
|
|
18
|
+
: undefined;
|
|
19
|
+
|
|
20
|
+
if (override) {
|
|
21
|
+
// Use the override
|
|
22
|
+
return {
|
|
23
|
+
execute: async <
|
|
24
|
+
TRow extends Record<string, unknown> = Record<string, unknown>,
|
|
25
|
+
>(
|
|
26
|
+
query: string,
|
|
27
|
+
...args: unknown[]
|
|
28
|
+
): Promise<TRow[]> => {
|
|
29
|
+
return await override.exec<TRow>(query, ...args);
|
|
30
|
+
},
|
|
31
|
+
close: async () => {
|
|
32
|
+
// Override clients don't need cleanup
|
|
33
|
+
},
|
|
34
|
+
} satisfies RawAccess;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Construct KV-backed client using actor driver's KV operations
|
|
38
|
+
if (!ctx.sqliteVfs) {
|
|
39
|
+
throw new Error("SqliteVfs instance not provided in context. The driver must provide a sqliteVfs instance.");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const kvStore = createActorKvStore(ctx.kv);
|
|
43
|
+
const db = await ctx.sqliteVfs.open(ctx.actorId, kvStore);
|
|
44
|
+
let closed = false;
|
|
45
|
+
const mutex = new AsyncMutex();
|
|
46
|
+
const ensureOpen = () => {
|
|
47
|
+
if (closed) {
|
|
48
|
+
throw new Error("database is closed");
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
execute: async <
|
|
54
|
+
TRow extends Record<string, unknown> = Record<string, unknown>,
|
|
55
|
+
>(
|
|
56
|
+
query: string,
|
|
57
|
+
...args: unknown[]
|
|
58
|
+
): Promise<TRow[]> => {
|
|
59
|
+
return await mutex.run(async () => {
|
|
60
|
+
ensureOpen();
|
|
61
|
+
|
|
62
|
+
// `db.exec` does not support binding `?` placeholders.
|
|
63
|
+
// Use `db.query` for statements that return rows and `db.run` for
|
|
64
|
+
// statements that mutate data when parameters are provided.
|
|
65
|
+
// Keep using `db.exec` for non-parameterized SQL because it
|
|
66
|
+
// supports multi-statement migrations.
|
|
67
|
+
if (args.length > 0) {
|
|
68
|
+
const bindings = toSqliteBindings(args);
|
|
69
|
+
const token = query.trimStart().slice(0, 16).toUpperCase();
|
|
70
|
+
const returnsRows =
|
|
71
|
+
token.startsWith("SELECT") ||
|
|
72
|
+
token.startsWith("PRAGMA") ||
|
|
73
|
+
token.startsWith("WITH");
|
|
74
|
+
|
|
75
|
+
if (returnsRows) {
|
|
76
|
+
const { rows, columns } = await db.query(query, bindings);
|
|
77
|
+
return rows.map((row: unknown[]) => {
|
|
78
|
+
const rowObj: Record<string, unknown> = {};
|
|
79
|
+
for (let i = 0; i < columns.length; i++) {
|
|
80
|
+
rowObj[columns[i]] = row[i];
|
|
81
|
+
}
|
|
82
|
+
return rowObj;
|
|
83
|
+
}) as TRow[];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
await db.run(query, bindings);
|
|
87
|
+
return [] as TRow[];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const results: Record<string, unknown>[] = [];
|
|
91
|
+
let columnNames: string[] | null = null;
|
|
92
|
+
await db.exec(query, (row: unknown[], columns: string[]) => {
|
|
93
|
+
if (!columnNames) {
|
|
94
|
+
columnNames = columns;
|
|
95
|
+
}
|
|
96
|
+
const rowObj: Record<string, unknown> = {};
|
|
97
|
+
for (let i = 0; i < row.length; i++) {
|
|
98
|
+
rowObj[columnNames[i]] = row[i];
|
|
99
|
+
}
|
|
100
|
+
results.push(rowObj);
|
|
101
|
+
});
|
|
102
|
+
return results as TRow[];
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
close: async () => {
|
|
106
|
+
await mutex.run(async () => {
|
|
107
|
+
if (closed) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
closed = true;
|
|
111
|
+
await db.close();
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
} satisfies RawAccess;
|
|
115
|
+
},
|
|
116
|
+
onMigrate: async (client) => {
|
|
117
|
+
if (onMigrate) {
|
|
118
|
+
await onMigrate(client);
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
onDestroy: async (client) => {
|
|
122
|
+
await client.close();
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|