rivetkit 2.0.20 → 2.0.21

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 (169) hide show
  1. package/dist/tsup/actor/errors.cjs.map +1 -1
  2. package/dist/tsup/{chunk-L3YPHXPE.js → chunk-2POQCWMA.js} +481 -100
  3. package/dist/tsup/chunk-2POQCWMA.js.map +1 -0
  4. package/dist/tsup/{chunk-5F6X4AFU.js → chunk-3UIGKLZW.js} +6 -6
  5. package/dist/tsup/chunk-3UIGKLZW.js.map +1 -0
  6. package/dist/tsup/{chunk-M6LIJ6BK.js → chunk-4OINFQBR.js} +3 -3
  7. package/dist/tsup/{chunk-ZODINJWN.cjs → chunk-65SAIRRY.cjs} +12 -12
  8. package/dist/tsup/chunk-65SAIRRY.cjs.map +1 -0
  9. package/dist/tsup/{chunk-RI4YHZZW.js → chunk-6G76WIWL.js} +2 -2
  10. package/dist/tsup/{chunk-RI4YHZZW.js.map → chunk-6G76WIWL.js.map} +1 -1
  11. package/dist/tsup/{chunk-YFFCPYHY.js → chunk-D2LS4X6E.js} +11 -5
  12. package/dist/tsup/chunk-D2LS4X6E.js.map +1 -0
  13. package/dist/tsup/{chunk-QRUGCDA5.js → chunk-DYA34FHW.js} +2 -2
  14. package/dist/tsup/{chunk-KUZWEM23.cjs → chunk-ELDFBXDV.cjs} +8 -4
  15. package/dist/tsup/chunk-ELDFBXDV.cjs.map +1 -0
  16. package/dist/tsup/{chunk-FYP3TZXD.cjs → chunk-FDJ3AVNB.cjs} +32 -26
  17. package/dist/tsup/chunk-FDJ3AVNB.cjs.map +1 -0
  18. package/dist/tsup/{chunk-ER5OT3SQ.js → chunk-FUX6U6TL.js} +2 -2
  19. package/dist/tsup/chunk-FUX6U6TL.js.map +1 -0
  20. package/dist/tsup/{chunk-RJVSNJO7.cjs → chunk-HN7UXCYQ.cjs} +7 -7
  21. package/dist/tsup/chunk-HN7UXCYQ.cjs.map +1 -0
  22. package/dist/tsup/{chunk-QMVCFQ37.js → chunk-HUGSRAGL.js} +8 -4
  23. package/dist/tsup/chunk-HUGSRAGL.js.map +1 -0
  24. package/dist/tsup/{chunk-PV22ZBDE.cjs → chunk-JKOUXDK6.cjs} +16 -10
  25. package/dist/tsup/chunk-JKOUXDK6.cjs.map +1 -0
  26. package/dist/tsup/{chunk-2I6L3VRO.cjs → chunk-JTIBPF7N.cjs} +14 -14
  27. package/dist/tsup/chunk-JTIBPF7N.cjs.map +1 -0
  28. package/dist/tsup/chunk-KSRXX3Z4.cjs.map +1 -1
  29. package/dist/tsup/{chunk-JZD6FEOE.cjs → chunk-LMJHBF26.cjs} +455 -289
  30. package/dist/tsup/chunk-LMJHBF26.cjs.map +1 -0
  31. package/dist/tsup/{chunk-KKRR7DSG.cjs → chunk-LWGCMELP.cjs} +3 -3
  32. package/dist/tsup/chunk-LWGCMELP.cjs.map +1 -0
  33. package/dist/tsup/{chunk-2S7HJMMY.cjs → chunk-M5BHNJHB.cjs} +630 -249
  34. package/dist/tsup/chunk-M5BHNJHB.cjs.map +1 -0
  35. package/dist/tsup/{chunk-G6JGHCG4.cjs → chunk-O4GUKGK4.cjs} +6 -6
  36. package/dist/tsup/chunk-O4GUKGK4.cjs.map +1 -0
  37. package/dist/tsup/{chunk-7ACKZS3T.js → chunk-RZZDFDB6.js} +13 -7
  38. package/dist/tsup/chunk-RZZDFDB6.js.map +1 -0
  39. package/dist/tsup/{chunk-MGHPBNWB.js → chunk-VLR3TDHT.js} +2 -2
  40. package/dist/tsup/{chunk-GQ5WTE64.js → chunk-Y2QONT7B.js} +263 -97
  41. package/dist/tsup/chunk-Y2QONT7B.js.map +1 -0
  42. package/dist/tsup/{chunk-DUOTOMP7.cjs → chunk-ZNWE3XBT.cjs} +3 -3
  43. package/dist/tsup/chunk-ZNWE3XBT.cjs.map +1 -0
  44. package/dist/tsup/client/mod.cjs +9 -9
  45. package/dist/tsup/client/mod.cjs.map +1 -1
  46. package/dist/tsup/client/mod.d.cts +2 -2
  47. package/dist/tsup/client/mod.d.ts +2 -2
  48. package/dist/tsup/client/mod.js +8 -8
  49. package/dist/tsup/common/log.cjs +3 -3
  50. package/dist/tsup/common/log.cjs.map +1 -1
  51. package/dist/tsup/common/log.js +2 -2
  52. package/dist/tsup/common/websocket.cjs +4 -4
  53. package/dist/tsup/common/websocket.cjs.map +1 -1
  54. package/dist/tsup/common/websocket.js +3 -3
  55. package/dist/tsup/{conn-CmPcqOCF.d.ts → conn-Clu655RU.d.ts} +72 -71
  56. package/dist/tsup/{conn-DU5EbfCu.d.cts → conn-lUvFLo_q.d.cts} +72 -71
  57. package/dist/tsup/driver-helpers/mod.cjs +5 -5
  58. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  59. package/dist/tsup/driver-helpers/mod.d.cts +1 -1
  60. package/dist/tsup/driver-helpers/mod.d.ts +1 -1
  61. package/dist/tsup/driver-helpers/mod.js +4 -4
  62. package/dist/tsup/driver-test-suite/mod.cjs +603 -294
  63. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  64. package/dist/tsup/driver-test-suite/mod.d.cts +1 -1
  65. package/dist/tsup/driver-test-suite/mod.d.ts +1 -1
  66. package/dist/tsup/driver-test-suite/mod.js +574 -265
  67. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  68. package/dist/tsup/inspector/mod.cjs +6 -6
  69. package/dist/tsup/inspector/mod.cjs.map +1 -1
  70. package/dist/tsup/inspector/mod.d.cts +68 -7
  71. package/dist/tsup/inspector/mod.d.ts +68 -7
  72. package/dist/tsup/inspector/mod.js +5 -5
  73. package/dist/tsup/mod.cjs +10 -10
  74. package/dist/tsup/mod.cjs.map +1 -1
  75. package/dist/tsup/mod.d.cts +2 -2
  76. package/dist/tsup/mod.d.ts +2 -2
  77. package/dist/tsup/mod.js +9 -9
  78. package/dist/tsup/test/mod.cjs +11 -11
  79. package/dist/tsup/test/mod.cjs.map +1 -1
  80. package/dist/tsup/test/mod.d.cts +1 -1
  81. package/dist/tsup/test/mod.d.ts +1 -1
  82. package/dist/tsup/test/mod.js +10 -10
  83. package/dist/tsup/utils.cjs +2 -2
  84. package/dist/tsup/utils.cjs.map +1 -1
  85. package/dist/tsup/utils.js +1 -1
  86. package/package.json +4 -3
  87. package/src/actor/config.ts +108 -15
  88. package/src/actor/conn-drivers.ts +2 -1
  89. package/src/actor/instance.ts +119 -35
  90. package/src/actor/keys.test.ts +13 -4
  91. package/src/actor/protocol/old.ts +10 -3
  92. package/src/actor/router-endpoints.ts +26 -16
  93. package/src/actor/router.ts +41 -13
  94. package/src/actor/unstable-react.ts +1 -1
  95. package/src/client/actor-common.ts +3 -1
  96. package/src/client/actor-conn.ts +44 -12
  97. package/src/client/actor-handle.ts +4 -1
  98. package/src/client/client.ts +32 -18
  99. package/src/client/utils.ts +21 -8
  100. package/src/common/actor-router-consts.ts +2 -0
  101. package/src/common/inline-websocket-adapter2.ts +24 -6
  102. package/src/common/log.ts +6 -2
  103. package/src/common/logfmt.ts +3 -1
  104. package/src/common/router.ts +3 -1
  105. package/src/common/utils.ts +6 -2
  106. package/src/driver-helpers/utils.ts +4 -1
  107. package/src/driver-test-suite/mod.ts +15 -4
  108. package/src/driver-test-suite/test-inline-client-driver.ts +35 -13
  109. package/src/driver-test-suite/tests/action-features.ts +6 -2
  110. package/src/driver-test-suite/tests/actor-conn-state.ts +18 -8
  111. package/src/driver-test-suite/tests/actor-conn.ts +35 -13
  112. package/src/driver-test-suite/tests/actor-handle.ts +35 -15
  113. package/src/driver-test-suite/tests/actor-inline-client.ts +34 -23
  114. package/src/driver-test-suite/tests/actor-inspector.ts +241 -131
  115. package/src/driver-test-suite/tests/actor-reconnect.ts +14 -4
  116. package/src/driver-test-suite/tests/actor-schedule.ts +12 -3
  117. package/src/driver-test-suite/tests/actor-sleep.ts +6 -3
  118. package/src/driver-test-suite/tests/actor-vars.ts +6 -2
  119. package/src/driver-test-suite/tests/manager-driver.ts +16 -6
  120. package/src/driver-test-suite/tests/raw-http-request-properties.ts +64 -25
  121. package/src/driver-test-suite/tests/raw-http.ts +17 -5
  122. package/src/driver-test-suite/tests/raw-websocket.ts +36 -12
  123. package/src/driver-test-suite/tests/request-access.ts +18 -8
  124. package/src/drivers/engine/actor-driver.ts +46 -25
  125. package/src/drivers/engine/config.ts +2 -1
  126. package/src/drivers/file-system/global-state.ts +58 -16
  127. package/src/drivers/file-system/manager.ts +35 -12
  128. package/src/drivers/file-system/mod.ts +6 -1
  129. package/src/drivers/file-system/utils.ts +8 -2
  130. package/src/engine-process/mod.ts +15 -4
  131. package/src/inspector/actor.ts +63 -23
  132. package/src/inspector/config.ts +2 -1
  133. package/src/inspector/manager.ts +10 -3
  134. package/src/inspector/utils.ts +2 -1
  135. package/src/manager/driver.ts +4 -1
  136. package/src/manager/gateway.ts +278 -8
  137. package/src/manager/hono-websocket-adapter.ts +33 -10
  138. package/src/manager/router-schema.ts +4 -2
  139. package/src/manager/router.ts +78 -12
  140. package/src/manager-api/actors.ts +2 -0
  141. package/src/registry/mod.ts +31 -9
  142. package/src/registry/run-config.ts +3 -1
  143. package/src/remote-manager-driver/api-endpoints.ts +2 -2
  144. package/src/remote-manager-driver/mod.ts +23 -7
  145. package/src/remote-manager-driver/ws-proxy.ts +21 -5
  146. package/src/serde.ts +6 -2
  147. package/src/test/mod.ts +2 -1
  148. package/src/utils.ts +6 -2
  149. package/dist/tsup/chunk-2I6L3VRO.cjs.map +0 -1
  150. package/dist/tsup/chunk-2S7HJMMY.cjs.map +0 -1
  151. package/dist/tsup/chunk-5F6X4AFU.js.map +0 -1
  152. package/dist/tsup/chunk-7ACKZS3T.js.map +0 -1
  153. package/dist/tsup/chunk-DUOTOMP7.cjs.map +0 -1
  154. package/dist/tsup/chunk-ER5OT3SQ.js.map +0 -1
  155. package/dist/tsup/chunk-FYP3TZXD.cjs.map +0 -1
  156. package/dist/tsup/chunk-G6JGHCG4.cjs.map +0 -1
  157. package/dist/tsup/chunk-GQ5WTE64.js.map +0 -1
  158. package/dist/tsup/chunk-JZD6FEOE.cjs.map +0 -1
  159. package/dist/tsup/chunk-KKRR7DSG.cjs.map +0 -1
  160. package/dist/tsup/chunk-KUZWEM23.cjs.map +0 -1
  161. package/dist/tsup/chunk-L3YPHXPE.js.map +0 -1
  162. package/dist/tsup/chunk-PV22ZBDE.cjs.map +0 -1
  163. package/dist/tsup/chunk-QMVCFQ37.js.map +0 -1
  164. package/dist/tsup/chunk-RJVSNJO7.cjs.map +0 -1
  165. package/dist/tsup/chunk-YFFCPYHY.js.map +0 -1
  166. package/dist/tsup/chunk-ZODINJWN.cjs.map +0 -1
  167. /package/dist/tsup/{chunk-M6LIJ6BK.js.map → chunk-4OINFQBR.js.map} +0 -0
  168. /package/dist/tsup/{chunk-QRUGCDA5.js.map → chunk-DYA34FHW.js.map} +0 -0
  169. /package/dist/tsup/{chunk-MGHPBNWB.js.map → chunk-VLR3TDHT.js.map} +0 -0
@@ -1,7 +1,9 @@
1
1
  import { z } from "zod";
2
2
 
3
3
  export const ServerlessStartHeadersSchema = z.object({
4
- endpoint: z.string({ required_error: "x-rivet-endpoint header is required" }),
4
+ endpoint: z.string({
5
+ required_error: "x-rivet-endpoint header is required",
6
+ }),
5
7
  token: z
6
8
  .string({ invalid_type_error: "x-rivet-token header must be a string" })
7
9
  .optional(),
@@ -15,6 +17,6 @@ export const ServerlessStartHeadersSchema = z.object({
15
17
  required_error: "x-rivet-runner-name header is required",
16
18
  }),
17
19
  namespace: z.string({
18
- required_error: "x-rivet-namespace-id header is required",
20
+ required_error: "x-rivet-namespace-name header is required",
19
21
  }),
20
22
  });
@@ -166,7 +166,7 @@ function addServerlessRoutes(
166
166
  token: c.req.header("x-rivet-token") ?? undefined,
167
167
  totalSlots: c.req.header("x-rivet-total-slots"),
168
168
  runnerName: c.req.header("x-rivet-runner-name"),
169
- namespace: c.req.header("x-rivet-namespace-id"),
169
+ namespace: c.req.header("x-rivet-namespace-name"),
170
170
  });
171
171
  if (!parseResult.success) {
172
172
  throw new InvalidRequest(
@@ -262,7 +262,7 @@ function addManagerRoutes(
262
262
  path: "/actors",
263
263
  request: {
264
264
  query: z.object({
265
- name: z.string(),
265
+ name: z.string().optional(),
266
266
  actor_ids: z.string().optional(),
267
267
  key: z.string().optional(),
268
268
  }),
@@ -282,6 +282,36 @@ function addManagerRoutes(
282
282
 
283
283
  const actors: ActorOutput[] = [];
284
284
 
285
+ // Validate: cannot provide both actor_ids and (name or key)
286
+ if (actorIdsParsed && (name || key)) {
287
+ return c.json(
288
+ {
289
+ error: "Cannot provide both actor_ids and (name + key). Use either actor_ids or (name + key).",
290
+ },
291
+ 400,
292
+ );
293
+ }
294
+
295
+ // Validate: when key is provided, name must also be provided
296
+ if (key && !name) {
297
+ return c.json(
298
+ {
299
+ error: "When providing 'key', 'name' must also be provided.",
300
+ },
301
+ 400,
302
+ );
303
+ }
304
+
305
+ // Validate: must provide either actor_ids or (name + key)
306
+ if (!actorIdsParsed && !key) {
307
+ return c.json(
308
+ {
309
+ error: "Must provide either 'actor_ids' or both 'name' and 'key'.",
310
+ },
311
+ 400,
312
+ );
313
+ }
314
+
285
315
  if (actorIdsParsed) {
286
316
  if (actorIdsParsed.length > 32) {
287
317
  return c.json(
@@ -298,8 +328,10 @@ function addManagerRoutes(
298
328
  });
299
329
  }
300
330
 
331
+ // Fetch actors by ID
301
332
  for (const actorId of actorIdsParsed) {
302
333
  if (name) {
334
+ // If name is provided, use it directly
303
335
  const actorOutput = await managerDriver.getForId({
304
336
  c,
305
337
  name,
@@ -308,12 +340,29 @@ function addManagerRoutes(
308
340
  if (actorOutput) {
309
341
  actors.push(actorOutput);
310
342
  }
343
+ } else {
344
+ // If no name is provided, try all registered actor types
345
+ // Actor IDs are globally unique, so we'll find it in one of them
346
+ for (const actorName of Object.keys(
347
+ registryConfig.use,
348
+ )) {
349
+ const actorOutput = await managerDriver.getForId({
350
+ c,
351
+ name: actorName,
352
+ actorId,
353
+ });
354
+ if (actorOutput) {
355
+ actors.push(actorOutput);
356
+ break; // Found the actor, no need to check other names
357
+ }
358
+ }
311
359
  }
312
360
  }
313
361
  } else if (key) {
362
+ // At this point, name is guaranteed to be defined due to validation above
314
363
  const actorOutput = await managerDriver.getWithKey({
315
364
  c,
316
- name,
365
+ name: name!,
317
366
  key: [key], // Convert string to ActorKey array
318
367
  });
319
368
  if (actorOutput) {
@@ -449,8 +498,14 @@ function addManagerRoutes(
449
498
  router.post(".test/inline-driver/call", async (c) => {
450
499
  // TODO: use openapi instead
451
500
  const buffer = await c.req.arrayBuffer();
452
- const { encoding, transport, method, args }: TestInlineDriverCallRequest =
453
- cbor.decode(new Uint8Array(buffer));
501
+ const {
502
+ encoding,
503
+ transport,
504
+ method,
505
+ args,
506
+ }: TestInlineDriverCallRequest = cbor.decode(
507
+ new Uint8Array(buffer),
508
+ );
454
509
 
455
510
  logger().debug({
456
511
  msg: "received inline request",
@@ -463,7 +518,9 @@ function addManagerRoutes(
463
518
  // Forward inline driver request
464
519
  let response: TestInlineDriverCallResponse<unknown>;
465
520
  try {
466
- const output = await ((managerDriver as any)[method] as any)(...args);
521
+ const output = await ((managerDriver as any)[method] as any)(
522
+ ...args,
523
+ );
467
524
  response = { ok: output };
468
525
  } catch (rawErr) {
469
526
  const err = deconstructError(rawErr, logger(), {}, true);
@@ -476,11 +533,15 @@ function addManagerRoutes(
476
533
 
477
534
  router.get(".test/inline-driver/connect-websocket/*", async (c) => {
478
535
  const upgradeWebSocket = runConfig.getUpgradeWebSocket?.();
479
- invariant(upgradeWebSocket, "websockets not supported on this platform");
536
+ invariant(
537
+ upgradeWebSocket,
538
+ "websockets not supported on this platform",
539
+ );
480
540
 
481
541
  return upgradeWebSocket(async (c: any) => {
482
542
  // Extract information from sec-websocket-protocol header
483
- const protocolHeader = c.req.header("sec-websocket-protocol") || "";
543
+ const protocolHeader =
544
+ c.req.header("sec-websocket-protocol") || "";
484
545
  const protocols = protocolHeader.split(/,\s*/);
485
546
 
486
547
  // Parse protocols to extract connection info
@@ -515,7 +576,9 @@ function addManagerRoutes(
515
576
  } else if (protocol.startsWith(WS_PROTOCOL_CONN_ID)) {
516
577
  connId = protocol.substring(WS_PROTOCOL_CONN_ID.length);
517
578
  } else if (protocol.startsWith(WS_PROTOCOL_CONN_TOKEN)) {
518
- connToken = protocol.substring(WS_PROTOCOL_CONN_TOKEN.length);
579
+ connToken = protocol.substring(
580
+ WS_PROTOCOL_CONN_TOKEN.length,
581
+ );
519
582
  }
520
583
  }
521
584
 
@@ -619,9 +682,12 @@ function addManagerRoutes(
619
682
  // Send a special request to the actor to force disconnect the connection
620
683
  const response = await managerDriver.sendRequest(
621
684
  actorId,
622
- new Request(`http://actor/.test/force-disconnect?conn=${connId}`, {
623
- method: "POST",
624
- }),
685
+ new Request(
686
+ `http://actor/.test/force-disconnect?conn=${connId}`,
687
+ {
688
+ method: "POST",
689
+ },
690
+ ),
625
691
  );
626
692
 
627
693
  if (!response.ok) {
@@ -23,6 +23,7 @@ export type ActorsListResponse = z.infer<typeof ActorsListResponseSchema>;
23
23
 
24
24
  // MARK: POST /actors
25
25
  export const ActorsCreateRequestSchema = z.object({
26
+ datacenter: z.string().optional(),
26
27
  name: z.string(),
27
28
  runner_name_selector: z.string(),
28
29
  crash_policy: z.string(),
@@ -38,6 +39,7 @@ export type ActorsCreateResponse = z.infer<typeof ActorsCreateResponseSchema>;
38
39
 
39
40
  // MARK: PUT /actors
40
41
  export const ActorsGetOrCreateRequestSchema = z.object({
42
+ datacenter: z.string().optional(),
41
43
  name: z.string(),
42
44
  key: z.string(),
43
45
  runner_name_selector: z.string(),
@@ -62,7 +62,10 @@ export class Registry<A extends RegistryActors> {
62
62
  const config = RunnerConfigSchema.parse(inputConfig);
63
63
 
64
64
  // Validate autoConfigureServerless is only used with serverless runner
65
- if (config.autoConfigureServerless && config.runnerKind !== "serverless") {
65
+ if (
66
+ config.autoConfigureServerless &&
67
+ config.runnerKind !== "serverless"
68
+ ) {
66
69
  throw new Error(
67
70
  "autoConfigureServerless can only be configured when runnerKind is 'serverless'",
68
71
  );
@@ -171,7 +174,10 @@ export class Registry<A extends RegistryActors> {
171
174
  ...driverLog,
172
175
  });
173
176
  if (isInspectorEnabled(config, "manager") && managerDriver.inspector) {
174
- logger().info({ msg: "inspector ready", url: getInspectorUrl(config) });
177
+ logger().info({
178
+ msg: "inspector ready",
179
+ url: getInspectorUrl(config),
180
+ });
175
181
  }
176
182
 
177
183
  // Print welcome information
@@ -182,7 +188,9 @@ export class Registry<A extends RegistryActors> {
182
188
  if (!config.disableDefaultServer) {
183
189
  console.log(` - Endpoint: ${getEndpoint(config)}`);
184
190
  } else if (config.overrideServerAddress) {
185
- console.log(` - Endpoint: ${config.overrideServerAddress}`);
191
+ console.log(
192
+ ` - Endpoint: ${config.overrideServerAddress}`,
193
+ );
186
194
  }
187
195
  if (config.runEngine) {
188
196
  const padding = " ".repeat(Math.max(0, 13 - "Engine".length));
@@ -192,7 +200,10 @@ export class Registry<A extends RegistryActors> {
192
200
  const padding = " ".repeat(Math.max(0, 13 - k.length));
193
201
  console.log(` - ${k}:${padding}${v}`);
194
202
  }
195
- if (isInspectorEnabled(config, "manager") && managerDriver.inspector) {
203
+ if (
204
+ isInspectorEnabled(config, "manager") &&
205
+ managerDriver.inspector
206
+ ) {
196
207
  console.log(` - Inspector: ${getInspectorUrl(config)}`);
197
208
  }
198
209
  console.log();
@@ -210,7 +221,10 @@ export class Registry<A extends RegistryActors> {
210
221
  }
211
222
 
212
223
  // Configure serverless runner if enabled when actor driver is disabled
213
- if (config.runnerKind === "serverless" && config.autoConfigureServerless) {
224
+ if (
225
+ config.runnerKind === "serverless" &&
226
+ config.autoConfigureServerless
227
+ ) {
214
228
  Promise.all(readyPromises).then(async () => {
215
229
  await configureServerlessRunner(config);
216
230
  });
@@ -245,13 +259,19 @@ async function configureServerlessRunner(config: RunnerConfig): Promise<void> {
245
259
  try {
246
260
  // Ensure we have required config values
247
261
  if (!config.runnerName) {
248
- throw new Error("runnerName is required for serverless configuration");
262
+ throw new Error(
263
+ "runnerName is required for serverless configuration",
264
+ );
249
265
  }
250
266
  if (!config.namespace) {
251
- throw new Error("namespace is required for serverless configuration");
267
+ throw new Error(
268
+ "namespace is required for serverless configuration",
269
+ );
252
270
  }
253
271
  if (!config.endpoint) {
254
- throw new Error("endpoint is required for serverless configuration");
272
+ throw new Error(
273
+ "endpoint is required for serverless configuration",
274
+ );
255
275
  }
256
276
 
257
277
  // Prepare the configuration
@@ -288,7 +308,9 @@ async function configureServerlessRunner(config: RunnerConfig): Promise<void> {
288
308
  });
289
309
  const serverlessConfig = {
290
310
  serverless: {
291
- url: customConfig.url || `http://localhost:${config.defaultServerPort}`,
311
+ url:
312
+ customConfig.url ||
313
+ `http://localhost:${config.defaultServerPort}`,
292
314
  headers: customConfig.headers || {},
293
315
  max_runners: customConfig.maxRunners ?? 100,
294
316
  min_runners: customConfig.minRunners ?? 0,
@@ -50,7 +50,9 @@ export const RunnerConfigSchema = z
50
50
  runEngineVersion: z
51
51
  .string()
52
52
  .optional()
53
- .default(() => getEnvUniversal("RIVET_RUN_ENGINE_VERSION") ?? "25.8.1"),
53
+ .default(
54
+ () => getEnvUniversal("RIVET_RUN_ENGINE_VERSION") ?? "25.8.2",
55
+ ),
54
56
 
55
57
  /** @experimental */
56
58
  overrideServerAddress: z.string().optional(),
@@ -15,13 +15,13 @@ import { apiCall } from "./api-utils";
15
15
  // MARK: Get actor
16
16
  export async function getActor(
17
17
  config: ClientConfig,
18
- name: string,
18
+ _: string,
19
19
  actorId: RivetId,
20
20
  ): Promise<ActorsListResponse> {
21
21
  return apiCall<never, ActorsListResponse>(
22
22
  config,
23
23
  "GET",
24
- `/actors?name=${name}&actor_ids=${encodeURIComponent(actorId)}`,
24
+ `/actors?actor_ids=${encodeURIComponent(actorId)}`,
25
25
  );
26
26
  }
27
27
 
@@ -60,7 +60,9 @@ export class RemoteManagerDriver implements ManagerDriver {
60
60
  //
61
61
  // See https://github.com/vercel/next.js/blob/5e6b008b561caf2710ab7be63320a3d549474a5b/packages/next/shared/lib/constants.ts#L19-L23
62
62
  if (getEnvUniversal("NEXT_PHASE") === "phase-production-build") {
63
- logger().info("detected next.js build phase, disabling health check");
63
+ logger().info(
64
+ "detected next.js build phase, disabling health check",
65
+ );
64
66
  runConfig.disableHealthCheck = true;
65
67
  }
66
68
 
@@ -70,10 +72,10 @@ export class RemoteManagerDriver implements ManagerDriver {
70
72
  if (!runConfig.disableHealthCheck) {
71
73
  this.#metadataPromise = this.#performMetadataCheck(runConfig);
72
74
  this.#metadataPromise.catch((error) => {
73
- // TODO: Promot to error after metadata endpoint merged on prod
74
- logger().info({
75
+ logger().error({
75
76
  msg: "metadata check failed",
76
- error: error instanceof Error ? error.message : String(error),
77
+ error:
78
+ error instanceof Error ? error.message : String(error),
77
79
  });
78
80
  });
79
81
  }
@@ -219,6 +221,7 @@ export class RemoteManagerDriver implements ManagerDriver {
219
221
  });
220
222
 
221
223
  const { actor, created } = await getOrCreateActor(this.#config, {
224
+ datacenter: region,
222
225
  name,
223
226
  key: serializeActorKey(key),
224
227
  runner_name_selector: this.#config.runnerName,
@@ -250,6 +253,7 @@ export class RemoteManagerDriver implements ManagerDriver {
250
253
  name,
251
254
  key,
252
255
  input,
256
+ region,
253
257
  }: CreateInput): Promise<ActorOutput> {
254
258
  // Wait for metadata check to complete if in progress
255
259
  if (this.#metadataPromise) {
@@ -260,6 +264,7 @@ export class RemoteManagerDriver implements ManagerDriver {
260
264
 
261
265
  // Create actor via engine API
262
266
  const result = await createActor(this.#config, {
267
+ datacenter: region,
263
268
  name,
264
269
  runner_name_selector: this.#config.runnerName,
265
270
  key: serializeActorKey(key),
@@ -290,13 +295,20 @@ export class RemoteManagerDriver implements ManagerDriver {
290
295
  logger().info({ msg: "actor destroyed", actorId });
291
296
  }
292
297
 
293
- async sendRequest(actorId: string, actorRequest: Request): Promise<Response> {
298
+ async sendRequest(
299
+ actorId: string,
300
+ actorRequest: Request,
301
+ ): Promise<Response> {
294
302
  // Wait for metadata check to complete if in progress
295
303
  if (this.#metadataPromise) {
296
304
  await this.#metadataPromise;
297
305
  }
298
306
 
299
- return await sendHttpRequestToActor(this.#config, actorId, actorRequest);
307
+ return await sendHttpRequestToActor(
308
+ this.#config,
309
+ actorId,
310
+ actorRequest,
311
+ );
300
312
  }
301
313
 
302
314
  async openWebSocket(
@@ -333,7 +345,11 @@ export class RemoteManagerDriver implements ManagerDriver {
333
345
  await this.#metadataPromise;
334
346
  }
335
347
 
336
- return await sendHttpRequestToActor(this.#config, actorId, actorRequest);
348
+ return await sendHttpRequestToActor(
349
+ this.#config,
350
+ actorId,
351
+ actorRequest,
352
+ );
337
353
  }
338
354
 
339
355
  async proxyWebSocket(
@@ -42,7 +42,10 @@ export async function createWebSocketProxy(
42
42
  // Setup connection promise
43
43
  state.connectPromise = new Promise<void>((resolve, reject) => {
44
44
  targetWs.addEventListener("open", () => {
45
- logger().debug({ msg: "target websocket connected", targetUrl });
45
+ logger().debug({
46
+ msg: "target websocket connected",
47
+ targetUrl,
48
+ });
46
49
 
47
50
  if (clientWs.readyState !== 1) {
48
51
  logger().warn({
@@ -102,7 +105,10 @@ export async function createWebSocketProxy(
102
105
 
103
106
  onMessage: async (event: any, clientWs: WSContext) => {
104
107
  if (!state.targetWs || !state.connectPromise) {
105
- logger().error({ msg: "websocket state not initialized", targetUrl });
108
+ logger().error({
109
+ msg: "websocket state not initialized",
110
+ targetUrl,
111
+ });
106
112
  return;
107
113
  }
108
114
 
@@ -123,7 +129,11 @@ export async function createWebSocketProxy(
123
129
  targetUrl,
124
130
  error,
125
131
  });
126
- closeWebSocketIfOpen(clientWs, 1011, "Failed to connect to target");
132
+ closeWebSocketIfOpen(
133
+ clientWs,
134
+ 1011,
135
+ "Failed to connect to target",
136
+ );
127
137
  }
128
138
  },
129
139
 
@@ -141,7 +151,10 @@ export async function createWebSocketProxy(
141
151
  state.targetWs.readyState === WebSocket.OPEN ||
142
152
  state.targetWs.readyState === WebSocket.CONNECTING
143
153
  ) {
144
- state.targetWs.close(1000, event.reason || "Client disconnected");
154
+ state.targetWs.close(
155
+ 1000,
156
+ event.reason || "Client disconnected",
157
+ );
145
158
  }
146
159
  }
147
160
  },
@@ -167,7 +180,10 @@ function closeWebSocketIfOpen(
167
180
  ): void {
168
181
  if (ws.readyState === 1) {
169
182
  ws.close(code, reason);
170
- } else if ("close" in ws && (ws as WebSocket).readyState === WebSocket.OPEN) {
183
+ } else if (
184
+ "close" in ws &&
185
+ (ws as WebSocket).readyState === WebSocket.OPEN
186
+ ) {
171
187
  ws.close(code, reason);
172
188
  }
173
189
  }
package/src/serde.ts CHANGED
@@ -63,7 +63,9 @@ export function serializeWithEncoding<T>(
63
63
  return cbor.encode(value);
64
64
  } else if (encoding === "bare") {
65
65
  if (!versionedDataHandler) {
66
- throw new Error("VersionedDataHandler is required for 'bare' encoding");
66
+ throw new Error(
67
+ "VersionedDataHandler is required for 'bare' encoding",
68
+ );
67
69
  }
68
70
  return versionedDataHandler.serializeWithEmbeddedVersion(value);
69
71
  } else {
@@ -96,7 +98,9 @@ export function deserializeWithEncoding<T>(
96
98
  "buffer cannot be string for bare encoding",
97
99
  );
98
100
  if (!versionedDataHandler) {
99
- throw new Error("VersionedDataHandler is required for 'bare' encoding");
101
+ throw new Error(
102
+ "VersionedDataHandler is required for 'bare' encoding",
103
+ );
100
104
  }
101
105
  return versionedDataHandler.deserializeWithEmbeddedVersion(buffer);
102
106
  } else {
package/src/test/mod.ts CHANGED
@@ -94,7 +94,8 @@ export async function setupTest<A extends Registry<any>>(
94
94
  const port = await getPort();
95
95
  const server = serve(registry, { port });
96
96
  c.onTestFinished(
97
- async () => await new Promise((resolve) => server.close(() => resolve())),
97
+ async () =>
98
+ await new Promise((resolve) => server.close(() => resolve())),
98
99
  );
99
100
 
100
101
  throw "TODO: Fix engine port";
package/src/utils.ts CHANGED
@@ -19,7 +19,8 @@ export function httpUserAgent(): string {
19
19
  let userAgent = `RivetKit/${VERSION}`;
20
20
 
21
21
  // Navigator
22
- const navigatorObj = typeof navigator !== "undefined" ? navigator : undefined;
22
+ const navigatorObj =
23
+ typeof navigator !== "undefined" ? navigator : undefined;
23
24
  if (navigatorObj?.userAgent) userAgent += ` ${navigatorObj.userAgent}`;
24
25
 
25
26
  _userAgent = userAgent;
@@ -62,7 +63,10 @@ export function toUint8Array(data: ArrayBuffer | ArrayBufferView): Uint8Array {
62
63
  } else if (ArrayBuffer.isView(data)) {
63
64
  // Handle other ArrayBufferView types (Int8Array, Uint16Array, DataView, etc.)
64
65
  return new Uint8Array(
65
- data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength),
66
+ data.buffer.slice(
67
+ data.byteOffset,
68
+ data.byteOffset + data.byteLength,
69
+ ),
66
70
  );
67
71
  } else {
68
72
  throw new TypeError("Input must be ArrayBuffer or ArrayBufferView");
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/nathan/rivetkit/packages/rivetkit/dist/tsup/chunk-2I6L3VRO.cjs","../../src/test/mod.ts","../../src/test/config.ts","../../src/test/log.ts"],"names":["server"],"mappings":"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","file":"/Users/nathan/rivetkit/packages/rivetkit/dist/tsup/chunk-2I6L3VRO.cjs","sourcesContent":[null,"import { createServer } from \"node:net\";\nimport { serve as honoServe, type ServerType } from \"@hono/node-server\";\nimport { createNodeWebSocket } from \"@hono/node-ws\";\nimport { type TestContext, vi } from \"vitest\";\nimport { ClientConfigSchema } from \"@/client/config\";\nimport { type Client, createClient } from \"@/client/mod\";\nimport { chooseDefaultDriver } from \"@/drivers/default\";\nimport { createFileSystemOrMemoryDriver } from \"@/drivers/file-system/mod\";\nimport {\n\tconfigureInspectorAccessToken,\n\tgetInspectorUrl,\n} from \"@/inspector/utils\";\nimport { createManagerRouter } from \"@/manager/router\";\nimport { createClientWithDriver } from \"@/mod\";\nimport type { Registry } from \"@/registry/mod\";\nimport { RunnerConfigSchema } from \"@/registry/run-config\";\nimport { ConfigSchema, type InputConfig } from \"./config\";\nimport { logger } from \"./log\";\n\nfunction serve(registry: Registry<any>, inputConfig?: InputConfig): ServerType {\n\t// Configure default configuration\n\tinputConfig ??= {};\n\n\tconst config = ConfigSchema.parse(inputConfig);\n\n\tlet upgradeWebSocket: any;\n\tif (!config.getUpgradeWebSocket) {\n\t\tconfig.getUpgradeWebSocket = () => upgradeWebSocket!;\n\t}\n\n\t// Create router\n\tconst runConfig = RunnerConfigSchema.parse(inputConfig);\n\tconst driver = inputConfig.driver ?? createFileSystemOrMemoryDriver(false);\n\tconst managerDriver = driver.manager(registry.config, config);\n\tconst client = createClientWithDriver(\n\t\tmanagerDriver,\n\t\tClientConfigSchema.parse({}),\n\t);\n\tconfigureInspectorAccessToken(config, managerDriver);\n\tconst { router } = createManagerRouter(\n\t\tregistry.config,\n\t\trunConfig,\n\t\tmanagerDriver,\n\t\tdriver,\n\t\tclient,\n\t);\n\n\t// Inject WebSocket\n\tconst nodeWebSocket = createNodeWebSocket({ app: router });\n\tupgradeWebSocket = nodeWebSocket.upgradeWebSocket;\n\n\tconst server = honoServe({\n\t\tfetch: router.fetch,\n\t\thostname: config.hostname,\n\t\tport: config.port,\n\t});\n\tnodeWebSocket.injectWebSocket(server);\n\n\tlogger().info({\n\t\tmsg: \"rivetkit started\",\n\t\thostname: config.hostname,\n\t\tport: config.port,\n\t\tdefinitions: Object.keys(registry.config.use).length,\n\t});\n\n\treturn server;\n}\n\nexport interface SetupTestResult<A extends Registry<any>> {\n\tclient: Client<A>;\n\tmockDriver: {\n\t\tactorDriver: {\n\t\t\tsetCreateVarsContext: (ctx: any) => void;\n\t\t};\n\t};\n}\n\n// Must use `TestContext` since global hooks do not work when running concurrently\nexport async function setupTest<A extends Registry<any>>(\n\tc: TestContext,\n\tregistry: A,\n): Promise<SetupTestResult<A>> {\n\tvi.useFakeTimers();\n\n\t// Set up mock driver for testing createVars context\n\tconst mockDriverContext: any = {};\n\tconst setDriverContextFn = (ctx: any) => {\n\t\tmockDriverContext.current = ctx;\n\t};\n\n\t// We don't need to modify the driver context anymore since we're testing with the actual context\n\n\t// Start server with a random port\n\tconst port = await getPort();\n\tconst server = serve(registry, { port });\n\tc.onTestFinished(\n\t\tasync () => await new Promise((resolve) => server.close(() => resolve())),\n\t);\n\n\tthrow \"TODO: Fix engine port\";\n\n\t// // TODO: Figure out how to make this the correct endpoint\n\t// // Create client\n\t// const client = createClient<A>(`http://127.0.0.1:${port}`);\n\t// c.onTestFinished(async () => await client.dispose());\n\t//\n\t// return {\n\t// \tclient,\n\t// \tmockDriver: {\n\t// \t\tactorDriver: {\n\t// \t\t\tsetCreateVarsContext: setDriverContextFn,\n\t// \t\t},\n\t// \t},\n\t// };\n}\n\nexport async function getPort(): Promise<number> {\n\t// Pick random port between 10000 and 65535 (avoiding well-known and registered ports)\n\tconst MIN_PORT = 10000;\n\tconst MAX_PORT = 65535;\n\tconst getRandomPort = () =>\n\t\tMath.floor(Math.random() * (MAX_PORT - MIN_PORT + 1)) + MIN_PORT;\n\n\tlet port = getRandomPort();\n\tlet maxAttempts = 10;\n\n\twhile (maxAttempts > 0) {\n\t\ttry {\n\t\t\t// Try to create a server on the port to check if it's available\n\t\t\tconst server = await new Promise<any>((resolve, reject) => {\n\t\t\t\tconst server = createServer();\n\n\t\t\t\tserver.once(\"error\", (err: Error & { code?: string }) => {\n\t\t\t\t\tif (err.code === \"EADDRINUSE\") {\n\t\t\t\t\t\treject(new Error(`Port ${port} is in use`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\treject(err);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tserver.once(\"listening\", () => {\n\t\t\t\t\tresolve(server);\n\t\t\t\t});\n\n\t\t\t\tserver.listen(port);\n\t\t\t});\n\n\t\t\t// Close the server since we're just checking availability\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tserver.close(() => resolve());\n\t\t\t});\n\n\t\t\treturn port;\n\t\t} catch (err) {\n\t\t\t// If port is in use, try a different one\n\t\t\tmaxAttempts--;\n\t\t\tif (maxAttempts <= 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tport = getRandomPort();\n\t\t}\n\t}\n\n\tthrow new Error(\"Could not find an available port after multiple attempts\");\n}\n","import { z } from \"zod\";\nimport { RunnerConfigSchema } from \"@/registry/run-config\";\n\nexport const ConfigSchema = RunnerConfigSchema.removeDefault()\n\t.extend({\n\t\thostname: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.default(process.env.HOSTNAME ?? \"127.0.0.1\"),\n\t\tport: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.default(Number.parseInt(process.env.PORT ?? \"8080\")),\n\t})\n\t.default({});\nexport type InputConfig = z.input<typeof ConfigSchema>;\n","import { getLogger } from \"@/common/log\";\n\nexport function logger() {\n\treturn getLogger(\"test\");\n}\n"]}