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
|
@@ -3,10 +3,25 @@ import { setupDriverTest } from "../utils";
|
|
|
3
3
|
import { describe, expect, test, type TestContext } from "vitest";
|
|
4
4
|
|
|
5
5
|
export function runActorKvTests(driverTestConfig: DriverTestConfig) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
type KvTextHandle = {
|
|
7
|
+
putText: (key: string, value: string) => Promise<unknown>;
|
|
8
|
+
getText: (key: string) => Promise<string | null>;
|
|
9
|
+
listText: (prefix: string) => Promise<Array<{ key: string; value: string }>>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type KvArrayBufferHandle = {
|
|
13
|
+
roundtripArrayBuffer: (key: string, bytes: number[]) => Promise<number[]>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
describe("Actor KV Tests", () => {
|
|
17
|
+
test("supports text encoding and decoding", async (c: TestContext) => {
|
|
18
|
+
const { client: rawClient } = await setupDriverTest(
|
|
19
|
+
c,
|
|
20
|
+
driverTestConfig,
|
|
21
|
+
);
|
|
22
|
+
const client = rawClient as any;
|
|
23
|
+
const kvHandle =
|
|
24
|
+
client.kvActor.getOrCreate(["kv-text"]) as unknown as KvTextHandle;
|
|
10
25
|
|
|
11
26
|
await kvHandle.putText("greeting", "hello");
|
|
12
27
|
const value = await kvHandle.getText("greeting");
|
|
@@ -26,19 +41,25 @@ export function runActorKvTests(driverTestConfig: DriverTestConfig) {
|
|
|
26
41
|
test(
|
|
27
42
|
"supports arrayBuffer encoding and decoding",
|
|
28
43
|
async (c: TestContext) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
const { client: rawClient } = await setupDriverTest(
|
|
45
|
+
c,
|
|
46
|
+
driverTestConfig,
|
|
47
|
+
);
|
|
48
|
+
const client = rawClient as any;
|
|
49
|
+
const kvHandle = client.kvActor.getOrCreate([
|
|
50
|
+
"kv-array-buffer",
|
|
51
|
+
]) as unknown as KvArrayBufferHandle;
|
|
52
|
+
|
|
53
|
+
const values = await kvHandle.roundtripArrayBuffer("bytes", [
|
|
54
|
+
4,
|
|
55
|
+
8,
|
|
56
|
+
15,
|
|
57
|
+
16,
|
|
58
|
+
23,
|
|
59
|
+
42,
|
|
60
|
+
]);
|
|
61
|
+
expect(values).toEqual([4, 8, 15, 16, 23, 42]);
|
|
62
|
+
},
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import type { ActorError } from "@/client/mod";
|
|
3
|
+
import type { DriverTestConfig } from "../mod";
|
|
4
|
+
import { setupDriverTest, waitFor } from "../utils";
|
|
5
|
+
|
|
6
|
+
export function runActorQueueTests(driverTestConfig: DriverTestConfig) {
|
|
7
|
+
describe("Actor Queue Tests", () => {
|
|
8
|
+
test("client can send to actor queue", async (c) => {
|
|
9
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
10
|
+
const handle = client.queueActor.getOrCreate(["client-send"]);
|
|
11
|
+
|
|
12
|
+
await handle.send("greeting", { hello: "world" });
|
|
13
|
+
|
|
14
|
+
const message = await handle.receiveOne("greeting");
|
|
15
|
+
expect(message).toEqual({
|
|
16
|
+
name: "greeting",
|
|
17
|
+
body: { hello: "world" },
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("actor can send to its own queue", async (c) => {
|
|
22
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
23
|
+
const handle = client.queueActor.getOrCreate(["self-send"]);
|
|
24
|
+
|
|
25
|
+
await handle.sendToSelf("self", { value: 42 });
|
|
26
|
+
|
|
27
|
+
const message = await handle.receiveOne("self");
|
|
28
|
+
expect(message).toEqual({ name: "self", body: { value: 42 } });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("next supports name arrays and counts", async (c) => {
|
|
32
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
33
|
+
const handle = client.queueActor.getOrCreate(["receive-array"]);
|
|
34
|
+
|
|
35
|
+
await handle.send("a", 1);
|
|
36
|
+
await handle.send("b", 2);
|
|
37
|
+
await handle.send("c", 3);
|
|
38
|
+
|
|
39
|
+
const messages = await handle.receiveMany(["a", "b"], { count: 2 });
|
|
40
|
+
expect(messages).toEqual([
|
|
41
|
+
{ name: "a", body: 1 },
|
|
42
|
+
{ name: "b", body: 2 },
|
|
43
|
+
]);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("next supports request objects", async (c) => {
|
|
47
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
48
|
+
const handle = client.queueActor.getOrCreate(["receive-request"]);
|
|
49
|
+
|
|
50
|
+
await handle.send("one", "first");
|
|
51
|
+
await handle.send("two", "second");
|
|
52
|
+
|
|
53
|
+
const messages = await handle.receiveRequest({
|
|
54
|
+
names: ["one", "two"],
|
|
55
|
+
count: 2,
|
|
56
|
+
});
|
|
57
|
+
expect(messages).toEqual([
|
|
58
|
+
{ name: "one", body: "first" },
|
|
59
|
+
{ name: "two", body: "second" },
|
|
60
|
+
]);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("next defaults to all names when names is omitted", async (c) => {
|
|
64
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
65
|
+
const handle = client.queueActor.getOrCreate([
|
|
66
|
+
"receive-request-all",
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
await handle.send("one", "first");
|
|
70
|
+
await handle.send("two", "second");
|
|
71
|
+
|
|
72
|
+
const messages = await handle.receiveRequest({ count: 2 });
|
|
73
|
+
expect(messages).toEqual([
|
|
74
|
+
{ name: "one", body: "first" },
|
|
75
|
+
{ name: "two", body: "second" },
|
|
76
|
+
]);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("next timeout returns empty array", async (c) => {
|
|
80
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
81
|
+
const handle = client.queueActor.getOrCreate(["receive-timeout"]);
|
|
82
|
+
|
|
83
|
+
const promise = handle.receiveMany(["missing"], { timeout: 50 });
|
|
84
|
+
await waitFor(driverTestConfig, 60);
|
|
85
|
+
const messages = await promise;
|
|
86
|
+
expect(messages).toEqual([]);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("tryNext does not wait and returns empty array", async (c) => {
|
|
90
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
91
|
+
const handle = client.queueActor.getOrCreate(["try-next-empty"]);
|
|
92
|
+
|
|
93
|
+
const messages = await handle.tryReceiveMany({
|
|
94
|
+
names: ["missing"],
|
|
95
|
+
count: 1,
|
|
96
|
+
});
|
|
97
|
+
expect(messages).toEqual([]);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("abort throws ActorAborted", async (c) => {
|
|
101
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
102
|
+
const handle = client.queueActor.getOrCreate(["abort-test"]);
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
await handle.waitForAbort();
|
|
106
|
+
expect.fail("expected ActorAborted error");
|
|
107
|
+
} catch (error) {
|
|
108
|
+
expect((error as ActorError).group).toBe("actor");
|
|
109
|
+
expect((error as ActorError).code).toBe("aborted");
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test("next supports signal abort", async (c) => {
|
|
114
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
115
|
+
const handle = client.queueActor.getOrCreate(["signal-abort-next"]);
|
|
116
|
+
|
|
117
|
+
const result = await handle.waitForSignalAbort();
|
|
118
|
+
expect(result).toEqual({
|
|
119
|
+
group: "actor",
|
|
120
|
+
code: "aborted",
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("next supports actor abort when signal is provided", async (c) => {
|
|
125
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
126
|
+
const handle = client.queueActor.getOrCreate([
|
|
127
|
+
"actor-abort-with-signal-next",
|
|
128
|
+
]);
|
|
129
|
+
|
|
130
|
+
const result = await handle.waitForActorAbortWithSignal();
|
|
131
|
+
expect(result).toEqual({
|
|
132
|
+
group: "actor",
|
|
133
|
+
code: "aborted",
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test("iter supports signal abort", async (c) => {
|
|
138
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
139
|
+
const handle = client.queueActor.getOrCreate(["signal-abort-iter"]);
|
|
140
|
+
|
|
141
|
+
const result = await handle.iterWithSignalAbort();
|
|
142
|
+
expect(result).toEqual({ ok: true });
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test("enforces queue size limit", async (c) => {
|
|
146
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
147
|
+
const key = `size-limit-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
148
|
+
const handle = client.queueLimitedActor.getOrCreate([key]);
|
|
149
|
+
|
|
150
|
+
await handle.send("message", 1);
|
|
151
|
+
|
|
152
|
+
await waitFor(driverTestConfig, 10);
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
await handle.send("message", 2);
|
|
156
|
+
expect.fail("expected queue full error");
|
|
157
|
+
} catch (error) {
|
|
158
|
+
expect(error).toBeInstanceOf(Error);
|
|
159
|
+
expect((error as Error).message).toContain(
|
|
160
|
+
"Queue is full. Limit is",
|
|
161
|
+
);
|
|
162
|
+
if (driverTestConfig.clientType !== "http") {
|
|
163
|
+
expect((error as ActorError).group).toBe("queue");
|
|
164
|
+
expect((error as ActorError).code).toBe("full");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test("enforces message size limit", async (c) => {
|
|
170
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
171
|
+
const handle = client.queueLimitedActor.getOrCreate([
|
|
172
|
+
"message-limit",
|
|
173
|
+
]);
|
|
174
|
+
const largePayload = "a".repeat(200);
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
await handle.send("oversize", largePayload);
|
|
178
|
+
expect.fail("expected message_too_large error");
|
|
179
|
+
} catch (error) {
|
|
180
|
+
expect((error as ActorError).group).toBe("queue");
|
|
181
|
+
expect((error as ActorError).code).toBe("message_too_large");
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test("wait send returns completion response", async (c) => {
|
|
186
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
187
|
+
const handle = client.queueActor.getOrCreate(["wait-complete"]);
|
|
188
|
+
|
|
189
|
+
const actionPromise = handle.receiveAndComplete("tasks");
|
|
190
|
+
const result = await handle.send("tasks",
|
|
191
|
+
{ value: 123 },
|
|
192
|
+
{ wait: true, timeout: 1_000 },
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
await actionPromise;
|
|
196
|
+
expect(result).toEqual({
|
|
197
|
+
status: "completed",
|
|
198
|
+
response: { echo: { value: 123 } },
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test("wait send times out", async (c) => {
|
|
203
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
204
|
+
const handle = client.queueActor.getOrCreate(["wait-timeout"]);
|
|
205
|
+
|
|
206
|
+
const resultPromise = handle.send("timeout",
|
|
207
|
+
{ value: 456 },
|
|
208
|
+
{ wait: true, timeout: 50 },
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
await waitFor(driverTestConfig, 60);
|
|
212
|
+
const result = await resultPromise;
|
|
213
|
+
|
|
214
|
+
expect(result.status).toBe("timedOut");
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
test("manual receive retries message when not completed", async (c) => {
|
|
218
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
219
|
+
const handle = client.queueActor.getOrCreate([
|
|
220
|
+
"manual-retry-uncompleted",
|
|
221
|
+
]);
|
|
222
|
+
|
|
223
|
+
await handle.send("tasks", { value: 789 });
|
|
224
|
+
const first = await handle.receiveWithoutComplete("tasks");
|
|
225
|
+
expect(first).toEqual({ name: "tasks", body: { value: 789 } });
|
|
226
|
+
|
|
227
|
+
const retried = await handle.receiveOne("tasks", { timeout: 1_000 });
|
|
228
|
+
expect(retried).toEqual({ name: "tasks", body: { value: 789 } });
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test("next throws when previous manual message is not completed", async (c) => {
|
|
232
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
233
|
+
const handle = client.queueActor.getOrCreate([
|
|
234
|
+
"manual-next-requires-complete",
|
|
235
|
+
]);
|
|
236
|
+
|
|
237
|
+
await handle.send("tasks", { value: 111 });
|
|
238
|
+
const result = await handle.receiveManualThenNextWithoutComplete(
|
|
239
|
+
"tasks",
|
|
240
|
+
);
|
|
241
|
+
expect(result).toEqual({
|
|
242
|
+
group: "queue",
|
|
243
|
+
code: "previous_message_not_completed",
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test("manual receive includes complete even without completion schema", async (c) => {
|
|
248
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
249
|
+
const handle = client.queueActor.getOrCreate([
|
|
250
|
+
"complete-not-allowed",
|
|
251
|
+
]);
|
|
252
|
+
|
|
253
|
+
await handle.send("nowait", { value: "test" });
|
|
254
|
+
const result = await handle.receiveWithoutCompleteMethod("nowait");
|
|
255
|
+
|
|
256
|
+
expect(result).toEqual({
|
|
257
|
+
hasComplete: true,
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test("manual receive retries queues without completion schema until completed", async (c) => {
|
|
262
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
263
|
+
const handle = client.queueActor.getOrCreate([
|
|
264
|
+
"complete-not-allowed-consume",
|
|
265
|
+
]);
|
|
266
|
+
|
|
267
|
+
await handle.send("nowait", { value: "test" });
|
|
268
|
+
const result = await handle.receiveWithoutCompleteMethod("nowait");
|
|
269
|
+
expect(result).toEqual({ hasComplete: true });
|
|
270
|
+
|
|
271
|
+
const next = await handle.receiveOne("nowait", { timeout: 1_000 });
|
|
272
|
+
expect(next).toEqual({ name: "nowait", body: { value: "test" } });
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test("complete throws when called twice", async (c) => {
|
|
276
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
277
|
+
const handle = client.queueActor.getOrCreate([
|
|
278
|
+
"complete-twice",
|
|
279
|
+
]);
|
|
280
|
+
|
|
281
|
+
await handle.send("twice", { value: "test" });
|
|
282
|
+
const result = await handle.receiveAndCompleteTwice("twice");
|
|
283
|
+
|
|
284
|
+
expect(result).toEqual({
|
|
285
|
+
group: "queue",
|
|
286
|
+
code: "already_completed",
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
test("wait send no longer requires queue completion schema", async (c) => {
|
|
291
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
292
|
+
const handle = client.queueActor.getOrCreate([
|
|
293
|
+
"missing-completion-schema",
|
|
294
|
+
]);
|
|
295
|
+
|
|
296
|
+
const result = await handle.send(
|
|
297
|
+
"nowait",
|
|
298
|
+
{ value: "test" },
|
|
299
|
+
{ wait: true, timeout: 50 },
|
|
300
|
+
);
|
|
301
|
+
expect(result).toEqual({ status: "timedOut" });
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
test("iter can consume queued messages", async (c) => {
|
|
305
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
306
|
+
const handle = client.queueActor.getOrCreate(["iter-consume"]);
|
|
307
|
+
|
|
308
|
+
await handle.send("one", "first");
|
|
309
|
+
const message = await handle.receiveWithIterator("one");
|
|
310
|
+
expect(message).toEqual({ name: "one", body: "first" });
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
test("queue async iterator can consume queued messages", async (c) => {
|
|
314
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
315
|
+
const handle = client.queueActor.getOrCreate([
|
|
316
|
+
"async-iter-consume",
|
|
317
|
+
]);
|
|
318
|
+
|
|
319
|
+
await handle.send("two", "second");
|
|
320
|
+
const message = await handle.receiveWithAsyncIterator();
|
|
321
|
+
expect(message).toEqual({ name: "two", body: "second" });
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { RUN_SLEEP_TIMEOUT } from "../../../fixtures/driver-test-suite/run";
|
|
3
|
+
import type { DriverTestConfig } from "../mod";
|
|
4
|
+
import { setupDriverTest, waitFor } from "../utils";
|
|
5
|
+
|
|
6
|
+
export function runActorRunTests(driverTestConfig: DriverTestConfig) {
|
|
7
|
+
describe.skipIf(driverTestConfig.skip?.sleep)("Actor Run Tests", () => {
|
|
8
|
+
test("run handler starts after actor startup", async (c) => {
|
|
9
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
10
|
+
|
|
11
|
+
const actor = client.runWithTicks.getOrCreate(["run-starts"]);
|
|
12
|
+
|
|
13
|
+
// Wait a bit for run handler to start
|
|
14
|
+
await waitFor(driverTestConfig, 100);
|
|
15
|
+
|
|
16
|
+
const state = await actor.getState();
|
|
17
|
+
expect(state.runStarted).toBe(true);
|
|
18
|
+
expect(state.tickCount).toBeGreaterThan(0);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("run handler ticks continuously", async (c) => {
|
|
22
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
23
|
+
|
|
24
|
+
const actor = client.runWithTicks.getOrCreate(["run-ticks"]);
|
|
25
|
+
|
|
26
|
+
// Wait for some ticks
|
|
27
|
+
await waitFor(driverTestConfig, 200);
|
|
28
|
+
|
|
29
|
+
const state1 = await actor.getState();
|
|
30
|
+
expect(state1.tickCount).toBeGreaterThan(0);
|
|
31
|
+
|
|
32
|
+
const count1 = state1.tickCount;
|
|
33
|
+
|
|
34
|
+
// Wait more and check tick count increased
|
|
35
|
+
await waitFor(driverTestConfig, 200);
|
|
36
|
+
|
|
37
|
+
const state2 = await actor.getState();
|
|
38
|
+
expect(state2.tickCount).toBeGreaterThan(count1);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("active run handler keeps actor awake past sleep timeout", async (c) => {
|
|
42
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
43
|
+
|
|
44
|
+
const actor = client.runWithTicks.getOrCreate([
|
|
45
|
+
"run-stays-awake",
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
// Wait for run to start
|
|
49
|
+
await waitFor(driverTestConfig, 100);
|
|
50
|
+
|
|
51
|
+
const state1 = await actor.getState();
|
|
52
|
+
expect(state1.runStarted).toBe(true);
|
|
53
|
+
const tickCount1 = state1.tickCount;
|
|
54
|
+
|
|
55
|
+
// Active run loops should keep the actor awake.
|
|
56
|
+
await waitFor(driverTestConfig, RUN_SLEEP_TIMEOUT + 300);
|
|
57
|
+
|
|
58
|
+
const state2 = await actor.getState();
|
|
59
|
+
expect(state2.runStarted).toBe(true);
|
|
60
|
+
expect(state2.runExited).toBe(false);
|
|
61
|
+
expect(state2.tickCount).toBeGreaterThan(tickCount1);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("actor without run handler works normally", async (c) => {
|
|
65
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
66
|
+
|
|
67
|
+
const actor = client.runWithoutHandler.getOrCreate([
|
|
68
|
+
"no-run-handler",
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
const state = await actor.getState();
|
|
72
|
+
expect(state.wakeCount).toBe(1);
|
|
73
|
+
|
|
74
|
+
// Wait for sleep and wake again
|
|
75
|
+
await waitFor(driverTestConfig, RUN_SLEEP_TIMEOUT + 300);
|
|
76
|
+
|
|
77
|
+
const state2 = await actor.getState();
|
|
78
|
+
expect(state2.wakeCount).toBe(2);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("run handler can consume from queue", async (c) => {
|
|
82
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
83
|
+
|
|
84
|
+
const actor = client.runWithQueueConsumer.getOrCreate([
|
|
85
|
+
"queue-consumer",
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
// Wait for run handler to start
|
|
89
|
+
await waitFor(driverTestConfig, 100);
|
|
90
|
+
|
|
91
|
+
// Send some messages to the queue
|
|
92
|
+
await actor.sendMessage({ type: "test", value: 1 });
|
|
93
|
+
await actor.sendMessage({ type: "test", value: 2 });
|
|
94
|
+
await actor.sendMessage({ type: "test", value: 3 });
|
|
95
|
+
|
|
96
|
+
// Wait for messages to be consumed
|
|
97
|
+
await waitFor(driverTestConfig, 1200);
|
|
98
|
+
|
|
99
|
+
const state = await actor.getState();
|
|
100
|
+
expect(state.runStarted).toBe(true);
|
|
101
|
+
expect(state.messagesReceived.length).toBe(3);
|
|
102
|
+
expect(state.messagesReceived[0].body).toEqual({
|
|
103
|
+
type: "test",
|
|
104
|
+
value: 1,
|
|
105
|
+
});
|
|
106
|
+
expect(state.messagesReceived[1].body).toEqual({
|
|
107
|
+
type: "test",
|
|
108
|
+
value: 2,
|
|
109
|
+
});
|
|
110
|
+
expect(state.messagesReceived[2].body).toEqual({
|
|
111
|
+
type: "test",
|
|
112
|
+
value: 3,
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test("queue-waiting run handler can sleep and resume", async (c) => {
|
|
117
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
118
|
+
|
|
119
|
+
const actor = client.runWithQueueConsumer.getOrCreate([
|
|
120
|
+
"queue-consumer-sleep",
|
|
121
|
+
]);
|
|
122
|
+
|
|
123
|
+
await waitFor(driverTestConfig, 100);
|
|
124
|
+
const state1 = await actor.getState();
|
|
125
|
+
expect(state1.runStarted).toBe(true);
|
|
126
|
+
|
|
127
|
+
await waitFor(driverTestConfig, RUN_SLEEP_TIMEOUT + 500);
|
|
128
|
+
const state2 = await actor.getState();
|
|
129
|
+
|
|
130
|
+
expect(state2.wakeCount).toBeGreaterThan(state1.wakeCount);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test("run handler that exits early triggers destroy", async (c) => {
|
|
134
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
135
|
+
|
|
136
|
+
const actor = client.runWithEarlyExit.getOrCreate(["early-exit"]);
|
|
137
|
+
|
|
138
|
+
// Wait for run to start and exit
|
|
139
|
+
await waitFor(driverTestConfig, 100);
|
|
140
|
+
|
|
141
|
+
const state1 = await actor.getState();
|
|
142
|
+
expect(state1.runStarted).toBe(true);
|
|
143
|
+
|
|
144
|
+
// Wait for the actor to be destroyed
|
|
145
|
+
await waitFor(driverTestConfig, 300);
|
|
146
|
+
|
|
147
|
+
// After the run handler exits early, the actor should be destroyed.
|
|
148
|
+
// Depending on the driver, it may be in a destroyed state or recreated.
|
|
149
|
+
// In the file-system driver test environment, the actor is not automatically
|
|
150
|
+
// rescheduled, so we just verify the initial behavior worked.
|
|
151
|
+
// A new getOrCreate should create a fresh actor.
|
|
152
|
+
const actor2 = client.runWithEarlyExit.getOrCreate([
|
|
153
|
+
"early-exit-fresh",
|
|
154
|
+
]);
|
|
155
|
+
const state2 = await actor2.getState();
|
|
156
|
+
expect(state2.runStarted).toBe(true);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test("run handler that throws error triggers destroy", async (c) => {
|
|
160
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
161
|
+
|
|
162
|
+
const actor = client.runWithError.getOrCreate(["run-error"]);
|
|
163
|
+
|
|
164
|
+
// Wait for run to start and throw
|
|
165
|
+
await waitFor(driverTestConfig, 100);
|
|
166
|
+
|
|
167
|
+
const state1 = await actor.getState();
|
|
168
|
+
expect(state1.runStarted).toBe(true);
|
|
169
|
+
|
|
170
|
+
// Wait for the actor to be destroyed
|
|
171
|
+
await waitFor(driverTestConfig, 300);
|
|
172
|
+
|
|
173
|
+
// After the run handler throws, the actor should be destroyed.
|
|
174
|
+
// Similar to the early exit test, the driver may not automatically reschedule.
|
|
175
|
+
// A new getOrCreate should create a fresh actor.
|
|
176
|
+
const actor2 = client.runWithError.getOrCreate(["run-error-fresh"]);
|
|
177
|
+
const state2 = await actor2.getState();
|
|
178
|
+
expect(state2.runStarted).toBe(true);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
}
|
|
@@ -76,12 +76,15 @@ export function runActorScheduleTests(driverTestConfig: DriverTestConfig) {
|
|
|
76
76
|
// Wait for first task only
|
|
77
77
|
await waitFor(driverTestConfig, 500);
|
|
78
78
|
const history1 = await scheduled.getTaskHistory();
|
|
79
|
-
expect(history1).
|
|
79
|
+
expect(history1[0]).toBe("first");
|
|
80
80
|
|
|
81
81
|
// Wait for second task
|
|
82
82
|
await waitFor(driverTestConfig, 500);
|
|
83
83
|
const history2 = await scheduled.getTaskHistory();
|
|
84
|
-
expect(history2).toEqual([
|
|
84
|
+
expect(history2.slice(0, 2)).toEqual([
|
|
85
|
+
"first",
|
|
86
|
+
"second",
|
|
87
|
+
]);
|
|
85
88
|
|
|
86
89
|
// Wait for third task
|
|
87
90
|
await waitFor(driverTestConfig, 500);
|
|
@@ -283,7 +283,7 @@ export function runActorSleepTests(driverTestConfig: DriverTestConfig) {
|
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
// Connect WebSocket
|
|
286
|
-
const ws = await sleepActor.
|
|
286
|
+
const ws = await sleepActor.webSocket();
|
|
287
287
|
|
|
288
288
|
await new Promise<void>((resolve, reject) => {
|
|
289
289
|
ws.onopen = () => resolve();
|
|
@@ -292,7 +292,7 @@ export function runActorSleepTests(driverTestConfig: DriverTestConfig) {
|
|
|
292
292
|
|
|
293
293
|
// Wait for connection message
|
|
294
294
|
await new Promise<void>((resolve) => {
|
|
295
|
-
ws.onmessage = (event) => {
|
|
295
|
+
ws.onmessage = (event: { data: string }) => {
|
|
296
296
|
const data = JSON.parse(event.data);
|
|
297
297
|
if (data.type === "connected") {
|
|
298
298
|
resolve();
|
|
@@ -307,7 +307,7 @@ export function runActorSleepTests(driverTestConfig: DriverTestConfig) {
|
|
|
307
307
|
ws.send(JSON.stringify({ type: "getCounts" }));
|
|
308
308
|
|
|
309
309
|
const counts = await new Promise<any>((resolve) => {
|
|
310
|
-
ws.onmessage = (event) => {
|
|
310
|
+
ws.onmessage = (event: { data: string }) => {
|
|
311
311
|
const data = JSON.parse(event.data);
|
|
312
312
|
if (data.type === "counts") {
|
|
313
313
|
resolve(data);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import type { DriverTestConfig } from "../mod";
|
|
3
|
+
import { setupDriverTest } from "../utils";
|
|
4
|
+
|
|
5
|
+
export function runActorStatelessTests(driverTestConfig: DriverTestConfig) {
|
|
6
|
+
describe("Actor Stateless Tests", () => {
|
|
7
|
+
describe("Stateless Actor Operations", () => {
|
|
8
|
+
test("can call actions on stateless actor", async (c) => {
|
|
9
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
10
|
+
|
|
11
|
+
const instance = client.statelessActor.getOrCreate();
|
|
12
|
+
|
|
13
|
+
const result = await instance.ping();
|
|
14
|
+
expect(result).toBe("pong");
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("can echo messages", async (c) => {
|
|
18
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
19
|
+
|
|
20
|
+
const instance = client.statelessActor.getOrCreate();
|
|
21
|
+
|
|
22
|
+
const message = "Hello, World!";
|
|
23
|
+
const result = await instance.echo(message);
|
|
24
|
+
expect(result).toBe(message);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("can access actorId", async (c) => {
|
|
28
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
29
|
+
|
|
30
|
+
const instance = client.statelessActor.getOrCreate(["test-id"]);
|
|
31
|
+
|
|
32
|
+
const actorId = await instance.getActorId();
|
|
33
|
+
expect(actorId).toBeDefined();
|
|
34
|
+
expect(typeof actorId).toBe("string");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("accessing state throws StateNotEnabled", async (c) => {
|
|
38
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
39
|
+
|
|
40
|
+
const instance = client.statelessActor.getOrCreate();
|
|
41
|
+
|
|
42
|
+
const result = await instance.tryGetState();
|
|
43
|
+
expect(result.success).toBe(false);
|
|
44
|
+
expect(result.error).toContain("state");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("accessing db throws DatabaseNotEnabled", async (c) => {
|
|
48
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
49
|
+
|
|
50
|
+
const instance = client.statelessActor.getOrCreate();
|
|
51
|
+
|
|
52
|
+
const result = await instance.tryGetDb();
|
|
53
|
+
expect(result.success).toBe(false);
|
|
54
|
+
expect(result.error).toContain("database");
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("multiple stateless actors can exist independently", async (c) => {
|
|
58
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
59
|
+
|
|
60
|
+
const actor1 = client.statelessActor.getOrCreate(["actor-1"]);
|
|
61
|
+
const actor2 = client.statelessActor.getOrCreate(["actor-2"]);
|
|
62
|
+
|
|
63
|
+
const id1 = await actor1.getActorId();
|
|
64
|
+
const id2 = await actor2.getActorId();
|
|
65
|
+
|
|
66
|
+
expect(id1).not.toBe(id2);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|