rivetkit 2.0.27 → 2.0.28

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 (124) hide show
  1. package/dist/schemas/file-system-driver/v3.ts +167 -0
  2. package/dist/tsup/{chunk-4GJQDTAG.cjs → chunk-3ZC6SBX6.cjs} +652 -329
  3. package/dist/tsup/chunk-3ZC6SBX6.cjs.map +1 -0
  4. package/dist/tsup/{chunk-D7A47BVR.js → chunk-7IAEY5UZ.js} +2 -2
  5. package/dist/tsup/{chunk-6F2NCX7R.js → chunk-AE7BB3M2.js} +2 -2
  6. package/dist/tsup/{chunk-XU4GGB6J.js → chunk-AHPMXTSB.js} +503 -180
  7. package/dist/tsup/chunk-AHPMXTSB.js.map +1 -0
  8. package/dist/tsup/{chunk-XNKWXMIT.cjs → chunk-CJLXW36F.cjs} +768 -292
  9. package/dist/tsup/chunk-CJLXW36F.cjs.map +1 -0
  10. package/dist/tsup/chunk-DATRTJVZ.js +891 -0
  11. package/dist/tsup/chunk-DATRTJVZ.js.map +1 -0
  12. package/dist/tsup/{chunk-C3UREFUI.js → chunk-EJXISR3H.js} +14 -5
  13. package/dist/tsup/chunk-EJXISR3H.js.map +1 -0
  14. package/dist/tsup/{chunk-GUH2PNPG.js → chunk-IDYDUETM.js} +3 -3
  15. package/dist/tsup/{chunk-2NNICHGY.js → chunk-ILK4JEMF.js} +2 -2
  16. package/dist/tsup/chunk-JALGQWHW.cjs +129 -0
  17. package/dist/tsup/chunk-JALGQWHW.cjs.map +1 -0
  18. package/dist/tsup/{chunk-BBTOBXEO.js → chunk-KXSSOVFA.js} +578 -102
  19. package/dist/tsup/chunk-KXSSOVFA.js.map +1 -0
  20. package/dist/tsup/{chunk-DRJCTDDT.cjs → chunk-M54KFQQP.cjs} +18 -9
  21. package/dist/tsup/chunk-M54KFQQP.cjs.map +1 -0
  22. package/dist/tsup/chunk-NQZ643FB.cjs +891 -0
  23. package/dist/tsup/chunk-NQZ643FB.cjs.map +1 -0
  24. package/dist/tsup/{chunk-LZADH4QA.cjs → chunk-NR2N4UA2.cjs} +10 -10
  25. package/dist/tsup/{chunk-LZADH4QA.cjs.map → chunk-NR2N4UA2.cjs.map} +1 -1
  26. package/dist/tsup/{chunk-KSQQU7NC.js → chunk-S5URQ3CI.js} +7 -6
  27. package/dist/tsup/chunk-S5URQ3CI.js.map +1 -0
  28. package/dist/tsup/{chunk-QC4AE54W.cjs → chunk-VQRYS6VW.cjs} +3 -3
  29. package/dist/tsup/{chunk-QC4AE54W.cjs.map → chunk-VQRYS6VW.cjs.map} +1 -1
  30. package/dist/tsup/{chunk-TJ2PJ5C7.cjs → chunk-Y2AKEZRY.cjs} +3 -3
  31. package/dist/tsup/{chunk-TJ2PJ5C7.cjs.map → chunk-Y2AKEZRY.cjs.map} +1 -1
  32. package/dist/tsup/{chunk-F3SQLO3X.cjs → chunk-Y5LN2XRH.cjs} +7 -6
  33. package/dist/tsup/chunk-Y5LN2XRH.cjs.map +1 -0
  34. package/dist/tsup/{chunk-G7YZSSWV.cjs → chunk-YW2E3UPH.cjs} +6 -6
  35. package/dist/tsup/{chunk-G7YZSSWV.cjs.map → chunk-YW2E3UPH.cjs.map} +1 -1
  36. package/dist/tsup/{chunk-VRZNWBDK.js → chunk-ZL3SUOIM.js} +45 -46
  37. package/dist/tsup/chunk-ZL3SUOIM.js.map +1 -0
  38. package/dist/tsup/client/mod.cjs +8 -8
  39. package/dist/tsup/client/mod.d.cts +3 -2
  40. package/dist/tsup/client/mod.d.ts +3 -2
  41. package/dist/tsup/client/mod.js +7 -7
  42. package/dist/tsup/common/log.cjs +2 -2
  43. package/dist/tsup/common/log.d.cts +9 -1
  44. package/dist/tsup/common/log.d.ts +9 -1
  45. package/dist/tsup/common/log.js +1 -1
  46. package/dist/tsup/common/websocket.cjs +3 -3
  47. package/dist/tsup/common/websocket.js +2 -2
  48. package/dist/tsup/{config-Bo-blHpJ.d.ts → config-CcMdKDv9.d.ts} +301 -899
  49. package/dist/tsup/{config-BRDYDraU.d.cts → config-DxlmiJS1.d.cts} +301 -899
  50. package/dist/tsup/driver-helpers/mod.cjs +4 -4
  51. package/dist/tsup/driver-helpers/mod.d.cts +2 -1
  52. package/dist/tsup/driver-helpers/mod.d.ts +2 -1
  53. package/dist/tsup/driver-helpers/mod.js +3 -3
  54. package/dist/tsup/driver-test-suite/mod.cjs +71 -71
  55. package/dist/tsup/driver-test-suite/mod.d.cts +2 -1
  56. package/dist/tsup/driver-test-suite/mod.d.ts +2 -1
  57. package/dist/tsup/driver-test-suite/mod.js +10 -10
  58. package/dist/tsup/inspector/mod.cjs +5 -5
  59. package/dist/tsup/inspector/mod.d.cts +5 -4
  60. package/dist/tsup/inspector/mod.d.ts +5 -4
  61. package/dist/tsup/inspector/mod.js +4 -4
  62. package/dist/tsup/mod.cjs +9 -9
  63. package/dist/tsup/mod.d.cts +3 -2
  64. package/dist/tsup/mod.d.ts +3 -2
  65. package/dist/tsup/mod.js +8 -8
  66. package/dist/tsup/test/mod.cjs +11 -10
  67. package/dist/tsup/test/mod.cjs.map +1 -1
  68. package/dist/tsup/test/mod.d.cts +2 -6
  69. package/dist/tsup/test/mod.d.ts +2 -6
  70. package/dist/tsup/test/mod.js +10 -9
  71. package/dist/tsup/utils.cjs +2 -2
  72. package/dist/tsup/utils.js +1 -1
  73. package/package.json +7 -6
  74. package/src/actor/config.ts +21 -20
  75. package/src/actor/conn/mod.ts +5 -1
  76. package/src/actor/instance/connection-manager.ts +5 -1
  77. package/src/actor/instance/event-manager.ts +5 -1
  78. package/src/actor/instance/state-manager.ts +19 -3
  79. package/src/actor/protocol/old.ts +3 -0
  80. package/src/actor/protocol/serde.ts +5 -1
  81. package/src/actor/router-endpoints.ts +2 -0
  82. package/src/client/actor-conn.ts +2 -0
  83. package/src/client/actor-handle.ts +3 -0
  84. package/src/client/config.ts +1 -1
  85. package/src/client/utils.ts +4 -1
  86. package/src/common/router.ts +5 -1
  87. package/src/driver-helpers/utils.ts +8 -2
  88. package/src/drivers/engine/config.ts +6 -3
  89. package/src/drivers/file-system/global-state.ts +46 -1
  90. package/src/drivers/file-system/manager.ts +4 -0
  91. package/src/inspector/config.ts +1 -2
  92. package/src/manager/driver.ts +4 -0
  93. package/src/manager/router-schema.ts +7 -7
  94. package/src/manager/router.ts +4 -4
  95. package/src/registry/run-config.ts +9 -5
  96. package/src/remote-manager-driver/actor-http-client.ts +1 -1
  97. package/src/remote-manager-driver/api-utils.ts +2 -0
  98. package/src/schemas/actor-persist/versioned.ts +126 -54
  99. package/src/schemas/client-protocol/versioned.ts +173 -42
  100. package/src/schemas/file-system-driver/mod.ts +1 -1
  101. package/src/schemas/file-system-driver/versioned.ts +129 -45
  102. package/src/serde.ts +9 -2
  103. package/src/test/config.ts +13 -12
  104. package/src/test/mod.ts +56 -82
  105. package/dist/tsup/chunk-2TZH6VO6.cjs +0 -514
  106. package/dist/tsup/chunk-2TZH6VO6.cjs.map +0 -1
  107. package/dist/tsup/chunk-4GJQDTAG.cjs.map +0 -1
  108. package/dist/tsup/chunk-5YDKTW6Y.js +0 -514
  109. package/dist/tsup/chunk-5YDKTW6Y.js.map +0 -1
  110. package/dist/tsup/chunk-BBTOBXEO.js.map +0 -1
  111. package/dist/tsup/chunk-C3UREFUI.js.map +0 -1
  112. package/dist/tsup/chunk-DRJCTDDT.cjs.map +0 -1
  113. package/dist/tsup/chunk-F3SQLO3X.cjs.map +0 -1
  114. package/dist/tsup/chunk-FYZLEH57.cjs +0 -130
  115. package/dist/tsup/chunk-FYZLEH57.cjs.map +0 -1
  116. package/dist/tsup/chunk-KSQQU7NC.js.map +0 -1
  117. package/dist/tsup/chunk-VRZNWBDK.js.map +0 -1
  118. package/dist/tsup/chunk-XNKWXMIT.cjs.map +0 -1
  119. package/dist/tsup/chunk-XU4GGB6J.js.map +0 -1
  120. package/src/common/versioned-data.ts +0 -95
  121. /package/dist/tsup/{chunk-D7A47BVR.js.map → chunk-7IAEY5UZ.js.map} +0 -0
  122. /package/dist/tsup/{chunk-6F2NCX7R.js.map → chunk-AE7BB3M2.js.map} +0 -0
  123. /package/dist/tsup/{chunk-GUH2PNPG.js.map → chunk-IDYDUETM.js.map} +0 -0
  124. /package/dist/tsup/{chunk-2NNICHGY.js.map → chunk-ILK4JEMF.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import * as cbor from "cbor-x";
2
2
  import { z } from "zod";
3
3
  import * as errors from "@/actor/errors";
4
- import type { VersionedDataHandler } from "@/common/versioned-data";
4
+ import type { VersionedDataHandler } from "vbare";
5
5
  import { serializeWithEncoding } from "@/serde";
6
6
  import { loggerWithoutContext } from "../log";
7
7
  import { assertUnreachable } from "../utils";
@@ -26,6 +26,7 @@ export class CachedSerializer<TBare, TJson, T = TBare> {
26
26
  #data: T;
27
27
  #cache = new Map<Encoding, OutputData>();
28
28
  #versionedDataHandler: VersionedDataHandler<TBare>;
29
+ #version: number;
29
30
  #zodSchema: z.ZodType<TJson>;
30
31
  #toJson: (value: T) => TJson;
31
32
  #toBare: (value: T) => TBare;
@@ -33,12 +34,14 @@ export class CachedSerializer<TBare, TJson, T = TBare> {
33
34
  constructor(
34
35
  data: T,
35
36
  versionedDataHandler: VersionedDataHandler<TBare>,
37
+ version: number,
36
38
  zodSchema: z.ZodType<TJson>,
37
39
  toJson: (value: T) => TJson,
38
40
  toBare: (value: T) => TBare,
39
41
  ) {
40
42
  this.#data = data;
41
43
  this.#versionedDataHandler = versionedDataHandler;
44
+ this.#version = version;
42
45
  this.#zodSchema = zodSchema;
43
46
  this.#toJson = toJson;
44
47
  this.#toBare = toBare;
@@ -57,6 +60,7 @@ export class CachedSerializer<TBare, TJson, T = TBare> {
57
60
  encoding,
58
61
  this.#data,
59
62
  this.#versionedDataHandler,
63
+ this.#version,
60
64
  this.#zodSchema,
61
65
  this.#toJson,
62
66
  this.#toBare,
@@ -16,6 +16,7 @@ import { stringifyError } from "@/common/utils";
16
16
  import type { RunnerConfig } from "@/registry/run-config";
17
17
  import type * as protocol from "@/schemas/client-protocol/mod";
18
18
  import {
19
+ CURRENT_VERSION as CLIENT_PROTOCOL_CURRENT_VERSION,
19
20
  HTTP_ACTION_REQUEST_VERSIONED,
20
21
  HTTP_ACTION_RESPONSE_VERSIONED,
21
22
  } from "@/schemas/client-protocol/versioned";
@@ -120,6 +121,7 @@ export async function handleAction(
120
121
  encoding,
121
122
  output,
122
123
  HTTP_ACTION_RESPONSE_VERSIONED,
124
+ CLIENT_PROTOCOL_CURRENT_VERSION,
123
125
  HttpActionResponseSchema,
124
126
  // JSON: output is the raw value (will be serialized by jsonStringifyCompat)
125
127
  (value): HttpActionResponseJson => ({ output: value }),
@@ -22,6 +22,7 @@ import type { ManagerDriver } from "@/driver-helpers/mod";
22
22
  import type { ActorQuery } from "@/manager/protocol/query";
23
23
  import type * as protocol from "@/schemas/client-protocol/mod";
24
24
  import {
25
+ CURRENT_VERSION as CLIENT_PROTOCOL_CURRENT_VERSION,
25
26
  TO_CLIENT_VERSIONED,
26
27
  TO_SERVER_VERSIONED,
27
28
  } from "@/schemas/client-protocol/versioned";
@@ -749,6 +750,7 @@ enc
749
750
  this.#encoding,
750
751
  message,
751
752
  TO_SERVER_VERSIONED,
753
+ CLIENT_PROTOCOL_CURRENT_VERSION,
752
754
  ToServerSchema,
753
755
  // JSON: args is the raw value
754
756
  (msg): ToServerJson => msg as ToServerJson,
@@ -12,6 +12,7 @@ import {
12
12
  import type { ActorQuery } from "@/manager/protocol/query";
13
13
  import type * as protocol from "@/schemas/client-protocol/mod";
14
14
  import {
15
+ CURRENT_VERSION as CLIENT_PROTOCOL_CURRENT_VERSION,
15
16
  HTTP_ACTION_REQUEST_VERSIONED,
16
17
  HTTP_ACTION_RESPONSE_VERSIONED,
17
18
  } from "@/schemas/client-protocol/versioned";
@@ -128,7 +129,9 @@ export class ActorHandleRaw {
128
129
  actorId,
129
130
  ),
130
131
  signal: opts?.signal,
132
+ requestVersion: CLIENT_PROTOCOL_CURRENT_VERSION,
131
133
  requestVersionedDataHandler: HTTP_ACTION_REQUEST_VERSIONED,
134
+ responseVersion: CLIENT_PROTOCOL_CURRENT_VERSION,
132
135
  responseVersionedDataHandler: HTTP_ACTION_RESPONSE_VERSIONED,
133
136
  requestZodSchema: HttpActionRequestSchema,
134
137
  responseZodSchema: HttpActionResponseSchema,
@@ -32,7 +32,7 @@ export const ClientConfigSchema = z.object({
32
32
 
33
33
  encoding: EncodingSchema.default("bare"),
34
34
 
35
- headers: z.record(z.string()).optional().default({}),
35
+ headers: z.record(z.string(), z.string()).optional().default(() => ({})),
36
36
 
37
37
  // See RunConfig.getUpgradeWebSocket
38
38
  getUpgradeWebSocket: z.custom<GetUpgradeWebSocket>().optional(),
@@ -3,7 +3,7 @@ import invariant from "invariant";
3
3
  import type { z } from "zod";
4
4
  import type { Encoding } from "@/actor/protocol/serde";
5
5
  import { assertUnreachable } from "@/common/utils";
6
- import type { VersionedDataHandler } from "@/common/versioned-data";
6
+ import type { VersionedDataHandler } from "vbare";
7
7
  import type { HttpResponseError } from "@/schemas/client-protocol/mod";
8
8
  import { HTTP_RESPONSE_ERROR_VERSIONED } from "@/schemas/client-protocol/versioned";
9
9
  import {
@@ -55,9 +55,11 @@ export interface HttpRequestOpts<
55
55
  signal?: AbortSignal;
56
56
  customFetch?: (req: globalThis.Request) => Promise<globalThis.Response>;
57
57
  requestVersionedDataHandler: VersionedDataHandler<RequestBare> | undefined;
58
+ requestVersion: number | undefined;
58
59
  responseVersionedDataHandler:
59
60
  | VersionedDataHandler<ResponseBare>
60
61
  | undefined;
62
+ responseVersion: number | undefined;
61
63
  requestZodSchema: z.ZodType<RequestJson>;
62
64
  responseZodSchema: z.ZodType<ResponseJson>;
63
65
  requestToJson: (value: Request) => RequestJson;
@@ -99,6 +101,7 @@ export async function sendHttpRequest<
99
101
  opts.encoding,
100
102
  opts.body,
101
103
  opts.requestVersionedDataHandler,
104
+ opts.requestVersion,
102
105
  opts.requestZodSchema,
103
106
  opts.requestToJson,
104
107
  opts.requestToBare,
@@ -8,7 +8,10 @@ import {
8
8
  import { buildActorNames, type RegistryConfig } from "@/registry/config";
9
9
  import type { RunnerConfig } from "@/registry/run-config";
10
10
  import type * as protocol from "@/schemas/client-protocol/mod";
11
- import { HTTP_RESPONSE_ERROR_VERSIONED } from "@/schemas/client-protocol/versioned";
11
+ import {
12
+ CURRENT_VERSION as CLIENT_PROTOCOL_CURRENT_VERSION,
13
+ HTTP_RESPONSE_ERROR_VERSIONED,
14
+ } from "@/schemas/client-protocol/versioned";
12
15
  import {
13
16
  type HttpResponseError as HttpResponseErrorJson,
14
17
  HttpResponseErrorSchema,
@@ -76,6 +79,7 @@ export function handleRouteError(error: unknown, c: HonoContext) {
76
79
  encoding,
77
80
  errorData,
78
81
  HTTP_RESPONSE_ERROR_VERSIONED,
82
+ CLIENT_PROTOCOL_CURRENT_VERSION,
79
83
  HttpResponseErrorSchema,
80
84
  // JSON: metadata is the raw value (will be serialized by jsonStringifyCompat)
81
85
  (value): HttpResponseErrorJson => ({
@@ -1,7 +1,10 @@
1
1
  import * as cbor from "cbor-x";
2
2
  import { KEYS } from "@/actor/instance/kv";
3
3
  import type * as persistSchema from "@/schemas/actor-persist/mod";
4
- import { ACTOR_VERSIONED } from "@/schemas/actor-persist/versioned";
4
+ import {
5
+ ACTOR_VERSIONED,
6
+ CURRENT_VERSION,
7
+ } from "@/schemas/actor-persist/versioned";
5
8
  import { bufferToArrayBuffer } from "@/utils";
6
9
  import type { ActorDriver } from "./mod";
7
10
 
@@ -15,7 +18,10 @@ function serializeEmptyPersistData(input: unknown | undefined): Uint8Array {
15
18
  state: bufferToArrayBuffer(cbor.encode(undefined)),
16
19
  scheduledEvents: [],
17
20
  };
18
- return ACTOR_VERSIONED.serializeWithEmbeddedVersion(persistData);
21
+ return ACTOR_VERSIONED.serializeWithEmbeddedVersion(
22
+ persistData,
23
+ CURRENT_VERSION,
24
+ );
19
25
  }
20
26
 
21
27
  /**
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import { ClientConfigSchema } from "@/client/config";
3
3
  import { getEnvUniversal } from "@/utils";
4
4
 
5
- export const EngingConfigSchema = z
5
+ const EngineConfigSchemaBase = z
6
6
  .object({
7
7
  /** Unique key for this runner. Runners connecting a given key will replace any other runner connected with the same key. */
8
8
  runnerKey: z
@@ -14,8 +14,11 @@ export const EngingConfigSchema = z
14
14
  totalSlots: z.number().default(100_000),
15
15
  })
16
16
  // We include the client config since this includes the common properties like endpoint, namespace, etc.
17
- .merge(ClientConfigSchema)
18
- .default({});
17
+ .merge(ClientConfigSchema);
18
+
19
+ export const EngingConfigSchema = EngineConfigSchemaBase.default(() =>
20
+ EngineConfigSchemaBase.parse({}),
21
+ );
19
22
 
20
23
  export type EngineConfig = z.infer<typeof EngingConfigSchema>;
21
24
  export type EngineConfigInput = z.input<typeof EngingConfigSchema>;
@@ -12,6 +12,7 @@ import type * as schema from "@/schemas/file-system-driver/mod";
12
12
  import {
13
13
  ACTOR_ALARM_VERSIONED,
14
14
  ACTOR_STATE_VERSIONED,
15
+ CURRENT_VERSION as FILE_SYSTEM_DRIVER_CURRENT_VERSION,
15
16
  } from "@/schemas/file-system-driver/versioned";
16
17
  import {
17
18
  arrayBuffersEqual,
@@ -263,6 +264,10 @@ export class FileSystemGlobalState {
263
264
  key,
264
265
  createdAt: BigInt(Date.now()),
265
266
  kvStorage,
267
+ startTs: null,
268
+ connectableTs: null,
269
+ sleepTs: null,
270
+ destroyTs: null,
266
271
  };
267
272
  entry.lifecycleState = ActorLifecycleState.AWAKE;
268
273
 
@@ -369,6 +374,10 @@ export class FileSystemGlobalState {
369
374
  key: key as readonly string[],
370
375
  createdAt: BigInt(Date.now()),
371
376
  kvStorage,
377
+ startTs: null,
378
+ connectableTs: null,
379
+ sleepTs: null,
380
+ destroyTs: null,
372
381
  };
373
382
  await this.writeActor(actorId, entry.generation, entry.state);
374
383
  }
@@ -396,6 +405,15 @@ export class FileSystemGlobalState {
396
405
  if (actor.startPromise?.promise)
397
406
  await actor.startPromise.promise.catch();
398
407
 
408
+ // Update state with sleep timestamp
409
+ if (actor.state) {
410
+ actor.state = {
411
+ ...actor.state,
412
+ sleepTs: BigInt(Date.now()),
413
+ };
414
+ await this.writeActor(actorId, actor.generation, actor.state);
415
+ }
416
+
399
417
  // Stop actor
400
418
  invariant(actor.actor, "actor should be loaded");
401
419
  await actor.actor.onStop("sleep");
@@ -420,6 +438,15 @@ export class FileSystemGlobalState {
420
438
  if (actor.startPromise?.promise)
421
439
  await actor.startPromise.promise.catch();
422
440
 
441
+ // Update state with destroy timestamp
442
+ if (actor.state) {
443
+ actor.state = {
444
+ ...actor.state,
445
+ destroyTs: BigInt(Date.now()),
446
+ };
447
+ await this.writeActor(actorId, actor.generation, actor.state);
448
+ }
449
+
423
450
  // Stop actor if it's running
424
451
  if (actor.actor) {
425
452
  await actor.actor.onStop("destroy");
@@ -561,6 +588,7 @@ export class FileSystemGlobalState {
561
588
  const data =
562
589
  ACTOR_ALARM_VERSIONED.serializeWithEmbeddedVersion(
563
590
  alarmData,
591
+ FILE_SYSTEM_DRIVER_CURRENT_VERSION,
564
592
  );
565
593
  const fs = getNodeFs();
566
594
  await fs.writeFile(tempPath, data);
@@ -621,11 +649,18 @@ export class FileSystemGlobalState {
621
649
  key: state.key,
622
650
  createdAt: state.createdAt,
623
651
  kvStorage: state.kvStorage,
652
+ startTs: state.startTs,
653
+ connectableTs: state.connectableTs,
654
+ sleepTs: state.sleepTs,
655
+ destroyTs: state.destroyTs,
624
656
  };
625
657
 
626
658
  // Perform atomic write
627
659
  const serializedState =
628
- ACTOR_STATE_VERSIONED.serializeWithEmbeddedVersion(bareState);
660
+ ACTOR_STATE_VERSIONED.serializeWithEmbeddedVersion(
661
+ bareState,
662
+ FILE_SYSTEM_DRIVER_CURRENT_VERSION,
663
+ );
629
664
  const fs = getNodeFs();
630
665
  await fs.writeFile(tempPath, serializedState);
631
666
 
@@ -738,6 +773,16 @@ export class FileSystemGlobalState {
738
773
  "unknown",
739
774
  );
740
775
 
776
+ // Update state with start timestamp
777
+ // NOTE: connectableTs is always in sync with startTs since actors become connectable immediately after starting
778
+ const now = BigInt(Date.now());
779
+ entry.state = {
780
+ ...entry.state,
781
+ startTs: now,
782
+ connectableTs: now,
783
+ };
784
+ await this.writeActor(actorId, entry.generation, entry.state);
785
+
741
786
  // Finish
742
787
  entry.startPromise.resolve();
743
788
  entry.startPromise = undefined;
@@ -315,6 +315,10 @@ export class FileSystemManagerDriver implements ManagerDriver {
315
315
  name: actor.name,
316
316
  key: actor.key as string[],
317
317
  createTs: Number(actor.createdAt),
318
+ startTs: actor.startTs !== null ? Number(actor.startTs) : null,
319
+ connectableTs: actor.connectableTs !== null ? Number(actor.connectableTs) : null,
320
+ sleepTs: actor.sleepTs !== null ? Number(actor.sleepTs) : null,
321
+ destroyTs: actor.destroyTs !== null ? Number(actor.destroyTs) : null,
318
322
  });
319
323
  }
320
324
  }
@@ -35,8 +35,7 @@ export const InspectorConfigSchema = z
35
35
  * Token used to access the Inspector.
36
36
  */
37
37
  token: z
38
- .function()
39
- .returns(z.string())
38
+ .custom<() => string>()
40
39
  .optional()
41
40
  .default(() => defaultTokenFn),
42
41
 
@@ -105,4 +105,8 @@ export interface ActorOutput {
105
105
  name: string;
106
106
  key: ActorKey;
107
107
  createTs?: number;
108
+ startTs?: number | null;
109
+ connectableTs?: number | null;
110
+ sleepTs?: number | null;
111
+ destroyTs?: number | null;
108
112
  }
@@ -2,21 +2,21 @@ import { z } from "zod";
2
2
 
3
3
  export const ServerlessStartHeadersSchema = z.object({
4
4
  endpoint: z.string({
5
- required_error: "x-rivet-endpoint header is required",
5
+ error: "x-rivet-endpoint header is required",
6
6
  }),
7
7
  token: z
8
- .string({ invalid_type_error: "x-rivet-token header must be a string" })
8
+ .string({ error: "x-rivet-token header must be a string" })
9
9
  .optional(),
10
10
  totalSlots: z.coerce
11
11
  .number({
12
- invalid_type_error: "x-rivet-total-slots header must be a number",
12
+ error: "x-rivet-total-slots header must be a number",
13
13
  })
14
- .int("x-rivet-total-slots header must be an integer")
15
- .gte(1, "x-rivet-total-slots header must be positive"),
14
+ .int({ error: "x-rivet-total-slots header must be an integer" })
15
+ .gte(1, { error: "x-rivet-total-slots header must be positive" }),
16
16
  runnerName: z.string({
17
- required_error: "x-rivet-runner-name header is required",
17
+ error: "x-rivet-runner-name header is required",
18
18
  }),
19
19
  namespace: z.string({
20
- required_error: "x-rivet-namespace-name header is required",
20
+ error: "x-rivet-namespace-name header is required",
21
21
  }),
22
22
  });
@@ -731,9 +731,9 @@ function createApiActor(
731
731
  namespace_id: "default", // Assert default namespace
732
732
  runner_name_selector: runnerName,
733
733
  create_ts: actor.createTs ?? Date.now(),
734
- connectable_ts: null,
735
- destroy_ts: null,
736
- sleep_ts: null,
737
- start_ts: null,
734
+ connectable_ts: actor.connectableTs ?? null,
735
+ destroy_ts: actor.destroyTs ?? null,
736
+ sleep_ts: actor.sleepTs ?? null,
737
+ start_ts: actor.startTs ?? null,
738
738
  };
739
739
  }
@@ -18,7 +18,7 @@ export const DriverConfigSchema = z.object({
18
18
  export type DriverConfig = z.infer<typeof DriverConfigSchema>;
19
19
 
20
20
  /** Base config used for the actor config across all platforms. */
21
- export const RunnerConfigSchema = z
21
+ const RunnerConfigSchemaUnmerged = z
22
22
  .object({
23
23
  driver: DriverConfigSchema.optional(),
24
24
 
@@ -95,7 +95,7 @@ export const RunnerConfigSchema = z
95
95
  level: LogLevelSchema.optional(),
96
96
  })
97
97
  .optional()
98
- .default({}),
98
+ .default(() => ({})),
99
99
 
100
100
  /**
101
101
  * @experimental
@@ -115,7 +115,7 @@ export const RunnerConfigSchema = z
115
115
  requestLifespan: z.number().optional(),
116
116
  runnersMargin: z.number().optional(),
117
117
  slotsPerRunner: z.number().optional(),
118
- metadata: z.record(z.unknown()).optional(),
118
+ metadata: z.record(z.string(), z.unknown()).optional(),
119
119
  }),
120
120
  ])
121
121
  .optional(),
@@ -126,8 +126,12 @@ export const RunnerConfigSchema = z
126
126
  // created or must be imported async using `await import(...)`
127
127
  getUpgradeWebSocket: z.custom<GetUpgradeWebSocket>().optional(),
128
128
  })
129
- .merge(EngineConfigSchema.removeDefault())
130
- .default({});
129
+ .merge(EngineConfigSchema.removeDefault());
130
+
131
+ const RunnerConfigSchemaBase = RunnerConfigSchemaUnmerged;
132
+ export const RunnerConfigSchema = RunnerConfigSchemaBase.default(() =>
133
+ RunnerConfigSchemaBase.parse({}),
134
+ );
131
135
 
132
136
  export type RunnerConfig = z.infer<typeof RunnerConfigSchema>;
133
137
  export type RunnerConfigInput = z.input<typeof RunnerConfigSchema>;
@@ -72,7 +72,7 @@ function buildGuardHeadersForHttp(
72
72
  }
73
73
  // Add extra headers from config
74
74
  for (const [key, value] of Object.entries(runConfig.headers)) {
75
- headers.set(key, value);
75
+ headers.set(key, value as string);
76
76
  }
77
77
  // Add guard-specific headers
78
78
  if (runConfig.token) {
@@ -51,7 +51,9 @@ export async function apiCall<TInput = unknown, TOutput = unknown>(
51
51
  encoding: "json",
52
52
  skipParseResponse: false,
53
53
  requestVersionedDataHandler: undefined,
54
+ requestVersion: undefined,
54
55
  responseVersionedDataHandler: undefined,
56
+ responseVersion: undefined,
55
57
  requestZodSchema: z.any() as z.ZodType<TInput>,
56
58
  responseZodSchema: z.any() as z.ZodType<TOutput>,
57
59
  // Identity conversions (passthrough for generic API calls)
@@ -1,66 +1,138 @@
1
- import {
2
- createVersionedDataHandler,
3
- type MigrationFn,
4
- } from "@/common/versioned-data";
5
- import type * as v1 from "../../../dist/schemas/actor-persist/v1";
6
- import type * as v2 from "../../../dist/schemas/actor-persist/v2";
1
+ import { createVersionedDataHandler } from "vbare";
2
+ import * as v1 from "../../../dist/schemas/actor-persist/v1";
3
+ import * as v2 from "../../../dist/schemas/actor-persist/v2";
7
4
  import * as v3 from "../../../dist/schemas/actor-persist/v3";
8
5
 
9
6
  export const CURRENT_VERSION = 3;
10
7
 
11
- const migrations = new Map<number, MigrationFn<any, any>>([
12
- [
13
- 1,
14
- (v1Data: v1.PersistedActor): v2.PersistedActor => ({
15
- ...v1Data,
16
- connections: v1Data.connections.map((conn) => ({
17
- ...conn,
18
- hibernatableRequestId: null,
19
- })),
20
- hibernatableWebSockets: [],
21
- }),
22
- ],
23
- [
24
- 2,
25
- (v2Data: v2.PersistedActor): v3.Actor => {
26
- // Transform scheduled events from nested structure to flat structure
27
- const scheduledEvents: v3.ScheduleEvent[] =
28
- v2Data.scheduledEvents.map((event) => {
29
- // Extract action and args from the kind wrapper
30
- if (event.kind.tag === "GenericPersistedScheduleEvent") {
31
- return {
32
- eventId: event.eventId,
33
- timestamp: event.timestamp,
34
- action: event.kind.val.action,
35
- args: event.kind.val.args,
36
- };
37
- }
38
- // Fallback for unknown kinds
39
- throw new Error(
40
- `Unknown schedule event kind: ${event.kind.tag}`,
41
- );
42
- });
8
+ // Converter from v1 to v2
9
+ const v1ToV2 = (v1Data: v1.PersistedActor): v2.PersistedActor => ({
10
+ ...v1Data,
11
+ connections: v1Data.connections.map((conn) => ({
12
+ ...conn,
13
+ hibernatableRequestId: null,
14
+ })),
15
+ hibernatableWebSockets: [],
16
+ });
43
17
 
44
- return {
45
- input: v2Data.input,
46
- hasInitialized: v2Data.hasInitialized,
47
- state: v2Data.state,
48
- scheduledEvents,
49
- };
18
+ // Converter from v2 to v3
19
+ const v2ToV3 = (v2Data: v2.PersistedActor): v3.Actor => {
20
+ // Transform scheduled events from nested structure to flat structure
21
+ const scheduledEvents: v3.ScheduleEvent[] = v2Data.scheduledEvents.map(
22
+ (event) => {
23
+ // Extract action and args from the kind wrapper
24
+ if (event.kind.tag === "GenericPersistedScheduleEvent") {
25
+ return {
26
+ eventId: event.eventId,
27
+ timestamp: event.timestamp,
28
+ action: event.kind.val.action,
29
+ args: event.kind.val.args,
30
+ };
31
+ }
32
+ // Fallback for unknown kinds
33
+ throw new Error(`Unknown schedule event kind: ${event.kind.tag}`);
50
34
  },
51
- ],
52
- ]);
35
+ );
36
+
37
+ return {
38
+ input: v2Data.input,
39
+ hasInitialized: v2Data.hasInitialized,
40
+ state: v2Data.state,
41
+ scheduledEvents,
42
+ };
43
+ };
44
+
45
+ // Converter from v3 to v2
46
+ const v3ToV2 = (v3Data: v3.Actor): v2.PersistedActor => {
47
+ // Transform scheduled events from flat structure back to nested structure
48
+ const scheduledEvents: v2.PersistedScheduleEvent[] = v3Data.scheduledEvents.map(
49
+ (event) => ({
50
+ eventId: event.eventId,
51
+ timestamp: event.timestamp,
52
+ kind: {
53
+ tag: "GenericPersistedScheduleEvent" as const,
54
+ val: {
55
+ action: event.action,
56
+ args: event.args,
57
+ },
58
+ },
59
+ }),
60
+ );
61
+
62
+ return {
63
+ input: v3Data.input,
64
+ hasInitialized: v3Data.hasInitialized,
65
+ state: v3Data.state,
66
+ scheduledEvents,
67
+ connections: [],
68
+ hibernatableWebSockets: [],
69
+ };
70
+ };
71
+
72
+ // Converter from v2 to v1
73
+ const v2ToV1 = (v2Data: v2.PersistedActor): v1.PersistedActor => {
74
+ return {
75
+ input: v2Data.input,
76
+ hasInitialized: v2Data.hasInitialized,
77
+ state: v2Data.state,
78
+ scheduledEvents: v2Data.scheduledEvents,
79
+ connections: v2Data.connections.map((conn) => {
80
+ const { hibernatableRequestId, ...rest } = conn;
81
+ return rest;
82
+ }),
83
+ };
84
+ };
53
85
 
54
86
  export const ACTOR_VERSIONED = createVersionedDataHandler<v3.Actor>({
55
- currentVersion: CURRENT_VERSION,
56
- migrations,
57
- serializeVersion: (data) => v3.encodeActor(data),
58
- deserializeVersion: (bytes) => v3.decodeActor(bytes),
87
+ deserializeVersion: (bytes, version) => {
88
+ switch (version) {
89
+ case 1:
90
+ return v1.decodePersistedActor(bytes);
91
+ case 2:
92
+ return v2.decodePersistedActor(bytes);
93
+ case 3:
94
+ return v3.decodeActor(bytes);
95
+ default:
96
+ throw new Error(`Unknown version ${version}`);
97
+ }
98
+ },
99
+ serializeVersion: (data, version) => {
100
+ switch (version) {
101
+ case 1:
102
+ return v1.encodePersistedActor(data as v1.PersistedActor);
103
+ case 2:
104
+ return v2.encodePersistedActor(data as v2.PersistedActor);
105
+ case 3:
106
+ return v3.encodeActor(data as v3.Actor);
107
+ default:
108
+ throw new Error(`Unknown version ${version}`);
109
+ }
110
+ },
111
+ deserializeConverters: () => [v1ToV2, v2ToV3],
112
+ serializeConverters: () => [v3ToV2, v2ToV1],
59
113
  });
60
114
 
61
115
  export const CONN_VERSIONED = createVersionedDataHandler<v3.Conn>({
62
- currentVersion: CURRENT_VERSION,
63
- migrations: new Map(),
64
- serializeVersion: (data) => v3.encodeConn(data),
65
- deserializeVersion: (bytes) => v3.decodeConn(bytes),
116
+ deserializeVersion: (bytes, version) => {
117
+ switch (version) {
118
+ case 3:
119
+ return v3.decodeConn(bytes);
120
+ default:
121
+ throw new Error(
122
+ `Conn type only exists in version 3+, got version ${version}`,
123
+ );
124
+ }
125
+ },
126
+ serializeVersion: (data, version) => {
127
+ switch (version) {
128
+ case 3:
129
+ return v3.encodeConn(data as v3.Conn);
130
+ default:
131
+ throw new Error(
132
+ `Conn type only exists in version 3+, got version ${version}`,
133
+ );
134
+ }
135
+ },
136
+ deserializeConverters: () => [],
137
+ serializeConverters: () => [],
66
138
  });