rivetkit 2.0.5 → 2.0.7-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.
Files changed (178) hide show
  1. package/dist/schemas/actor-persist/v1.ts +0 -6
  2. package/dist/tsup/actor-router-consts-B3Lu87yJ.d.cts +28 -0
  3. package/dist/tsup/actor-router-consts-B3Lu87yJ.d.ts +28 -0
  4. package/dist/tsup/{chunk-5YTI25C3.cjs → chunk-3MBP4WNC.cjs} +7 -7
  5. package/dist/tsup/{chunk-5YTI25C3.cjs.map → chunk-3MBP4WNC.cjs.map} +1 -1
  6. package/dist/tsup/chunk-3Y45CIF4.cjs +3726 -0
  7. package/dist/tsup/chunk-3Y45CIF4.cjs.map +1 -0
  8. package/dist/tsup/chunk-4GP7BZSR.js +102 -0
  9. package/dist/tsup/chunk-4GP7BZSR.js.map +1 -0
  10. package/dist/tsup/chunk-5ZOHIKWG.cjs +4071 -0
  11. package/dist/tsup/chunk-5ZOHIKWG.cjs.map +1 -0
  12. package/dist/tsup/{chunk-WADSS5X4.cjs → chunk-6EUWRXLT.cjs} +21 -7
  13. package/dist/tsup/chunk-6EUWRXLT.cjs.map +1 -0
  14. package/dist/tsup/{chunk-D7NWUCRK.cjs → chunk-6OVKCDSH.cjs} +6 -6
  15. package/dist/tsup/{chunk-D7NWUCRK.cjs.map → chunk-6OVKCDSH.cjs.map} +1 -1
  16. package/dist/tsup/{chunk-I5VTWPHW.js → chunk-7N56ZUC7.js} +3 -3
  17. package/dist/tsup/{chunk-LZIBTLEY.cjs → chunk-B3TLRM4Q.cjs} +13 -25
  18. package/dist/tsup/chunk-B3TLRM4Q.cjs.map +1 -0
  19. package/dist/tsup/chunk-BW5DPM6Z.js +4071 -0
  20. package/dist/tsup/chunk-BW5DPM6Z.js.map +1 -0
  21. package/dist/tsup/chunk-DFS77KAA.cjs +1046 -0
  22. package/dist/tsup/chunk-DFS77KAA.cjs.map +1 -0
  23. package/dist/tsup/{chunk-PG3K2LI7.js → chunk-E4UVJKSV.js} +2 -2
  24. package/dist/tsup/chunk-G4ABMAQY.cjs +102 -0
  25. package/dist/tsup/chunk-G4ABMAQY.cjs.map +1 -0
  26. package/dist/tsup/{chunk-CKA54YQN.js → chunk-GZVBFXBI.js} +3 -15
  27. package/dist/tsup/chunk-GZVBFXBI.js.map +1 -0
  28. package/dist/tsup/chunk-HPT3I7UU.js +3726 -0
  29. package/dist/tsup/chunk-HPT3I7UU.js.map +1 -0
  30. package/dist/tsup/chunk-JD54PXWP.js +1046 -0
  31. package/dist/tsup/chunk-JD54PXWP.js.map +1 -0
  32. package/dist/tsup/{chunk-PHSQJ6QI.cjs → chunk-K4ENQCC4.cjs} +3 -3
  33. package/dist/tsup/{chunk-PHSQJ6QI.cjs.map → chunk-K4ENQCC4.cjs.map} +1 -1
  34. package/dist/tsup/{chunk-WNGOBAA7.js → chunk-PUSQNDJG.js} +2 -2
  35. package/dist/tsup/{chunk-CFFKMUYH.js → chunk-RVP5RUSC.js} +20 -6
  36. package/dist/tsup/chunk-RVP5RUSC.js.map +1 -0
  37. package/dist/tsup/chunk-SAZCNSVY.cjs +259 -0
  38. package/dist/tsup/chunk-SAZCNSVY.cjs.map +1 -0
  39. package/dist/tsup/{chunk-YW6Y6VNE.js → chunk-SBKRVQS2.js} +9 -5
  40. package/dist/tsup/chunk-SBKRVQS2.js.map +1 -0
  41. package/dist/tsup/{chunk-FGFT4FVX.cjs → chunk-TZGUSEIJ.cjs} +14 -10
  42. package/dist/tsup/chunk-TZGUSEIJ.cjs.map +1 -0
  43. package/dist/tsup/chunk-YQ4XQYPM.js +259 -0
  44. package/dist/tsup/chunk-YQ4XQYPM.js.map +1 -0
  45. package/dist/tsup/client/mod.cjs +9 -9
  46. package/dist/tsup/client/mod.d.cts +7 -8
  47. package/dist/tsup/client/mod.d.ts +7 -8
  48. package/dist/tsup/client/mod.js +8 -8
  49. package/dist/tsup/common/log.cjs +3 -3
  50. package/dist/tsup/common/log.js +2 -2
  51. package/dist/tsup/common/websocket.cjs +4 -4
  52. package/dist/tsup/common/websocket.js +3 -3
  53. package/dist/tsup/{connection-BvE-Oq7t.d.ts → conn-DCSQgIlw.d.ts} +1605 -1353
  54. package/dist/tsup/{connection-DTzmWwU5.d.cts → conn-DdzHTm2E.d.cts} +1605 -1353
  55. package/dist/tsup/driver-helpers/mod.cjs +31 -5
  56. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  57. package/dist/tsup/driver-helpers/mod.d.cts +7 -8
  58. package/dist/tsup/driver-helpers/mod.d.ts +7 -8
  59. package/dist/tsup/driver-helpers/mod.js +33 -7
  60. package/dist/tsup/driver-test-suite/mod.cjs +319 -216
  61. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  62. package/dist/tsup/driver-test-suite/mod.d.cts +7 -7
  63. package/dist/tsup/driver-test-suite/mod.d.ts +7 -7
  64. package/dist/tsup/driver-test-suite/mod.js +588 -485
  65. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  66. package/dist/tsup/inspector/mod.cjs +17 -5
  67. package/dist/tsup/inspector/mod.cjs.map +1 -1
  68. package/dist/tsup/inspector/mod.d.cts +34 -7
  69. package/dist/tsup/inspector/mod.d.ts +34 -7
  70. package/dist/tsup/inspector/mod.js +20 -8
  71. package/dist/tsup/mod.cjs +10 -17
  72. package/dist/tsup/mod.cjs.map +1 -1
  73. package/dist/tsup/mod.d.cts +56 -9
  74. package/dist/tsup/mod.d.ts +56 -9
  75. package/dist/tsup/mod.js +17 -24
  76. package/dist/tsup/test/mod.cjs +11 -9
  77. package/dist/tsup/test/mod.cjs.map +1 -1
  78. package/dist/tsup/test/mod.d.cts +6 -7
  79. package/dist/tsup/test/mod.d.ts +6 -7
  80. package/dist/tsup/test/mod.js +10 -8
  81. package/dist/tsup/utils.cjs +4 -2
  82. package/dist/tsup/utils.cjs.map +1 -1
  83. package/dist/tsup/utils.d.cts +11 -1
  84. package/dist/tsup/utils.d.ts +11 -1
  85. package/dist/tsup/utils.js +3 -1
  86. package/package.json +8 -4
  87. package/src/actor/action.ts +1 -1
  88. package/src/actor/config.ts +1 -1
  89. package/src/actor/conn-drivers.ts +205 -0
  90. package/src/actor/conn-socket.ts +6 -0
  91. package/src/actor/{connection.ts → conn.ts} +78 -84
  92. package/src/actor/context.ts +1 -1
  93. package/src/actor/driver.ts +4 -43
  94. package/src/actor/instance.ts +162 -86
  95. package/src/actor/mod.ts +6 -14
  96. package/src/actor/persisted.ts +2 -5
  97. package/src/actor/protocol/old.ts +1 -1
  98. package/src/actor/router-endpoints.ts +147 -138
  99. package/src/actor/router.ts +89 -52
  100. package/src/actor/utils.ts +5 -1
  101. package/src/client/actor-conn.ts +163 -31
  102. package/src/client/actor-handle.ts +0 -1
  103. package/src/client/client.ts +2 -2
  104. package/src/client/config.ts +7 -0
  105. package/src/client/raw-utils.ts +1 -1
  106. package/src/client/utils.ts +1 -1
  107. package/src/common/actor-router-consts.ts +59 -0
  108. package/src/common/router.ts +2 -1
  109. package/src/common/versioned-data.ts +5 -5
  110. package/src/driver-helpers/mod.ts +15 -2
  111. package/src/driver-test-suite/mod.ts +11 -2
  112. package/src/driver-test-suite/test-inline-client-driver.ts +40 -22
  113. package/src/driver-test-suite/tests/actor-conn-state.ts +66 -22
  114. package/src/driver-test-suite/tests/actor-conn.ts +65 -126
  115. package/src/driver-test-suite/tests/actor-reconnect.ts +160 -0
  116. package/src/driver-test-suite/tests/actor-sleep.ts +0 -1
  117. package/src/driver-test-suite/tests/raw-websocket.ts +0 -35
  118. package/src/driver-test-suite/utils.ts +8 -3
  119. package/src/drivers/default.ts +8 -7
  120. package/src/drivers/engine/actor-driver.ts +67 -44
  121. package/src/drivers/engine/config.ts +4 -0
  122. package/src/drivers/file-system/actor.ts +0 -6
  123. package/src/drivers/file-system/global-state.ts +3 -14
  124. package/src/drivers/file-system/manager.ts +12 -8
  125. package/src/inspector/actor.ts +4 -3
  126. package/src/inspector/config.ts +10 -1
  127. package/src/inspector/mod.ts +1 -0
  128. package/src/inspector/utils.ts +23 -4
  129. package/src/manager/driver.ts +12 -2
  130. package/src/manager/gateway.ts +407 -0
  131. package/src/manager/protocol/query.ts +1 -1
  132. package/src/manager/router.ts +269 -468
  133. package/src/manager-api/actors.ts +61 -0
  134. package/src/manager-api/common.ts +4 -0
  135. package/src/mod.ts +1 -1
  136. package/src/registry/mod.ts +126 -12
  137. package/src/registry/serve.ts +8 -3
  138. package/src/remote-manager-driver/actor-http-client.ts +30 -19
  139. package/src/remote-manager-driver/actor-websocket-client.ts +45 -18
  140. package/src/remote-manager-driver/api-endpoints.ts +19 -21
  141. package/src/remote-manager-driver/api-utils.ts +10 -1
  142. package/src/remote-manager-driver/mod.ts +53 -53
  143. package/src/remote-manager-driver/ws-proxy.ts +2 -9
  144. package/src/test/mod.ts +6 -2
  145. package/src/utils.ts +21 -2
  146. package/dist/tsup/chunk-2MD57QF4.js +0 -1794
  147. package/dist/tsup/chunk-2MD57QF4.js.map +0 -1
  148. package/dist/tsup/chunk-B2QGJGZQ.js +0 -338
  149. package/dist/tsup/chunk-B2QGJGZQ.js.map +0 -1
  150. package/dist/tsup/chunk-CFFKMUYH.js.map +0 -1
  151. package/dist/tsup/chunk-CKA54YQN.js.map +0 -1
  152. package/dist/tsup/chunk-FGFT4FVX.cjs.map +0 -1
  153. package/dist/tsup/chunk-IRMBWX36.cjs +0 -1794
  154. package/dist/tsup/chunk-IRMBWX36.cjs.map +0 -1
  155. package/dist/tsup/chunk-L7QRXNWP.js +0 -6562
  156. package/dist/tsup/chunk-L7QRXNWP.js.map +0 -1
  157. package/dist/tsup/chunk-LZIBTLEY.cjs.map +0 -1
  158. package/dist/tsup/chunk-MRZS2J4X.cjs +0 -6562
  159. package/dist/tsup/chunk-MRZS2J4X.cjs.map +0 -1
  160. package/dist/tsup/chunk-RM2SVURR.cjs +0 -338
  161. package/dist/tsup/chunk-RM2SVURR.cjs.map +0 -1
  162. package/dist/tsup/chunk-WADSS5X4.cjs.map +0 -1
  163. package/dist/tsup/chunk-YW6Y6VNE.js.map +0 -1
  164. package/dist/tsup/common-CXCe7s6i.d.cts +0 -218
  165. package/dist/tsup/common-CXCe7s6i.d.ts +0 -218
  166. package/dist/tsup/router-endpoints-CctffZNL.d.cts +0 -65
  167. package/dist/tsup/router-endpoints-DFm1BglJ.d.ts +0 -65
  168. package/src/actor/generic-conn-driver.ts +0 -246
  169. package/src/common/fake-event-source.ts +0 -267
  170. package/src/manager-api/routes/actors-create.ts +0 -16
  171. package/src/manager-api/routes/actors-delete.ts +0 -4
  172. package/src/manager-api/routes/actors-get-by-id.ts +0 -7
  173. package/src/manager-api/routes/actors-get-or-create-by-id.ts +0 -29
  174. package/src/manager-api/routes/actors-get.ts +0 -7
  175. package/src/manager-api/routes/common.ts +0 -18
  176. /package/dist/tsup/{chunk-I5VTWPHW.js.map → chunk-7N56ZUC7.js.map} +0 -0
  177. /package/dist/tsup/{chunk-PG3K2LI7.js.map → chunk-E4UVJKSV.js.map} +0 -0
  178. /package/dist/tsup/{chunk-WNGOBAA7.js.map → chunk-PUSQNDJG.js.map} +0 -0
@@ -1,4 +1,5 @@
1
- import { describe, expect, test } from "vitest";
1
+ import { describe, expect, test, vi } from "vitest";
2
+ import { SSE_PING_INTERVAL } from "@/actor/router-endpoints";
2
3
  import type { DriverTestConfig } from "../mod";
3
4
  import { FAKE_TIME, setupDriverTest, waitFor } from "../utils";
4
5
 
@@ -84,28 +85,27 @@ export function runActorConnTests(driverTestConfig: DriverTestConfig) {
84
85
 
85
86
  // Set up event listener
86
87
  const receivedEvents: number[] = [];
87
- const receivedEventsPromise = new Promise((resolve) => {
88
- connection.on("newCount", (count: number) => {
89
- receivedEvents.push(count);
90
- if (
91
- receivedEvents.includes(1) &&
92
- receivedEvents.includes(6) &&
93
- receivedEvents.includes(9)
94
- )
95
- resolve(undefined);
96
- });
88
+ connection.on("newCount", (count: number) => {
89
+ receivedEvents.push(count);
97
90
  });
98
91
 
99
- // Send one RPC call over the connection to ensure it's open
100
- await connection.increment(1);
92
+ // TODO: There is a race condition with opening subscription and sending events on SSE, so we need to wait for a successful round trip on the event
93
+ await vi.waitFor(async () => {
94
+ // Send one RPC call over the connection to ensure it's open
95
+ await connection.setCount(1);
96
+ expect(receivedEvents).includes(1);
97
+ });
101
98
 
102
99
  // Now use stateless RPC calls through the handle (no connection)
103
100
  // These should still trigger events that the connection receives
104
- await handle.increment(5);
105
- await handle.increment(3);
101
+ await handle.setCount(2);
102
+ await handle.setCount(3);
106
103
 
107
104
  // Wait for all events to be received
108
- await receivedEventsPromise;
105
+ await vi.waitFor(() => {
106
+ expect(receivedEvents).includes(2);
107
+ expect(receivedEvents).includes(3);
108
+ });
109
109
 
110
110
  // Clean up
111
111
  await connection.dispose();
@@ -124,13 +124,17 @@ export function runActorConnTests(driverTestConfig: DriverTestConfig) {
124
124
  receivedEvents.push(count);
125
125
  });
126
126
 
127
- // Trigger broadcast events
128
- await connection.increment(5);
129
- await connection.increment(3);
130
-
127
+ // HACK: Race condition between subscribing & sending events in SSE
131
128
  // Verify events were received
132
- expect(receivedEvents).toContain(5);
133
- expect(receivedEvents).toContain(8);
129
+ await vi.waitFor(
130
+ async () => {
131
+ await connection.setCount(5);
132
+ await connection.setCount(8);
133
+ expect(receivedEvents).toContain(5);
134
+ expect(receivedEvents).toContain(8);
135
+ },
136
+ { timeout: 10_000 },
137
+ );
134
138
 
135
139
  // Clean up
136
140
  await connection.dispose();
@@ -154,8 +158,10 @@ export function runActorConnTests(driverTestConfig: DriverTestConfig) {
154
158
  await connection.increment(3);
155
159
 
156
160
  // Verify only the first event was received
157
- expect(receivedEvents).toEqual([5]);
158
- expect(receivedEvents).not.toContain(8);
161
+ await vi.waitFor(() => {
162
+ expect(receivedEvents).toEqual([5]);
163
+ expect(receivedEvents).not.toContain(8);
164
+ });
159
165
 
160
166
  // Clean up
161
167
  await connection.dispose();
@@ -174,17 +180,20 @@ export function runActorConnTests(driverTestConfig: DriverTestConfig) {
174
180
  receivedEvents.push(count);
175
181
  });
176
182
 
183
+ // TODO: SSE has race condition with subscriptions & publishing messages
177
184
  // Trigger first event
178
- await connection.increment(5);
185
+ await vi.waitFor(async () => {
186
+ await connection.setCount(5);
187
+ expect(receivedEvents).toEqual([5]);
188
+ });
179
189
 
180
190
  // Unsubscribe
181
191
  unsubscribe();
182
192
 
183
193
  // Trigger second event, should not be received
184
- await connection.increment(3);
194
+ await connection.setCount(8);
185
195
 
186
196
  // Verify only the first event was received
187
- expect(receivedEvents).toEqual([5]);
188
197
  expect(receivedEvents).not.toContain(8);
189
198
 
190
199
  // Clean up
@@ -225,7 +234,10 @@ export function runActorConnTests(driverTestConfig: DriverTestConfig) {
225
234
  });
226
235
 
227
236
  describe("Lifecycle Hooks", () => {
228
- test("should trigger lifecycle hooks", async (c) => {
237
+ test.skipIf(
238
+ driverTestConfig.transport === "sse" &&
239
+ driverTestConfig.clientType === "inline",
240
+ )("should trigger lifecycle hooks", async (c) => {
229
241
  const { client } = await setupDriverTest(c, driverTestConfig);
230
242
 
231
243
  // Create and connect
@@ -244,104 +256,31 @@ export function runActorConnTests(driverTestConfig: DriverTestConfig) {
244
256
  // Disconnect should trigger onDisconnect
245
257
  await connection.dispose();
246
258
 
247
- // Reconnect to check if onDisconnect was called
248
- const handle = client.counterWithLifecycle.getOrCreate([
249
- "test-lifecycle",
250
- ]);
251
- const finalEvents = await handle.getEvents();
252
- expect(finalEvents).toBeOneOf([
253
- // Still active
254
- ["onStart", "onBeforeConnect", "onConnect", "onDisconnect"],
255
- // Went to sleep and woke back up
256
- [
257
- "onStart",
258
- "onBeforeConnect",
259
- "onConnect",
260
- "onDisconnect",
261
- "onStart",
262
- ],
263
- ]);
264
- });
265
- });
266
-
267
- describe("Connection Liveness", () => {
268
- // TODO: KIT-242
269
- test.skip("should return correct liveness status for connections", async (c) => {
270
- const { client } = await setupDriverTest(c, driverTestConfig);
271
-
272
- // Create actor and connection
273
- const handle = client.connLivenessActor.getOrCreate([
274
- "test-liveness-status",
275
- ]);
276
- const connA = handle.connect();
277
- const connB = handle.connect();
278
-
279
- const connAId = await connA.getConnectionId();
280
- const connBId = await connB.getConnectionId();
281
-
282
- // Verify connection works initially
283
- await connA.increment(5);
284
- await connB.increment(5);
285
-
286
- const counter = await handle.getCounter();
287
- expect(counter).toBe(10);
288
-
289
- const connectionsStatusBeforeKill =
290
- await handle.getWsConnectionsLiveness();
291
- expect(connectionsStatusBeforeKill).toHaveLength(2);
292
- expect(connectionsStatusBeforeKill).toContainEqual(
293
- expect.objectContaining({
294
- id: connAId,
295
- status: "connected",
296
- lastSeen: FAKE_TIME.getTime(),
297
- }),
298
- );
299
- expect(connectionsStatusBeforeKill).toContainEqual(
300
- expect.objectContaining({
301
- id: connBId,
302
- status: "connected",
303
- lastSeen: FAKE_TIME.getTime(),
304
- }),
305
- );
306
-
307
- // Kill one connection
308
- await handle.kill(connAId); // instead of dispose, we use kill to simulate a disconnection (e.g. network failure)
309
- // connA.dispose();
310
- // we killed the connection, but the actor instance does not know about it yet
311
- // it should still be in the list of connections, but with a status of "reconnecting"
312
- const connectionsStatusAfterKill =
313
- await handle.getWsConnectionsLiveness();
314
- expect(connectionsStatusAfterKill).toEqual(
315
- expect.arrayContaining([
316
- expect.objectContaining({
317
- id: connAId,
318
- status: "reconnecting",
319
- lastSeen: FAKE_TIME.getTime(),
320
- }),
321
- expect.objectContaining({
322
- id: connBId,
323
- status: "connected",
324
- lastSeen: FAKE_TIME.getTime(),
325
- }),
326
- ]),
327
- );
328
-
329
- // default time to wait for cleanup is 5 seconds
330
- // check actor options
331
- await waitFor(driverTestConfig, 5_000);
332
-
333
- // After timeout, the killed connection should be unavailable, since the manager has cleaned it up
334
- const connectionsStatusAfterCleanup =
335
- await handle.getWsConnectionsLiveness();
336
- expect(connectionsStatusAfterCleanup).not.toContainEqual(
337
- expect.objectContaining({
338
- id: connAId,
339
- }),
340
- );
341
- expect(connectionsStatusAfterCleanup).toContainEqual(
342
- expect.objectContaining({
343
- id: connBId,
344
- }),
259
+ await vi.waitFor(
260
+ async () => {
261
+ // Reconnect to check if onDisconnect was called
262
+ const handle = client.counterWithLifecycle.getOrCreate([
263
+ "test-lifecycle",
264
+ ]);
265
+ const finalEvents = await handle.getEvents();
266
+ expect(finalEvents).toBeOneOf([
267
+ // Still active
268
+ ["onStart", "onBeforeConnect", "onConnect", "onDisconnect"],
269
+ // Went to sleep and woke back up
270
+ [
271
+ "onStart",
272
+ "onBeforeConnect",
273
+ "onConnect",
274
+ "onDisconnect",
275
+ "onStart",
276
+ ],
277
+ ]);
278
+ },
279
+ // NOTE: High timeout required for Cloudflare Workers
280
+ {
281
+ timeout: 10_000,
282
+ interval: 100,
283
+ },
345
284
  );
346
285
  });
347
286
  });
@@ -0,0 +1,160 @@
1
+ import { describe, expect, test, vi } from "vitest";
2
+ import type { ActorConnRaw } from "@/client/actor-conn";
3
+ import type { DriverTestConfig } from "../mod";
4
+ import { setupDriverTest } from "../utils";
5
+
6
+ export function runActorReconnectTests(driverTestConfig: DriverTestConfig) {
7
+ describe("Actor Reconnection Tests", () => {
8
+ test("should reconnect and preserve connection state after non-clean disconnect", async (c) => {
9
+ const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
10
+
11
+ // Create actor and connect
12
+ const handle = client.counterConn.getOrCreate(["test-reconnect"]);
13
+ const connection = handle.connect();
14
+
15
+ // Set an initial count on the connection
16
+ await connection.increment(5);
17
+
18
+ // Verify connection count is 1
19
+ const connCount1 = await connection.getConnectionCount();
20
+ expect(connCount1).toBe(1);
21
+
22
+ // Force disconnect (non-clean) - simulates network failure
23
+ const connRaw = connection as unknown as ActorConnRaw;
24
+ await forceUncleanDisconnect(
25
+ endpoint,
26
+ connRaw.actorId!,
27
+ connRaw.connectionId!,
28
+ );
29
+
30
+ // Wait a bit for the disconnection to be processed
31
+ await vi.waitFor(
32
+ async () => {
33
+ const countAfterReconnect = await connection.getCount();
34
+ expect(countAfterReconnect).toBe(5); // Should preserve the count
35
+ },
36
+ { timeout: 5000, interval: 100 },
37
+ );
38
+
39
+ // Verify connection count is still 1 (same connection reconnected)
40
+ const connCount2 = await connection.getConnectionCount();
41
+ expect(connCount2).toBe(1);
42
+
43
+ // Verify we can still increment the counter
44
+ const newCount = await connection.getCount();
45
+ expect(newCount).toBe(5);
46
+
47
+ // Clean up
48
+ await connection.dispose();
49
+ });
50
+
51
+ test("should not preserve connection state after clean disconnect", async (c) => {
52
+ const { client } = await setupDriverTest(c, driverTestConfig);
53
+
54
+ // Create actor and connect
55
+ const handle = client.counterConn.getOrCreate(["test-clean-disconnect"]);
56
+ const connection = handle.connect();
57
+
58
+ // Set an initial count on the connection
59
+ await connection.increment(10);
60
+
61
+ // Verify connection count is 1
62
+ const connCount1 = await connection.getConnectionCount();
63
+ expect(connCount1).toBe(1);
64
+
65
+ // Clean disconnect
66
+ await connection.dispose();
67
+
68
+ // Wait a bit to ensure disconnection is processed
69
+ await vi.waitFor(
70
+ async () => {
71
+ // Check that connection count is now 0
72
+ const handle2 = client.counterConn.get(["test-clean-disconnect"]);
73
+ const connCount = await handle2.getConnectionCount();
74
+ // This counts the current action caller
75
+ expect(connCount).toBe(1);
76
+ },
77
+ { timeout: 5000 },
78
+ );
79
+
80
+ // Create a new connection
81
+ const connection2 = handle.connect();
82
+
83
+ // The count should be reset since it's a new connection
84
+ const countNewConnection = await connection2.getCount();
85
+ expect(countNewConnection).toBe(0); // Should be reset
86
+
87
+ // Verify connection count is 1 again (new connection)
88
+ const connCount3 = await connection2.getConnectionCount();
89
+ expect(connCount3).toBe(1);
90
+
91
+ // Clean up
92
+ await connection2.dispose();
93
+ });
94
+
95
+ test("should handle multiple non-clean disconnects and reconnects", async (c) => {
96
+ const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
97
+
98
+ // Create actor and connect
99
+ const handle = client.counterConn.getOrCreate([
100
+ "test-multiple-reconnect",
101
+ ]);
102
+ const connection = handle.connect();
103
+
104
+ // Set an initial count
105
+ await connection.setCount(100);
106
+
107
+ // Perform multiple disconnect-reconnect cycles
108
+ for (let i = 0; i < 3; i++) {
109
+ // Increment before disconnect
110
+ await connection.increment(1);
111
+
112
+ // Force disconnect
113
+ const connRaw = connection as unknown as ActorConnRaw;
114
+ await forceUncleanDisconnect(
115
+ endpoint,
116
+ connRaw.actorId!,
117
+ connRaw.connectionId!,
118
+ );
119
+
120
+ // Wait for reconnection and verify state is preserved
121
+ await vi.waitFor(
122
+ async () => {
123
+ const countAfter = await connection.getCount();
124
+ expect(countAfter).toBe(101 + i);
125
+ },
126
+ { timeout: 5000 },
127
+ );
128
+
129
+ // Verify connection count remains 1
130
+ const connCount = await connection.getConnectionCount();
131
+ expect(connCount).toBe(1);
132
+ }
133
+
134
+ // Final verification
135
+ const finalCount = await connection.getCount();
136
+ expect(finalCount).toBe(103);
137
+
138
+ // Clean up
139
+ await connection.dispose();
140
+ });
141
+ });
142
+ }
143
+
144
+ async function forceUncleanDisconnect(
145
+ endpoint: string,
146
+ actorId: string,
147
+ connId: string,
148
+ ): Promise<void> {
149
+ const response = await fetch(
150
+ `${endpoint}/.test/force-disconnect?actor=${actorId}&conn=${connId}`,
151
+ {
152
+ method: "POST",
153
+ },
154
+ );
155
+
156
+ if (!response.ok) {
157
+ const text = await response.text();
158
+ throw new Error(`Failed to force disconnect: ${text}`);
159
+ }
160
+ }
@@ -318,7 +318,6 @@ export function runActorSleepTests(driverTestConfig: DriverTestConfig) {
318
318
 
319
319
  // Close WebSocket
320
320
  ws.close();
321
- await new Promise((resolve) => setTimeout(resolve, 100));
322
321
 
323
322
  // Wait for sleep timeout after WebSocket closed
324
323
  await waitFor(driverTestConfig, SLEEP_TIMEOUT + 100);
@@ -277,41 +277,6 @@ export function runRawWebSocketTests(driverTestConfig: DriverTestConfig) {
277
277
  ws.close();
278
278
  });
279
279
 
280
- test("should pass connection parameters through subprotocols", async (c) => {
281
- const { client } = await setupDriverTest(c, driverTestConfig);
282
-
283
- // Create actor with connection parameters
284
- const testParams = { userId: "test123", role: "admin" };
285
- const actor = client.rawWebSocketActor.getOrCreate(["params"], {
286
- params: testParams,
287
- });
288
-
289
- const ws = await actor.websocket();
290
-
291
- await new Promise<void>((resolve) => {
292
- ws.addEventListener("open", () => resolve(), { once: true });
293
- });
294
-
295
- // Send a request to echo the auth data (which should include conn params from auth)
296
- ws.send(JSON.stringify({ type: "getAuthData" }));
297
-
298
- const response = await new Promise<any>((resolve, reject) => {
299
- ws.addEventListener("message", (event: any) => {
300
- const data = JSON.parse(event.data as string);
301
- if (data.type === "authData") {
302
- resolve(data);
303
- }
304
- });
305
- ws.addEventListener("close", reject);
306
- });
307
-
308
- // For now, just verify we get a response
309
- // The actual connection params handling needs to be implemented
310
- expect(response).toBeDefined();
311
-
312
- ws.close();
313
- });
314
-
315
280
  test("should handle connection close properly", async (c) => {
316
281
  const { client } = await setupDriverTest(c, driverTestConfig);
317
282
  const actor = client.rawWebSocketActor.getOrCreate(["close-test"]);
@@ -1,7 +1,8 @@
1
- import { resolve } from "node:path";
1
+ import invariant from "invariant";
2
2
  import { type TestContext, vi } from "vitest";
3
3
  import { assertUnreachable } from "@/actor/utils";
4
4
  import { type Client, createClient } from "@/client/mod";
5
+ import { RunConfigSchema } from "@/driver-helpers/mod";
5
6
  import { createClientWithDriver } from "@/mod";
6
7
  import type { registry } from "../../fixtures/driver-test-suite/registry";
7
8
  import type { DriverTestConfig } from "./mod";
@@ -38,12 +39,16 @@ export async function setupDriverTest(
38
39
  });
39
40
  } else if (driverTestConfig.clientType === "inline") {
40
41
  // Use inline client from driver
42
+ const transport = driverTestConfig.transport ?? "websocket";
41
43
  const managerDriver = createTestInlineClientDriver(
42
44
  endpoint,
43
45
  "bare",
44
- driverTestConfig.transport ?? "websocket",
46
+ transport,
45
47
  );
46
- client = createClientWithDriver(managerDriver);
48
+ const runConfig = RunConfigSchema.parse({
49
+ transport: transport,
50
+ });
51
+ client = createClientWithDriver(managerDriver, runConfig);
47
52
  } else {
48
53
  assertUnreachable(driverTestConfig.clientType);
49
54
  }
@@ -3,15 +3,12 @@ import { loggerWithoutContext } from "@/actor/log";
3
3
  import { createEngineDriver } from "@/drivers/engine/mod";
4
4
  import { createFileSystemOrMemoryDriver } from "@/drivers/file-system/mod";
5
5
  import type { DriverConfig, RunConfig } from "@/registry/run-config";
6
- import { getEnvUniversal } from "@/utils";
7
6
 
8
7
  /**
9
8
  * Chooses the appropriate driver based on the run configuration.
10
9
  */
11
10
  export function chooseDefaultDriver(runConfig: RunConfig): DriverConfig {
12
- const engineEndpoint = runConfig.endpoint ?? getEnvUniversal("RIVET_ENGINE");
13
-
14
- if (engineEndpoint && runConfig.driver) {
11
+ if (runConfig.endpoint && runConfig.driver) {
15
12
  throw new UserError(
16
13
  "Cannot specify both 'engine' and 'driver' in configuration",
17
14
  );
@@ -21,12 +18,16 @@ export function chooseDefaultDriver(runConfig: RunConfig): DriverConfig {
21
18
  return runConfig.driver;
22
19
  }
23
20
 
24
- if (engineEndpoint) {
21
+ if (runConfig.endpoint) {
25
22
  loggerWithoutContext().debug({
26
23
  msg: "using rivet engine driver",
27
- endpoint: engineEndpoint,
24
+ endpoint: runConfig.endpoint,
25
+ });
26
+ // TODO: Add all properties from config
27
+ return createEngineDriver({
28
+ endpoint: runConfig.endpoint,
29
+ token: runConfig.token,
28
30
  });
29
- return createEngineDriver({ endpoint: engineEndpoint });
30
31
  }
31
32
 
32
33
  loggerWithoutContext().debug({ msg: "using default file system driver" });