rivetkit 2.3.30 → 3.0.0-preview.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.
Files changed (135) hide show
  1. package/dist/browser/client.d.ts +58 -9
  2. package/dist/browser/client.js +193 -20
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.js +1 -2
  5. package/dist/browser/inspector/client.js.map +1 -1
  6. package/dist/tsup/{chunk-5UUOECX2.cjs → chunk-3E2BPHQO.cjs} +10 -10
  7. package/dist/tsup/{chunk-5UUOECX2.cjs.map → chunk-3E2BPHQO.cjs.map} +1 -1
  8. package/dist/tsup/{chunk-I472KTIC.js → chunk-3MMTF3QA.js} +188 -28
  9. package/dist/tsup/chunk-3MMTF3QA.js.map +1 -0
  10. package/dist/tsup/{chunk-CORYIKDC.js → chunk-5OCN7VHH.js} +10 -11
  11. package/dist/tsup/chunk-5OCN7VHH.js.map +1 -0
  12. package/dist/tsup/{chunk-OJFVABRH.cjs → chunk-6DDQSAAT.cjs} +7 -7
  13. package/dist/tsup/{chunk-OJFVABRH.cjs.map → chunk-6DDQSAAT.cjs.map} +1 -1
  14. package/dist/tsup/{chunk-JI6GZ2C2.js → chunk-A2CF6PFH.js} +18 -1
  15. package/dist/tsup/chunk-A2CF6PFH.js.map +1 -0
  16. package/dist/tsup/{chunk-P2PHHJMH.cjs → chunk-CTQKKUZC.cjs} +327 -167
  17. package/dist/tsup/chunk-CTQKKUZC.cjs.map +1 -0
  18. package/dist/tsup/{chunk-H3SGQEHZ.js → chunk-DCDCHB5J.js} +2 -2
  19. package/dist/tsup/{chunk-EKAQ7HG2.js → chunk-DQ6K3VVV.js} +3 -3
  20. package/dist/tsup/{chunk-OUB7SGSA.js → chunk-H6W37YLT.js} +2 -2
  21. package/dist/tsup/{chunk-5SN6GAYX.cjs → chunk-HW2D5OFJ.cjs} +3 -3
  22. package/dist/tsup/{chunk-5SN6GAYX.cjs.map → chunk-HW2D5OFJ.cjs.map} +1 -1
  23. package/dist/tsup/{chunk-2BIRGEIU.cjs → chunk-IBEFA6CX.cjs} +10 -11
  24. package/dist/tsup/chunk-IBEFA6CX.cjs.map +1 -0
  25. package/dist/tsup/{chunk-GEUBEODU.cjs → chunk-JLBPBEWC.cjs} +3 -3
  26. package/dist/tsup/{chunk-GEUBEODU.cjs.map → chunk-JLBPBEWC.cjs.map} +1 -1
  27. package/dist/tsup/{chunk-4SNS3PYZ.js → chunk-KQ2WQDYT.js} +2 -2
  28. package/dist/tsup/{chunk-MYWZCDML.cjs → chunk-RTWH3AX3.cjs} +19 -2
  29. package/dist/tsup/chunk-RTWH3AX3.cjs.map +1 -0
  30. package/dist/tsup/{chunk-6LOYTFPZ.js → chunk-SJPPKBT3.js} +2 -2
  31. package/dist/tsup/{chunk-MXV26ZBB.js → chunk-TBJ4I3R3.js} +4 -4
  32. package/dist/tsup/{chunk-ZIIQQHC3.cjs → chunk-VCVV726P.cjs} +4 -4
  33. package/dist/tsup/{chunk-ZIIQQHC3.cjs.map → chunk-VCVV726P.cjs.map} +1 -1
  34. package/dist/tsup/{chunk-ABPZG7QV.cjs → chunk-XUO6G4H6.cjs} +3 -3
  35. package/dist/tsup/{chunk-ABPZG7QV.cjs.map → chunk-XUO6G4H6.cjs.map} +1 -1
  36. package/dist/tsup/client/mod.cjs +6 -6
  37. package/dist/tsup/client/mod.d.cts +15 -3
  38. package/dist/tsup/client/mod.d.ts +15 -3
  39. package/dist/tsup/client/mod.js +5 -5
  40. package/dist/tsup/common/log.cjs +2 -2
  41. package/dist/tsup/common/log.js +1 -1
  42. package/dist/tsup/common/websocket.cjs +3 -3
  43. package/dist/tsup/common/websocket.js +2 -2
  44. package/dist/tsup/{config-osdJqQwX.d.cts → config-8NgsxIcT.d.cts} +43 -12
  45. package/dist/tsup/{config-ey2I2zz5.d.ts → config-B2wlj9wx.d.cts} +7 -1
  46. package/dist/tsup/{config-ey2I2zz5.d.cts → config-B2wlj9wx.d.ts} +7 -1
  47. package/dist/tsup/{config-Cv6pjCt-.d.ts → config-DJ3KW-fe.d.ts} +43 -12
  48. package/dist/tsup/{context-CoVbKBuk.d.ts → context-BL8kUGjq.d.ts} +2 -2
  49. package/dist/tsup/{context-DpjrM7n7.d.cts → context-_RoE_YHL.d.cts} +2 -2
  50. package/dist/tsup/db/drizzle.cjs +2 -2
  51. package/dist/tsup/db/drizzle.d.cts +1 -1
  52. package/dist/tsup/db/drizzle.d.ts +1 -1
  53. package/dist/tsup/db/drizzle.js +1 -1
  54. package/dist/tsup/db/mod.cjs +3 -3
  55. package/dist/tsup/db/mod.d.cts +2 -2
  56. package/dist/tsup/db/mod.d.ts +2 -2
  57. package/dist/tsup/db/mod.js +2 -2
  58. package/dist/tsup/dynamic/mod.d.cts +2 -2
  59. package/dist/tsup/dynamic/mod.d.ts +2 -2
  60. package/dist/tsup/inspector/mod.cjs +5 -5
  61. package/dist/tsup/inspector/mod.js +4 -4
  62. package/dist/tsup/inspector/workflow.cjs +4 -4
  63. package/dist/tsup/inspector/workflow.js +3 -3
  64. package/dist/tsup/inspector-tab/mod.d.cts +3 -3
  65. package/dist/tsup/inspector-tab/mod.d.ts +3 -3
  66. package/dist/tsup/mod.cjs +254 -166
  67. package/dist/tsup/mod.cjs.map +1 -1
  68. package/dist/tsup/mod.d.cts +4 -4
  69. package/dist/tsup/mod.d.ts +4 -4
  70. package/dist/tsup/mod.js +168 -80
  71. package/dist/tsup/mod.js.map +1 -1
  72. package/dist/tsup/test/mod.cjs +7 -7
  73. package/dist/tsup/test/mod.d.cts +2 -2
  74. package/dist/tsup/test/mod.d.ts +2 -2
  75. package/dist/tsup/test/mod.js +5 -5
  76. package/dist/tsup/unstable/migrations.d.cts +1 -1
  77. package/dist/tsup/unstable/migrations.d.ts +1 -1
  78. package/dist/tsup/utils.cjs +2 -2
  79. package/dist/tsup/utils.js +1 -1
  80. package/dist/tsup/workflow/mod.cjs +17 -17
  81. package/dist/tsup/workflow/mod.d.cts +4 -4
  82. package/dist/tsup/workflow/mod.d.ts +4 -4
  83. package/dist/tsup/workflow/mod.js +5 -5
  84. package/package.json +9 -10
  85. package/src/actor/keys.ts +86 -0
  86. package/src/client/actor-conn.ts +92 -6
  87. package/src/client/actor-handle.ts +21 -3
  88. package/src/client/client.ts +6 -0
  89. package/src/client/config.ts +12 -1
  90. package/src/client/lifecycle-errors.ts +16 -1
  91. package/src/client/retry-budget.ts +78 -0
  92. package/src/client/utils.ts +13 -2
  93. package/src/common/database/config.ts +7 -1
  94. package/src/common/database/native-database.ts +17 -6
  95. package/src/common/router.ts +1 -1
  96. package/src/engine-api/actors.ts +3 -3
  97. package/src/engine-client/actor-websocket-client.ts +4 -2
  98. package/src/engine-client/api-endpoints.ts +44 -14
  99. package/src/engine-client/mod.ts +2 -2
  100. package/src/registry/config/envoy.ts +1 -1
  101. package/src/registry/config/index.ts +28 -31
  102. package/src/registry/index.ts +51 -19
  103. package/src/registry/napi-runtime.ts +3 -2
  104. package/src/registry/native.ts +126 -34
  105. package/src/registry/runtime.ts +27 -10
  106. package/src/registry/wasm-runtime.ts +6 -3
  107. package/src/utils/env-vars.ts +15 -10
  108. package/dist/tsup/chunk-2BIRGEIU.cjs.map +0 -1
  109. package/dist/tsup/chunk-CORYIKDC.js.map +0 -1
  110. package/dist/tsup/chunk-I472KTIC.js.map +0 -1
  111. package/dist/tsup/chunk-JI6GZ2C2.js.map +0 -1
  112. package/dist/tsup/chunk-MYWZCDML.cjs.map +0 -1
  113. package/dist/tsup/chunk-P2PHHJMH.cjs.map +0 -1
  114. package/src/actor/config.test.ts +0 -78
  115. package/src/actor/keys.test.ts +0 -275
  116. package/src/actor/utils.test.ts +0 -48
  117. package/src/client/test.ts +0 -44
  118. package/src/client/token-provider.test.ts +0 -86
  119. package/src/common/database/mod.test.ts +0 -364
  120. package/src/common/database/native-database.test.ts +0 -220
  121. package/src/common/inline-websocket-adapter.test.ts +0 -51
  122. package/src/db/drizzle.test.ts +0 -164
  123. package/src/registry/config/index.test.ts +0 -25
  124. package/src/registry/run-handler-coordinator.test.ts +0 -252
  125. package/src/registry/runtime.test.ts +0 -124
  126. package/src/unstable/migrations.test.ts +0 -170
  127. package/src/utils/endpoint-parser.test.ts +0 -206
  128. package/src/utils.test.ts +0 -34
  129. package/src/workflow/driver.test.ts +0 -62
  130. /package/dist/tsup/{chunk-H3SGQEHZ.js.map → chunk-DCDCHB5J.js.map} +0 -0
  131. /package/dist/tsup/{chunk-EKAQ7HG2.js.map → chunk-DQ6K3VVV.js.map} +0 -0
  132. /package/dist/tsup/{chunk-OUB7SGSA.js.map → chunk-H6W37YLT.js.map} +0 -0
  133. /package/dist/tsup/{chunk-4SNS3PYZ.js.map → chunk-KQ2WQDYT.js.map} +0 -0
  134. /package/dist/tsup/{chunk-6LOYTFPZ.js.map → chunk-SJPPKBT3.js.map} +0 -0
  135. /package/dist/tsup/{chunk-MXV26ZBB.js.map → chunk-TBJ4I3R3.js.map} +0 -0
@@ -1,170 +0,0 @@
1
- import { DatabaseSync } from "node:sqlite";
2
- import { afterEach, describe, expect, test } from "vitest";
3
- import {
4
- DEFAULT_MIGRATION_TABLE_NAME,
5
- migrations,
6
- type MigrationDatabase,
7
- } from "./migrations";
8
-
9
- const databases: DatabaseSync[] = [];
10
-
11
- afterEach(() => {
12
- for (const database of databases.splice(0)) database.close();
13
- });
14
-
15
- function createDatabase(): { raw: DatabaseSync; db: MigrationDatabase } {
16
- const raw = new DatabaseSync(":memory:");
17
- databases.push(raw);
18
- return {
19
- raw,
20
- db: {
21
- execute: async <TRow extends Record<string, unknown>>(
22
- sql: string,
23
- ...args: unknown[]
24
- ): Promise<TRow[]> => {
25
- if (args.length > 0 || /^\s*SELECT\b/i.test(sql)) {
26
- return raw.prepare(sql).all(...(args as never[])) as TRow[];
27
- }
28
- raw.exec(sql);
29
- return [];
30
- },
31
- },
32
- };
33
- }
34
-
35
- describe("migrations", () => {
36
- test("applies SQL and function migrations once in order", async () => {
37
- const { raw, db } = createDatabase();
38
- const applied: number[] = [];
39
- const migrate = migrations({
40
- tableName: "app_schema_version",
41
- migrations: [
42
- {
43
- version: 1,
44
- sql: "CREATE TABLE items (id INTEGER PRIMARY KEY, name TEXT NOT NULL)",
45
- },
46
- {
47
- version: 2,
48
- up: async (database) => {
49
- applied.push(2);
50
- await database.execute(
51
- "ALTER TABLE items ADD COLUMN active INTEGER NOT NULL DEFAULT 1",
52
- );
53
- },
54
- },
55
- ],
56
- });
57
-
58
- await migrate(db);
59
- await migrate(db);
60
-
61
- expect(applied).toEqual([2]);
62
- expect(
63
- raw
64
- .prepare(
65
- "SELECT schema_version FROM app_schema_version WHERE singleton = 1",
66
- )
67
- .get(),
68
- ).toEqual({ schema_version: 2 });
69
- expect(
70
- raw
71
- .prepare("PRAGMA table_info(items)")
72
- .all()
73
- .map((row) => row.name),
74
- ).toEqual(["id", "name", "active"]);
75
- });
76
-
77
- test("uses the default migration table", async () => {
78
- const { raw, db } = createDatabase();
79
- await migrations({
80
- migrations: [{ version: 1, sql: "CREATE TABLE item (id INTEGER)" }],
81
- })(db);
82
-
83
- expect(
84
- raw
85
- .prepare(
86
- `SELECT schema_version FROM ${DEFAULT_MIGRATION_TABLE_NAME} WHERE singleton = 1`,
87
- )
88
- .get(),
89
- ).toEqual({ schema_version: 1 });
90
- });
91
-
92
- test("adopts an unversioned schema before applying later migrations", async () => {
93
- const { raw, db } = createDatabase();
94
- raw.exec(
95
- "CREATE TABLE items (id INTEGER PRIMARY KEY, name TEXT NOT NULL)",
96
- );
97
- const applied: number[] = [];
98
-
99
- await migrations({
100
- tableName: "app_schema_version",
101
- adopt: async (database) => {
102
- const tables = await database.execute<{ name: string }>(
103
- "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'items'",
104
- );
105
- return tables.length === 0 ? 0 : 1;
106
- },
107
- migrations: [
108
- {
109
- version: 1,
110
- up: () => {
111
- throw new Error("already applied migration ran");
112
- },
113
- },
114
- {
115
- version: 2,
116
- up: async (database) => {
117
- applied.push(2);
118
- await database.execute(
119
- "ALTER TABLE items ADD COLUMN active INTEGER NOT NULL DEFAULT 1",
120
- );
121
- },
122
- },
123
- ],
124
- })(db);
125
-
126
- expect(applied).toEqual([2]);
127
- expect(
128
- raw
129
- .prepare(
130
- "SELECT schema_version FROM app_schema_version WHERE singleton = 1",
131
- )
132
- .get(),
133
- ).toEqual({ schema_version: 2 });
134
- });
135
-
136
- test("rejects invalid ladders and table names before executing", () => {
137
- expect(() => migrations({ migrations: [] })).toThrow(
138
- "must not be empty",
139
- );
140
- expect(() =>
141
- migrations({
142
- migrations: [{ version: 2, sql: "SELECT 1" }],
143
- }),
144
- ).toThrow("expected version 1");
145
- expect(() =>
146
- migrations({
147
- tableName: "schema; DROP TABLE items",
148
- migrations: [{ version: 1, sql: "SELECT 1" }],
149
- }),
150
- ).toThrow("invalid migration table name");
151
- });
152
-
153
- test("rejects a database newer than the migration ladder", async () => {
154
- const { raw, db } = createDatabase();
155
- raw.exec(`
156
- CREATE TABLE app_schema_version (
157
- singleton INTEGER PRIMARY KEY,
158
- schema_version INTEGER NOT NULL
159
- ) STRICT;
160
- INSERT INTO app_schema_version VALUES (1, 2);
161
- `);
162
-
163
- await expect(
164
- migrations({
165
- tableName: "app_schema_version",
166
- migrations: [{ version: 1, sql: "SELECT 1" }],
167
- })(db),
168
- ).rejects.toThrow("newer than supported version 1");
169
- });
170
- });
@@ -1,206 +0,0 @@
1
- import { describe, expect, test } from "vitest";
2
- import type { z } from "zod/v4";
3
- import { tryParseEndpoint } from "./endpoint-parser";
4
-
5
- // Helper to create a mock Zod refinement context for testing
6
- function createMockCtx(): { ctx: z.RefinementCtx; issues: z.ZodIssue[] } {
7
- const issues: z.ZodIssue[] = [];
8
- const ctx = {
9
- addIssue: (issue: z.IssueData) => {
10
- issues.push(issue as z.ZodIssue);
11
- },
12
- path: [],
13
- value: undefined,
14
- issues: [],
15
- } as unknown as z.RefinementCtx;
16
- return { ctx, issues };
17
- }
18
-
19
- describe("tryParseEndpoint", () => {
20
- describe("basic parsing", () => {
21
- test("parses endpoint with full auth", () => {
22
- const { ctx, issues } = createMockCtx();
23
- const result = tryParseEndpoint(ctx, {
24
- endpoint: "https://foo:bar@api.rivet.dev",
25
- });
26
- expect(issues).toHaveLength(0);
27
- expect(result).toEqual({
28
- endpoint: "https://api.rivet.dev/",
29
- namespace: "foo",
30
- token: "bar",
31
- });
32
- });
33
-
34
- test("parses endpoint with namespace only", () => {
35
- const { ctx, issues } = createMockCtx();
36
- const result = tryParseEndpoint(ctx, {
37
- endpoint: "https://foo@api.rivet.dev",
38
- });
39
- expect(issues).toHaveLength(0);
40
- expect(result).toEqual({
41
- endpoint: "https://api.rivet.dev/",
42
- namespace: "foo",
43
- token: undefined,
44
- });
45
- });
46
-
47
- test("parses endpoint without auth", () => {
48
- const { ctx, issues } = createMockCtx();
49
- const result = tryParseEndpoint(ctx, {
50
- endpoint: "https://api.rivet.dev",
51
- });
52
- expect(issues).toHaveLength(0);
53
- expect(result).toEqual({
54
- endpoint: "https://api.rivet.dev/",
55
- namespace: undefined,
56
- token: undefined,
57
- });
58
- });
59
-
60
- test("preserves path", () => {
61
- const { ctx, issues } = createMockCtx();
62
- const result = tryParseEndpoint(ctx, {
63
- endpoint: "https://foo:bar@api.rivet.dev/v1/actors",
64
- });
65
- expect(issues).toHaveLength(0);
66
- expect(result).toEqual({
67
- endpoint: "https://api.rivet.dev/v1/actors",
68
- namespace: "foo",
69
- token: "bar",
70
- });
71
- });
72
- });
73
-
74
- describe("validation errors", () => {
75
- test("adds issue for invalid URL", () => {
76
- const { ctx, issues } = createMockCtx();
77
- const result = tryParseEndpoint(ctx, { endpoint: "not-a-url" });
78
- expect(result).toBeUndefined();
79
- expect(issues).toHaveLength(1);
80
- expect(issues[0]?.message).toContain("invalid URL");
81
- });
82
-
83
- test("adds issue for query string", () => {
84
- const { ctx, issues } = createMockCtx();
85
- const result = tryParseEndpoint(ctx, {
86
- endpoint: "https://foo:bar@api.rivet.dev?region=us",
87
- });
88
- expect(result).toBeUndefined();
89
- expect(issues).toHaveLength(1);
90
- expect(issues[0]?.message).toBe(
91
- "endpoint cannot contain a query string",
92
- );
93
- });
94
-
95
- test("adds issue for fragment", () => {
96
- const { ctx, issues } = createMockCtx();
97
- const result = tryParseEndpoint(ctx, {
98
- endpoint: "https://foo:bar@api.rivet.dev#section",
99
- });
100
- expect(result).toBeUndefined();
101
- expect(issues).toHaveLength(1);
102
- expect(issues[0]?.message).toBe(
103
- "endpoint cannot contain a fragment",
104
- );
105
- });
106
-
107
- test("adds issue for token without namespace", () => {
108
- const { ctx, issues } = createMockCtx();
109
- const result = tryParseEndpoint(ctx, {
110
- endpoint: "https://:token@api.rivet.dev",
111
- });
112
- expect(result).toBeUndefined();
113
- expect(issues).toHaveLength(1);
114
- expect(issues[0]?.message).toBe(
115
- "endpoint cannot have a token without a namespace",
116
- );
117
- });
118
- });
119
-
120
- describe("duplicate credential checking", () => {
121
- test("adds issue when namespace in URL and config", () => {
122
- const { ctx, issues } = createMockCtx();
123
- const result = tryParseEndpoint(ctx, {
124
- endpoint: "https://url-ns@api.rivet.dev",
125
- path: ["endpoint"],
126
- namespace: "config-ns",
127
- });
128
- // Still returns result, but adds issue
129
- expect(result).toEqual({
130
- endpoint: "https://api.rivet.dev/",
131
- namespace: "url-ns",
132
- token: undefined,
133
- });
134
- expect(issues).toHaveLength(1);
135
- expect(issues[0]?.message).toContain(
136
- "cannot specify namespace both in endpoint URL and as a separate config option",
137
- );
138
- expect(issues[0]?.path).toEqual(["namespace"]);
139
- });
140
-
141
- test("adds issue when token in URL and config", () => {
142
- const { ctx, issues } = createMockCtx();
143
- const result = tryParseEndpoint(ctx, {
144
- endpoint: "https://ns:url-token@api.rivet.dev",
145
- path: ["endpoint"],
146
- token: "config-token",
147
- });
148
- // Still returns result, but adds issue
149
- expect(result).toEqual({
150
- endpoint: "https://api.rivet.dev/",
151
- namespace: "ns",
152
- token: "url-token",
153
- });
154
- expect(issues).toHaveLength(1);
155
- expect(issues[0]?.message).toContain(
156
- "cannot specify token both in endpoint URL and as a separate config option",
157
- );
158
- expect(issues[0]?.path).toEqual(["token"]);
159
- });
160
-
161
- test("adds issues for both namespace and token duplicates", () => {
162
- const { ctx, issues } = createMockCtx();
163
- const result = tryParseEndpoint(ctx, {
164
- endpoint: "https://url-ns:url-token@api.rivet.dev",
165
- path: ["endpoint"],
166
- namespace: "config-ns",
167
- token: "config-token",
168
- });
169
- expect(result).toBeDefined();
170
- expect(issues).toHaveLength(2);
171
- });
172
-
173
- test("no issue when namespace only in URL", () => {
174
- const { ctx, issues } = createMockCtx();
175
- const result = tryParseEndpoint(ctx, {
176
- endpoint: "https://url-ns@api.rivet.dev",
177
- path: ["endpoint"],
178
- token: "config-token",
179
- });
180
- expect(result).toBeDefined();
181
- expect(issues).toHaveLength(0);
182
- });
183
-
184
- test("no issue when namespace only in config", () => {
185
- const { ctx, issues } = createMockCtx();
186
- const result = tryParseEndpoint(ctx, {
187
- endpoint: "https://api.rivet.dev",
188
- path: ["endpoint"],
189
- namespace: "config-ns",
190
- });
191
- expect(result).toBeDefined();
192
- expect(issues).toHaveLength(0);
193
- });
194
- });
195
-
196
- describe("custom path", () => {
197
- test("uses custom path in error issues", () => {
198
- const { ctx, issues } = createMockCtx();
199
- tryParseEndpoint(ctx, {
200
- endpoint: "not-a-url",
201
- path: ["serverless", "publicEndpoint"],
202
- });
203
- expect(issues[0]?.path).toEqual(["serverless", "publicEndpoint"]);
204
- });
205
- });
206
- });
package/src/utils.test.ts DELETED
@@ -1,34 +0,0 @@
1
- import { describe, expect, test } from "vitest";
2
- import { joinSignals } from "./utils";
3
-
4
- describe("joinSignals", () => {
5
- test("returns a non-aborted signal when no inputs are provided", () => {
6
- const signal = joinSignals();
7
- expect(signal.aborted).toBe(false);
8
- });
9
-
10
- test("returns the same signal when only one input is provided", () => {
11
- const controller = new AbortController();
12
- const signal = joinSignals(controller.signal);
13
- expect(signal).toBe(controller.signal);
14
- });
15
-
16
- test("aborts immediately when any input signal is already aborted", () => {
17
- const controllerA = new AbortController();
18
- const controllerB = new AbortController();
19
- controllerA.abort("already-aborted");
20
-
21
- const signal = joinSignals(controllerA.signal, controllerB.signal);
22
- expect(signal.aborted).toBe(true);
23
- });
24
-
25
- test("aborts when one of the joined signals aborts", () => {
26
- const controllerA = new AbortController();
27
- const controllerB = new AbortController();
28
- const signal = joinSignals(controllerA.signal, controllerB.signal);
29
-
30
- expect(signal.aborted).toBe(false);
31
- controllerB.abort("stopped");
32
- expect(signal.aborted).toBe(true);
33
- });
34
- });
@@ -1,62 +0,0 @@
1
- import { describe, expect, test } from "vitest";
2
- import { ActorWorkflowDriver, chunkWorkflowWrites } from "./driver";
3
-
4
- function write(keyBytes: number, valueBytes: number) {
5
- return {
6
- key: new Uint8Array(keyBytes),
7
- value: new Uint8Array(valueBytes),
8
- };
9
- }
10
-
11
- describe("workflow sqlite batching", () => {
12
- test.each([
13
- [127, 1],
14
- [128, 1],
15
- [129, 2],
16
- ])("chunks %i rows into %i transaction(s)", (rowCount, chunkCount) => {
17
- const chunks = chunkWorkflowWrites(
18
- Array.from({ length: rowCount }, () => write(1, 1)),
19
- );
20
- expect(chunks).toHaveLength(chunkCount);
21
- expect(chunks.flat()).toHaveLength(rowCount);
22
- expect(chunks.every((chunk) => chunk.length <= 128)).toBe(true);
23
- });
24
-
25
- test("splits immediately above the 512 KiB payload budget", () => {
26
- // Each persisted key also includes the two-byte workflow namespace.
27
- const exact = [write(1, 256 * 1024 - 3), write(1, 256 * 1024 - 3)];
28
- expect(chunkWorkflowWrites(exact)).toHaveLength(1);
29
-
30
- const over = [write(1, 256 * 1024 - 3), write(1, 256 * 1024 - 2)];
31
- expect(chunkWorkflowWrites(over)).toHaveLength(2);
32
- });
33
-
34
- test("delegates actor state and the whole workflow batch to one atomic runtime call", async () => {
35
- let receivedWrites: Array<{ key: Uint8Array; value: Uint8Array }> = [];
36
- const sql = {
37
- query: async () => ({ columns: [], rows: [] }),
38
- execute: async () => [],
39
- run: async () => ({ changes: 0 }),
40
- executeBatch: async () => [],
41
- };
42
- const actor = {
43
- stateManager: {
44
- saveStateAndWorkflowBatch: async (
45
- writes: Array<{ key: Uint8Array; value: Uint8Array }>,
46
- ) => {
47
- receivedWrites = writes;
48
- },
49
- },
50
- queueManager: {},
51
- };
52
- const runCtx = {
53
- sql,
54
- internalKeepAwake: async <T>(promise: Promise<T>) => await promise,
55
- };
56
- const driver = new ActorWorkflowDriver(actor as never, runCtx as never);
57
- const writes = [write(1, 1), write(2, 2)];
58
- await driver.batch(writes);
59
- expect(driver.atomicBatch).toBe(true);
60
- expect(receivedWrites).toBe(writes);
61
- });
62
- });