rivetkit 2.0.21 → 2.0.22-rc.2

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 (140) hide show
  1. package/dist/schemas/actor-persist/v2.ts +259 -0
  2. package/dist/tsup/actor/errors.cjs.map +1 -1
  3. package/dist/tsup/{chunk-HN7UXCYQ.cjs → chunk-5N6F5PXD.cjs} +31 -12
  4. package/dist/tsup/chunk-5N6F5PXD.cjs.map +1 -0
  5. package/dist/tsup/{chunk-FDJ3AVNB.cjs → chunk-5TRXLS6X.cjs} +71 -67
  6. package/dist/tsup/chunk-5TRXLS6X.cjs.map +1 -0
  7. package/dist/tsup/{chunk-HUGSRAGL.js → chunk-7RUROQAZ.js} +36 -16
  8. package/dist/tsup/chunk-7RUROQAZ.js.map +1 -0
  9. package/dist/tsup/{chunk-Y2QONT7B.js → chunk-AMK3AACS.js} +272 -89
  10. package/dist/tsup/chunk-AMK3AACS.js.map +1 -0
  11. package/dist/tsup/{chunk-RZZDFDB6.js → chunk-BHLQTKOD.js} +51 -47
  12. package/dist/tsup/chunk-BHLQTKOD.js.map +1 -0
  13. package/dist/tsup/{chunk-DYA34FHW.js → chunk-C4FPCW7T.js} +2 -2
  14. package/dist/tsup/{chunk-D2LS4X6E.js → chunk-CVLO2OOK.js} +3 -3
  15. package/dist/tsup/{chunk-6G76WIWL.js → chunk-EJXZYQ3N.js} +2 -2
  16. package/dist/tsup/{chunk-VLR3TDHT.js → chunk-F7WVJXPB.js} +2 -2
  17. package/dist/tsup/{chunk-4OINFQBR.js → chunk-FLVL7RGH.js} +3 -3
  18. package/dist/tsup/{chunk-JKOUXDK6.cjs → chunk-GXIO5YOT.cjs} +8 -8
  19. package/dist/tsup/chunk-GXIO5YOT.cjs.map +1 -0
  20. package/dist/tsup/{chunk-2POQCWMA.js → chunk-HLZT5C6A.js} +385 -104
  21. package/dist/tsup/chunk-HLZT5C6A.js.map +1 -0
  22. package/dist/tsup/chunk-KSRXX3Z4.cjs.map +1 -1
  23. package/dist/tsup/{chunk-JTIBPF7N.cjs → chunk-LFP446KS.cjs} +14 -14
  24. package/dist/tsup/chunk-LFP446KS.cjs.map +1 -0
  25. package/dist/tsup/{chunk-3UIGKLZW.js → chunk-MQDXPGNE.js} +6 -6
  26. package/dist/tsup/{chunk-O4GUKGK4.cjs → chunk-NDOG6IQ5.cjs} +6 -6
  27. package/dist/tsup/chunk-NDOG6IQ5.cjs.map +1 -0
  28. package/dist/tsup/{chunk-LMJHBF26.cjs → chunk-Q5CAVEKC.cjs} +467 -284
  29. package/dist/tsup/chunk-Q5CAVEKC.cjs.map +1 -0
  30. package/dist/tsup/{chunk-65SAIRRY.cjs → chunk-UBMUBNS2.cjs} +12 -12
  31. package/dist/tsup/chunk-UBMUBNS2.cjs.map +1 -0
  32. package/dist/tsup/{chunk-FUX6U6TL.js → chunk-VMFBKBJL.js} +26 -7
  33. package/dist/tsup/chunk-VMFBKBJL.js.map +1 -0
  34. package/dist/tsup/{chunk-M5BHNJHB.cjs → chunk-YLWF6RFL.cjs} +558 -277
  35. package/dist/tsup/chunk-YLWF6RFL.cjs.map +1 -0
  36. package/dist/tsup/{chunk-ELDFBXDV.cjs → chunk-YUBR6XCJ.cjs} +35 -15
  37. package/dist/tsup/chunk-YUBR6XCJ.cjs.map +1 -0
  38. package/dist/tsup/{chunk-ZNWE3XBT.cjs → chunk-ZL6NSKF2.cjs} +3 -3
  39. package/dist/tsup/chunk-ZL6NSKF2.cjs.map +1 -0
  40. package/dist/tsup/{chunk-LWGCMELP.cjs → chunk-ZY4DKLMT.cjs} +3 -3
  41. package/dist/tsup/chunk-ZY4DKLMT.cjs.map +1 -0
  42. package/dist/tsup/client/mod.cjs +9 -9
  43. package/dist/tsup/client/mod.cjs.map +1 -1
  44. package/dist/tsup/client/mod.d.cts +2 -2
  45. package/dist/tsup/client/mod.d.ts +2 -2
  46. package/dist/tsup/client/mod.js +8 -8
  47. package/dist/tsup/common/log.cjs +3 -3
  48. package/dist/tsup/common/log.cjs.map +1 -1
  49. package/dist/tsup/common/log.js +2 -2
  50. package/dist/tsup/common/websocket.cjs +4 -4
  51. package/dist/tsup/common/websocket.cjs.map +1 -1
  52. package/dist/tsup/common/websocket.js +3 -3
  53. package/dist/tsup/{conn-Clu655RU.d.ts → conn-BYXlxnh0.d.ts} +111 -102
  54. package/dist/tsup/{conn-lUvFLo_q.d.cts → conn-BiazosE_.d.cts} +111 -102
  55. package/dist/tsup/driver-helpers/mod.cjs +5 -5
  56. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  57. package/dist/tsup/driver-helpers/mod.d.cts +1 -1
  58. package/dist/tsup/driver-helpers/mod.d.ts +1 -1
  59. package/dist/tsup/driver-helpers/mod.js +4 -4
  60. package/dist/tsup/driver-test-suite/mod.cjs +71 -71
  61. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  62. package/dist/tsup/driver-test-suite/mod.d.cts +1 -1
  63. package/dist/tsup/driver-test-suite/mod.d.ts +1 -1
  64. package/dist/tsup/driver-test-suite/mod.js +11 -11
  65. package/dist/tsup/inspector/mod.cjs +6 -6
  66. package/dist/tsup/inspector/mod.cjs.map +1 -1
  67. package/dist/tsup/inspector/mod.d.cts +2 -2
  68. package/dist/tsup/inspector/mod.d.ts +2 -2
  69. package/dist/tsup/inspector/mod.js +5 -5
  70. package/dist/tsup/mod.cjs +10 -10
  71. package/dist/tsup/mod.cjs.map +1 -1
  72. package/dist/tsup/mod.d.cts +3 -3
  73. package/dist/tsup/mod.d.ts +3 -3
  74. package/dist/tsup/mod.js +9 -9
  75. package/dist/tsup/test/mod.cjs +11 -11
  76. package/dist/tsup/test/mod.cjs.map +1 -1
  77. package/dist/tsup/test/mod.d.cts +1 -1
  78. package/dist/tsup/test/mod.d.ts +1 -1
  79. package/dist/tsup/test/mod.js +10 -10
  80. package/dist/tsup/utils.cjs +8 -2
  81. package/dist/tsup/utils.cjs.map +1 -1
  82. package/dist/tsup/utils.d.cts +8 -1
  83. package/dist/tsup/utils.d.ts +8 -1
  84. package/dist/tsup/utils.js +7 -1
  85. package/package.json +5 -4
  86. package/src/actor/config.ts +10 -0
  87. package/src/actor/conn-drivers.ts +43 -1
  88. package/src/actor/conn-socket.ts +1 -1
  89. package/src/actor/conn.ts +22 -2
  90. package/src/actor/context.ts +1 -1
  91. package/src/actor/driver.ts +13 -2
  92. package/src/actor/instance.ts +248 -57
  93. package/src/actor/persisted.ts +7 -0
  94. package/src/actor/router-endpoints.ts +67 -45
  95. package/src/actor/router.ts +25 -17
  96. package/src/client/actor-conn.ts +9 -5
  97. package/src/common/cors.ts +57 -0
  98. package/src/common/log.ts +26 -5
  99. package/src/common/utils.ts +5 -9
  100. package/src/common/websocket-interface.ts +10 -0
  101. package/src/driver-helpers/utils.ts +1 -0
  102. package/src/drivers/engine/actor-driver.ts +261 -14
  103. package/src/drivers/engine/config.ts +2 -4
  104. package/src/drivers/file-system/actor.ts +3 -2
  105. package/src/drivers/file-system/global-state.ts +1 -1
  106. package/src/drivers/file-system/manager.ts +3 -0
  107. package/src/engine-process/mod.ts +22 -4
  108. package/src/inspector/config.ts +0 -45
  109. package/src/manager/gateway.ts +45 -32
  110. package/src/manager/hono-websocket-adapter.ts +31 -3
  111. package/src/manager/router.ts +11 -17
  112. package/src/registry/run-config.ts +2 -8
  113. package/src/remote-manager-driver/actor-http-client.ts +5 -8
  114. package/src/remote-manager-driver/actor-websocket-client.ts +2 -14
  115. package/src/remote-manager-driver/mod.ts +0 -1
  116. package/src/schemas/actor-persist/mod.ts +1 -1
  117. package/src/schemas/actor-persist/versioned.ts +22 -10
  118. package/src/utils.ts +26 -0
  119. package/dist/tsup/chunk-2POQCWMA.js.map +0 -1
  120. package/dist/tsup/chunk-65SAIRRY.cjs.map +0 -1
  121. package/dist/tsup/chunk-ELDFBXDV.cjs.map +0 -1
  122. package/dist/tsup/chunk-FDJ3AVNB.cjs.map +0 -1
  123. package/dist/tsup/chunk-FUX6U6TL.js.map +0 -1
  124. package/dist/tsup/chunk-HN7UXCYQ.cjs.map +0 -1
  125. package/dist/tsup/chunk-HUGSRAGL.js.map +0 -1
  126. package/dist/tsup/chunk-JKOUXDK6.cjs.map +0 -1
  127. package/dist/tsup/chunk-JTIBPF7N.cjs.map +0 -1
  128. package/dist/tsup/chunk-LMJHBF26.cjs.map +0 -1
  129. package/dist/tsup/chunk-LWGCMELP.cjs.map +0 -1
  130. package/dist/tsup/chunk-M5BHNJHB.cjs.map +0 -1
  131. package/dist/tsup/chunk-O4GUKGK4.cjs.map +0 -1
  132. package/dist/tsup/chunk-RZZDFDB6.js.map +0 -1
  133. package/dist/tsup/chunk-Y2QONT7B.js.map +0 -1
  134. package/dist/tsup/chunk-ZNWE3XBT.cjs.map +0 -1
  135. /package/dist/tsup/{chunk-DYA34FHW.js.map → chunk-C4FPCW7T.js.map} +0 -0
  136. /package/dist/tsup/{chunk-D2LS4X6E.js.map → chunk-CVLO2OOK.js.map} +0 -0
  137. /package/dist/tsup/{chunk-6G76WIWL.js.map → chunk-EJXZYQ3N.js.map} +0 -0
  138. /package/dist/tsup/{chunk-VLR3TDHT.js.map → chunk-F7WVJXPB.js.map} +0 -0
  139. /package/dist/tsup/{chunk-4OINFQBR.js.map → chunk-FLVL7RGH.js.map} +0 -0
  140. /package/dist/tsup/{chunk-3UIGKLZW.js.map → chunk-MQDXPGNE.js.map} +0 -0
@@ -134,8 +134,8 @@ async function handleHttpGatewayPathBased(
134
134
  * Routes requests using either path-based routing or header-based routing:
135
135
  *
136
136
  * Path-based routing (checked first):
137
- * - /gateway/actors/{actor_id}/tokens/{token}/route/{...path}
138
- * - /gateway/actors/{actor_id}/route/{...path}
137
+ * - /gateway/{actor_id}/{...path}
138
+ * - /gateway/{actor_id}@{token}/{...path}
139
139
  *
140
140
  * Header-based routing (fallback):
141
141
  * - WebSocket requests: Uses sec-websocket-protocol for routing (target.actor, actor.{id})
@@ -340,8 +340,8 @@ async function handleHttpGateway(
340
340
  /**
341
341
  * Parse actor routing information from path
342
342
  * Matches patterns:
343
- * - /gateway/actors/{actor_id}/tokens/{token}/route/{...path}
344
- * - /gateway/actors/{actor_id}/route/{...path}
343
+ * - /gateway/{actor_id}/{...path}
344
+ * - /gateway/{actor_id}@{token}/{...path}
345
345
  */
346
346
  export function parseActorPath(path: string): ActorPathInfo | null {
347
347
  // Find query string position (everything from ? onwards, but before fragment)
@@ -374,50 +374,63 @@ export function parseActorPath(path: string): ActorPathInfo | null {
374
374
  // Split the path into segments
375
375
  const segments = basePath.split("/").filter((s) => s.length > 0);
376
376
 
377
- // Check minimum required segments: gateway, actors, {actor_id}, route
378
- if (segments.length < 4) {
377
+ // Check minimum required segments: gateway, {actor_id}
378
+ if (segments.length < 2) {
379
379
  return null;
380
380
  }
381
381
 
382
- // Verify the fixed segments
383
- if (segments[0] !== "gateway" || segments[1] !== "actors") {
382
+ // Verify the first segment is "gateway"
383
+ if (segments[0] !== "gateway") {
384
384
  return null;
385
385
  }
386
386
 
387
- // Check for empty actor_id
388
- if (segments[2].length === 0) {
387
+ // Extract actor_id segment (may contain @token)
388
+ const actorSegment = segments[1];
389
+
390
+ // Check for empty actor segment
391
+ if (actorSegment.length === 0) {
389
392
  return null;
390
393
  }
391
394
 
392
- const actorId = segments[2];
393
-
394
- // Check for token or direct route
395
+ // Parse actor_id and optional token from the segment
396
+ let actorId: string;
395
397
  let token: string | undefined;
396
- let remainingPathStartIdx: number;
397
-
398
- if (
399
- segments.length >= 6 &&
400
- segments[3] === "tokens" &&
401
- segments[5] === "route"
402
- ) {
403
- // Pattern with token: /gateway/actors/{actor_id}/tokens/{token}/route/{...path}
404
- // Check for empty token
405
- if (segments[4].length === 0) {
398
+
399
+ const atPos = actorSegment.indexOf("@");
400
+ if (atPos !== -1) {
401
+ // Pattern: /gateway/{actor_id}@{token}/{...path}
402
+ const rawActorId = actorSegment.slice(0, atPos);
403
+ const rawToken = actorSegment.slice(atPos + 1);
404
+
405
+ // Check for empty actor_id or token
406
+ if (rawActorId.length === 0 || rawToken.length === 0) {
407
+ return null;
408
+ }
409
+
410
+ // URL-decode both actor_id and token
411
+ try {
412
+ actorId = decodeURIComponent(rawActorId);
413
+ token = decodeURIComponent(rawToken);
414
+ } catch (e) {
415
+ // Invalid URL encoding
406
416
  return null;
407
417
  }
408
- token = segments[4];
409
- remainingPathStartIdx = 6;
410
- } else if (segments.length >= 4 && segments[3] === "route") {
411
- // Pattern without token: /gateway/actors/{actor_id}/route/{...path}
412
- token = undefined;
413
- remainingPathStartIdx = 4;
414
418
  } else {
415
- return null;
419
+ // Pattern: /gateway/{actor_id}/{...path}
420
+ // URL-decode actor_id
421
+ try {
422
+ actorId = decodeURIComponent(actorSegment);
423
+ } catch (e) {
424
+ // Invalid URL encoding
425
+ return null;
426
+ }
427
+ token = undefined;
416
428
  }
417
429
 
418
- // Calculate the position in the original path where remaining path starts
430
+ // Calculate remaining path
431
+ // The remaining path starts after /gateway/{actor_id[@token]}/
419
432
  let prefixLen = 0;
420
- for (let i = 0; i < remainingPathStartIdx; i++) {
433
+ for (let i = 0; i < 2; i++) {
421
434
  prefixLen += 1 + segments[i].length; // +1 for the slash
422
435
  }
423
436
 
@@ -23,16 +23,28 @@ export class HonoWebSocketAdapter implements UniversalWebSocket {
23
23
  #eventListeners: Map<string, Set<(event: any) => void>> = new Map();
24
24
  #closeCode?: number;
25
25
  #closeReason?: string;
26
-
27
- constructor(ws: WSContext) {
26
+ readonly rivetRequestId?: ArrayBuffer;
27
+ readonly isHibernatable: boolean;
28
+
29
+ constructor(
30
+ ws: WSContext,
31
+ rivetRequestId: ArrayBuffer | undefined,
32
+ isHibernatable: boolean,
33
+ ) {
28
34
  this.#ws = ws;
35
+ this.rivetRequestId = rivetRequestId;
36
+ this.isHibernatable = isHibernatable;
29
37
 
30
38
  // The WSContext is already open when we receive it
31
39
  this.#readyState = this.OPEN;
32
40
 
33
41
  // Immediately fire the open event
34
42
  setTimeout(() => {
35
- this.#fireEvent("open", { type: "open", target: this });
43
+ this.#fireEvent("open", {
44
+ type: "open",
45
+ target: this,
46
+ rivetRequestId: this.rivetRequestId,
47
+ });
36
48
  }, 0);
37
49
  }
38
50
 
@@ -155,6 +167,7 @@ export class HonoWebSocketAdapter implements UniversalWebSocket {
155
167
  code,
156
168
  reason,
157
169
  wasClean: code === 1000,
170
+ rivetRequestId: this.rivetRequestId,
158
171
  });
159
172
  } catch (error) {
160
173
  logger().error({ msg: "error closing websocket", error });
@@ -165,6 +178,7 @@ export class HonoWebSocketAdapter implements UniversalWebSocket {
165
178
  code: 1006,
166
179
  reason: "Abnormal closure",
167
180
  wasClean: false,
181
+ rivetRequestId: this.rivetRequestId,
168
182
  });
169
183
  }
170
184
  }
@@ -204,6 +218,8 @@ export class HonoWebSocketAdapter implements UniversalWebSocket {
204
218
  _handleMessage(data: any): void {
205
219
  // Hono may pass either raw data or a MessageEvent-like object
206
220
  let messageData: string | ArrayBuffer | ArrayBufferView;
221
+ let rivetRequestId: ArrayBuffer | undefined;
222
+ let rivetMessageIndex: number | undefined;
207
223
 
208
224
  if (typeof data === "string") {
209
225
  messageData = data;
@@ -212,6 +228,14 @@ export class HonoWebSocketAdapter implements UniversalWebSocket {
212
228
  } else if (data && typeof data === "object" && "data" in data) {
213
229
  // Handle MessageEvent-like objects
214
230
  messageData = data.data;
231
+
232
+ // Preserve hibernation-related properties from engine runner
233
+ if ("rivetRequestId" in data) {
234
+ rivetRequestId = data.rivetRequestId;
235
+ }
236
+ if ("rivetMessageIndex" in data) {
237
+ rivetMessageIndex = data.rivetMessageIndex;
238
+ }
215
239
  } else {
216
240
  // Fallback - shouldn't happen in normal operation
217
241
  messageData = String(data);
@@ -222,12 +246,15 @@ export class HonoWebSocketAdapter implements UniversalWebSocket {
222
246
  dataType: typeof messageData,
223
247
  isArrayBuffer: messageData instanceof ArrayBuffer,
224
248
  dataStr: typeof messageData === "string" ? messageData : "<binary>",
249
+ rivetMessageIndex,
225
250
  });
226
251
 
227
252
  this.#fireEvent("message", {
228
253
  type: "message",
229
254
  target: this,
230
255
  data: messageData,
256
+ rivetRequestId,
257
+ rivetMessageIndex,
231
258
  });
232
259
  }
233
260
 
@@ -249,6 +276,7 @@ export class HonoWebSocketAdapter implements UniversalWebSocket {
249
276
  code,
250
277
  reason,
251
278
  wasClean: code === 1000,
279
+ rivetRequestId: this.rivetRequestId,
252
280
  });
253
281
  }
254
282
 
@@ -6,7 +6,6 @@ import {
6
6
  type MiddlewareHandler,
7
7
  type Next,
8
8
  } from "hono";
9
- import { cors as corsMiddleware } from "hono/cors";
10
9
  import { createMiddleware } from "hono/factory";
11
10
  import { streamSSE } from "hono/streaming";
12
11
  import invariant from "invariant";
@@ -23,13 +22,13 @@ import {
23
22
  WS_PROTOCOL_PATH,
24
23
  WS_PROTOCOL_TRANSPORT,
25
24
  } from "@/common/actor-router-consts";
25
+ import { cors } from "@/common/cors";
26
26
  import {
27
27
  handleHealthRequest,
28
28
  handleMetadataRequest,
29
29
  handleRouteError,
30
30
  handleRouteNotFound,
31
31
  loggerMiddleware,
32
- type MetadataResponse,
33
32
  } from "@/common/router";
34
33
  import {
35
34
  assertUnreachable,
@@ -37,7 +36,7 @@ import {
37
36
  noopNext,
38
37
  stringifyError,
39
38
  } from "@/common/utils";
40
- import { type ActorDriver, HEADER_ACTOR_ID } from "@/driver-helpers/mod";
39
+ import { HEADER_ACTOR_ID } from "@/driver-helpers/mod";
41
40
  import type {
42
41
  TestInlineDriverCallRequest,
43
42
  TestInlineDriverCallResponse,
@@ -45,11 +44,9 @@ import type {
45
44
  import { createManagerInspectorRouter } from "@/inspector/manager";
46
45
  import { isInspectorEnabled, secureInspector } from "@/inspector/utils";
47
46
  import {
48
- type ActorsCreateRequest,
49
47
  ActorsCreateRequestSchema,
50
48
  type ActorsCreateResponse,
51
49
  ActorsCreateResponseSchema,
52
- type ActorsGetOrCreateRequest,
53
50
  ActorsGetOrCreateRequestSchema,
54
51
  type ActorsGetOrCreateResponse,
55
52
  ActorsGetOrCreateResponseSchema,
@@ -57,11 +54,9 @@ import {
57
54
  ActorsListResponseSchema,
58
55
  type Actor as ApiActor,
59
56
  } from "@/manager-api/actors";
60
- import { RivetIdSchema } from "@/manager-api/common";
61
57
  import type { AnyClient } from "@/mod";
62
58
  import type { RegistryConfig } from "@/registry/config";
63
59
  import type { DriverConfig, RunnerConfig } from "@/registry/run-config";
64
- import { VERSION } from "@/utils";
65
60
  import type { ActorOutput, ManagerDriver } from "./driver";
66
61
  import { actorGateway, createTestWebSocketProxy } from "./gateway";
67
62
  import { logger } from "./log";
@@ -97,7 +92,7 @@ export function createManagerRouter(
97
92
  runConfig.basePath,
98
93
  );
99
94
 
100
- router.use("*", loggerMiddleware(logger()));
95
+ router.use("*", loggerMiddleware(logger()), cors());
101
96
 
102
97
  // HACK: Add Sec-WebSocket-Protocol header to fix KIT-339
103
98
  //
@@ -148,9 +143,6 @@ function addServerlessRoutes(
148
143
  client: AnyClient,
149
144
  router: OpenAPIHono,
150
145
  ) {
151
- // Apply CORS
152
- if (runConfig.cors) router.use("*", corsMiddleware(runConfig.cors));
153
-
154
146
  // GET /
155
147
  router.get("/", (c) => {
156
148
  return c.text(
@@ -194,6 +186,13 @@ function addServerlessRoutes(
194
186
  newRunConfig.totalSlots = totalSlots;
195
187
  newRunConfig.runnerName = runnerName;
196
188
  newRunConfig.namespace = namespace;
189
+ if (newRunConfig.runnerKey) {
190
+ logger().warn({
191
+ msg: "runner keys are not supported by serverless runners, this will be overwritten with a random runner key",
192
+ oldRunnerKey: newRunConfig.runnerKey,
193
+ });
194
+ newRunConfig.runnerKey = undefined;
195
+ }
197
196
 
198
197
  // Create new actor driver with updated config
199
198
  const actorDriver = driverConfig.actor(
@@ -223,8 +222,7 @@ function addManagerRoutes(
223
222
  managerDriver: ManagerDriver,
224
223
  router: OpenAPIHono,
225
224
  ) {
226
- // Serve inspector BEFORE the rest of the routes, since this has a special
227
- // CORS config that should take precedence for the `/inspector` path
225
+ // Inspector
228
226
  if (isInspectorEnabled(runConfig, "manager")) {
229
227
  if (!managerDriver.inspector) {
230
228
  throw new Unsupported("inspector");
@@ -232,7 +230,6 @@ function addManagerRoutes(
232
230
  router.route(
233
231
  "/inspect",
234
232
  new Hono<{ Variables: { inspector: any } }>()
235
- .use(corsMiddleware(runConfig.inspector.cors))
236
233
  .use(secureInspector(runConfig))
237
234
  .use((c, next) => {
238
235
  c.set("inspector", managerDriver.inspector!);
@@ -242,9 +239,6 @@ function addManagerRoutes(
242
239
  );
243
240
  }
244
241
 
245
- // Apply CORS
246
- if (runConfig.cors) router.use("*", corsMiddleware(runConfig.cors));
247
-
248
242
  // Actor gateway
249
243
  router.use("*", actorGateway.bind(undefined, runConfig, managerDriver));
250
244
 
@@ -1,4 +1,3 @@
1
- import type { cors } from "hono/cors";
2
1
  import type { Logger } from "pino";
3
2
  import { z } from "zod";
4
3
  import type { ActorDriverBuilder } from "@/actor/driver";
@@ -7,9 +6,7 @@ import { EngingConfigSchema as EngineConfigSchema } from "@/drivers/engine/confi
7
6
  import { InspectorConfigSchema } from "@/inspector/config";
8
7
  import type { ManagerDriverBuilder } from "@/manager/driver";
9
8
  import type { GetUpgradeWebSocket } from "@/utils";
10
- import { getEnvUniversal } from "@/utils";
11
-
12
- type CorsOptions = NonNullable<Parameters<typeof cors>[0]>;
9
+ import { getEnvUniversal, VERSION } from "@/utils";
13
10
 
14
11
  export const DriverConfigSchema = z.object({
15
12
  /** Machine-readable name to identify this driver by. */
@@ -25,9 +22,6 @@ export const RunnerConfigSchema = z
25
22
  .object({
26
23
  driver: DriverConfigSchema.optional(),
27
24
 
28
- /** CORS configuration for the router. Uses Hono's CORS middleware options. */
29
- cors: z.custom<CorsOptions>().optional(),
30
-
31
25
  /** @experimental */
32
26
  maxIncomingMessageSize: z.number().optional().default(65_536),
33
27
 
@@ -51,7 +45,7 @@ export const RunnerConfigSchema = z
51
45
  .string()
52
46
  .optional()
53
47
  .default(
54
- () => getEnvUniversal("RIVET_RUN_ENGINE_VERSION") ?? "25.8.2",
48
+ () => getEnvUniversal("RIVET_RUN_ENGINE_VERSION") ?? VERSION,
55
49
  ),
56
50
 
57
51
  /** @experimental */
@@ -1,9 +1,5 @@
1
1
  import type { ClientConfig } from "@/client/config";
2
- import {
3
- HEADER_RIVET_ACTOR,
4
- HEADER_RIVET_TARGET,
5
- HEADER_RIVET_TOKEN,
6
- } from "@/common/actor-router-consts";
2
+ import { HEADER_RIVET_TOKEN } from "@/common/actor-router-consts";
7
3
  import { combineUrlPath } from "@/utils";
8
4
  import { getEndpoint } from "./api-utils";
9
5
 
@@ -15,7 +11,10 @@ export async function sendHttpRequestToActor(
15
11
  // Route through guard port
16
12
  const url = new URL(actorRequest.url);
17
13
  const endpoint = getEndpoint(runConfig);
18
- const guardUrl = combineUrlPath(endpoint, url.pathname + url.search);
14
+ const guardUrl = combineUrlPath(
15
+ endpoint,
16
+ `/gateway/${actorId}${url.pathname}${url.search}`,
17
+ );
19
18
 
20
19
  // Handle body properly based on method and presence
21
20
  let bodyToSend: ArrayBuffer | null = null;
@@ -76,8 +75,6 @@ function buildGuardHeadersForHttp(
76
75
  headers.set(key, value);
77
76
  }
78
77
  // Add guard-specific headers
79
- headers.set(HEADER_RIVET_TARGET, "actor");
80
- headers.set(HEADER_RIVET_ACTOR, actorId);
81
78
  if (runConfig.token) {
82
79
  headers.set(HEADER_RIVET_TOKEN, runConfig.token);
83
80
  }
@@ -2,13 +2,11 @@ import type { ClientConfig } from "@/client/config";
2
2
  import {
3
3
  HEADER_CONN_PARAMS,
4
4
  HEADER_ENCODING,
5
- WS_PROTOCOL_ACTOR,
6
5
  WS_PROTOCOL_CONN_ID,
7
6
  WS_PROTOCOL_CONN_PARAMS,
8
7
  WS_PROTOCOL_CONN_TOKEN,
9
8
  WS_PROTOCOL_ENCODING,
10
9
  WS_PROTOCOL_STANDARD as WS_PROTOCOL_RIVETKIT,
11
- WS_PROTOCOL_TARGET,
12
10
  WS_PROTOCOL_TOKEN,
13
11
  } from "@/common/actor-router-consts";
14
12
  import { importWebSocket } from "@/common/websocket";
@@ -30,7 +28,7 @@ export async function openWebSocketToActor(
30
28
 
31
29
  // WebSocket connections go through guard
32
30
  const endpoint = getEndpoint(runConfig);
33
- const guardUrl = combineUrlPath(endpoint, path);
31
+ const guardUrl = combineUrlPath(endpoint, `/gateway/${actorId}${path}`);
34
32
 
35
33
  logger().debug({
36
34
  msg: "opening websocket to actor via guard",
@@ -42,14 +40,7 @@ export async function openWebSocketToActor(
42
40
  // Create WebSocket connection
43
41
  const ws = new WebSocket(
44
42
  guardUrl,
45
- buildWebSocketProtocols(
46
- runConfig,
47
- actorId,
48
- encoding,
49
- params,
50
- connId,
51
- connToken,
52
- ),
43
+ buildWebSocketProtocols(runConfig, encoding, params, connId, connToken),
53
44
  );
54
45
 
55
46
  // Set binary type to arraybuffer for proper encoding support
@@ -62,7 +53,6 @@ export async function openWebSocketToActor(
62
53
 
63
54
  export function buildWebSocketProtocols(
64
55
  runConfig: ClientConfig,
65
- actorId: string,
66
56
  encoding: Encoding,
67
57
  params?: unknown,
68
58
  connId?: string,
@@ -70,8 +60,6 @@ export function buildWebSocketProtocols(
70
60
  ): string[] {
71
61
  const protocols: string[] = [];
72
62
  protocols.push(WS_PROTOCOL_RIVETKIT);
73
- protocols.push(`${WS_PROTOCOL_TARGET}actor`);
74
- protocols.push(`${WS_PROTOCOL_ACTOR}${actorId}`);
75
63
  protocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);
76
64
  if (runConfig.token) {
77
65
  protocols.push(`${WS_PROTOCOL_TOKEN}${runConfig.token}`);
@@ -383,7 +383,6 @@ export class RemoteManagerDriver implements ManagerDriver {
383
383
  // Build protocols
384
384
  const protocols = buildWebSocketProtocols(
385
385
  this.#config,
386
- actorId,
387
386
  encoding,
388
387
  params,
389
388
  connId,
@@ -1 +1 @@
1
- export * from "../../../dist/schemas/actor-persist/v1";
1
+ export * from "../../../dist/schemas/actor-persist/v2";
@@ -2,24 +2,36 @@ import {
2
2
  createVersionedDataHandler,
3
3
  type MigrationFn,
4
4
  } from "@/common/versioned-data";
5
- import * as v1 from "../../../dist/schemas/actor-persist/v1";
5
+ import type * as v1 from "../../../dist/schemas/actor-persist/v1";
6
+ import * as v2 from "../../../dist/schemas/actor-persist/v2";
6
7
 
7
- export const CURRENT_VERSION = 1;
8
+ export const CURRENT_VERSION = 2;
8
9
 
9
- export type CurrentPersistedActor = v1.PersistedActor;
10
- export type CurrentPersistedConnection = v1.PersistedConnection;
11
- export type CurrentPersistedSubscription = v1.PersistedSubscription;
10
+ export type CurrentPersistedActor = v2.PersistedActor;
11
+ export type CurrentPersistedConnection = v2.PersistedConnection;
12
+ export type CurrentPersistedSubscription = v2.PersistedSubscription;
12
13
  export type CurrentGenericPersistedScheduleEvent =
13
- v1.GenericPersistedScheduleEvent;
14
- export type CurrentPersistedScheduleEventKind = v1.PersistedScheduleEventKind;
15
- export type CurrentPersistedScheduleEvent = v1.PersistedScheduleEvent;
14
+ v2.GenericPersistedScheduleEvent;
15
+ export type CurrentPersistedScheduleEventKind = v2.PersistedScheduleEventKind;
16
+ export type CurrentPersistedScheduleEvent = v2.PersistedScheduleEvent;
17
+ export type CurrentPersistedHibernatableWebSocket =
18
+ v2.PersistedHibernatableWebSocket;
16
19
 
17
20
  const migrations = new Map<number, MigrationFn<any, any>>();
18
21
 
22
+ // Migration from v1 to v2: Add hibernatableWebSocket field
23
+ migrations.set(
24
+ 1,
25
+ (v1Data: v1.PersistedActor): v2.PersistedActor => ({
26
+ ...v1Data,
27
+ hibernatableWebSocket: [],
28
+ }),
29
+ );
30
+
19
31
  export const PERSISTED_ACTOR_VERSIONED =
20
32
  createVersionedDataHandler<CurrentPersistedActor>({
21
33
  currentVersion: CURRENT_VERSION,
22
34
  migrations,
23
- serializeVersion: (data) => v1.encodePersistedActor(data),
24
- deserializeVersion: (bytes) => v1.decodePersistedActor(bytes),
35
+ serializeVersion: (data) => v2.encodePersistedActor(data),
36
+ deserializeVersion: (bytes) => v2.decodePersistedActor(bytes),
25
37
  });
package/src/utils.ts CHANGED
@@ -2,6 +2,7 @@ export { stringifyError } from "@/common/utils";
2
2
  export { assertUnreachable } from "./common/utils";
3
3
 
4
4
  import type { Context as HonoContext, Handler as HonoHandler } from "hono";
5
+ import { stringify as uuidstringify } from "uuid";
5
6
 
6
7
  import pkgJson from "../package.json" with { type: "json" };
7
8
 
@@ -248,3 +249,28 @@ export function combineUrlPath(
248
249
  const fullQuery = queryParts.length > 0 ? `?${queryParts.join("&")}` : "";
249
250
  return `${baseUrl.protocol}//${baseUrl.host}${fullPath}${fullQuery}`;
250
251
  }
252
+
253
+ export function arrayBuffersEqual(
254
+ buf1: ArrayBuffer,
255
+ buf2: ArrayBuffer,
256
+ ): boolean {
257
+ if (buf1.byteLength !== buf2.byteLength) return false;
258
+
259
+ const view1 = new Uint8Array(buf1);
260
+ const view2 = new Uint8Array(buf2);
261
+
262
+ for (let i = 0; i < view1.length; i++) {
263
+ if (view1[i] !== view2[i]) return false;
264
+ }
265
+ return true;
266
+ }
267
+
268
+ export const EXTRA_ERROR_LOG = {
269
+ issues: "https://github.com/rivet-dev/rivetkit/issues",
270
+ support: "https://rivet.dev/discord",
271
+ version: VERSION,
272
+ };
273
+
274
+ export function idToStr(id: ArrayBuffer): string {
275
+ return uuidstringify(new Uint8Array(id));
276
+ }