rivetkit 3.0.0-preview.2 → 3.0.0-preview.4

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 (66) hide show
  1. package/dist/browser/client.js +25 -10
  2. package/dist/browser/client.js.map +1 -1
  3. package/dist/browser/inspector/client.js +1 -1
  4. package/dist/browser/inspector/client.js.map +1 -1
  5. package/dist/tsup/{chunk-25MUHNWE.cjs → chunk-5IZ36V3N.cjs} +168 -153
  6. package/dist/tsup/chunk-5IZ36V3N.cjs.map +1 -0
  7. package/dist/tsup/{chunk-6IGGYL2C.js → chunk-C45DIKGB.js} +30 -15
  8. package/dist/tsup/chunk-C45DIKGB.js.map +1 -0
  9. package/dist/tsup/{chunk-WGQHG26S.js → chunk-DCUTYXIX.js} +2 -2
  10. package/dist/tsup/{chunk-WGKL7HMH.js → chunk-IPDSE33U.js} +2 -2
  11. package/dist/tsup/{chunk-442XBCAF.js → chunk-KM34T23X.js} +3 -3
  12. package/dist/tsup/{chunk-YZVVID47.cjs → chunk-KSQ3VVZX.cjs} +3 -3
  13. package/dist/tsup/{chunk-YZVVID47.cjs.map → chunk-KSQ3VVZX.cjs.map} +1 -1
  14. package/dist/tsup/{chunk-EPPV7WB2.cjs → chunk-LTMP7OMQ.cjs} +3 -3
  15. package/dist/tsup/{chunk-EPPV7WB2.cjs.map → chunk-LTMP7OMQ.cjs.map} +1 -1
  16. package/dist/tsup/{chunk-5F7FWAJI.js → chunk-MAUVZIXL.js} +2 -2
  17. package/dist/tsup/{chunk-5F7FWAJI.js.map → chunk-MAUVZIXL.js.map} +1 -1
  18. package/dist/tsup/{chunk-ANNVZW6B.js → chunk-OR3LWJGW.js} +2 -2
  19. package/dist/tsup/{chunk-3SPYZMME.cjs → chunk-S5QNPQ6K.cjs} +3 -3
  20. package/dist/tsup/{chunk-3SPYZMME.cjs.map → chunk-S5QNPQ6K.cjs.map} +1 -1
  21. package/dist/tsup/{chunk-BCG7PTBS.cjs → chunk-SLIGV2T4.cjs} +4 -4
  22. package/dist/tsup/{chunk-BCG7PTBS.cjs.map → chunk-SLIGV2T4.cjs.map} +1 -1
  23. package/dist/tsup/{chunk-XSOHGU4G.cjs → chunk-SR362FVR.cjs} +2 -2
  24. package/dist/tsup/{chunk-XSOHGU4G.cjs.map → chunk-SR362FVR.cjs.map} +1 -1
  25. package/dist/tsup/{chunk-QDRZMCX5.cjs → chunk-U2QBZJTL.cjs} +10 -10
  26. package/dist/tsup/{chunk-QDRZMCX5.cjs.map → chunk-U2QBZJTL.cjs.map} +1 -1
  27. package/dist/tsup/{chunk-CJ3MX5MI.cjs → chunk-WE5DMJFV.cjs} +7 -7
  28. package/dist/tsup/{chunk-CJ3MX5MI.cjs.map → chunk-WE5DMJFV.cjs.map} +1 -1
  29. package/dist/tsup/{chunk-OLZ4KAFL.js → chunk-WQFXPN6S.js} +4 -4
  30. package/dist/tsup/{chunk-3URL73AV.js → chunk-ZWBTTPP3.js} +2 -2
  31. package/dist/tsup/client/mod.cjs +5 -5
  32. package/dist/tsup/client/mod.js +4 -4
  33. package/dist/tsup/common/log.cjs +2 -2
  34. package/dist/tsup/common/log.js +1 -1
  35. package/dist/tsup/common/websocket.cjs +3 -3
  36. package/dist/tsup/common/websocket.js +2 -2
  37. package/dist/tsup/db/drizzle.cjs +2 -2
  38. package/dist/tsup/db/drizzle.js +1 -1
  39. package/dist/tsup/db/mod.cjs +3 -3
  40. package/dist/tsup/db/mod.js +2 -2
  41. package/dist/tsup/inspector/mod.cjs +5 -5
  42. package/dist/tsup/inspector/mod.js +4 -4
  43. package/dist/tsup/inspector/workflow.cjs +4 -4
  44. package/dist/tsup/inspector/workflow.js +3 -3
  45. package/dist/tsup/mod.cjs +93 -89
  46. package/dist/tsup/mod.cjs.map +1 -1
  47. package/dist/tsup/mod.js +13 -9
  48. package/dist/tsup/mod.js.map +1 -1
  49. package/dist/tsup/test/mod.cjs +6 -6
  50. package/dist/tsup/test/mod.js +4 -4
  51. package/dist/tsup/utils.cjs +2 -2
  52. package/dist/tsup/utils.js +1 -1
  53. package/dist/tsup/workflow/mod.cjs +7 -7
  54. package/dist/tsup/workflow/mod.js +4 -4
  55. package/package.json +9 -9
  56. package/src/client/actor-conn.ts +38 -9
  57. package/src/registry/config/index.ts +2 -1
  58. package/src/registry/index.ts +16 -3
  59. package/dist/tsup/chunk-25MUHNWE.cjs.map +0 -1
  60. package/dist/tsup/chunk-6IGGYL2C.js.map +0 -1
  61. /package/dist/tsup/{chunk-WGQHG26S.js.map → chunk-DCUTYXIX.js.map} +0 -0
  62. /package/dist/tsup/{chunk-WGKL7HMH.js.map → chunk-IPDSE33U.js.map} +0 -0
  63. /package/dist/tsup/{chunk-442XBCAF.js.map → chunk-KM34T23X.js.map} +0 -0
  64. /package/dist/tsup/{chunk-ANNVZW6B.js.map → chunk-OR3LWJGW.js.map} +0 -0
  65. /package/dist/tsup/{chunk-OLZ4KAFL.js.map → chunk-WQFXPN6S.js.map} +0 -0
  66. /package/dist/tsup/{chunk-3URL73AV.js.map → chunk-ZWBTTPP3.js.map} +0 -0
@@ -1,13 +1,13 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2
2
 
3
- var _chunkCJ3MX5MIcjs = require('../chunk-CJ3MX5MI.cjs');
3
+ var _chunkWE5DMJFVcjs = require('../chunk-WE5DMJFV.cjs');
4
4
 
5
5
 
6
- var _chunk25MUHNWEcjs = require('../chunk-25MUHNWE.cjs');
6
+ var _chunk5IZ36V3Ncjs = require('../chunk-5IZ36V3N.cjs');
7
7
  require('../chunk-RTWH3AX3.cjs');
8
+ require('../chunk-S5QNPQ6K.cjs');
8
9
  require('../chunk-KVFIONKQ.cjs');
9
- require('../chunk-3SPYZMME.cjs');
10
- require('../chunk-XSOHGU4G.cjs');
10
+ require('../chunk-SR362FVR.cjs');
11
11
  require('../chunk-MGI2VVF6.cjs');
12
12
 
13
13
  // src/test/ready.ts
@@ -36,8 +36,8 @@ async function setupTest(c, registry) {
36
36
  registry.config.noWelcome = true;
37
37
  registry.start();
38
38
  await waitForRegistryReady(registry);
39
- const client = _chunkCJ3MX5MIcjs.createClient.call(void 0, {
40
- ..._chunk25MUHNWEcjs.convertRegistryConfigToClientConfig.call(void 0, registry.parseConfig()),
39
+ const client = _chunkWE5DMJFVcjs.createClient.call(void 0, {
40
+ ..._chunk5IZ36V3Ncjs.convertRegistryConfigToClientConfig.call(void 0, registry.parseConfig()),
41
41
  disableMetadataLookup: false
42
42
  });
43
43
  c.onTestFinished(async () => {
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  createClient
3
- } from "../chunk-442XBCAF.js";
3
+ } from "../chunk-KM34T23X.js";
4
4
  import {
5
5
  convertRegistryConfigToClientConfig
6
- } from "../chunk-6IGGYL2C.js";
6
+ } from "../chunk-C45DIKGB.js";
7
7
  import "../chunk-A2CF6PFH.js";
8
+ import "../chunk-IPDSE33U.js";
8
9
  import "../chunk-JTHHCZCZ.js";
9
- import "../chunk-WGKL7HMH.js";
10
- import "../chunk-5F7FWAJI.js";
10
+ import "../chunk-MAUVZIXL.js";
11
11
  import "../chunk-ZOVJDAOW.js";
12
12
 
13
13
  // src/test/ready.ts
@@ -19,7 +19,7 @@
19
19
 
20
20
 
21
21
 
22
- var _chunkXSOHGU4Gcjs = require('./chunk-XSOHGU4G.cjs');
22
+ var _chunkSR362FVRcjs = require('./chunk-SR362FVR.cjs');
23
23
  require('./chunk-MGI2VVF6.cjs');
24
24
 
25
25
 
@@ -42,5 +42,5 @@ require('./chunk-MGI2VVF6.cjs');
42
42
 
43
43
 
44
44
 
45
- exports.EXTRA_ERROR_LOG = _chunkXSOHGU4Gcjs.EXTRA_ERROR_LOG; exports.SinglePromiseQueue = _chunkXSOHGU4Gcjs.SinglePromiseQueue; exports.VERSION = _chunkXSOHGU4Gcjs.VERSION; exports.arrayBuffersEqual = _chunkXSOHGU4Gcjs.arrayBuffersEqual; exports.assertUnreachable = _chunkXSOHGU4Gcjs.assertUnreachable; exports.bufferToArrayBuffer = _chunkXSOHGU4Gcjs.bufferToArrayBuffer; exports.combineUrlPath = _chunkXSOHGU4Gcjs.combineUrlPath; exports.dbg = _chunkXSOHGU4Gcjs.dbg; exports.detectRuntime = _chunkXSOHGU4Gcjs.detectRuntime; exports.getEnvUniversal = _chunkXSOHGU4Gcjs.getEnvUniversal; exports.httpUserAgent = _chunkXSOHGU4Gcjs.httpUserAgent; exports.interval = _chunkXSOHGU4Gcjs.interval; exports.joinSignals = _chunkXSOHGU4Gcjs.joinSignals; exports.jsonParseCompat = _chunkXSOHGU4Gcjs.jsonParseCompat; exports.jsonStringifyCompat = _chunkXSOHGU4Gcjs.jsonStringifyCompat; exports.promiseWithResolvers = _chunkXSOHGU4Gcjs.promiseWithResolvers; exports.setLongTimeout = _chunkXSOHGU4Gcjs.setLongTimeout; exports.sleep = _chunkXSOHGU4Gcjs.sleep; exports.stringifyError = _chunkXSOHGU4Gcjs.stringifyError; exports.toUint8Array = _chunkXSOHGU4Gcjs.toUint8Array;
45
+ exports.EXTRA_ERROR_LOG = _chunkSR362FVRcjs.EXTRA_ERROR_LOG; exports.SinglePromiseQueue = _chunkSR362FVRcjs.SinglePromiseQueue; exports.VERSION = _chunkSR362FVRcjs.VERSION; exports.arrayBuffersEqual = _chunkSR362FVRcjs.arrayBuffersEqual; exports.assertUnreachable = _chunkSR362FVRcjs.assertUnreachable; exports.bufferToArrayBuffer = _chunkSR362FVRcjs.bufferToArrayBuffer; exports.combineUrlPath = _chunkSR362FVRcjs.combineUrlPath; exports.dbg = _chunkSR362FVRcjs.dbg; exports.detectRuntime = _chunkSR362FVRcjs.detectRuntime; exports.getEnvUniversal = _chunkSR362FVRcjs.getEnvUniversal; exports.httpUserAgent = _chunkSR362FVRcjs.httpUserAgent; exports.interval = _chunkSR362FVRcjs.interval; exports.joinSignals = _chunkSR362FVRcjs.joinSignals; exports.jsonParseCompat = _chunkSR362FVRcjs.jsonParseCompat; exports.jsonStringifyCompat = _chunkSR362FVRcjs.jsonStringifyCompat; exports.promiseWithResolvers = _chunkSR362FVRcjs.promiseWithResolvers; exports.setLongTimeout = _chunkSR362FVRcjs.setLongTimeout; exports.sleep = _chunkSR362FVRcjs.sleep; exports.stringifyError = _chunkSR362FVRcjs.stringifyError; exports.toUint8Array = _chunkSR362FVRcjs.toUint8Array;
46
46
  //# sourceMappingURL=utils.cjs.map
@@ -19,7 +19,7 @@ import {
19
19
  sleep,
20
20
  stringifyError,
21
21
  toUint8Array
22
- } from "./chunk-5F7FWAJI.js";
22
+ } from "./chunk-MAUVZIXL.js";
23
23
  import "./chunk-ZOVJDAOW.js";
24
24
  export {
25
25
  EXTRA_ERROR_LOG,
@@ -1,8 +1,8 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } var _class; var _class2;
2
2
 
3
- var _chunkQDRZMCX5cjs = require('../chunk-QDRZMCX5.cjs');
4
- require('../chunk-YZVVID47.cjs');
5
- require('../chunk-BCG7PTBS.cjs');
3
+ var _chunkU2QBZJTLcjs = require('../chunk-U2QBZJTL.cjs');
4
+ require('../chunk-KSQ3VVZX.cjs');
5
+ require('../chunk-SLIGV2T4.cjs');
6
6
 
7
7
 
8
8
 
@@ -13,7 +13,7 @@ var _chunkHDVZ6YZGcjs = require('../chunk-HDVZ6YZG.cjs');
13
13
  var _chunkRTWH3AX3cjs = require('../chunk-RTWH3AX3.cjs');
14
14
 
15
15
 
16
- var _chunkXSOHGU4Gcjs = require('../chunk-XSOHGU4G.cjs');
16
+ var _chunkSR362FVRcjs = require('../chunk-SR362FVR.cjs');
17
17
 
18
18
 
19
19
 
@@ -743,7 +743,7 @@ function workflow(fn, options = {}) {
743
743
  function getWorkflowInspector(actorId) {
744
744
  let workflowInspector = workflowInspectors.get(actorId);
745
745
  if (!workflowInspector) {
746
- workflowInspector = _chunkQDRZMCX5cjs.createWorkflowInspectorAdapter.call(void 0, );
746
+ workflowInspector = _chunkU2QBZJTLcjs.createWorkflowInspectorAdapter.call(void 0, );
747
747
  workflowInspectors.set(actorId, workflowInspector);
748
748
  }
749
749
  return workflowInspector;
@@ -816,13 +816,13 @@ function workflow(fn, options = {}) {
816
816
  if (shouldRethrowWorkflowError(error)) {
817
817
  runCtx.log.error({
818
818
  msg: "workflow run failed",
819
- error: _chunkXSOHGU4Gcjs.stringifyError.call(void 0, error)
819
+ error: _chunkSR362FVRcjs.stringifyError.call(void 0, error)
820
820
  });
821
821
  throw error;
822
822
  }
823
823
  runCtx.log.warn({
824
824
  msg: "workflow failed and will sleep until woken",
825
- error: _chunkXSOHGU4Gcjs.stringifyError.call(void 0, error)
825
+ error: _chunkSR362FVRcjs.stringifyError.call(void 0, error)
826
826
  });
827
827
  } finally {
828
828
  runCtx.abortSignal.removeEventListener("abort", onAbort);
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  createWorkflowInspectorAdapter
3
- } from "../chunk-OLZ4KAFL.js";
4
- import "../chunk-WGQHG26S.js";
5
- import "../chunk-3URL73AV.js";
3
+ } from "../chunk-WQFXPN6S.js";
4
+ import "../chunk-DCUTYXIX.js";
5
+ import "../chunk-ZWBTTPP3.js";
6
6
  import {
7
7
  ACTOR_CONTEXT_INTERNAL_SYMBOL,
8
8
  defineRunHandler
@@ -13,7 +13,7 @@ import {
13
13
  } from "../chunk-A2CF6PFH.js";
14
14
  import {
15
15
  stringifyError
16
- } from "../chunk-5F7FWAJI.js";
16
+ } from "../chunk-MAUVZIXL.js";
17
17
  import {
18
18
  RivetError,
19
19
  isActorAbortedError
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rivetkit",
3
- "version": "3.0.0-preview.2",
3
+ "version": "3.0.0-preview.4",
4
4
  "description": "Lightweight libraries for building stateful actors on edge platforms",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -211,15 +211,15 @@
211
211
  "@hono/zod-openapi": "^1.1.5",
212
212
  "@opentelemetry/api": "^1.1.0",
213
213
  "@rivetkit/bare-ts": "^0.6.2",
214
- "@rivetkit/engine-api-full": "3.0.0-preview.2",
215
- "@rivetkit/engine-cli": "3.0.0-preview.2",
216
- "@rivetkit/engine-envoy-protocol": "3.0.0-preview.2",
214
+ "@rivetkit/engine-api-full": "3.0.0-preview.4",
215
+ "@rivetkit/engine-cli": "3.0.0-preview.4",
216
+ "@rivetkit/engine-envoy-protocol": "3.0.0-preview.4",
217
217
  "@rivetkit/on-change": "6.0.1",
218
- "@rivetkit/rivetkit-napi": "3.0.0-preview.2",
219
- "@rivetkit/rivetkit-wasm": "3.0.0-preview.2",
220
- "@rivetkit/traces": "3.0.0-preview.2",
221
- "@rivetkit/virtual-websocket": "3.0.0-preview.2",
222
- "@rivetkit/workflow-engine": "3.0.0-preview.2",
218
+ "@rivetkit/rivetkit-napi": "3.0.0-preview.4",
219
+ "@rivetkit/rivetkit-wasm": "3.0.0-preview.4",
220
+ "@rivetkit/traces": "3.0.0-preview.4",
221
+ "@rivetkit/virtual-websocket": "3.0.0-preview.4",
222
+ "@rivetkit/workflow-engine": "3.0.0-preview.4",
223
223
  "cbor-x": "^1.6.0",
224
224
  "drizzle-orm": "0.45.2",
225
225
  "hono": "^4.7.0",
@@ -611,6 +611,13 @@ export class ActorConnRaw {
611
611
  if (isConnectionOpenTimeout(error)) {
612
612
  return true;
613
613
  }
614
+ if (
615
+ error instanceof errors.ActorError &&
616
+ error.group === "client" &&
617
+ error.code === "connection_open_interrupted"
618
+ ) {
619
+ return true;
620
+ }
614
621
  if (
615
622
  error instanceof errors.ActorError &&
616
623
  isInvalidToken(error.group, error.code) &&
@@ -692,16 +699,18 @@ export class ActorConnRaw {
692
699
  });
693
700
  this.#websocket = ws;
694
701
  ws.addEventListener("open", () => {
695
- if (this.#abandonedSockets.has(ws)) return;
702
+ if (this.#websocket !== ws || this.#abandonedSockets.has(ws))
703
+ return;
696
704
  logger().debug({
697
705
  msg: "client websocket open",
698
706
  connId: this.#connId,
699
707
  });
700
708
  });
701
709
  ws.addEventListener("message", async (ev: { data: ConnMessage }) => {
702
- if (this.#abandonedSockets.has(ws)) return;
710
+ if (this.#websocket !== ws || this.#abandonedSockets.has(ws))
711
+ return;
703
712
  try {
704
- await this.#handleOnMessage(ev.data);
713
+ await this.#handleOnMessage(ev.data, ws);
705
714
  } catch (err) {
706
715
  logger().error({
707
716
  msg: "error in websocket message handler",
@@ -710,7 +719,8 @@ export class ActorConnRaw {
710
719
  }
711
720
  });
712
721
  ws.addEventListener("close", async (ev: Event | CloseEventLike) => {
713
- if (this.#abandonedSockets.has(ws)) return;
722
+ if (this.#websocket !== ws || this.#abandonedSockets.has(ws))
723
+ return;
714
724
  try {
715
725
  await this.#handleOnClose(ev);
716
726
  } catch (err) {
@@ -721,7 +731,8 @@ export class ActorConnRaw {
721
731
  }
722
732
  });
723
733
  ws.addEventListener("error", () => {
724
- if (this.#abandonedSockets.has(ws)) return;
734
+ if (this.#websocket !== ws || this.#abandonedSockets.has(ws))
735
+ return;
725
736
  try {
726
737
  this.#handleOnError();
727
738
  } catch (err) {
@@ -803,7 +814,7 @@ export class ActorConnRaw {
803
814
  }
804
815
 
805
816
  /** Called by the onmessage event from drivers. */
806
- async #handleOnMessage(data: any) {
817
+ async #handleOnMessage(data: any, socket: UniversalWebSocket) {
807
818
  logger().trace({
808
819
  msg: "received message",
809
820
  dataType: typeof data,
@@ -812,6 +823,10 @@ export class ActorConnRaw {
812
823
  });
813
824
 
814
825
  const response = await this.#parseMessage(data as ConnMessage);
826
+ // Decoding can yield while this socket closes and another connects. Apply
827
+ // the message only while its socket still owns the connection.
828
+ if (this.#websocket !== socket || this.#abandonedSockets.has(socket))
829
+ return;
815
830
  logger().trace(
816
831
  getLogMessage()
817
832
  ? {
@@ -897,6 +912,12 @@ export class ActorConnRaw {
897
912
  this.#actorResolutionState,
898
913
  this.#driver,
899
914
  );
915
+ if (
916
+ this.#websocket !== socket ||
917
+ this.#abandonedSockets.has(socket)
918
+ ) {
919
+ return;
920
+ }
900
921
  if (schedulingError) {
901
922
  errorToThrow = schedulingError;
902
923
  }
@@ -1047,9 +1068,17 @@ export class ActorConnRaw {
1047
1068
  this.#invalidateActorIfStale(group, code);
1048
1069
  } else {
1049
1070
  // Default error for non-structured close reasons
1050
- error = new Error(
1051
- `${wasClean ? "Connection closed" : "Connection lost"} (code: ${closeEvent.code}, reason: ${reason})`,
1052
- );
1071
+ const message = `${wasClean ? "Connection closed" : "Connection lost"} (code: ${closeEvent.code}, reason: ${reason})`;
1072
+ // A transport loss during the handshake can outlast an Engine
1073
+ // restart. Retry opening without replaying actions with unknown outcomes.
1074
+ error =
1075
+ !wasConnected && closeEvent.code === 1006
1076
+ ? new errors.ActorError(
1077
+ "client",
1078
+ "connection_open_interrupted",
1079
+ message,
1080
+ )
1081
+ : new Error(message);
1053
1082
  }
1054
1083
 
1055
1084
  this.#rejectPendingPromises(error, false);
@@ -291,7 +291,8 @@ export const RegistryConfigSchema = z
291
291
  * after calling `CoreRegistry::shutdown()`. Defaults to the
292
292
  * engine-provided actor stop threshold once the node connects. A
293
293
  * signal-driven shutdown of a managed local development engine waits
294
- * one second by default so a file watcher can restart promptly.
294
+ * four seconds by default so actors can acknowledge stopping before
295
+ * a file watcher restarts the process.
295
296
  *
296
297
  * Set a longer period when a complete graceful node drain is required.
297
298
  */
@@ -29,6 +29,13 @@ import type {
29
29
  type ShutdownSignal = "SIGINT" | "SIGTERM";
30
30
 
31
31
  const REGISTRY_READY_TIMEOUT_MS = 30_000;
32
+ // A managed Engine restart can wait for the old process to release storage and
33
+ // for its worker lease to expire before the replacement can register.
34
+ const LOCAL_ENGINE_READY_TIMEOUT_MS = 60_000;
35
+ // Core gives local actors three seconds to drain and acknowledge their stopped
36
+ // reports. Leave time to close the node connection after that, while staying
37
+ // below the five-second force-kill ceiling used by tsx watch.
38
+ const LOCAL_DEV_SHUTDOWN_GRACE_PERIOD_MS = 4_000;
32
39
 
33
40
  // Serverless is disabled for v3; keep the implementation for a later release.
34
41
  function rejectServerless(): void {
@@ -789,7 +796,7 @@ export class Registry<A extends RegistryActors> {
789
796
  let gracePeriodMs = config.shutdown?.gracePeriodMs;
790
797
  if (gracePeriodMs === undefined) {
791
798
  gracePeriodMs = localDevSignal
792
- ? 1_000
799
+ ? LOCAL_DEV_SHUTDOWN_GRACE_PERIOD_MS
793
800
  : ((await this.#actorStopThresholdMs(
794
801
  modeAPromise ?? modeBPromise,
795
802
  )) ?? 30 * 60 * 1000);
@@ -942,16 +949,22 @@ export class Registry<A extends RegistryActors> {
942
949
  throw new Error("registry envoy startup did not initialize");
943
950
  }
944
951
 
952
+ const readyTimeoutMs =
953
+ config.engineSpawn &&
954
+ config.endpoint !== undefined &&
955
+ isLocalEngineEndpoint(config.endpoint)
956
+ ? LOCAL_ENGINE_READY_TIMEOUT_MS
957
+ : REGISTRY_READY_TIMEOUT_MS;
945
958
  let timeout: ReturnType<typeof setTimeout> | undefined;
946
959
  const timeoutPromise = new Promise<never>((_resolve, reject) => {
947
960
  timeout = setTimeout(
948
961
  () =>
949
962
  reject(
950
963
  new Error(
951
- `RivetKit registry did not register with the Engine within ${REGISTRY_READY_TIMEOUT_MS}ms`,
964
+ `RivetKit registry did not register with the Engine within ${readyTimeoutMs}ms`,
952
965
  ),
953
966
  ),
954
- REGISTRY_READY_TIMEOUT_MS,
967
+ readyTimeoutMs,
955
968
  );
956
969
  timeout.unref?.();
957
970
  });