rivetkit 2.3.24-rc.1 → 2.3.24

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 (115) hide show
  1. package/dist/browser/client.d.ts +3 -2
  2. package/dist/browser/client.js +36 -17
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.js +1 -1
  5. package/dist/browser/inspector/client.js.map +1 -1
  6. package/dist/tsup/agent-os/index.cjs +1 -1
  7. package/dist/tsup/agent-os/index.cjs.map +1 -1
  8. package/dist/tsup/agent-os/index.d.cts +0 -2
  9. package/dist/tsup/agent-os/index.d.ts +0 -2
  10. package/dist/tsup/agent-os/index.js +1 -1
  11. package/dist/tsup/agent-os/index.js.map +1 -1
  12. package/dist/tsup/{chunk-6HW3TU7Q.js → chunk-45WBFRBN.js} +2 -2
  13. package/dist/tsup/{chunk-64CRWLOX.js → chunk-7OEOLF5T.js} +3 -3
  14. package/dist/tsup/{chunk-LTGBHN5Z.js → chunk-CSOHAAZK.js} +1 -1
  15. package/dist/tsup/chunk-CSOHAAZK.js.map +1 -0
  16. package/dist/tsup/{chunk-CE6NBGOL.cjs → chunk-JOJ42ZLR.cjs} +3 -3
  17. package/dist/tsup/{chunk-CE6NBGOL.cjs.map → chunk-JOJ42ZLR.cjs.map} +1 -1
  18. package/dist/tsup/{chunk-ERBNWARB.cjs → chunk-L4AZXL2Q.cjs} +4 -4
  19. package/dist/tsup/{chunk-ERBNWARB.cjs.map → chunk-L4AZXL2Q.cjs.map} +1 -1
  20. package/dist/tsup/{chunk-YVVFOKEP.cjs → chunk-NNM2X3ER.cjs} +2 -2
  21. package/dist/tsup/chunk-NNM2X3ER.cjs.map +1 -0
  22. package/dist/tsup/{chunk-OB5JLDBM.js → chunk-NSNBWLCG.js} +2 -2
  23. package/dist/tsup/{chunk-NGJWQMUU.cjs → chunk-NWCAIWHL.cjs} +1 -1
  24. package/dist/tsup/chunk-NWCAIWHL.cjs.map +1 -0
  25. package/dist/tsup/{chunk-M5J3PXNU.js → chunk-QMR2J7PT.js} +2 -2
  26. package/dist/tsup/{chunk-QQ454DVR.js → chunk-QZQE75U2.js} +2 -2
  27. package/dist/tsup/{chunk-B6WTPGOR.js → chunk-SW22GCYF.js} +30 -11
  28. package/dist/tsup/chunk-SW22GCYF.js.map +1 -0
  29. package/dist/tsup/{chunk-PFHGTLF2.cjs → chunk-TMMZAGZL.cjs} +10 -10
  30. package/dist/tsup/{chunk-PFHGTLF2.cjs.map → chunk-TMMZAGZL.cjs.map} +1 -1
  31. package/dist/tsup/{chunk-R3UI7MO3.cjs → chunk-TQNVNKDB.cjs} +165 -146
  32. package/dist/tsup/chunk-TQNVNKDB.cjs.map +1 -0
  33. package/dist/tsup/{chunk-JKDAOE4T.js → chunk-UIPQ7RI4.js} +4 -4
  34. package/dist/tsup/{chunk-SWQCSORE.cjs → chunk-WCSFWDKH.cjs} +3 -3
  35. package/dist/tsup/{chunk-SWQCSORE.cjs.map → chunk-WCSFWDKH.cjs.map} +1 -1
  36. package/dist/tsup/{chunk-DAC73W53.cjs → chunk-WTZGJFD4.cjs} +7 -7
  37. package/dist/tsup/{chunk-DAC73W53.cjs.map → chunk-WTZGJFD4.cjs.map} +1 -1
  38. package/dist/tsup/{chunk-JJCUSUWO.js → chunk-YH2CAWLD.js} +2 -2
  39. package/dist/tsup/chunk-YH2CAWLD.js.map +1 -0
  40. package/dist/tsup/{chunk-JMO6AVUC.cjs → chunk-ZCHJJ2FZ.cjs} +3 -3
  41. package/dist/tsup/{chunk-JMO6AVUC.cjs.map → chunk-ZCHJJ2FZ.cjs.map} +1 -1
  42. package/dist/tsup/client/mod.cjs +5 -5
  43. package/dist/tsup/client/mod.d.cts +5 -2
  44. package/dist/tsup/client/mod.d.ts +5 -2
  45. package/dist/tsup/client/mod.js +4 -4
  46. package/dist/tsup/common/log.cjs +2 -2
  47. package/dist/tsup/common/log.js +1 -1
  48. package/dist/tsup/common/websocket.cjs +3 -3
  49. package/dist/tsup/common/websocket.js +2 -2
  50. package/dist/tsup/{config-RV6gIa2L.d.ts → config-Cv6pjCt-.d.ts} +0 -4
  51. package/dist/tsup/{config-CuKzfH58.d.cts → config-osdJqQwX.d.cts} +0 -4
  52. package/dist/tsup/{context-DoMKZBQA.d.ts → context-CoVbKBuk.d.ts} +1 -1
  53. package/dist/tsup/{context-DPCxyjax.d.cts → context-DpjrM7n7.d.cts} +1 -1
  54. package/dist/tsup/db/drizzle.cjs +2 -2
  55. package/dist/tsup/db/drizzle.js +1 -1
  56. package/dist/tsup/db/mod.cjs +3 -3
  57. package/dist/tsup/db/mod.js +2 -2
  58. package/dist/tsup/dynamic/mod.cjs +2 -2
  59. package/dist/tsup/dynamic/mod.d.cts +1 -1
  60. package/dist/tsup/dynamic/mod.d.ts +1 -1
  61. package/dist/tsup/dynamic/mod.js +1 -1
  62. package/dist/tsup/inspector/mod.cjs +5 -5
  63. package/dist/tsup/inspector/mod.js +4 -4
  64. package/dist/tsup/inspector/workflow.cjs +4 -4
  65. package/dist/tsup/inspector/workflow.js +3 -3
  66. package/dist/tsup/inspector-tab/mod.cjs +2 -2
  67. package/dist/tsup/inspector-tab/mod.d.cts +2 -2
  68. package/dist/tsup/inspector-tab/mod.d.ts +2 -2
  69. package/dist/tsup/inspector-tab/mod.js +1 -1
  70. package/dist/tsup/mod.cjs +188 -416
  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 +90 -318
  75. package/dist/tsup/mod.js.map +1 -1
  76. package/dist/tsup/test/mod.cjs +6 -6
  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 +4 -4
  80. package/dist/tsup/utils.cjs +2 -2
  81. package/dist/tsup/utils.js +1 -1
  82. package/dist/tsup/workflow/mod.cjs +21 -69
  83. package/dist/tsup/workflow/mod.cjs.map +1 -1
  84. package/dist/tsup/workflow/mod.d.cts +3 -3
  85. package/dist/tsup/workflow/mod.d.ts +3 -3
  86. package/dist/tsup/workflow/mod.js +16 -64
  87. package/dist/tsup/workflow/mod.js.map +1 -1
  88. package/package.json +9 -9
  89. package/src/actor/config.ts +0 -2
  90. package/src/client/config.ts +3 -0
  91. package/src/client/raw-utils.ts +7 -2
  92. package/src/common/fetch-like.ts +14 -0
  93. package/src/engine-client/actor-http-client.ts +16 -6
  94. package/src/registry/napi-runtime.ts +0 -8
  95. package/src/registry/native.ts +65 -332
  96. package/src/registry/run-handler-coordinator.test.ts +0 -102
  97. package/src/registry/run-handler-coordinator.ts +17 -84
  98. package/src/registry/runtime.ts +0 -2
  99. package/src/registry/wasm-runtime.ts +0 -8
  100. package/src/workflow/context.ts +0 -20
  101. package/src/workflow/driver.ts +1 -25
  102. package/src/workflow/mod.ts +12 -46
  103. package/dist/tsup/chunk-B6WTPGOR.js.map +0 -1
  104. package/dist/tsup/chunk-JJCUSUWO.js.map +0 -1
  105. package/dist/tsup/chunk-LTGBHN5Z.js.map +0 -1
  106. package/dist/tsup/chunk-NGJWQMUU.cjs.map +0 -1
  107. package/dist/tsup/chunk-R3UI7MO3.cjs.map +0 -1
  108. package/dist/tsup/chunk-YVVFOKEP.cjs.map +0 -1
  109. package/src/registry/lost-callbacks.test.ts +0 -64
  110. /package/dist/tsup/{chunk-6HW3TU7Q.js.map → chunk-45WBFRBN.js.map} +0 -0
  111. /package/dist/tsup/{chunk-64CRWLOX.js.map → chunk-7OEOLF5T.js.map} +0 -0
  112. /package/dist/tsup/{chunk-OB5JLDBM.js.map → chunk-NSNBWLCG.js.map} +0 -0
  113. /package/dist/tsup/{chunk-M5J3PXNU.js.map → chunk-QMR2J7PT.js.map} +0 -0
  114. /package/dist/tsup/{chunk-QQ454DVR.js.map → chunk-QZQE75U2.js.map} +0 -0
  115. /package/dist/tsup/{chunk-JKDAOE4T.js.map → chunk-UIPQ7RI4.js.map} +0 -0
@@ -541,11 +541,8 @@ async function cleanupNativeSleepRuntimeState(
541
541
  void runtime
542
542
  .actorWaitForTrackedShutdownWorkUnbounded(ctx)
543
543
  .then(async () => {
544
- try {
545
- await afterTrackedWorkDrained?.();
546
- } finally {
547
- clearNativeRuntimeState(runtime, ctx);
548
- }
544
+ await afterTrackedWorkDrained?.();
545
+ clearNativeRuntimeState(runtime, ctx);
549
546
  })
550
547
  .catch((error) => {
551
548
  logger().warn({
@@ -556,31 +553,10 @@ async function cleanupNativeSleepRuntimeState(
556
553
  return;
557
554
  }
558
555
 
559
- try {
560
- await afterTrackedWorkDrained?.();
561
- } finally {
562
- try {
563
- await closeNativeDatabaseClient(runtime, ctx);
564
- await closeNativeSqlDatabase(runtime, ctx);
565
- } finally {
566
- clearNativeRuntimeState(runtime, ctx);
567
- }
568
- }
569
- }
570
-
571
- async function cleanupNativeLostRuntimeState(
572
- runtime: CoreRuntime,
573
- ctx: ActorContextHandle,
574
- ): Promise<void> {
575
- // Core has already abandoned a lost generation's user work, so this does not wait for it.
576
- // A custom database client's `close` is user code, so a lost generation drops the client
577
- // without calling it. The native database underneath is closed by the runtime.
556
+ await afterTrackedWorkDrained?.();
578
557
  await closeNativeDatabaseClient(runtime, ctx);
579
- try {
580
- await closeNativeSqlDatabase(runtime, ctx);
581
- } finally {
582
- clearNativeRuntimeState(runtime, ctx);
583
- }
558
+ await closeNativeSqlDatabase(runtime, ctx);
559
+ clearNativeRuntimeState(runtime, ctx);
584
560
  }
585
561
 
586
562
  function closeNativeSqlDatabase(
@@ -609,11 +585,6 @@ async function closeNativeDatabaseClient(
609
585
 
610
586
  runtimeState.databaseClient = undefined;
611
587
 
612
- // `close` is user code from a database provider. Cleanup paths await before reaching this,
613
- // so check here: a lost generation drops the client without calling it.
614
- if (callNativeSync(() => runtime.actorIsLost(ctx))) {
615
- return;
616
- }
617
588
  if (
618
589
  entry.client &&
619
590
  typeof entry.client === "object" &&
@@ -1330,76 +1301,6 @@ function wrapNativeCallback<Args extends Array<unknown>, Result>(
1330
1301
  };
1331
1302
  }
1332
1303
 
1333
- /**
1334
- * Callbacks that still run for a lost generation. They release the generation's runtime
1335
- * resources and skip the user hook themselves.
1336
- */
1337
- const LOST_GENERATION_CLEANUP_CALLBACKS = new Set(["onSleep", "onDestroy"]);
1338
-
1339
- /**
1340
- * Refuses to start a user callback for a generation that was declared lost. Call it right
1341
- * before the callback, after any other user code such as schema validation.
1342
- */
1343
- function throwIfActorLost(runtime: CoreRuntime, ctx: ActorContextHandle): void {
1344
- if (callNativeSync(() => runtime.actorIsLost(ctx))) {
1345
- throw actorGenerationLostError();
1346
- }
1347
- }
1348
-
1349
- function actorGenerationLostError(): RivetError {
1350
- return new RivetError(
1351
- "actor",
1352
- "stopping",
1353
- "Actor generation was declared lost; it starts no new user callbacks.",
1354
- );
1355
- }
1356
-
1357
- /**
1358
- * Refuses every runtime callback for a generation that has been declared lost. Runtime
1359
- * callbacks can be queued or spawned before the loss and only start afterward, so the check
1360
- * runs when JS actually enters the callback.
1361
- */
1362
- export function refuseCallbacksAfterLost<T extends Record<string, unknown>>(
1363
- runtime: CoreRuntime,
1364
- callbacks: T,
1365
- ): T {
1366
- const guard = (callback: (...args: unknown[]) => unknown) => {
1367
- return async (...args: unknown[]) => {
1368
- const ctx = (args[1] as { ctx?: ActorContextHandle } | undefined)
1369
- ?.ctx;
1370
- if (
1371
- ctx !== undefined &&
1372
- callNativeSync(() => runtime.actorIsLost(ctx))
1373
- ) {
1374
- throw encodeNativeCallbackError(actorGenerationLostError());
1375
- }
1376
- return await callback(...args);
1377
- };
1378
- };
1379
- const guarded: Record<string, unknown> = {};
1380
- for (const [name, value] of Object.entries(callbacks)) {
1381
- if (LOST_GENERATION_CLEANUP_CALLBACKS.has(name)) {
1382
- guarded[name] = value;
1383
- } else if (typeof value === "function") {
1384
- guarded[name] = guard(value as (...args: unknown[]) => unknown);
1385
- } else if (
1386
- name === "actions" &&
1387
- value !== null &&
1388
- typeof value === "object"
1389
- ) {
1390
- guarded[name] = Object.fromEntries(
1391
- Object.entries(value).map(([actionName, handler]) => [
1392
- actionName,
1393
- guard(handler as (...args: unknown[]) => unknown),
1394
- ]),
1395
- );
1396
- } else {
1397
- guarded[name] = value;
1398
- }
1399
- }
1400
- return guarded as T;
1401
- }
1402
-
1403
1304
  function decodeArgs(value?: RuntimeBytes | null): unknown[] {
1404
1305
  const decoded = decodeValue<unknown>(value);
1405
1306
  return normalizeArgs(decoded);
@@ -1979,26 +1880,9 @@ class NativeQueueAdapter {
1979
1880
  this.#schemas = schemas;
1980
1881
  }
1981
1882
 
1982
- // Queue results arrive after awaits, and their schema validation is user code, so each
1983
- // validation checks that the generation was not lost first.
1984
- #validateBody(name: string, body: unknown): unknown {
1985
- throwIfActorLost(this.#runtime, this.#ctx);
1986
- return validateQueueBody(this.#schemas, name, body);
1987
- }
1988
-
1989
- #validateComplete(name: string, response: unknown): unknown {
1990
- throwIfActorLost(this.#runtime, this.#ctx);
1991
- return validateQueueComplete(this.#schemas, name, response);
1992
- }
1993
-
1994
- #wrap(message: Parameters<typeof wrapQueueMessage>[0]) {
1995
- throwIfActorLost(this.#runtime, this.#ctx);
1996
- return wrapQueueMessage(message, this.#schemas);
1997
- }
1998
-
1999
1883
  async send(name: string, body: unknown) {
2000
- const validatedBody = this.#validateBody(name, body);
2001
- return this.#wrap(
1884
+ const validatedBody = validateQueueBody(this.#schemas, name, body);
1885
+ return wrapQueueMessage(
2002
1886
  await callNative(() =>
2003
1887
  this.#runtime.actorQueueSend(
2004
1888
  this.#ctx,
@@ -2006,6 +1890,7 @@ class NativeQueueAdapter {
2006
1890
  encodeValue(validatedBody),
2007
1891
  ),
2008
1892
  ),
1893
+ this.#schemas,
2009
1894
  );
2010
1895
  }
2011
1896
 
@@ -2063,7 +1948,9 @@ class NativeQueueAdapter {
2063
1948
  token,
2064
1949
  ),
2065
1950
  );
2066
- const wrapped = messages.map((message) => this.#wrap(message));
1951
+ const wrapped = messages.map((message) =>
1952
+ wrapQueueMessage(message, this.#schemas),
1953
+ );
2067
1954
  return completable
2068
1955
  ? wrapped.map((message) =>
2069
1956
  this.#makeCompletableMessage(message),
@@ -2088,7 +1975,7 @@ class NativeQueueAdapter {
2088
1975
  );
2089
1976
 
2090
1977
  try {
2091
- return this.#wrap(
1978
+ return wrapQueueMessage(
2092
1979
  await callNative(() =>
2093
1980
  this.#runtime.actorQueueWaitForNames(
2094
1981
  this.#ctx,
@@ -2100,6 +1987,7 @@ class NativeQueueAdapter {
2100
1987
  token,
2101
1988
  ),
2102
1989
  ),
1990
+ this.#schemas,
2103
1991
  );
2104
1992
  } finally {
2105
1993
  cleanup?.();
@@ -2144,7 +2032,8 @@ class NativeQueueAdapter {
2144
2032
  message: { id: number | bigint; name: string },
2145
2033
  response?: unknown,
2146
2034
  ): Promise<void> {
2147
- const validatedResponse = this.#validateComplete(
2035
+ const validatedResponse = validateQueueComplete(
2036
+ this.#schemas,
2148
2037
  message.name,
2149
2038
  response,
2150
2039
  );
@@ -2167,7 +2056,7 @@ class NativeQueueAdapter {
2167
2056
  signal?: AbortSignal;
2168
2057
  },
2169
2058
  ) {
2170
- const validatedBody = this.#validateBody(name, body);
2059
+ const validatedBody = validateQueueBody(this.#schemas, name, body);
2171
2060
  const { token, cleanup } = await createCancellationTokenHandle(
2172
2061
  this.#runtime,
2173
2062
  options?.signal,
@@ -2187,7 +2076,11 @@ class NativeQueueAdapter {
2187
2076
  );
2188
2077
  return response === undefined || response === null
2189
2078
  ? undefined
2190
- : this.#validateComplete(name, decodeValue(response));
2079
+ : validateQueueComplete(
2080
+ this.#schemas,
2081
+ name,
2082
+ decodeValue(response),
2083
+ );
2191
2084
  } finally {
2192
2085
  cleanup?.();
2193
2086
  }
@@ -2690,12 +2583,6 @@ class TrackedWebSocketHandleAdapter implements UniversalWebSocket {
2690
2583
  handler: TrackedWebSocketListener,
2691
2584
  event: any,
2692
2585
  ): void {
2693
- // Messages and opens start new user work, so a lost generation drops them. Each listener
2694
- // is checked because an earlier one can run while the generation is lost. Close and
2695
- // error still reach listeners, like the abort signal, so user code can wind down.
2696
- if ((type === "message" || type === "open") && this.#ctx.isLost) {
2697
- return;
2698
- }
2699
2586
  try {
2700
2587
  const result = handler(event);
2701
2588
  if (!this.#isPromiseLike(result)) {
@@ -3076,15 +2963,6 @@ export class ActorContextHandleAdapter {
3076
2963
  return callNativeSync(() => this.#runtime.actorId(this.#ctx));
3077
2964
  }
3078
2965
 
3079
- get actorGeneration(): number | undefined {
3080
- return callNativeSync(() => this.#runtime.actorGeneration(this.#ctx));
3081
- }
3082
-
3083
- /** Whether this generation was declared lost. A lost generation starts no new user code. */
3084
- get isLost(): boolean {
3085
- return callNativeSync(() => this.#runtime.actorIsLost(this.#ctx));
3086
- }
3087
-
3088
2966
  get name(): string {
3089
2967
  return callNativeSync(() => this.#runtime.actorName(this.#ctx));
3090
2968
  }
@@ -3218,10 +3096,6 @@ export class ActorContextHandleAdapter {
3218
3096
  }
3219
3097
 
3220
3098
  const actorId = this.actorId;
3221
- // `createClient` is user code from a database provider.
3222
- if (this.isLost) {
3223
- throw actorGenerationLostError();
3224
- }
3225
3099
  const createdClient = await this.#databaseProvider.createClient({
3226
3100
  actorId,
3227
3101
  kv: {
@@ -3399,12 +3273,9 @@ export class ActorContextHandleAdapter {
3399
3273
  return;
3400
3274
  }
3401
3275
 
3402
- const client = await this.ensureDatabaseClient();
3403
- // Creating the client awaits, and the generation can be lost meanwhile.
3404
- if (this.isLost) {
3405
- throw actorGenerationLostError();
3406
- }
3407
- await this.#databaseProvider.onMigrate(client as never);
3276
+ await this.#databaseProvider.onMigrate(
3277
+ (await this.ensureDatabaseClient()) as never,
3278
+ );
3408
3279
  }
3409
3280
 
3410
3281
  async closeDatabase(): Promise<void> {
@@ -3739,8 +3610,7 @@ export class ActorContextHandleAdapter {
3739
3610
  this.#runtime.actorRequestSave(this.#ctx, { immediate: false }),
3740
3611
  );
3741
3612
 
3742
- // State changes are flushed asynchronously and can land after the generation was lost.
3743
- if (!this.#onStateChange || this.isLost) {
3613
+ if (!this.#onStateChange) {
3744
3614
  return;
3745
3615
  }
3746
3616
 
@@ -3789,13 +3659,6 @@ class NativeWorkflowRuntimeAdapter {
3789
3659
  #completions = new Map<string, (response?: unknown) => Promise<void>>();
3790
3660
 
3791
3661
  readonly id: string;
3792
- /** Actor generation, used to keep workflow registrations of different generations apart. */
3793
- readonly generation: number | undefined;
3794
-
3795
- /** Whether this generation was declared lost. Workflow code checks it before each user callback. */
3796
- get isLost(): boolean {
3797
- return this.#ctx.isLost;
3798
- }
3799
3662
  readonly driver: {
3800
3663
  kvBatchGet: (
3801
3664
  actorId: string,
@@ -3867,7 +3730,6 @@ class NativeWorkflowRuntimeAdapter {
3867
3730
  this.#ctx = ctx;
3868
3731
  this.#onMessagesReceived = onMessagesReceived;
3869
3732
  this.id = ctx.actorId;
3870
- this.generation = ctx.actorGeneration;
3871
3733
  this.driver = {
3872
3734
  kvBatchGet: async (actorId, keys) => {
3873
3735
  this.#assertActorId(actorId);
@@ -4239,29 +4101,14 @@ export function buildNativeFactory(
4239
4101
  ? new RunHandlerCoordinator(config.run)
4240
4102
  : undefined;
4241
4103
  const getNativeWorkflowInspector = (ctx: ActorContextHandle) => {
4242
- // Inspector workflow calls run user code (history, state, replay). A lost generation
4243
- // exposes no workflow inspector.
4244
- if (callNativeSync(() => runtime.actorIsLost(ctx))) {
4245
- return undefined;
4246
- }
4247
4104
  const actorId = callNativeSync(() => runtime.actorId(ctx));
4248
4105
  const restart = () =>
4249
4106
  callNativeSync(() => runtime.actorRestartRunHandler(ctx));
4250
- const actorGeneration = callNativeSync(() =>
4251
- runtime.actorGeneration(ctx),
4252
- );
4253
- const inspector = (runHandlerCoordinator?.getInspector(
4254
- actorId,
4255
- restart,
4256
- actorGeneration,
4257
- )?.workflow ?? getRunInspectorConfig(config.run, actorId)?.workflow) as
4107
+ return (runHandlerCoordinator?.getInspector(actorId, restart)
4108
+ ?.workflow ??
4109
+ getRunInspectorConfig(config.run, actorId)?.workflow) as
4258
4110
  | NativeWorkflowInspectorConfig
4259
4111
  | undefined;
4260
- // Building the inspector can run a user factory, and the generation can be lost meanwhile.
4261
- if (callNativeSync(() => runtime.actorIsLost(ctx))) {
4262
- return undefined;
4263
- }
4264
- return inspector;
4265
4112
  };
4266
4113
  const onStateChange =
4267
4114
  typeof config.onStateChange === "function"
@@ -4381,11 +4228,6 @@ export function buildNativeFactory(
4381
4228
  }
4382
4229
  }
4383
4230
 
4384
- // Reading connection params runs the user schema, and authentication awaited before this.
4385
- const inspectorConnParams = (conn: { params: unknown }) => {
4386
- throwIfActorLost(runtime, ctx);
4387
- return conn.params;
4388
- };
4389
4231
  const workflowHistory = () =>
4390
4232
  serializeWorkflowHistoryForJson(
4391
4233
  getNativeWorkflowInspector(ctx)?.getHistory() ?? null,
@@ -4424,7 +4266,7 @@ export function buildNativeFactory(
4424
4266
  id: conn.id,
4425
4267
  details: {
4426
4268
  type: null,
4427
- params: inspectorConnParams(conn),
4269
+ params: conn.params,
4428
4270
  stateEnabled: true,
4429
4271
  state: conn.state,
4430
4272
  subscriptions: 0,
@@ -4684,7 +4526,7 @@ export function buildNativeFactory(
4684
4526
  id: conn.id,
4685
4527
  details: {
4686
4528
  type: null,
4687
- params: inspectorConnParams(conn),
4529
+ params: conn.params,
4688
4530
  stateEnabled: true,
4689
4531
  state: conn.state,
4690
4532
  subscriptions: 0,
@@ -4746,22 +4588,15 @@ export function buildNativeFactory(
4746
4588
  body.properties !== undefined
4747
4589
  ? [body.properties]
4748
4590
  : normalizeArgs(body.args);
4749
- // Authentication and body parsing may finish after the generation was lost.
4750
- if (callNativeSync(() => runtime.actorIsLost(ctx))) {
4751
- return jsonResponse(
4752
- { error: "actor generation was declared lost" },
4753
- { status: 503 },
4754
- );
4755
- }
4756
4591
  try {
4757
- const validatedArgs = validateActionArgs(
4758
- schemaConfig.actionInputSchemas,
4759
- actionName,
4760
- args,
4592
+ const output = await action(
4593
+ actorCtx,
4594
+ ...validateActionArgs(
4595
+ schemaConfig.actionInputSchemas,
4596
+ actionName,
4597
+ args,
4598
+ ),
4761
4599
  );
4762
- // Schema validation is user code and can run while the generation is lost.
4763
- throwIfActorLost(runtime, ctx);
4764
- const output = await action(actorCtx, ...validatedArgs);
4765
4600
  return jsonResponse({ output });
4766
4601
  } catch (error) {
4767
4602
  logger().error({
@@ -4903,14 +4738,7 @@ export function buildNativeFactory(
4903
4738
  await actorCtx.closeDatabase();
4904
4739
  }
4905
4740
  await actorCtx.runDatabaseMigrations();
4906
- // Migrations may finish after the generation was lost, and a lost
4907
- // generation starts no new user hooks.
4908
- if (
4909
- typeof config.onMigrate === "function" &&
4910
- !callNativeSync(() =>
4911
- runtime.actorIsLost(ctx),
4912
- )
4913
- ) {
4741
+ if (typeof config.onMigrate === "function") {
4914
4742
  await config.onMigrate(actorCtx, isNew);
4915
4743
  }
4916
4744
  } catch (error) {
@@ -4966,38 +4794,10 @@ export function buildNativeFactory(
4966
4794
  const { ctx } = unwrapTsfnPayload(error, payload);
4967
4795
  const actorCtx = makeActorCtx(ctx);
4968
4796
  const actorId = callNativeSync(() => runtime.actorId(ctx));
4969
- const actorGeneration = callNativeSync(() =>
4970
- runtime.actorGeneration(ctx),
4971
- );
4972
- // The engine can declare this generation lost before or during `onSleep`.
4973
- // A lost generation releases its own runtime resources only: no user hook,
4974
- // no state save, and nothing keyed by actor id alone.
4975
- const isLost = () =>
4976
- callNativeSync(() => runtime.actorIsLost(ctx));
4977
- if (isLost()) {
4978
- try {
4979
- await cleanupNativeLostRuntimeState(runtime, ctx);
4980
- } finally {
4981
- runHandlerCoordinator?.destroy(
4982
- actorId,
4983
- actorGeneration,
4984
- {
4985
- disposeInspector: false,
4986
- },
4987
- );
4988
- await actorCtx.dispose();
4989
- }
4990
- return;
4991
- }
4992
4797
  // TODO: Move this save hook into cleanupNativeSleepRuntimeState
4993
4798
  // so immediate and deferred sleep cleanup share one save-state
4994
4799
  // path instead of passing a callback through cleanup.
4995
4800
  const saveActorState = async () => {
4996
- // Cleanup waits on tracked work first, and the generation can be lost
4997
- // during that wait.
4998
- if (isLost()) {
4999
- return;
5000
- }
5001
4801
  if (runtime.kind === "wasm") {
5002
4802
  // Wasm cannot use the native context save helper here because
5003
4803
  // the runtime owns the serialized state handoff.
@@ -5018,26 +4818,14 @@ export function buildNativeFactory(
5018
4818
  await saveActorState();
5019
4819
  } finally {
5020
4820
  try {
5021
- if (isLost()) {
5022
- await cleanupNativeLostRuntimeState(runtime, ctx);
5023
- } else {
5024
- await cleanupNativeSleepRuntimeState(
5025
- runtime,
5026
- ctx,
5027
- saveActorState,
5028
- );
5029
- }
5030
- } finally {
5031
- runHandlerCoordinator?.destroy(
5032
- actorId,
5033
- actorGeneration,
5034
- {
5035
- disposeInspector: !isLost(),
5036
- },
4821
+ await cleanupNativeSleepRuntimeState(
4822
+ runtime,
4823
+ ctx,
4824
+ saveActorState,
5037
4825
  );
5038
- if (!isLost()) {
5039
- disposeRunInspector(config.run, actorId);
5040
- }
4826
+ } finally {
4827
+ runHandlerCoordinator?.destroy(actorId);
4828
+ disposeRunInspector(config.run, actorId);
5041
4829
  await actorCtx.dispose();
5042
4830
  }
5043
4831
  }
@@ -5048,22 +4836,12 @@ export function buildNativeFactory(
5048
4836
  const { ctx } = unwrapTsfnPayload(error, payload);
5049
4837
  const actorCtx = makeActorCtx(ctx);
5050
4838
  const actorId = callNativeSync(() => runtime.actorId(ctx));
5051
- // A lost generation still releases its runtime state but starts no user hook. Loss
5052
- // is rechecked before each user callback because it can happen while one runs.
5053
- const isLost = () =>
5054
- callNativeSync(() => runtime.actorIsLost(ctx));
5055
4839
  // Close run control before user cleanup so replay cannot race actor
5056
4840
  // destruction. Recreating this actor id receives a fresh controller.
5057
- runHandlerCoordinator?.destroy(
5058
- actorId,
5059
- callNativeSync(() => runtime.actorGeneration(ctx)),
5060
- { disposeInspector: !isLost() },
5061
- );
5062
- if (!isLost()) {
5063
- disposeRunInspector(config.run, actorId);
5064
- }
4841
+ runHandlerCoordinator?.destroy(actorId);
4842
+ disposeRunInspector(config.run, actorId);
5065
4843
  try {
5066
- if (typeof config.onDestroy === "function" && !isLost()) {
4844
+ if (typeof config.onDestroy === "function") {
5067
4845
  await config.onDestroy(actorCtx);
5068
4846
  }
5069
4847
  } finally {
@@ -5101,16 +4879,12 @@ export function buildNativeFactory(
5101
4879
  : undefined,
5102
4880
  );
5103
4881
  try {
5104
- const validatedParams = validateConnParams(
5105
- schemaConfig.connParamsSchema,
5106
- decodeValue(params),
5107
- );
5108
- // Schema validation is user code and can run while the
5109
- // generation is lost.
5110
- throwIfActorLost(runtime, ctx);
5111
4882
  await config.onBeforeConnect(
5112
4883
  actorCtx,
5113
- validatedParams,
4884
+ validateConnParams(
4885
+ schemaConfig.connParamsSchema,
4886
+ decodeValue(params),
4887
+ ),
5114
4888
  );
5115
4889
  } finally {
5116
4890
  await actorCtx.dispose();
@@ -5158,25 +4932,15 @@ export function buildNativeFactory(
5158
4932
  () => actorCtx.assertCanMutateState(),
5159
4933
  );
5160
4934
  try {
5161
- let nextConnState: unknown;
5162
- if (hasStaticConnState) {
5163
- nextConnState = structuredClone(
5164
- config.connState,
5165
- );
5166
- } else {
5167
- const validatedParams = validateConnParams(
5168
- schemaConfig.connParamsSchema,
5169
- decodeValue(params),
5170
- );
5171
- // Schema validation is user code and can run while the
5172
- // generation is lost.
5173
- throwIfActorLost(runtime, ctx);
5174
- nextConnState =
5175
- await config.createConnState(
4935
+ const nextConnState = hasStaticConnState
4936
+ ? structuredClone(config.connState)
4937
+ : await config.createConnState(
5176
4938
  actorCtx,
5177
- validatedParams,
4939
+ validateConnParams(
4940
+ schemaConfig.connParamsSchema,
4941
+ decodeValue(params),
4942
+ ),
5178
4943
  );
5179
- }
5180
4944
  connAdapter.initializeState(nextConnState);
5181
4945
  return encodeValue(nextConnState);
5182
4946
  } finally {
@@ -5335,13 +5099,6 @@ export function buildNativeFactory(
5335
5099
  ) => {
5336
5100
  const { ctx, name, args, output } =
5337
5101
  unwrapTsfnPayload(error, payload);
5338
- // The action may finish after its generation was lost, and a lost
5339
- // generation starts no new user callbacks.
5340
- if (
5341
- callNativeSync(() => runtime.actorIsLost(ctx))
5342
- ) {
5343
- return output;
5344
- }
5345
5102
  const actorCtx = makeActorCtx(ctx);
5346
5103
  try {
5347
5104
  return encodeValue(
@@ -5439,9 +5196,6 @@ export function buildNativeFactory(
5439
5196
  }
5440
5197
  };
5441
5198
  try {
5442
- // Inspector routing awaits, and the generation can be lost
5443
- // meanwhile. Schema validation is user code.
5444
- throwIfActorLost(runtime, ctx);
5445
5199
  const connParams = validateConnParams(
5446
5200
  schemaConfig.connParamsSchema,
5447
5201
  rawConnParams
@@ -5480,14 +5234,6 @@ export function buildNativeFactory(
5480
5234
  abortRequest,
5481
5235
  );
5482
5236
  }
5483
- // Connection setup awaits, and the generation can be lost meanwhile.
5484
- if (
5485
- callNativeSync(() =>
5486
- runtime.actorIsLost(ctx),
5487
- )
5488
- ) {
5489
- throw actorGenerationLostError();
5490
- }
5491
5237
  const response = await config.onRequest(
5492
5238
  requestCtx,
5493
5239
  handlerRequest,
@@ -5588,11 +5334,6 @@ export function buildNativeFactory(
5588
5334
  const { ctx } = unwrapTsfnPayload(error, payload);
5589
5335
  const actorId = callNativeSync(() => runtime.actorId(ctx));
5590
5336
  const executeRun = async () => {
5591
- // The coordinator can hold `run` behind other run work until after the
5592
- // generation was lost.
5593
- if (callNativeSync(() => runtime.actorIsLost(ctx))) {
5594
- return;
5595
- }
5596
5337
  const actorCtx = makeActorCtx(ctx);
5597
5338
  try {
5598
5339
  await run(actorCtx);
@@ -5608,7 +5349,6 @@ export function buildNativeFactory(
5608
5349
  runtime.actorRestartRunHandler(ctx),
5609
5350
  ),
5610
5351
  executeRun,
5611
- callNativeSync(() => runtime.actorGeneration(ctx)),
5612
5352
  );
5613
5353
  // Only a start suppressed behind a failed replay must preserve a
5614
5354
  // consumed durable wake. Closed actors must remain closed.
@@ -5685,18 +5425,14 @@ export function buildNativeFactory(
5685
5425
  : makeActorCtx(ctx, undefined, cancelToken);
5686
5426
  const runAction = async () => {
5687
5427
  try {
5688
- const validatedArgs = validateActionArgs(
5689
- schemaConfig.actionInputSchemas,
5690
- name,
5691
- decodeArgs(args),
5692
- );
5693
- // Schema validation is user code and can run while the
5694
- // generation is lost.
5695
- throwIfActorLost(runtime, ctx);
5696
5428
  return encodeValue(
5697
5429
  await handler(
5698
5430
  actorCtx,
5699
- ...validatedArgs,
5431
+ ...validateActionArgs(
5432
+ schemaConfig.actionInputSchemas,
5433
+ name,
5434
+ decodeArgs(args),
5435
+ ),
5700
5436
  ...(scheduledFire
5701
5437
  ? [scheduledFire]
5702
5438
  : []),
@@ -5775,9 +5511,6 @@ export function buildNativeFactory(
5775
5511
  if (canPublish && !(await canPublish(actorCtx))) {
5776
5512
  throw forbiddenError();
5777
5513
  }
5778
- // `canPublish` can finish after the generation was lost, and
5779
- // sending validates the body with user schema code.
5780
- throwIfActorLost(runtime, ctx);
5781
5514
 
5782
5515
  const decodedBody = decodeValue(body);
5783
5516
  if (wait) {
@@ -5851,7 +5584,7 @@ export function buildNativeFactory(
5851
5584
  };
5852
5585
 
5853
5586
  return runtime.createActorFactory(
5854
- refuseCallbacksAfterLost(runtime, callbacks),
5587
+ callbacks,
5855
5588
  buildActorConfig(definition, registryConfig, runtime.kind),
5856
5589
  );
5857
5590
  }