rivetkit 2.3.0-rc.9 → 2.3.0

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 (222) hide show
  1. package/dist/browser/client.d.ts +498 -62
  2. package/dist/browser/client.js +227 -171
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.js +50 -20
  5. package/dist/browser/inspector/client.js.map +1 -1
  6. package/dist/tsup/actor/errors.cjs +2 -2
  7. package/dist/tsup/actor/errors.d.cts +1 -1
  8. package/dist/tsup/actor/errors.d.ts +1 -1
  9. package/dist/tsup/actor/errors.js +1 -1
  10. package/dist/tsup/agent-os/index.cjs +2163 -2087
  11. package/dist/tsup/agent-os/index.cjs.map +1 -1
  12. package/dist/tsup/agent-os/index.d.cts +496 -69
  13. package/dist/tsup/agent-os/index.d.ts +496 -69
  14. package/dist/tsup/agent-os/index.js +2163 -2087
  15. package/dist/tsup/agent-os/index.js.map +1 -1
  16. package/dist/tsup/{chunk-W7EYSYVI.js → chunk-2OTRTA3J.js} +134 -20
  17. package/dist/tsup/chunk-2OTRTA3J.js.map +1 -0
  18. package/dist/tsup/{chunk-VJFRBJVQ.cjs → chunk-3677IIOV.cjs} +138 -24
  19. package/dist/tsup/chunk-3677IIOV.cjs.map +1 -0
  20. package/dist/tsup/{chunk-4CGA6QJO.cjs → chunk-47HHIEXH.cjs} +24 -9
  21. package/dist/tsup/chunk-47HHIEXH.cjs.map +1 -0
  22. package/dist/tsup/{chunk-F3Q5BFQ6.js → chunk-4JDSFJS5.js} +66 -79
  23. package/dist/tsup/chunk-4JDSFJS5.js.map +1 -0
  24. package/dist/tsup/{chunk-GVTOE34S.cjs → chunk-7QKCIVAY.cjs} +222 -235
  25. package/dist/tsup/chunk-7QKCIVAY.cjs.map +1 -0
  26. package/dist/tsup/{chunk-CPA4Y3RG.cjs → chunk-B6VUNZUD.cjs} +10 -10
  27. package/dist/tsup/chunk-B6VUNZUD.cjs.map +1 -0
  28. package/dist/tsup/{chunk-H37XQU3I.js → chunk-BEI24WTI.js} +2 -2
  29. package/dist/tsup/{chunk-KIWH5H3K.js → chunk-BRP62GZC.js} +3 -3
  30. package/dist/tsup/chunk-BRP62GZC.js.map +1 -0
  31. package/dist/tsup/{chunk-T6YVRM4K.js → chunk-DPIMKYNB.js} +63 -2
  32. package/dist/tsup/chunk-DPIMKYNB.js.map +1 -0
  33. package/dist/tsup/{chunk-Y5NSCZA2.cjs → chunk-DXXJPH55.cjs} +44 -15
  34. package/dist/tsup/chunk-DXXJPH55.cjs.map +1 -0
  35. package/dist/tsup/{chunk-3YY5S6TV.js → chunk-HXUEHHJF.js} +2 -2
  36. package/dist/tsup/chunk-HXUEHHJF.js.map +1 -0
  37. package/dist/tsup/{chunk-4WPEZBK4.cjs → chunk-I4LN3FNT.cjs} +10 -10
  38. package/dist/tsup/chunk-I4LN3FNT.cjs.map +1 -0
  39. package/dist/tsup/{chunk-PCBNKI2J.js → chunk-JZ7TWV65.js} +1 -1
  40. package/dist/tsup/chunk-JZ7TWV65.js.map +1 -0
  41. package/dist/tsup/{chunk-QAZLM4WT.cjs → chunk-KORQB2IR.cjs} +3 -3
  42. package/dist/tsup/{chunk-QAZLM4WT.cjs.map → chunk-KORQB2IR.cjs.map} +1 -1
  43. package/dist/tsup/{chunk-MALSPBAF.cjs → chunk-LVTBW2RE.cjs} +3 -3
  44. package/dist/tsup/{chunk-MALSPBAF.cjs.map → chunk-LVTBW2RE.cjs.map} +1 -1
  45. package/dist/tsup/{chunk-H7P7WR2Y.js → chunk-MEHBWPLJ.js} +6 -6
  46. package/dist/tsup/chunk-MEHBWPLJ.js.map +1 -0
  47. package/dist/tsup/{chunk-WQ4HNA4W.cjs → chunk-NIY3RSPX.cjs} +64 -3
  48. package/dist/tsup/chunk-NIY3RSPX.cjs.map +1 -0
  49. package/dist/tsup/{chunk-MMMEZM5J.js → chunk-P2GNQ4RN.js} +4 -4
  50. package/dist/tsup/chunk-P2GNQ4RN.js.map +1 -0
  51. package/dist/tsup/{chunk-KJTA3ATT.js → chunk-UMZVD6DQ.js} +22 -7
  52. package/dist/tsup/chunk-UMZVD6DQ.js.map +1 -0
  53. package/dist/tsup/{chunk-LD5YASJU.cjs → chunk-VE2X4KMG.cjs} +2 -2
  54. package/dist/tsup/{chunk-LD5YASJU.cjs.map → chunk-VE2X4KMG.cjs.map} +1 -1
  55. package/dist/tsup/{chunk-VRCIXJRN.js → chunk-VTTFNQQI.js} +36 -7
  56. package/dist/tsup/chunk-VTTFNQQI.js.map +1 -0
  57. package/dist/tsup/{chunk-2NDZ7JCR.cjs → chunk-ZA7FLHKH.cjs} +1 -1
  58. package/dist/tsup/chunk-ZA7FLHKH.cjs.map +1 -0
  59. package/dist/tsup/client/mod.cjs +9 -9
  60. package/dist/tsup/client/mod.d.cts +5 -5
  61. package/dist/tsup/client/mod.d.ts +5 -5
  62. package/dist/tsup/client/mod.js +8 -8
  63. package/dist/tsup/common/log.cjs +3 -3
  64. package/dist/tsup/common/log.js +2 -2
  65. package/dist/tsup/common/websocket.cjs +4 -4
  66. package/dist/tsup/common/websocket.js +3 -3
  67. package/dist/tsup/{config-0Ta55UV0.d.ts → config-BxWAw3iH.d.ts} +529 -23
  68. package/dist/tsup/{config-Ca8dN4cS.d.cts → config-CZQQ-mso.d.cts} +529 -23
  69. package/dist/tsup/{config-CxjGYf4K.d.cts → config-D49x8NpL.d.cts} +1 -2
  70. package/dist/tsup/{config-CxjGYf4K.d.ts → config-D49x8NpL.d.ts} +1 -2
  71. package/dist/tsup/{context-B_IWbWne.d.ts → context-Bw7xq8w3.d.cts} +8 -8
  72. package/dist/tsup/{context-CUrQ9MHc.d.cts → context-D8QA76sV.d.ts} +8 -8
  73. package/dist/tsup/db/drizzle.cjs +3 -3
  74. package/dist/tsup/db/drizzle.d.cts +1 -1
  75. package/dist/tsup/db/drizzle.d.ts +1 -1
  76. package/dist/tsup/db/drizzle.js +1 -1
  77. package/dist/tsup/db/mod.cjs +2 -2
  78. package/dist/tsup/db/mod.d.cts +2 -2
  79. package/dist/tsup/db/mod.d.ts +2 -2
  80. package/dist/tsup/db/mod.js +1 -1
  81. package/dist/tsup/dynamic/mod.cjs +24 -0
  82. package/dist/tsup/dynamic/mod.cjs.map +1 -0
  83. package/dist/tsup/dynamic/mod.d.cts +37 -0
  84. package/dist/tsup/dynamic/mod.d.ts +37 -0
  85. package/dist/tsup/dynamic/mod.js +24 -0
  86. package/dist/tsup/dynamic/mod.js.map +1 -0
  87. package/dist/tsup/inspector/mod.cjs +6 -6
  88. package/dist/tsup/inspector/mod.js +5 -5
  89. package/dist/tsup/inspector-tab/mod.cjs +173 -0
  90. package/dist/tsup/inspector-tab/mod.cjs.map +1 -0
  91. package/dist/tsup/inspector-tab/mod.d.cts +250 -0
  92. package/dist/tsup/inspector-tab/mod.d.ts +250 -0
  93. package/dist/tsup/inspector-tab/mod.js +173 -0
  94. package/dist/tsup/inspector-tab/mod.js.map +1 -0
  95. package/dist/tsup/mod.cjs +730 -336
  96. package/dist/tsup/mod.cjs.map +1 -1
  97. package/dist/tsup/mod.d.cts +5 -5
  98. package/dist/tsup/mod.d.ts +5 -5
  99. package/dist/tsup/mod.js +633 -239
  100. package/dist/tsup/mod.js.map +1 -1
  101. package/dist/tsup/test/mod.cjs +21 -18
  102. package/dist/tsup/test/mod.cjs.map +1 -1
  103. package/dist/tsup/test/mod.d.cts +4 -4
  104. package/dist/tsup/test/mod.d.ts +4 -4
  105. package/dist/tsup/test/mod.js +18 -15
  106. package/dist/tsup/test/mod.js.map +1 -1
  107. package/dist/tsup/{utils-DVekpm4I.d.cts → utils-DQosb24I.d.cts} +1 -1
  108. package/dist/tsup/{utils-DVekpm4I.d.ts → utils-DQosb24I.d.ts} +1 -1
  109. package/dist/tsup/utils.cjs +3 -3
  110. package/dist/tsup/utils.d.cts +1 -1
  111. package/dist/tsup/utils.d.ts +1 -1
  112. package/dist/tsup/utils.js +2 -2
  113. package/dist/tsup/workflow/mod.cjs +307 -282
  114. package/dist/tsup/workflow/mod.cjs.map +1 -1
  115. package/dist/tsup/workflow/mod.d.cts +6 -6
  116. package/dist/tsup/workflow/mod.d.ts +6 -6
  117. package/dist/tsup/workflow/mod.js +501 -476
  118. package/dist/tsup/workflow/mod.js.map +1 -1
  119. package/package.json +32 -11
  120. package/src/actor/config.ts +159 -51
  121. package/src/actor/contexts/index.ts +7 -2
  122. package/src/actor/definition.ts +17 -19
  123. package/src/actor/driver.ts +3 -3
  124. package/src/actor/errors.ts +9 -3
  125. package/src/actor/instance/mod.ts +26 -34
  126. package/src/actor/keys.ts +1 -1
  127. package/src/actor/mod.ts +22 -20
  128. package/src/actor/schema.ts +2 -2
  129. package/src/agent-os/actor/index.ts +38 -18
  130. package/src/agent-os/actor/preview.ts +1 -2
  131. package/src/agent-os/actor/session.ts +2 -2
  132. package/src/agent-os/config.ts +1 -1
  133. package/src/agent-os/fs/database-vfs.ts +1 -1
  134. package/src/agent-os/index.ts +16 -15
  135. package/src/client/actor-common.ts +87 -54
  136. package/src/client/actor-conn.ts +8 -36
  137. package/src/client/actor-handle.ts +69 -51
  138. package/src/client/actor-query.ts +5 -5
  139. package/src/client/errors.ts +1 -1
  140. package/src/client/lifecycle-errors.ts +2 -4
  141. package/src/client/query.ts +1 -1
  142. package/src/client/queue.ts +8 -3
  143. package/src/client/raw-utils.ts +8 -6
  144. package/src/client/resolve-gateway-target.ts +1 -1
  145. package/src/client/utils.ts +2 -7
  146. package/src/common/actor-websocket.ts +3 -1
  147. package/src/common/bare/actor-persist/v1.ts +205 -163
  148. package/src/common/bare/actor-persist/v2.ts +265 -213
  149. package/src/common/bare/actor-persist/v3.ts +176 -172
  150. package/src/common/bare/actor-persist/v4.ts +254 -253
  151. package/src/common/bare/transport/v1.ts +659 -543
  152. package/src/common/client-protocol-versioned.ts +66 -64
  153. package/src/common/database/config.ts +2 -8
  154. package/src/common/database/native-database.ts +1 -1
  155. package/src/common/database/shared.ts +1 -0
  156. package/src/common/encoding.ts +250 -16
  157. package/src/common/engine.ts +28 -1
  158. package/src/common/eventsource.ts +1 -1
  159. package/src/common/inline-websocket-adapter.ts +14 -13
  160. package/src/common/log.ts +1 -0
  161. package/src/common/router.ts +13 -17
  162. package/src/common/utils.ts +1 -150
  163. package/src/common/websocket-interface.ts +1 -1
  164. package/src/db/mod.ts +1 -1
  165. package/src/devtools-loader/index.ts +4 -7
  166. package/src/devtools-loader/serve-devtools.ts +26 -0
  167. package/src/drivers/engine/actor-driver.ts +58 -56
  168. package/src/dynamic/instance.ts +32 -0
  169. package/src/dynamic/internal.ts +50 -0
  170. package/src/dynamic/isolate-runtime.ts +66 -0
  171. package/src/dynamic/mod.ts +32 -0
  172. package/src/engine-client/actor-http-client.ts +3 -3
  173. package/src/engine-client/actor-websocket-client.ts +6 -5
  174. package/src/engine-client/api-endpoints.ts +51 -2
  175. package/src/engine-client/api-utils.ts +2 -2
  176. package/src/engine-client/driver.ts +1 -1
  177. package/src/engine-client/mod.ts +6 -3
  178. package/src/engine-client/ws-proxy.ts +9 -4
  179. package/src/inspector/client.browser.ts +5 -11
  180. package/src/inspector/mod.ts +1 -3
  181. package/src/inspector-tab/mod.ts +315 -0
  182. package/src/registry/config/envoy.ts +1 -2
  183. package/src/registry/config/index.ts +40 -16
  184. package/src/registry/index.ts +154 -74
  185. package/src/registry/napi-runtime.ts +13 -2
  186. package/src/registry/native-validation.ts +10 -12
  187. package/src/registry/native.ts +367 -181
  188. package/src/registry/process-metrics.ts +250 -0
  189. package/src/registry/runtime.ts +41 -1
  190. package/src/registry/wasm-runtime.ts +18 -2
  191. package/src/registry/write-through-proxy.ts +40 -0
  192. package/src/serde.ts +2 -2
  193. package/src/serverless/configure.ts +18 -7
  194. package/src/test/mod.ts +11 -8
  195. package/src/utils/endpoint-parser.ts +1 -1
  196. package/src/utils/env-vars.ts +6 -0
  197. package/src/utils/router.ts +1 -1
  198. package/src/utils/serve.ts +4 -5
  199. package/src/utils.ts +1 -2
  200. package/src/workflow/context.ts +61 -33
  201. package/src/workflow/driver.ts +4 -6
  202. package/src/workflow/inspector.ts +4 -3
  203. package/src/workflow/mod.ts +15 -17
  204. package/dist/tsup/chunk-2NDZ7JCR.cjs.map +0 -1
  205. package/dist/tsup/chunk-3YY5S6TV.js.map +0 -1
  206. package/dist/tsup/chunk-4CGA6QJO.cjs.map +0 -1
  207. package/dist/tsup/chunk-4WPEZBK4.cjs.map +0 -1
  208. package/dist/tsup/chunk-CPA4Y3RG.cjs.map +0 -1
  209. package/dist/tsup/chunk-F3Q5BFQ6.js.map +0 -1
  210. package/dist/tsup/chunk-GVTOE34S.cjs.map +0 -1
  211. package/dist/tsup/chunk-H7P7WR2Y.js.map +0 -1
  212. package/dist/tsup/chunk-KIWH5H3K.js.map +0 -1
  213. package/dist/tsup/chunk-KJTA3ATT.js.map +0 -1
  214. package/dist/tsup/chunk-MMMEZM5J.js.map +0 -1
  215. package/dist/tsup/chunk-PCBNKI2J.js.map +0 -1
  216. package/dist/tsup/chunk-T6YVRM4K.js.map +0 -1
  217. package/dist/tsup/chunk-VJFRBJVQ.cjs.map +0 -1
  218. package/dist/tsup/chunk-VRCIXJRN.js.map +0 -1
  219. package/dist/tsup/chunk-W7EYSYVI.js.map +0 -1
  220. package/dist/tsup/chunk-WQ4HNA4W.cjs.map +0 -1
  221. package/dist/tsup/chunk-Y5NSCZA2.cjs.map +0 -1
  222. /package/dist/tsup/{chunk-H37XQU3I.js.map → chunk-BEI24WTI.js.map} +0 -0
package/dist/tsup/mod.js CHANGED
@@ -1,14 +1,15 @@
1
+ import {
2
+ decodeWorkflowHistoryTransport
3
+ } from "./chunk-UMZVD6DQ.js";
1
4
  import {
2
5
  ACTOR_CONTEXT_INTERNAL_SYMBOL,
3
6
  ActorConfigSchema,
4
7
  CONN_STATE_MANAGER_SYMBOL,
8
+ RAW_STATE_SYMBOL,
5
9
  getRunFunction,
6
10
  getRunInspectorConfig,
7
11
  getRunMetadata
8
- } from "./chunk-T6YVRM4K.js";
9
- import {
10
- decodeWorkflowHistoryTransport
11
- } from "./chunk-KJTA3ATT.js";
12
+ } from "./chunk-DPIMKYNB.js";
12
13
  import {
13
14
  ALLOWED_PUBLIC_HEADERS,
14
15
  HEADER_CONN_PARAMS,
@@ -18,7 +19,7 @@ import {
18
19
  getDatacenters,
19
20
  tryParseEndpoint,
20
21
  updateRunnerConfig
21
- } from "./chunk-F3Q5BFQ6.js";
22
+ } from "./chunk-4JDSFJS5.js";
22
23
  import {
23
24
  KEYS,
24
25
  makePrefixedKey,
@@ -26,18 +27,19 @@ import {
26
27
  queueMetadataKey,
27
28
  removePrefixFromKey,
28
29
  workflowStoragePrefix
29
- } from "./chunk-3YY5S6TV.js";
30
+ } from "./chunk-HXUEHHJF.js";
30
31
  import {
32
+ assertJsonCompatValue,
31
33
  decodeCborCompat,
32
- decodeCborJsonCompat,
33
34
  encodeCborCompat
34
- } from "./chunk-W7EYSYVI.js";
35
- import "./chunk-PCBNKI2J.js";
36
- import "./chunk-H37XQU3I.js";
35
+ } from "./chunk-2OTRTA3J.js";
36
+ import "./chunk-JZ7TWV65.js";
37
+ import "./chunk-BEI24WTI.js";
37
38
  import {
38
39
  LogLevelSchema,
39
40
  VERSION,
40
41
  deconstructError,
42
+ detectRuntime,
41
43
  getEnvUniversal,
42
44
  getLogger,
43
45
  getNodeEnv,
@@ -49,6 +51,8 @@ import {
49
51
  getRivetPublicEndpoint,
50
52
  getRivetPublicToken,
51
53
  getRivetRunEngine,
54
+ getRivetRunEngineHost,
55
+ getRivetRunEnginePort,
52
56
  getRivetRunEngineVersion,
53
57
  getRivetToken,
54
58
  getRivetTotalSlots,
@@ -57,7 +61,7 @@ import {
57
61
  noopNext,
58
62
  stringifyError,
59
63
  toUint8Array
60
- } from "./chunk-VRCIXJRN.js";
64
+ } from "./chunk-VTTFNQQI.js";
61
65
  import {
62
66
  INTERNAL_ERROR_CODE,
63
67
  RivetError,
@@ -68,7 +72,7 @@ import {
68
72
  isRivetErrorLike,
69
73
  toRivetError,
70
74
  unsupportedFeature
71
- } from "./chunk-KIWH5H3K.js";
75
+ } from "./chunk-BRP62GZC.js";
72
76
 
73
77
  // src/actor/log.ts
74
78
  function loggerWithoutContext() {
@@ -140,7 +144,7 @@ function hasSchemaConfigKey(schemas, key) {
140
144
  if (!schemas) {
141
145
  return false;
142
146
  }
143
- return Object.prototype.hasOwnProperty.call(schemas, key);
147
+ return Object.hasOwn(schemas, key);
144
148
  }
145
149
  function getEventCanSubscribe(schemas, key) {
146
150
  const schema = schemas == null ? void 0 : schemas[key];
@@ -201,8 +205,8 @@ function validateSchemaSync(schemas, key, data) {
201
205
  }
202
206
 
203
207
  // src/common/inline-websocket-adapter.ts
204
- import { WSContext } from "hono/ws";
205
208
  import { VirtualWebSocket } from "@rivetkit/virtual-websocket";
209
+ import { WSContext } from "hono/ws";
206
210
  function logger() {
207
211
  return getLogger("inline-websocket-adapter");
208
212
  }
@@ -314,24 +318,24 @@ var InlineWebSocketAdapter = class {
314
318
  this.#close(1011, "Internal error during initialization");
315
319
  }
316
320
  }
317
- #handleError(err) {
318
- console.error("INLINE_WEBSOCKET_ADAPTER_ERROR", err);
321
+ #handleError(error) {
322
+ console.error("INLINE_WEBSOCKET_ADAPTER_ERROR", error);
319
323
  logger().error({
320
324
  msg: "error in websocket",
321
- error: err,
322
- errorMessage: err instanceof Error ? err.message : String(err),
323
- stack: err instanceof Error ? err.stack : void 0
325
+ error,
326
+ errorMessage: error instanceof Error ? error.message : String(error),
327
+ stack: error instanceof Error ? error.stack : void 0
324
328
  });
325
329
  try {
326
- this.#handler.onError(err, this.#wsContext);
327
- } catch (handlerErr) {
330
+ this.#handler.onError(error, this.#wsContext);
331
+ } catch (error2) {
328
332
  logger().error({
329
333
  msg: "error in onError handler",
330
- error: handlerErr
334
+ error: error2
331
335
  });
332
336
  }
333
- this.#clientWs.triggerError(err);
334
- this.#actorWs.triggerError(err);
337
+ this.#clientWs.triggerError(error);
338
+ this.#actorWs.triggerError(error);
335
339
  }
336
340
  #close(code, reason) {
337
341
  if (this.#readyState === 3 || this.#readyState === 2) {
@@ -344,8 +348,8 @@ var InlineWebSocketAdapter = class {
344
348
  { code, reason, wasClean: true },
345
349
  this.#wsContext
346
350
  );
347
- } catch (err) {
348
- logger().error({ msg: "error closing websocket", error: err });
351
+ } catch (error) {
352
+ logger().error({ msg: "error closing websocket", error });
349
353
  } finally {
350
354
  this.#readyState = 3;
351
355
  this.#clientWs.triggerClose(code, reason);
@@ -354,9 +358,27 @@ var InlineWebSocketAdapter = class {
354
358
  }
355
359
  };
356
360
 
361
+ // src/registry/index.ts
362
+ import { Hono } from "hono";
363
+
357
364
  // src/common/engine.ts
365
+ var ENGINE_HOST = "127.0.0.1";
358
366
  var ENGINE_PORT = 6420;
359
- var ENGINE_ENDPOINT = `http://127.0.0.1:${ENGINE_PORT}`;
367
+ var ENGINE_ENDPOINT = buildEngineEndpoint(ENGINE_HOST, ENGINE_PORT);
368
+ function buildEngineEndpoint(host, port) {
369
+ const urlHost = host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
370
+ return `http://${urlHost}:${port}`;
371
+ }
372
+ function isLocalEngineEndpoint(endpoint) {
373
+ let url;
374
+ try {
375
+ url = new URL(endpoint);
376
+ } catch {
377
+ return false;
378
+ }
379
+ const hostname = url.hostname.toLowerCase();
380
+ return hostname === "localhost" || hostname === "0.0.0.0" || hostname === "::" || hostname === "[::]" || hostname === "::1" || hostname === "[::1]" || /^127(?:\.\d{1,3}){0,3}$/.test(hostname);
381
+ }
360
382
 
361
383
  // src/registry/log.ts
362
384
  function logger2() {
@@ -371,10 +393,13 @@ function sleep(ms) {
371
393
  }
372
394
  function configureTimeoutMs() {
373
395
  const value = process.env.RIVET_SERVERLESS_CONFIGURE_TIMEOUT_MS;
374
- if (value === void 0 || value === "") return DEFAULT_CONFIGURE_TIMEOUT_MS;
396
+ if (value === void 0 || value === "")
397
+ return DEFAULT_CONFIGURE_TIMEOUT_MS;
375
398
  const parsed = Number(value);
376
399
  if (!Number.isFinite(parsed) || parsed < 0) {
377
- throw new Error("RIVET_SERVERLESS_CONFIGURE_TIMEOUT_MS must be a finite non-negative number");
400
+ throw new Error(
401
+ "RIVET_SERVERLESS_CONFIGURE_TIMEOUT_MS must be a finite non-negative number"
402
+ );
378
403
  }
379
404
  return parsed;
380
405
  }
@@ -388,13 +413,19 @@ async function configureServerlessPool(config) {
388
413
  attempts += 1;
389
414
  try {
390
415
  if (!config.namespace) {
391
- throw new Error("namespace is required for serverless configuration");
416
+ throw new Error(
417
+ "namespace is required for serverless configuration"
418
+ );
392
419
  }
393
420
  if (!config.endpoint) {
394
- throw new Error("endpoint is required for serverless configuration");
421
+ throw new Error(
422
+ "endpoint is required for serverless configuration"
423
+ );
395
424
  }
396
425
  if (!config.configurePool) {
397
- throw new Error("configurePool is required for serverless configuration");
426
+ throw new Error(
427
+ "configurePool is required for serverless configuration"
428
+ );
398
429
  }
399
430
  const customConfig = config.configurePool;
400
431
  const clientConfig = convertRegistryConfigToClientConfig(config);
@@ -450,6 +481,145 @@ async function configureServerlessPool(config) {
450
481
  throw lastError;
451
482
  }
452
483
 
484
+ // src/utils/serve.ts
485
+ import getPort from "get-port";
486
+ var serveStaticLoaderPromises = {};
487
+ async function crossPlatformServe(config, httpPort, app, runtime = detectRuntime()) {
488
+ logger2().debug({ msg: "detected runtime for serve", runtime });
489
+ switch (runtime) {
490
+ case "deno":
491
+ return serveDeno(config, httpPort, app);
492
+ case "bun":
493
+ return serveBun(config, httpPort, app);
494
+ case "node":
495
+ return serveNode(config, httpPort, app);
496
+ default:
497
+ return serveNode(config, httpPort, app);
498
+ }
499
+ }
500
+ async function loadRuntimeServeStatic(runtime) {
501
+ if (!serveStaticLoaderPromises[runtime]) {
502
+ if (runtime === "node") {
503
+ const nodeServeStaticModule = "@hono/node-server/serve-static";
504
+ serveStaticLoaderPromises[runtime] = import(
505
+ /* webpackIgnore: true */
506
+ nodeServeStaticModule
507
+ ).then((x) => x.serveStatic);
508
+ } else if (runtime === "bun") {
509
+ const bunModule = "hono/bun";
510
+ serveStaticLoaderPromises[runtime] = import(
511
+ /* webpackIgnore: true */
512
+ bunModule
513
+ ).then((x) => x.serveStatic);
514
+ } else if (runtime === "deno") {
515
+ const denoModule = "hono/deno";
516
+ serveStaticLoaderPromises[runtime] = import(
517
+ /* webpackIgnore: true */
518
+ denoModule
519
+ ).then((x) => x.serveStatic);
520
+ } else {
521
+ throw new Error(`unsupported runtime: ${runtime}`);
522
+ }
523
+ }
524
+ return await serveStaticLoaderPromises[runtime];
525
+ }
526
+ async function serveNode(config, httpPort, app) {
527
+ const nodeServerModule = "@hono/node-server";
528
+ let serve;
529
+ try {
530
+ const dep = await import(
531
+ /* webpackIgnore: true */
532
+ nodeServerModule
533
+ );
534
+ serve = dep.serve;
535
+ } catch (err) {
536
+ logger2().error({
537
+ msg: "failed to import @hono/node-server. please run 'npm install @hono/node-server @hono/node-ws'",
538
+ error: stringifyError(err)
539
+ });
540
+ process.exit(1);
541
+ }
542
+ const nodeWsModule = "@hono/node-ws";
543
+ let createNodeWebSocket;
544
+ try {
545
+ const dep = await import(
546
+ /* webpackIgnore: true */
547
+ nodeWsModule
548
+ );
549
+ createNodeWebSocket = dep.createNodeWebSocket;
550
+ } catch (err) {
551
+ logger2().error({
552
+ msg: "failed to import @hono/node-ws. please run 'npm install @hono/node-server @hono/node-ws'",
553
+ error: stringifyError(err)
554
+ });
555
+ process.exit(1);
556
+ }
557
+ const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({
558
+ app
559
+ });
560
+ const port = httpPort;
561
+ const hostname = config.httpHost;
562
+ const server = serve(
563
+ { fetch: app.fetch, port, hostname },
564
+ () => logger2().info({ msg: "server listening", port, hostname })
565
+ );
566
+ injectWebSocket(server);
567
+ const closeServer = () => {
568
+ server.close();
569
+ };
570
+ return { upgradeWebSocket, closeServer };
571
+ }
572
+ async function serveDeno(config, httpPort, app) {
573
+ const honoDenoModule = "hono/deno";
574
+ let upgradeWebSocket;
575
+ try {
576
+ const dep = await import(
577
+ /* webpackIgnore: true */
578
+ honoDenoModule
579
+ );
580
+ upgradeWebSocket = dep.upgradeWebSocket;
581
+ } catch (err) {
582
+ logger2().error({
583
+ msg: "failed to import hono/deno",
584
+ error: stringifyError(err)
585
+ });
586
+ process.exit(1);
587
+ }
588
+ const port = httpPort;
589
+ const hostname = config.httpHost;
590
+ Deno.serve({ port, hostname }, app.fetch);
591
+ logger2().info({ msg: "server listening", port, hostname });
592
+ return { upgradeWebSocket };
593
+ }
594
+ async function serveBun(config, httpPort, app) {
595
+ const honoBunModule = "hono/bun";
596
+ let createBunWebSocket;
597
+ try {
598
+ const dep = await import(
599
+ /* webpackIgnore: true */
600
+ honoBunModule
601
+ );
602
+ createBunWebSocket = dep.createBunWebSocket;
603
+ } catch (err) {
604
+ logger2().error({
605
+ msg: "failed to import hono/bun",
606
+ error: stringifyError(err)
607
+ });
608
+ process.exit(1);
609
+ }
610
+ const { websocket, upgradeWebSocket } = createBunWebSocket();
611
+ const port = httpPort;
612
+ const hostname = config.httpHost;
613
+ Bun.serve({
614
+ fetch: app.fetch,
615
+ port,
616
+ hostname,
617
+ websocket
618
+ });
619
+ logger2().info({ msg: "server listening", port, hostname });
620
+ return { upgradeWebSocket };
621
+ }
622
+
453
623
  // src/registry/config/index.ts
454
624
  import { z as z3 } from "zod";
455
625
 
@@ -668,6 +838,18 @@ var RegistryConfigSchema = z3.object({
668
838
  * Starts the full Rust engine process locally.
669
839
  */
670
840
  startEngine: z3.boolean().default(() => getRivetRunEngine()),
841
+ /**
842
+ * @experimental
843
+ *
844
+ * Host to bind the spawned local engine process to.
845
+ */
846
+ engineHost: z3.string().optional().default(() => getRivetRunEngineHost() ?? ENGINE_HOST),
847
+ /**
848
+ * @experimental
849
+ *
850
+ * Port to bind the spawned local engine process to.
851
+ */
852
+ enginePort: z3.number().int().min(1).max(65535).optional().default(() => getRivetRunEnginePort() ?? ENGINE_PORT),
671
853
  /** @experimental */
672
854
  engineVersion: z3.string().optional().default(() => getRivetRunEngineVersion() ?? VERSION),
673
855
  /**
@@ -703,7 +885,7 @@ var RegistryConfigSchema = z3.object({
703
885
  * after calling `CoreRegistry::shutdown()`. Defaults to the
704
886
  * engine-provided actor stop threshold once the envoy connects.
705
887
  *
706
- * Must be >= rivetkit-core's drain timeout (20s) + margin.
888
+ * Must be long enough for rivetkit-core to drain the envoy.
707
889
  */
708
890
  gracePeriodMs: z3.number().int().min(1e3).optional(),
709
891
  /**
@@ -745,7 +927,11 @@ var RegistryConfigSchema = z3.object({
745
927
  message: "configurePool requires either endpoint or startEngine"
746
928
  });
747
929
  }
748
- const endpoint = config.startEngine ? ENGINE_ENDPOINT : (parsedEndpoint == null ? void 0 : parsedEndpoint.endpoint) ?? (isDevEnv ? ENGINE_ENDPOINT : void 0);
930
+ const localEngineEndpoint = buildEngineEndpoint(
931
+ config.engineHost,
932
+ config.enginePort
933
+ );
934
+ const endpoint = config.startEngine ? localEngineEndpoint : (parsedEndpoint == null ? void 0 : parsedEndpoint.endpoint) ?? (isDevEnv ? buildEngineEndpoint(ENGINE_HOST, ENGINE_PORT) : void 0);
749
935
  const validateServerlessEndpoint = Boolean(
750
936
  config.startEngine || parsedEndpoint
751
937
  );
@@ -762,7 +948,7 @@ var RegistryConfigSchema = z3.object({
762
948
  path: ["serverless", "publicEndpoint"]
763
949
  });
764
950
  }
765
- const publicEndpoint = (parsedPublicEndpoint == null ? void 0 : parsedPublicEndpoint.endpoint) ?? (isDevEnv && config.startEngine ? ENGINE_ENDPOINT : void 0);
951
+ const publicEndpoint = (parsedPublicEndpoint == null ? void 0 : parsedPublicEndpoint.endpoint) ?? (isDevEnv && config.startEngine ? endpoint : void 0);
766
952
  const publicNamespace = parsedPublicEndpoint == null ? void 0 : parsedPublicEndpoint.namespace;
767
953
  const publicToken = (parsedPublicEndpoint == null ? void 0 : parsedPublicEndpoint.token) ?? config.serverless.publicToken;
768
954
  return {
@@ -1424,6 +1610,9 @@ var NapiCoreRuntime = class {
1424
1610
  async actorWaitForTrackedShutdownWork(ctx) {
1425
1611
  return await asNativeActorContext(ctx).waitForTrackedShutdownWork();
1426
1612
  }
1613
+ async actorWaitForTrackedShutdownWorkUnbounded(ctx) {
1614
+ await asNativeActorContext(ctx).waitForTrackedShutdownWorkUnbounded();
1615
+ }
1427
1616
  actorKeepAwake(ctx, promise) {
1428
1617
  asNativeActorContext(ctx).keepAwake(promise);
1429
1618
  }
@@ -1535,8 +1724,12 @@ var NapiCoreRuntime = class {
1535
1724
  )
1536
1725
  );
1537
1726
  }
1538
- async actorQueueWaitForNamesAvailable(ctx, names, options) {
1539
- await asNativeActorContext(ctx).queue().waitForNamesAvailable(names, options);
1727
+ async actorQueueWaitForNamesAvailable(ctx, names, options, signal) {
1728
+ await asNativeActorContext(ctx).queue().waitForNamesAvailable(
1729
+ names,
1730
+ options,
1731
+ signal ? asNativeCancellationToken(signal) : signal
1732
+ );
1540
1733
  }
1541
1734
  async actorQueueEnqueueAndWait(ctx, name, body, options, signal) {
1542
1735
  return await asNativeActorContext(ctx).queue().enqueueAndWait(
@@ -1670,20 +1863,18 @@ function validateQueueComplete(schemas, name, response) {
1670
1863
  response
1671
1864
  );
1672
1865
  if (!result.success) {
1673
- throw validationError(`queue \`${name}\` completion response`, result.issues);
1866
+ throw validationError(
1867
+ `queue \`${name}\` completion response`,
1868
+ result.issues
1869
+ );
1674
1870
  }
1675
1871
  return result.data;
1676
1872
  }
1677
1873
  function validationError(target, issues) {
1678
- return new RivetError(
1679
- "actor",
1680
- "validation_error",
1681
- `Invalid ${target}`,
1682
- {
1683
- public: true,
1684
- metadata: { issues }
1685
- }
1686
- );
1874
+ return new RivetError("actor", "validation_error", `Invalid ${target}`, {
1875
+ public: true,
1876
+ metadata: { issues }
1877
+ });
1687
1878
  }
1688
1879
 
1689
1880
  // src/registry/wasm-runtime.ts
@@ -2007,6 +2198,12 @@ var WasmCoreRuntime = class {
2007
2198
  "waitForTrackedShutdownWork"
2008
2199
  );
2009
2200
  }
2201
+ async actorWaitForTrackedShutdownWorkUnbounded(ctx) {
2202
+ await callHandle(
2203
+ asWasmActorContext(ctx),
2204
+ "waitForTrackedShutdownWorkUnbounded"
2205
+ );
2206
+ }
2010
2207
  actorKeepAwake(ctx, promise) {
2011
2208
  const wasmCtx = asWasmActorContext(ctx);
2012
2209
  const regionId = callHandle(wasmCtx, "beginKeepAwake");
@@ -2154,9 +2351,15 @@ var WasmCoreRuntime = class {
2154
2351
  )
2155
2352
  );
2156
2353
  }
2157
- async actorQueueWaitForNamesAvailable(ctx, names, options) {
2354
+ async actorQueueWaitForNamesAvailable(ctx, names, options, signal) {
2158
2355
  const queue2 = childHandle(asWasmActorContext(ctx), "queue");
2159
- await callHandleAsync(queue2, "waitForNamesAvailable", names, options);
2356
+ await callHandleAsync(
2357
+ queue2,
2358
+ "waitForNamesAvailable",
2359
+ names,
2360
+ options,
2361
+ signal
2362
+ );
2160
2363
  }
2161
2364
  async actorQueueEnqueueAndWait(ctx, name, body, options, signal) {
2162
2365
  const queue2 = childHandle(asWasmActorContext(ctx), "queue");
@@ -2248,6 +2451,33 @@ async function loadWasmRuntime(config) {
2248
2451
  };
2249
2452
  }
2250
2453
 
2454
+ // src/registry/native.ts
2455
+ import nodeFs from "fs";
2456
+ import nodePath from "path";
2457
+
2458
+ // src/registry/write-through-proxy.ts
2459
+ import onChange from "@rivetkit/on-change";
2460
+ function createWriteThroughProxy(value, commit, beforeChange) {
2461
+ if (!value || typeof value !== "object") {
2462
+ return value;
2463
+ }
2464
+ return onChange(
2465
+ value,
2466
+ () => {
2467
+ commit(value);
2468
+ },
2469
+ {
2470
+ // Rejection is throw-based: beforeChange throws to prevent the
2471
+ // mutation. We always return true so on-change applies the change
2472
+ // if beforeChange did not throw.
2473
+ onValidate(_path, newValue) {
2474
+ beforeChange == null ? void 0 : beforeChange(newValue);
2475
+ return true;
2476
+ }
2477
+ }
2478
+ );
2479
+ }
2480
+
2251
2481
  // src/registry/native.ts
2252
2482
  var textEncoder = new TextEncoder();
2253
2483
  var textDecoder = new TextDecoder();
@@ -2401,6 +2631,14 @@ function databaseNotConfiguredError() {
2401
2631
  { public: true }
2402
2632
  );
2403
2633
  }
2634
+ function databaseClientNotReadyError() {
2635
+ return new RivetError(
2636
+ "actor",
2637
+ "database_client_not_ready",
2638
+ "actor database client was not initialized before user code ran. this is an internal lifecycle error; the migration callback should have pre-warmed the client. file an issue if you can reproduce.",
2639
+ { public: true }
2640
+ );
2641
+ }
2404
2642
  function stateNotEnabledError() {
2405
2643
  return new RivetError(
2406
2644
  "actor",
@@ -2452,8 +2690,23 @@ function resolveNativeDestroy(runtime, ctx) {
2452
2690
  function clearNativeRuntimeState(runtime, ctx) {
2453
2691
  callNativeSync(() => runtime.actorClearRuntimeState(ctx));
2454
2692
  }
2455
- async function cleanupNativeSleepRuntimeState(runtime, ctx) {
2456
- await runtime.actorWaitForTrackedShutdownWork(ctx);
2693
+ async function cleanupNativeSleepRuntimeState(runtime, ctx, afterTrackedWorkDrained) {
2694
+ const drained = await runtime.actorWaitForTrackedShutdownWork(ctx);
2695
+ if (!drained) {
2696
+ await closeNativeDatabaseClient(runtime, ctx);
2697
+ await closeNativeSqlDatabase(runtime, ctx);
2698
+ void runtime.actorWaitForTrackedShutdownWorkUnbounded(ctx).then(async () => {
2699
+ await (afterTrackedWorkDrained == null ? void 0 : afterTrackedWorkDrained());
2700
+ clearNativeRuntimeState(runtime, ctx);
2701
+ }).catch((error) => {
2702
+ logger2().warn({
2703
+ msg: "deferred native sleep cleanup failed",
2704
+ error: stringifyError(error)
2705
+ });
2706
+ });
2707
+ return;
2708
+ }
2709
+ await (afterTrackedWorkDrained == null ? void 0 : afterTrackedWorkDrained());
2457
2710
  await closeNativeDatabaseClient(runtime, ctx);
2458
2711
  await closeNativeSqlDatabase(runtime, ctx);
2459
2712
  clearNativeRuntimeState(runtime, ctx);
@@ -2558,11 +2811,14 @@ function decodeValue(value) {
2558
2811
  if (!value || value.length === 0) {
2559
2812
  return void 0;
2560
2813
  }
2561
- return decodeCborJsonCompat(value);
2814
+ return decodeCborCompat(value);
2562
2815
  }
2563
2816
  function encodeValue(value) {
2564
2817
  return encodeCborCompat(value);
2565
2818
  }
2819
+ function normalizeArgs(value) {
2820
+ return Array.isArray(value) ? value : value === void 0 || value === null ? [] : [value];
2821
+ }
2566
2822
  function unwrapTsfnPayload(error, payload) {
2567
2823
  if (error !== null && error !== void 0) {
2568
2824
  throw error;
@@ -2618,12 +2874,6 @@ function callNativeSync(invoke) {
2618
2874
  throw normalizeNativeBridgeError(error);
2619
2875
  }
2620
2876
  }
2621
- function actorAbortedError() {
2622
- return Object.assign(new Error("Actor aborted"), {
2623
- group: "actor",
2624
- code: "aborted"
2625
- });
2626
- }
2627
2877
  function isClosedTaskRegistrationError(error) {
2628
2878
  const metadata = error instanceof RivetError ? error.metadata : void 0;
2629
2879
  const metadataError = metadata && typeof metadata === "object" && "error" in metadata ? metadata.error : void 0;
@@ -2756,7 +3006,7 @@ function serializeWorkflowHistoryForJson(data) {
2756
3006
  return null;
2757
3007
  }
2758
3008
  const history = decodeWorkflowHistoryTransport(data);
2759
- return {
3009
+ return jsonSafe({
2760
3010
  nameRegistry: [...history.nameRegistry],
2761
3011
  entries: history.entries.map((entry) => ({
2762
3012
  id: entry.id,
@@ -2780,7 +3030,7 @@ function serializeWorkflowHistoryForJson(data) {
2780
3030
  ]
2781
3031
  )
2782
3032
  )
2783
- };
3033
+ });
2784
3034
  }
2785
3035
  function toHttpJsonCompatible(value) {
2786
3036
  return JSON.parse(
@@ -2831,45 +3081,7 @@ function wrapNativeCallback(callback) {
2831
3081
  }
2832
3082
  function decodeArgs(value) {
2833
3083
  const decoded = decodeValue(value);
2834
- return Array.isArray(decoded) ? decoded : decoded === void 0 ? [] : [decoded];
2835
- }
2836
- function createWriteThroughProxy(value, commit, beforeChange) {
2837
- if (!value || typeof value !== "object") {
2838
- return value;
2839
- }
2840
- const proxies = /* @__PURE__ */ new WeakMap();
2841
- const wrap = (target) => {
2842
- const cached = proxies.get(target);
2843
- if (cached) {
2844
- return cached;
2845
- }
2846
- const proxy = new Proxy(target, {
2847
- get(innerTarget, property, receiver) {
2848
- const result = Reflect.get(innerTarget, property, receiver);
2849
- return result && typeof result === "object" ? wrap(result) : result;
2850
- },
2851
- set(innerTarget, property, nextValue, receiver) {
2852
- beforeChange == null ? void 0 : beforeChange();
2853
- const updated = Reflect.set(
2854
- innerTarget,
2855
- property,
2856
- nextValue,
2857
- receiver
2858
- );
2859
- commit(value);
2860
- return updated;
2861
- },
2862
- deleteProperty(innerTarget, property) {
2863
- beforeChange == null ? void 0 : beforeChange();
2864
- const updated = Reflect.deleteProperty(innerTarget, property);
2865
- commit(value);
2866
- return updated;
2867
- }
2868
- });
2869
- proxies.set(target, proxy);
2870
- return proxy;
2871
- };
2872
- return wrap(value);
3084
+ return normalizeArgs(decoded);
2873
3085
  }
2874
3086
  function buildRequest(init) {
2875
3087
  const url = init.uri.startsWith("http") ? init.uri : new URL(init.uri, "http://127.0.0.1").toString();
@@ -2923,13 +3135,23 @@ var NativeConnAdapter = class {
2923
3135
  decodeValue(this.#runtime.connParams(this.#conn))
2924
3136
  );
2925
3137
  }
3138
+ [RAW_STATE_SYMBOL]() {
3139
+ return this.#readState();
3140
+ }
2926
3141
  get state() {
2927
3142
  const nextState = this.#readState();
2928
- return createWriteThroughProxy(nextState, (nextValue) => {
2929
- this.#writeState(nextValue, { writeNative: true });
2930
- });
3143
+ return createWriteThroughProxy(
3144
+ nextState,
3145
+ (nextValue) => {
3146
+ this.#writeState(nextValue, { writeNative: true });
3147
+ },
3148
+ (newValue) => {
3149
+ assertJsonCompatValue(newValue);
3150
+ }
3151
+ );
2931
3152
  }
2932
3153
  set state(value) {
3154
+ assertJsonCompatValue(value);
2933
3155
  this.#writeState(value, { writeNative: true });
2934
3156
  }
2935
3157
  initializeState(value) {
@@ -3281,44 +3503,23 @@ var NativeQueueAdapter = class {
3281
3503
  }
3282
3504
  }
3283
3505
  async waitForNamesAvailable(names, options) {
3284
- if (!(options == null ? void 0 : options.signal)) {
3506
+ const { token, cleanup } = await createCancellationTokenHandle(
3507
+ this.#runtime,
3508
+ options == null ? void 0 : options.signal
3509
+ );
3510
+ try {
3285
3511
  await callNative(
3286
3512
  () => this.#runtime.actorQueueWaitForNamesAvailable(
3287
3513
  this.#ctx,
3288
3514
  [...names],
3289
3515
  {
3290
3516
  timeoutMs: options == null ? void 0 : options.timeout
3291
- }
3517
+ },
3518
+ token
3292
3519
  )
3293
3520
  );
3294
- return;
3295
- }
3296
- const deadline = options.timeout === void 0 ? void 0 : Date.now() + options.timeout;
3297
- for (; ; ) {
3298
- if (options.signal.aborted) {
3299
- throw actorAbortedError();
3300
- }
3301
- const remainingTimeout = deadline === void 0 ? void 0 : Math.max(0, deadline - Date.now());
3302
- const sliceTimeout = remainingTimeout === void 0 ? 100 : Math.min(remainingTimeout, 100);
3303
- try {
3304
- await callNative(
3305
- () => this.#runtime.actorQueueWaitForNamesAvailable(
3306
- this.#ctx,
3307
- [...names],
3308
- {
3309
- timeoutMs: sliceTimeout
3310
- }
3311
- )
3312
- );
3313
- return;
3314
- } catch (error) {
3315
- if (error.group === "queue" && error.code === "timed_out") {
3316
- if (remainingTimeout === void 0 || remainingTimeout > 100) {
3317
- continue;
3318
- }
3319
- }
3320
- throw error;
3321
- }
3521
+ } finally {
3522
+ cleanup == null ? void 0 : cleanup();
3322
3523
  }
3323
3524
  }
3324
3525
  async enqueueAndWait(name, body, options) {
@@ -3753,6 +3954,68 @@ var TrackedWebSocketHandleAdapter = class {
3753
3954
  return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
3754
3955
  }
3755
3956
  };
3957
+ var NativeConnectionMap = class {
3958
+ #runtime;
3959
+ #ctx;
3960
+ #schemas;
3961
+ constructor(runtime, ctx, schemas) {
3962
+ this.#runtime = runtime;
3963
+ this.#ctx = ctx;
3964
+ this.#schemas = schemas;
3965
+ }
3966
+ #connToAdapter(conn) {
3967
+ return new NativeConnAdapter(
3968
+ this.#runtime,
3969
+ conn,
3970
+ this.#schemas,
3971
+ this.#ctx,
3972
+ (connId) => callNativeSync(
3973
+ () => this.#runtime.actorQueueHibernationRemoval(
3974
+ this.#ctx,
3975
+ connId
3976
+ )
3977
+ )
3978
+ );
3979
+ }
3980
+ get size() {
3981
+ return callNativeSync(() => this.#runtime.actorConns(this.#ctx)).length;
3982
+ }
3983
+ get(key) {
3984
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
3985
+ const conn = conns.find((c) => this.#runtime.connId(c) === key);
3986
+ if (!conn) return void 0;
3987
+ return this.#connToAdapter(conn);
3988
+ }
3989
+ has(key) {
3990
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
3991
+ return conns.some((c) => this.#runtime.connId(c) === key);
3992
+ }
3993
+ keys() {
3994
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
3995
+ return conns.map((c) => this.#runtime.connId(c))[Symbol.iterator]();
3996
+ }
3997
+ values() {
3998
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
3999
+ return conns.map((c) => this.#connToAdapter(c))[Symbol.iterator]();
4000
+ }
4001
+ entries() {
4002
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
4003
+ return conns.map(
4004
+ (c) => [this.#runtime.connId(c), this.#connToAdapter(c)]
4005
+ )[Symbol.iterator]();
4006
+ }
4007
+ forEach(callback, thisArg) {
4008
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
4009
+ for (const conn of conns) {
4010
+ const id = this.#runtime.connId(conn);
4011
+ callback.call(thisArg, this.#connToAdapter(conn), id, this);
4012
+ }
4013
+ }
4014
+ [Symbol.iterator]() {
4015
+ return this.entries();
4016
+ }
4017
+ [Symbol.toStringTag] = "NativeConnectionMap";
4018
+ };
3756
4019
  var ActorContextHandleAdapter = class {
3757
4020
  #runtime;
3758
4021
  #ctx;
@@ -3761,9 +4024,9 @@ var ActorContextHandleAdapter = class {
3761
4024
  #abortSignalCleanup;
3762
4025
  #client;
3763
4026
  #clientFactory;
4027
+ #connMap;
3764
4028
  #databaseProvider;
3765
4029
  #db;
3766
- #dbProxy;
3767
4030
  #dispatchCancelToken;
3768
4031
  #kv;
3769
4032
  #queue;
@@ -3806,30 +4069,22 @@ var ActorContextHandleAdapter = class {
3806
4069
  if (!this.#databaseProvider) {
3807
4070
  throw databaseNotConfiguredError();
3808
4071
  }
3809
- if (!this.#dbProxy) {
3810
- this.#dbProxy = new Proxy(
3811
- {},
3812
- {
3813
- get: (_target, property) => {
3814
- if (property === "then") {
3815
- return void 0;
3816
- }
3817
- return async (...args) => {
3818
- const client = await this.ensureDatabaseClient();
3819
- const value = Reflect.get(
3820
- client,
3821
- property
3822
- );
3823
- if (typeof value !== "function") {
3824
- return value;
3825
- }
3826
- return await value.apply(client, args);
3827
- };
3828
- }
3829
- }
3830
- );
4072
+ if (this.#db) {
4073
+ return this.#db;
3831
4074
  }
3832
- return this.#dbProxy;
4075
+ const runtimeState = getNativeRuntimeState(this.#runtime, this.#ctx);
4076
+ const cachedClient = runtimeState.databaseClient;
4077
+ if (cachedClient) {
4078
+ this.#db = cachedClient.client;
4079
+ return this.#db;
4080
+ }
4081
+ throw databaseClientNotReadyError();
4082
+ }
4083
+ [RAW_STATE_SYMBOL]() {
4084
+ if (!this.#stateEnabled) {
4085
+ throw stateNotEnabledError();
4086
+ }
4087
+ return this.#readState();
3833
4088
  }
3834
4089
  get state() {
3835
4090
  if (!this.#stateEnabled) {
@@ -3844,8 +4099,9 @@ var ActorContextHandleAdapter = class {
3844
4099
  (nextValue) => {
3845
4100
  this.#writeState(nextValue, { scheduleSave: true });
3846
4101
  },
3847
- () => {
4102
+ (newValue) => {
3848
4103
  this.#assertCanMutateState();
4104
+ assertJsonCompatValue(newValue);
3849
4105
  }
3850
4106
  );
3851
4107
  }
@@ -3856,6 +4112,7 @@ var ActorContextHandleAdapter = class {
3856
4112
  throw stateNotEnabledError();
3857
4113
  }
3858
4114
  this.#assertCanMutateState();
4115
+ assertJsonCompatValue(value);
3859
4116
  this.#writeState(value, { scheduleSave: true });
3860
4117
  }
3861
4118
  initializeState(value) {
@@ -3912,25 +4169,14 @@ var ActorContextHandleAdapter = class {
3912
4169
  return callNativeSync(() => this.#runtime.actorRegion(this.#ctx));
3913
4170
  }
3914
4171
  get conns() {
3915
- return new Map(
3916
- callNativeSync(() => this.#runtime.actorConns(this.#ctx)).map(
3917
- (conn) => [
3918
- this.#runtime.connId(conn),
3919
- new NativeConnAdapter(
3920
- this.#runtime,
3921
- conn,
3922
- this.#schemas,
3923
- this.#ctx,
3924
- (connId) => callNativeSync(
3925
- () => this.#runtime.actorQueueHibernationRemoval(
3926
- this.#ctx,
3927
- connId
3928
- )
3929
- )
3930
- )
3931
- ]
3932
- )
3933
- );
4172
+ if (!this.#connMap) {
4173
+ this.#connMap = new NativeConnectionMap(
4174
+ this.#runtime,
4175
+ this.#ctx,
4176
+ this.#schemas
4177
+ );
4178
+ }
4179
+ return this.#connMap;
3934
4180
  }
3935
4181
  get log() {
3936
4182
  return logger2();
@@ -4207,6 +4453,7 @@ var ActorContextHandleAdapter = class {
4207
4453
  return false;
4208
4454
  }
4209
4455
  sleep() {
4456
+ this.#flushStateChange();
4210
4457
  callNativeSync(() => this.#runtime.actorSleep(this.#ctx));
4211
4458
  }
4212
4459
  destroy() {
@@ -4496,9 +4743,62 @@ function buildActorConfig(definition, registryConfig) {
4496
4743
  maxOutgoingMessageSize: registryConfig.maxOutgoingMessageSize,
4497
4744
  preloadMaxWorkflowBytes: options.preloadMaxWorkflowBytes,
4498
4745
  preloadMaxConnectionsBytes: options.preloadMaxConnectionsBytes,
4499
- actions: Object.keys(config.actions ?? {}).sort().map((name) => ({ name }))
4746
+ actions: Object.keys(config.actions ?? {}).sort().map((name) => ({ name })),
4747
+ inspectorTabs: buildInspectorTabs(config.inspector)
4500
4748
  };
4501
4749
  }
4750
+ function buildInspectorTabs(inspector) {
4751
+ if (!inspector || typeof inspector !== "object") return void 0;
4752
+ const tabs = inspector.tabs;
4753
+ if (!Array.isArray(tabs) || tabs.length === 0) return void 0;
4754
+ return tabs.map((raw) => {
4755
+ const entry = raw;
4756
+ if (entry.hidden === true) {
4757
+ return { id: entry.id, hidden: true };
4758
+ }
4759
+ const resolved = entry.source !== void 0 ? nodePath.resolve(entry.source) : void 0;
4760
+ if (resolved !== void 0) {
4761
+ validateInspectorTabSource(entry.id, resolved);
4762
+ }
4763
+ return {
4764
+ id: entry.id,
4765
+ label: entry.label,
4766
+ icon: entry.icon,
4767
+ source: resolved
4768
+ };
4769
+ });
4770
+ }
4771
+ function validateInspectorTabSource(tabId, resolved) {
4772
+ if (resolved === nodePath.parse(resolved).root) {
4773
+ throw new Error(
4774
+ `inspector.tabs[id="${tabId}"].source resolves to the filesystem root (${resolved}). Point it at the tab's own static-asset directory instead.`
4775
+ );
4776
+ }
4777
+ let stat;
4778
+ try {
4779
+ stat = nodeFs.statSync(resolved);
4780
+ } catch (err) {
4781
+ const code = err == null ? void 0 : err.code;
4782
+ if (code === "ENOENT") {
4783
+ throw new Error(
4784
+ `inspector.tabs[id="${tabId}"].source (${resolved}) does not exist.`
4785
+ );
4786
+ }
4787
+ if (code === "EACCES") {
4788
+ throw new Error(
4789
+ `inspector.tabs[id="${tabId}"].source (${resolved}) is not readable (EACCES).`
4790
+ );
4791
+ }
4792
+ throw new Error(
4793
+ `inspector.tabs[id="${tabId}"].source (${resolved}) could not be stat'd: ${(err == null ? void 0 : err.message) ?? err}`
4794
+ );
4795
+ }
4796
+ if (!stat.isDirectory()) {
4797
+ throw new Error(
4798
+ `inspector.tabs[id="${tabId}"].source (${resolved}) must be a directory, got ${stat.isFile() ? "file" : "non-directory"}.`
4799
+ );
4800
+ }
4801
+ }
4502
4802
  function buildNativeFactory(runtime, registryConfig, definition) {
4503
4803
  var _a;
4504
4804
  const config = definition.config;
@@ -4687,6 +4987,10 @@ function buildNativeFactory(runtime, registryConfig, definition) {
4687
4987
  isWorkflowEnabled: getNativeWorkflowInspector(ctx) !== void 0
4688
4988
  });
4689
4989
  } catch (error) {
4990
+ logger2().error({
4991
+ msg: "error replaying workflow history",
4992
+ error
4993
+ });
4690
4994
  return errorResponse(error);
4691
4995
  }
4692
4996
  }
@@ -4827,17 +5131,34 @@ function buildNativeFactory(runtime, registryConfig, definition) {
4827
5131
  );
4828
5132
  }
4829
5133
  const body = await jsRequest.json();
5134
+ if (body.args !== void 0 && body.properties !== void 0) {
5135
+ return jsonResponse(
5136
+ { error: "use either args or properties, not both" },
5137
+ { status: 400 }
5138
+ );
5139
+ }
5140
+ if (body.properties !== void 0 && (body.properties === null || typeof body.properties !== "object" || Array.isArray(body.properties))) {
5141
+ return jsonResponse(
5142
+ { error: "properties must be an object" },
5143
+ { status: 400 }
5144
+ );
5145
+ }
5146
+ const args = body.properties !== void 0 ? [body.properties] : normalizeArgs(body.args);
4830
5147
  try {
4831
5148
  const output = await action(
4832
5149
  actorCtx,
4833
5150
  ...validateActionArgs(
4834
5151
  schemaConfig.actionInputSchemas,
4835
5152
  actionName,
4836
- body.args ?? []
5153
+ args
4837
5154
  )
4838
5155
  );
4839
5156
  return jsonResponse({ output });
4840
5157
  } catch (error) {
5158
+ logger2().error({
5159
+ msg: "Error handling inspector action request",
5160
+ error
5161
+ });
4841
5162
  return errorResponse(error);
4842
5163
  }
4843
5164
  }
@@ -4851,6 +5172,10 @@ function buildNativeFactory(runtime, registryConfig, definition) {
4851
5172
  { status: 404 }
4852
5173
  );
4853
5174
  } catch (error) {
5175
+ logger2().error({
5176
+ msg: "Error handling inspector request",
5177
+ error
5178
+ });
4854
5179
  return errorResponse(error);
4855
5180
  } finally {
4856
5181
  await actorCtx.dispose();
@@ -4973,24 +5298,30 @@ function buildNativeFactory(runtime, registryConfig, definition) {
4973
5298
  async (error, payload) => {
4974
5299
  const { ctx } = unwrapTsfnPayload(error, payload);
4975
5300
  const actorCtx = makeActorCtx(ctx);
5301
+ const saveActorState = async () => {
5302
+ if (runtime.kind === "wasm") {
5303
+ await runtime.actorSaveState(
5304
+ ctx,
5305
+ actorCtx.serializeForTick("save")
5306
+ );
5307
+ } else {
5308
+ await actorCtx.saveState({
5309
+ immediate: true
5310
+ });
5311
+ }
5312
+ };
4976
5313
  try {
4977
5314
  if (onSleep) {
4978
- try {
4979
- await onSleep(actorCtx);
4980
- } finally {
4981
- if (runtime.kind === "wasm") {
4982
- await runtime.actorSaveState(
4983
- ctx,
4984
- actorCtx.serializeForTick("save")
4985
- );
4986
- } else {
4987
- await actorCtx.saveState({ immediate: true });
4988
- }
4989
- }
5315
+ await onSleep(actorCtx);
4990
5316
  }
5317
+ await saveActorState();
4991
5318
  } finally {
4992
5319
  try {
4993
- await cleanupNativeSleepRuntimeState(runtime, ctx);
5320
+ await cleanupNativeSleepRuntimeState(
5321
+ runtime,
5322
+ ctx,
5323
+ saveActorState
5324
+ );
4994
5325
  } finally {
4995
5326
  await actorCtx.dispose();
4996
5327
  }
@@ -5435,10 +5766,17 @@ async function buildServeConfig(config) {
5435
5766
  serverlessValidateEndpoint: config.validateServerlessEndpoint,
5436
5767
  serverlessMaxStartPayloadBytes: config.serverless.maxStartPayloadBytes
5437
5768
  };
5438
- if (config.startEngine) {
5769
+ try {
5439
5770
  const { getEnginePath } = await loadEngineCli();
5440
5771
  serveConfig.engineBinaryPath = getEnginePath();
5772
+ } catch (error) {
5773
+ logger2().warn({
5774
+ msg: "could not resolve a local engine binary; if a local engine must be spawned it will fail with engine.binary_unavailable \u2014 set RIVET_ENGINE_BINARY_PATH or install the @rivetkit/engine-cli platform package",
5775
+ error: stringifyError(error)
5776
+ });
5441
5777
  }
5778
+ serveConfig.engineHost = config.engineHost;
5779
+ serveConfig.enginePort = config.enginePort;
5442
5780
  if ((_a = config.test) == null ? void 0 : _a.enabled) {
5443
5781
  serveConfig.inspectorTestToken = getEnvUniversal("_RIVET_TEST_INSPECTOR_TOKEN") ?? "token";
5444
5782
  }
@@ -5488,6 +5826,7 @@ function finishShutdownSignal(signal) {
5488
5826
  }
5489
5827
  var Registry = class {
5490
5828
  #config;
5829
+ #buildConfiguredRegistry;
5491
5830
  routes;
5492
5831
  get config() {
5493
5832
  return this.#config;
@@ -5503,8 +5842,9 @@ var Registry = class {
5503
5842
  #shutdownInstalled = false;
5504
5843
  #shutdownInFlight = null;
5505
5844
  #signalHandlers = {};
5506
- constructor(config) {
5845
+ constructor(config, deps) {
5507
5846
  this.#config = config;
5847
+ this.#buildConfiguredRegistry = (deps == null ? void 0 : deps.buildConfiguredRegistry) ?? buildConfiguredRegistry;
5508
5848
  this.routes = {
5509
5849
  health: () => this.#healthRoute(),
5510
5850
  metadata: () => this.#metadataRoute(),
@@ -5514,12 +5854,12 @@ var Registry = class {
5514
5854
  #ensureServerlessPoolConfigured(config) {
5515
5855
  if (!config.configurePool) return void 0;
5516
5856
  if (!this.#configureServerlessPoolPromise) {
5517
- this.#configureServerlessPoolPromise = configureServerlessPool(config).catch(
5518
- (error) => {
5519
- this.#configureServerlessPoolPromise = void 0;
5520
- throw error;
5521
- }
5522
- );
5857
+ this.#configureServerlessPoolPromise = configureServerlessPool(
5858
+ config
5859
+ ).catch((error) => {
5860
+ this.#configureServerlessPoolPromise = void 0;
5861
+ throw error;
5862
+ });
5523
5863
  this.#configureServerlessPoolPromise.catch(() => {
5524
5864
  });
5525
5865
  }
@@ -5540,7 +5880,7 @@ var Registry = class {
5540
5880
  const config = this.parseConfig();
5541
5881
  this.#printWelcome(config, "serverless");
5542
5882
  if (!this.#runtimeServerlessPromise) {
5543
- this.#runtimeServerlessPromise = buildConfiguredRegistry(config);
5883
+ this.#runtimeServerlessPromise = this.#buildConfiguredRegistry(config);
5544
5884
  }
5545
5885
  const { runtime, registry, serveConfig } = await this.#runtimeServerlessPromise;
5546
5886
  const isStartRequest = isServerlessStartRequest(
@@ -5555,7 +5895,7 @@ var Registry = class {
5555
5895
  if (isStartRequest) {
5556
5896
  try {
5557
5897
  await this.#ensureServerlessPoolConfigured(config);
5558
- } catch (error) {
5898
+ } catch (_error) {
5559
5899
  return new Response(
5560
5900
  JSON.stringify({
5561
5901
  group: "guard",
@@ -5669,7 +6009,7 @@ var Registry = class {
5669
6009
  if (isMetadataRequest && !isEngineMetadataRequest) {
5670
6010
  try {
5671
6011
  await this.#ensureServerlessPoolConfigured(config);
5672
- } catch (error) {
6012
+ } catch (_error) {
5673
6013
  return new Response(
5674
6014
  JSON.stringify({
5675
6015
  group: "guard",
@@ -5702,6 +6042,33 @@ var Registry = class {
5702
6042
  fetch: (request) => this.handler(request)
5703
6043
  };
5704
6044
  }
6045
+ /**
6046
+ * Starts an HTTP server that dispatches every request through the
6047
+ * serverless handler. Uses `crossPlatformServe` to pick the right
6048
+ * runtime (Node, Bun, Deno).
6049
+ *
6050
+ * @param opts.port Port to listen on. Defaults to 3000.
6051
+ * @param opts.publicDir If set, serves static files from this directory
6052
+ * before falling through to the registry handler.
6053
+ *
6054
+ * @example
6055
+ * ```ts
6056
+ * await registry.listen();
6057
+ * await registry.listen({ port: 8080, publicDir: "./public" });
6058
+ * ```
6059
+ */
6060
+ async listen(opts = {}) {
6061
+ const port = opts.port ?? 3e3;
6062
+ const config = this.parseConfig();
6063
+ const runtime = detectRuntime();
6064
+ const app = new Hono();
6065
+ if (opts.publicDir) {
6066
+ const serveStatic = await loadRuntimeServeStatic(runtime);
6067
+ app.use("*", serveStatic({ root: opts.publicDir }));
6068
+ }
6069
+ app.all("*", (c) => this.handler(c.req.raw));
6070
+ await crossPlatformServe(config, port, app, runtime);
6071
+ }
5705
6072
  /**
5706
6073
  * Returns a health response suitable for mounting in a user-owned router.
5707
6074
  */
@@ -5791,20 +6158,20 @@ var Registry = class {
5791
6158
  */
5792
6159
  #startEnvoy(config, printWelcome) {
5793
6160
  if (!this.#runtimeServePromise) {
5794
- const configuredRegistryPromise = buildConfiguredRegistry(config);
6161
+ const configuredRegistryPromise = this.#buildConfiguredRegistry(config);
5795
6162
  this.#runtimeServeConfiguredPromise = configuredRegistryPromise;
5796
6163
  this.#runtimeServePromise = configuredRegistryPromise.then(async ({ runtime, registry, serveConfig }) => {
5797
6164
  await runtime.serveRegistry(registry, serveConfig);
5798
- }).catch((err) => {
5799
- logger2().warn({ err }, "runtime registry serve errored");
6165
+ }).catch((error) => {
6166
+ logger2().warn({ error }, "runtime registry serve errored");
5800
6167
  });
5801
- this.#installSignalHandlers(config, configuredRegistryPromise);
6168
+ this.#installSignalHandlers(config);
5802
6169
  }
5803
6170
  if (printWelcome) {
5804
6171
  this.#printWelcome(config, "serverful");
5805
6172
  }
5806
6173
  }
5807
- #installSignalHandlers(config, configuredRegistryPromise) {
6174
+ #installSignalHandlers(config) {
5808
6175
  var _a;
5809
6176
  if (this.#shutdownInstalled) return;
5810
6177
  if ((_a = config.shutdown) == null ? void 0 : _a.disableSignalHandlers) return;
@@ -5813,58 +6180,86 @@ var Registry = class {
5813
6180
  }
5814
6181
  this.#shutdownInstalled = true;
5815
6182
  const install = (signal) => {
5816
- const handler = () => this.#onShutdownSignal(
5817
- signal,
5818
- config,
5819
- configuredRegistryPromise
5820
- );
6183
+ const handler = () => this.#onShutdownSignal(signal, config);
5821
6184
  this.#signalHandlers[signal] = handler;
5822
6185
  process.on(signal, handler);
5823
6186
  };
5824
6187
  install("SIGINT");
5825
6188
  install("SIGTERM");
5826
6189
  }
5827
- #onShutdownSignal(signal, config, configuredRegistryPromise) {
6190
+ #onShutdownSignal(signal, config) {
5828
6191
  if (this.#shutdownInFlight !== null) {
5829
6192
  this.#removeSignalHandlers();
5830
6193
  finishShutdownSignal(signal);
5831
6194
  return;
5832
6195
  }
5833
- this.#shutdownInFlight = this.#runShutdown(
5834
- signal,
5835
- config,
5836
- configuredRegistryPromise
5837
- ).catch((err) => {
6196
+ this.#shutdownInFlight = this.#drain(config).catch((err) => {
5838
6197
  logger2().warn({ err }, "shutdown error");
6198
+ }).then(() => {
6199
+ this.#removeSignalHandlers();
6200
+ finishShutdownSignal(signal);
5839
6201
  });
5840
6202
  }
5841
- async #runShutdown(signal, config, configuredRegistryPromise) {
6203
+ /**
6204
+ * Gracefully drains all live registries.
6205
+ *
6206
+ * Programmatic counterpart to the SIGINT/SIGTERM handlers: tears down
6207
+ * every live `CoreRegistry` (both `start()` and `handler()` modes) and
6208
+ * waits for the serve promise to resolve, all bounded by the shutdown
6209
+ * grace period. Unlike a signal-driven shutdown, this does not re-raise a
6210
+ * signal or exit the process. The caller owns process lifetime.
6211
+ *
6212
+ * Idempotent: concurrent or repeated calls share a single drain. Safe to
6213
+ * call even if nothing has been started.
6214
+ *
6215
+ * @example
6216
+ * ```ts
6217
+ * const registry = setup({ use: { counter } });
6218
+ * registry.start();
6219
+ * // ...later, on your own shutdown trigger:
6220
+ * await registry.shutdown();
6221
+ * ```
6222
+ */
6223
+ async shutdown() {
6224
+ if (this.#shutdownInFlight !== null) return this.#shutdownInFlight;
6225
+ const config = this.parseConfig();
6226
+ this.#removeSignalHandlers();
6227
+ this.#shutdownInFlight = this.#drain(config).catch((err) => {
6228
+ logger2().warn({ err }, "shutdown error");
6229
+ });
6230
+ return this.#shutdownInFlight;
6231
+ }
6232
+ async #drain(config) {
5842
6233
  var _a;
5843
- const gracePeriodMs = ((_a = config.shutdown) == null ? void 0 : _a.gracePeriodMs) ?? await this.#actorStopThresholdMs(configuredRegistryPromise) ?? 30 * 60 * 1e3;
6234
+ const modeAPromise = this.#runtimeServeConfiguredPromise;
6235
+ const modeBPromise = this.#runtimeServerlessPromise;
6236
+ const gracePeriodMs = ((_a = config.shutdown) == null ? void 0 : _a.gracePeriodMs) ?? await this.#actorStopThresholdMs(modeAPromise ?? modeBPromise) ?? 30 * 60 * 1e3;
5844
6237
  const drain = async () => {
5845
- const registries = [
5846
- (async () => {
5847
- try {
5848
- const { runtime, registry } = await configuredRegistryPromise;
5849
- await runtime.shutdownRegistry(registry);
5850
- } catch (err) {
5851
- logger2().warn(
5852
- { err },
5853
- "runtime registry shutdown errored (mode A)"
5854
- );
5855
- }
5856
- })()
5857
- ];
5858
- const runtimeServerlessPromise = this.#runtimeServerlessPromise;
5859
- if (runtimeServerlessPromise !== void 0) {
6238
+ const registries = [];
6239
+ if (modeAPromise !== void 0) {
5860
6240
  registries.push(
5861
6241
  (async () => {
5862
6242
  try {
5863
- const { runtime, registry } = await runtimeServerlessPromise;
6243
+ const { runtime, registry } = await modeAPromise;
5864
6244
  await runtime.shutdownRegistry(registry);
5865
6245
  } catch (err) {
5866
6246
  logger2().warn(
5867
6247
  { err },
6248
+ "runtime registry shutdown errored (mode A)"
6249
+ );
6250
+ }
6251
+ })()
6252
+ );
6253
+ }
6254
+ if (modeBPromise !== void 0) {
6255
+ registries.push(
6256
+ (async () => {
6257
+ try {
6258
+ const { runtime, registry } = await modeBPromise;
6259
+ await runtime.shutdownRegistry(registry);
6260
+ } catch (err) {
6261
+ logger2().warn(
6262
+ { error: err },
5868
6263
  "runtime registry shutdown errored (mode B)"
5869
6264
  );
5870
6265
  }
@@ -5886,11 +6281,10 @@ var Registry = class {
5886
6281
  }
5887
6282
  )
5888
6283
  ]);
5889
- this.#removeSignalHandlers();
5890
- finishShutdownSignal(signal);
5891
6284
  }
5892
6285
  async #actorStopThresholdMs(configuredRegistryPromise) {
5893
6286
  var _a;
6287
+ if (configuredRegistryPromise === void 0) return void 0;
5894
6288
  try {
5895
6289
  const { runtime, registry } = await configuredRegistryPromise;
5896
6290
  const thresholdMs = await ((_a = runtime.registryActorStopThresholdMs) == null ? void 0 : _a.call(runtime, registry));
@@ -5944,7 +6338,7 @@ var Registry = class {
5944
6338
  logLine("Namespace", config.namespace);
5945
6339
  }
5946
6340
  if (config.endpoint) {
5947
- const endpointType = config.endpoint === ENGINE_ENDPOINT ? "local native" : "remote";
6341
+ const endpointType = config.startEngine || isLocalEngineEndpoint(config.endpoint) ? "local native" : "remote";
5948
6342
  logLine("Endpoint", `${config.endpoint} (${endpointType})`);
5949
6343
  }
5950
6344
  if (kind === "serverless" && config.publicEndpoint) {