rivetkit 2.3.0-rc.5 → 2.3.0-rc.7

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 (142) hide show
  1. package/dist/browser/client.d.ts +35 -3
  2. package/dist/browser/client.js +795 -200
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.js +4 -3
  5. package/dist/browser/inspector/client.js.map +1 -1
  6. package/dist/tsup/actor/errors.cjs +4 -2
  7. package/dist/tsup/actor/errors.cjs.map +1 -1
  8. package/dist/tsup/actor/errors.d.cts +1 -74
  9. package/dist/tsup/actor/errors.d.ts +1 -74
  10. package/dist/tsup/actor/errors.js +3 -1
  11. package/dist/tsup/agent-os/index.cjs +7 -5
  12. package/dist/tsup/agent-os/index.cjs.map +1 -1
  13. package/dist/tsup/agent-os/index.d.cts +35 -3
  14. package/dist/tsup/agent-os/index.d.ts +35 -3
  15. package/dist/tsup/agent-os/index.js +7 -5
  16. package/dist/tsup/agent-os/index.js.map +1 -1
  17. package/dist/tsup/{chunk-2GANBXVP.cjs → chunk-2H4ISA4Y.cjs} +10 -10
  18. package/dist/tsup/chunk-2H4ISA4Y.cjs.map +1 -0
  19. package/dist/tsup/{chunk-UXTP4EBU.js → chunk-4DJMFOSU.js} +2 -2
  20. package/dist/tsup/{chunk-LDTT6WKJ.js → chunk-4LTY5TOO.js} +132 -4
  21. package/dist/tsup/chunk-4LTY5TOO.js.map +1 -0
  22. package/dist/tsup/{chunk-PGYEMIOE.js → chunk-52TPEKEC.js} +2 -2
  23. package/dist/tsup/{chunk-OVJX4IFY.cjs → chunk-55E7IR6D.cjs} +4 -4
  24. package/dist/tsup/{chunk-OVJX4IFY.cjs.map → chunk-55E7IR6D.cjs.map} +1 -1
  25. package/dist/tsup/{chunk-V3QNBJ7N.cjs → chunk-63WNTDRC.cjs} +31 -10
  26. package/dist/tsup/chunk-63WNTDRC.cjs.map +1 -0
  27. package/dist/tsup/{chunk-SULB574D.js → chunk-CMV6N5OX.js} +3 -3
  28. package/dist/tsup/{chunk-T6YVRM4K.js → chunk-D5G75T7J.js} +3 -1
  29. package/dist/tsup/chunk-D5G75T7J.js.map +1 -0
  30. package/dist/tsup/{chunk-NW2J4SOL.cjs → chunk-FEOG44WH.cjs} +137 -9
  31. package/dist/tsup/chunk-FEOG44WH.cjs.map +1 -0
  32. package/dist/tsup/{chunk-HR547GVH.cjs → chunk-G5HUSWP4.cjs} +8 -8
  33. package/dist/tsup/{chunk-HR547GVH.cjs.map → chunk-G5HUSWP4.cjs.map} +1 -1
  34. package/dist/tsup/{chunk-N2DQSJIW.js → chunk-HERL2VQ2.js} +17 -48
  35. package/dist/tsup/chunk-HERL2VQ2.js.map +1 -0
  36. package/dist/tsup/{chunk-LELRJK66.cjs → chunk-SJLPZEA3.cjs} +3 -3
  37. package/dist/tsup/{chunk-LELRJK66.cjs.map → chunk-SJLPZEA3.cjs.map} +1 -1
  38. package/dist/tsup/{chunk-WQ4HNA4W.cjs → chunk-SRNOPUC6.cjs} +4 -2
  39. package/dist/tsup/chunk-SRNOPUC6.cjs.map +1 -0
  40. package/dist/tsup/{chunk-K34B3OVG.js → chunk-TMLOKTRB.js} +30 -9
  41. package/dist/tsup/chunk-TMLOKTRB.js.map +1 -0
  42. package/dist/tsup/{chunk-NATOT3ET.js → chunk-VFIY6GWO.js} +4 -4
  43. package/dist/tsup/chunk-VFIY6GWO.js.map +1 -0
  44. package/dist/tsup/{chunk-JY73X7VU.js → chunk-VJ4Y4WBT.js} +692 -114
  45. package/dist/tsup/chunk-VJ4Y4WBT.js.map +1 -0
  46. package/dist/tsup/{chunk-JRCZDHXT.cjs → chunk-X6HIFXNK.cjs} +23 -54
  47. package/dist/tsup/chunk-X6HIFXNK.cjs.map +1 -0
  48. package/dist/tsup/{chunk-FTZIZ3JG.cjs → chunk-ZGPX6KAH.cjs} +838 -260
  49. package/dist/tsup/chunk-ZGPX6KAH.cjs.map +1 -0
  50. package/dist/tsup/client/mod.cjs +7 -7
  51. package/dist/tsup/client/mod.d.cts +3 -4
  52. package/dist/tsup/client/mod.d.ts +3 -4
  53. package/dist/tsup/client/mod.js +6 -6
  54. package/dist/tsup/common/log.cjs +3 -3
  55. package/dist/tsup/common/log.js +2 -2
  56. package/dist/tsup/common/websocket.cjs +4 -4
  57. package/dist/tsup/common/websocket.js +3 -3
  58. package/dist/tsup/{config-CvQUtDp9.d.ts → config-Ak1lv4gF.d.ts} +27 -5
  59. package/dist/tsup/{config-C-a9vrke.d.cts → config-DU_xj4qZ.d.cts} +27 -5
  60. package/dist/tsup/{context-A7R0bsZL.d.ts → context-DAAp4Lpg.d.ts} +1 -1
  61. package/dist/tsup/{context-CA3r-pf2.d.cts → context-Dt_L55q8.d.cts} +1 -1
  62. package/dist/tsup/inspector/mod.cjs +6 -6
  63. package/dist/tsup/inspector/mod.js +5 -5
  64. package/dist/tsup/mod.cjs +507 -308
  65. package/dist/tsup/mod.cjs.map +1 -1
  66. package/dist/tsup/mod.d.cts +4 -5
  67. package/dist/tsup/mod.d.ts +4 -5
  68. package/dist/tsup/mod.js +432 -233
  69. package/dist/tsup/mod.js.map +1 -1
  70. package/dist/tsup/process-metrics-NW754INA.js +118 -0
  71. package/dist/tsup/process-metrics-NW754INA.js.map +1 -0
  72. package/dist/tsup/process-metrics-TYAGKCEJ.cjs +118 -0
  73. package/dist/tsup/process-metrics-TYAGKCEJ.cjs.map +1 -0
  74. package/dist/tsup/test/mod.cjs +10 -10
  75. package/dist/tsup/test/mod.d.cts +2 -3
  76. package/dist/tsup/test/mod.d.ts +2 -3
  77. package/dist/tsup/test/mod.js +6 -6
  78. package/dist/tsup/utils-DVekpm4I.d.cts +103 -0
  79. package/dist/tsup/utils-DVekpm4I.d.ts +103 -0
  80. package/dist/tsup/utils.cjs +3 -3
  81. package/dist/tsup/utils.d.cts +1 -1
  82. package/dist/tsup/utils.d.ts +1 -1
  83. package/dist/tsup/utils.js +2 -2
  84. package/dist/tsup/workflow/mod.cjs +41 -16
  85. package/dist/tsup/workflow/mod.cjs.map +1 -1
  86. package/dist/tsup/workflow/mod.d.cts +4 -5
  87. package/dist/tsup/workflow/mod.d.ts +4 -5
  88. package/dist/tsup/workflow/mod.js +35 -10
  89. package/dist/tsup/workflow/mod.js.map +1 -1
  90. package/package.json +11 -10
  91. package/src/actor/config.ts +3 -0
  92. package/src/actor/errors.ts +53 -7
  93. package/src/agent-os/actor/session.ts +2 -2
  94. package/src/client/actor-conn.ts +55 -60
  95. package/src/client/actor-handle.ts +59 -24
  96. package/src/client/errors.ts +2 -1
  97. package/src/client/queue.ts +2 -1
  98. package/src/client/raw-utils.ts +2 -4
  99. package/src/client/utils.ts +32 -4
  100. package/src/common/actor-router-consts.ts +4 -0
  101. package/src/common/bare/generated/client-protocol/v4.ts +599 -0
  102. package/src/common/client-protocol-versioned.ts +125 -18
  103. package/src/common/client-protocol-zod.ts +7 -0
  104. package/src/common/client-protocol.ts +1 -1
  105. package/src/common/database/native-database.test.ts +35 -0
  106. package/src/common/database/native-database.ts +8 -4
  107. package/src/common/encoding.ts +243 -5
  108. package/src/common/inline-websocket-adapter.ts +12 -12
  109. package/src/common/log.ts +1 -0
  110. package/src/common/router.ts +40 -10
  111. package/src/common/utils.ts +9 -200
  112. package/src/drivers/engine/actor-driver.ts +29 -28
  113. package/src/engine-client/actor-websocket-client.ts +2 -1
  114. package/src/engine-client/mod.ts +3 -2
  115. package/src/registry/config/index.ts +3 -5
  116. package/src/registry/index.ts +90 -16
  117. package/src/registry/napi-runtime.ts +15 -0
  118. package/src/registry/native.ts +197 -255
  119. package/src/registry/process-metrics.ts +183 -0
  120. package/src/registry/runtime.ts +4 -0
  121. package/src/registry/wasm-runtime.ts +9 -0
  122. package/src/registry/write-through-proxy.ts +40 -0
  123. package/src/serde.ts +2 -2
  124. package/src/workflow/context.ts +32 -5
  125. package/src/workflow/inspector.ts +2 -1
  126. package/dist/tsup/chunk-2GANBXVP.cjs.map +0 -1
  127. package/dist/tsup/chunk-FTZIZ3JG.cjs.map +0 -1
  128. package/dist/tsup/chunk-JRCZDHXT.cjs.map +0 -1
  129. package/dist/tsup/chunk-JY73X7VU.js.map +0 -1
  130. package/dist/tsup/chunk-K34B3OVG.js.map +0 -1
  131. package/dist/tsup/chunk-LDTT6WKJ.js.map +0 -1
  132. package/dist/tsup/chunk-N2DQSJIW.js.map +0 -1
  133. package/dist/tsup/chunk-NATOT3ET.js.map +0 -1
  134. package/dist/tsup/chunk-NW2J4SOL.cjs.map +0 -1
  135. package/dist/tsup/chunk-T6YVRM4K.js.map +0 -1
  136. package/dist/tsup/chunk-V3QNBJ7N.cjs.map +0 -1
  137. package/dist/tsup/chunk-WQ4HNA4W.cjs.map +0 -1
  138. package/dist/tsup/utils-fwx3o3K9.d.cts +0 -18
  139. package/dist/tsup/utils-fwx3o3K9.d.ts +0 -18
  140. /package/dist/tsup/{chunk-UXTP4EBU.js.map → chunk-4DJMFOSU.js.map} +0 -0
  141. /package/dist/tsup/{chunk-PGYEMIOE.js.map → chunk-52TPEKEC.js.map} +0 -0
  142. /package/dist/tsup/{chunk-SULB574D.js.map → chunk-CMV6N5OX.js.map} +0 -0
package/dist/tsup/mod.js CHANGED
@@ -2,27 +2,24 @@ import {
2
2
  ACTOR_CONTEXT_INTERNAL_SYMBOL,
3
3
  ActorConfigSchema,
4
4
  CONN_STATE_MANAGER_SYMBOL,
5
+ RAW_STATE_SYMBOL,
5
6
  getRunFunction,
6
7
  getRunInspectorConfig,
7
8
  getRunMetadata
8
- } from "./chunk-T6YVRM4K.js";
9
+ } from "./chunk-D5G75T7J.js";
9
10
  import {
10
11
  decodeWorkflowHistoryTransport
11
- } from "./chunk-PGYEMIOE.js";
12
+ } from "./chunk-52TPEKEC.js";
12
13
  import {
13
14
  ALLOWED_PUBLIC_HEADERS,
14
- CURRENT_VERSION,
15
15
  HEADER_CONN_PARAMS,
16
- HEADER_ENCODING,
17
- HTTP_RESPONSE_ERROR_VERSIONED,
18
- HttpResponseErrorSchema,
19
16
  RemoteEngineControlClient,
20
17
  convertRegistryConfigToClientConfig,
21
18
  createClientWithDriver,
22
19
  getDatacenters,
23
20
  tryParseEndpoint,
24
21
  updateRunnerConfig
25
- } from "./chunk-JY73X7VU.js";
22
+ } from "./chunk-VJ4Y4WBT.js";
26
23
  import {
27
24
  KEYS,
28
25
  makePrefixedKey,
@@ -32,18 +29,18 @@ import {
32
29
  workflowStoragePrefix
33
30
  } from "./chunk-3YY5S6TV.js";
34
31
  import {
35
- contentTypeForEncoding,
32
+ assertJsonCompatValue,
36
33
  decodeCborCompat,
37
34
  decodeCborJsonCompat,
38
- encodeCborCompat,
39
- serializeWithEncoding
40
- } from "./chunk-LDTT6WKJ.js";
35
+ encodeCborCompat
36
+ } from "./chunk-4LTY5TOO.js";
41
37
  import "./chunk-PCBNKI2J.js";
42
- import "./chunk-UXTP4EBU.js";
38
+ import "./chunk-4DJMFOSU.js";
43
39
  import {
44
40
  LogLevelSchema,
45
41
  VERSION,
46
42
  deconstructError,
43
+ detectRuntime,
47
44
  getEnvUniversal,
48
45
  getLogger,
49
46
  getNodeEnv,
@@ -63,7 +60,7 @@ import {
63
60
  noopNext,
64
61
  stringifyError,
65
62
  toUint8Array
66
- } from "./chunk-N2DQSJIW.js";
63
+ } from "./chunk-HERL2VQ2.js";
67
64
  import {
68
65
  INTERNAL_ERROR_CODE,
69
66
  RivetError,
@@ -74,7 +71,7 @@ import {
74
71
  isRivetErrorLike,
75
72
  toRivetError,
76
73
  unsupportedFeature
77
- } from "./chunk-K34B3OVG.js";
74
+ } from "./chunk-TMLOKTRB.js";
78
75
 
79
76
  // src/actor/log.ts
80
77
  function loggerWithoutContext() {
@@ -320,24 +317,24 @@ var InlineWebSocketAdapter = class {
320
317
  this.#close(1011, "Internal error during initialization");
321
318
  }
322
319
  }
323
- #handleError(err) {
324
- console.error("INLINE_WEBSOCKET_ADAPTER_ERROR", err);
320
+ #handleError(error) {
321
+ console.error("INLINE_WEBSOCKET_ADAPTER_ERROR", error);
325
322
  logger().error({
326
323
  msg: "error in websocket",
327
- error: err,
328
- errorMessage: err instanceof Error ? err.message : String(err),
329
- stack: err instanceof Error ? err.stack : void 0
324
+ error,
325
+ errorMessage: error instanceof Error ? error.message : String(error),
326
+ stack: error instanceof Error ? error.stack : void 0
330
327
  });
331
328
  try {
332
- this.#handler.onError(err, this.#wsContext);
333
- } catch (handlerErr) {
329
+ this.#handler.onError(error, this.#wsContext);
330
+ } catch (error2) {
334
331
  logger().error({
335
332
  msg: "error in onError handler",
336
- error: handlerErr
333
+ error: error2
337
334
  });
338
335
  }
339
- this.#clientWs.triggerError(err);
340
- this.#actorWs.triggerError(err);
336
+ this.#clientWs.triggerError(error);
337
+ this.#actorWs.triggerError(error);
341
338
  }
342
339
  #close(code, reason) {
343
340
  if (this.#readyState === 3 || this.#readyState === 2) {
@@ -350,8 +347,8 @@ var InlineWebSocketAdapter = class {
350
347
  { code, reason, wasClean: true },
351
348
  this.#wsContext
352
349
  );
353
- } catch (err) {
354
- logger().error({ msg: "error closing websocket", error: err });
350
+ } catch (error) {
351
+ logger().error({ msg: "error closing websocket", error });
355
352
  } finally {
356
353
  this.#readyState = 3;
357
354
  this.#clientWs.triggerClose(code, reason);
@@ -360,6 +357,9 @@ var InlineWebSocketAdapter = class {
360
357
  }
361
358
  };
362
359
 
360
+ // src/registry/index.ts
361
+ import { Hono } from "hono";
362
+
363
363
  // src/common/engine.ts
364
364
  var ENGINE_PORT = 6420;
365
365
  var ENGINE_ENDPOINT = `http://127.0.0.1:${ENGINE_PORT}`;
@@ -456,6 +456,145 @@ async function configureServerlessPool(config) {
456
456
  throw lastError;
457
457
  }
458
458
 
459
+ // src/utils/serve.ts
460
+ import getPort from "get-port";
461
+ var serveStaticLoaderPromises = {};
462
+ async function crossPlatformServe(config, httpPort, app, runtime = detectRuntime()) {
463
+ logger2().debug({ msg: "detected runtime for serve", runtime });
464
+ switch (runtime) {
465
+ case "deno":
466
+ return serveDeno(config, httpPort, app);
467
+ case "bun":
468
+ return serveBun(config, httpPort, app);
469
+ case "node":
470
+ return serveNode(config, httpPort, app);
471
+ default:
472
+ return serveNode(config, httpPort, app);
473
+ }
474
+ }
475
+ async function loadRuntimeServeStatic(runtime) {
476
+ if (!serveStaticLoaderPromises[runtime]) {
477
+ if (runtime === "node") {
478
+ const nodeServeStaticModule = "@hono/node-server/serve-static";
479
+ serveStaticLoaderPromises[runtime] = import(
480
+ /* webpackIgnore: true */
481
+ nodeServeStaticModule
482
+ ).then((x) => x.serveStatic);
483
+ } else if (runtime === "bun") {
484
+ const bunModule = "hono/bun";
485
+ serveStaticLoaderPromises[runtime] = import(
486
+ /* webpackIgnore: true */
487
+ bunModule
488
+ ).then((x) => x.serveStatic);
489
+ } else if (runtime === "deno") {
490
+ const denoModule = "hono/deno";
491
+ serveStaticLoaderPromises[runtime] = import(
492
+ /* webpackIgnore: true */
493
+ denoModule
494
+ ).then((x) => x.serveStatic);
495
+ } else {
496
+ throw new Error(`unsupported runtime: ${runtime}`);
497
+ }
498
+ }
499
+ return await serveStaticLoaderPromises[runtime];
500
+ }
501
+ async function serveNode(config, httpPort, app) {
502
+ const nodeServerModule = "@hono/node-server";
503
+ let serve;
504
+ try {
505
+ const dep = await import(
506
+ /* webpackIgnore: true */
507
+ nodeServerModule
508
+ );
509
+ serve = dep.serve;
510
+ } catch (err) {
511
+ logger2().error({
512
+ msg: "failed to import @hono/node-server. please run 'npm install @hono/node-server @hono/node-ws'",
513
+ error: stringifyError(err)
514
+ });
515
+ process.exit(1);
516
+ }
517
+ const nodeWsModule = "@hono/node-ws";
518
+ let createNodeWebSocket;
519
+ try {
520
+ const dep = await import(
521
+ /* webpackIgnore: true */
522
+ nodeWsModule
523
+ );
524
+ createNodeWebSocket = dep.createNodeWebSocket;
525
+ } catch (err) {
526
+ logger2().error({
527
+ msg: "failed to import @hono/node-ws. please run 'npm install @hono/node-server @hono/node-ws'",
528
+ error: stringifyError(err)
529
+ });
530
+ process.exit(1);
531
+ }
532
+ const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({
533
+ app
534
+ });
535
+ const port = httpPort;
536
+ const hostname = config.httpHost;
537
+ const server = serve(
538
+ { fetch: app.fetch, port, hostname },
539
+ () => logger2().info({ msg: "server listening", port, hostname })
540
+ );
541
+ injectWebSocket(server);
542
+ const closeServer = () => {
543
+ server.close();
544
+ };
545
+ return { upgradeWebSocket, closeServer };
546
+ }
547
+ async function serveDeno(config, httpPort, app) {
548
+ const honoDenoModule = "hono/deno";
549
+ let upgradeWebSocket;
550
+ try {
551
+ const dep = await import(
552
+ /* webpackIgnore: true */
553
+ honoDenoModule
554
+ );
555
+ upgradeWebSocket = dep.upgradeWebSocket;
556
+ } catch (err) {
557
+ logger2().error({
558
+ msg: "failed to import hono/deno",
559
+ error: stringifyError(err)
560
+ });
561
+ process.exit(1);
562
+ }
563
+ const port = httpPort;
564
+ const hostname = config.httpHost;
565
+ Deno.serve({ port, hostname }, app.fetch);
566
+ logger2().info({ msg: "server listening", port, hostname });
567
+ return { upgradeWebSocket };
568
+ }
569
+ async function serveBun(config, httpPort, app) {
570
+ const honoBunModule = "hono/bun";
571
+ let createBunWebSocket;
572
+ try {
573
+ const dep = await import(
574
+ /* webpackIgnore: true */
575
+ honoBunModule
576
+ );
577
+ createBunWebSocket = dep.createBunWebSocket;
578
+ } catch (err) {
579
+ logger2().error({
580
+ msg: "failed to import hono/bun",
581
+ error: stringifyError(err)
582
+ });
583
+ process.exit(1);
584
+ }
585
+ const { websocket, upgradeWebSocket } = createBunWebSocket();
586
+ const port = httpPort;
587
+ const hostname = config.httpHost;
588
+ Bun.serve({
589
+ fetch: app.fetch,
590
+ port,
591
+ hostname,
592
+ websocket
593
+ });
594
+ logger2().info({ msg: "server listening", port, hostname });
595
+ return { upgradeWebSocket };
596
+ }
597
+
459
598
  // src/registry/config/index.ts
460
599
  import { z as z3 } from "zod";
461
600
 
@@ -706,12 +845,12 @@ var RegistryConfigSchema = z3.object({
706
845
  shutdown: z3.object({
707
846
  /**
708
847
  * Wait this many milliseconds for the serve promise to resolve
709
- * after calling `CoreRegistry::shutdown()`. Defaults to 30s,
710
- * matching Kubernetes `terminationGracePeriodSeconds`.
848
+ * after calling `CoreRegistry::shutdown()`. Defaults to the
849
+ * engine-provided actor stop threshold once the envoy connects.
711
850
  *
712
851
  * Must be >= rivetkit-core's drain timeout (20s) + margin.
713
852
  */
714
- gracePeriodMs: z3.number().int().min(1e3).optional().default(3e4),
853
+ gracePeriodMs: z3.number().int().min(1e3).optional(),
715
854
  /**
716
855
  * If true, rivetkit will not install SIGINT/SIGTERM handlers.
717
856
  * Use when the host application owns signal policy and will
@@ -719,7 +858,6 @@ var RegistryConfigSchema = z3.object({
719
858
  */
720
859
  disableSignalHandlers: z3.boolean().optional().default(false)
721
860
  }).optional().default(() => ({
722
- gracePeriodMs: 3e4,
723
861
  disableSignalHandlers: false
724
862
  }))
725
863
  }).transform((config, ctx) => {
@@ -930,7 +1068,8 @@ function shouldAttachNativeKvError(message) {
930
1068
  }
931
1069
  function enrichNativeDatabaseError(database, error) {
932
1070
  var _a;
933
- const bridged = typeof error === "string" ? decodeBridgeRivetError(error) : error instanceof Error ? decodeBridgeRivetError(error.message) : void 0;
1071
+ const bridgeReason = typeof error === "string" ? error : error instanceof Error ? error.message : void 0;
1072
+ const bridged = bridgeReason === void 0 ? void 0 : decodeBridgeRivetError(bridgeReason);
934
1073
  if (bridged) {
935
1074
  throw bridged;
936
1075
  }
@@ -1160,6 +1299,29 @@ function lastInsertRowIdColumnName(sql) {
1160
1299
  return alias;
1161
1300
  }
1162
1301
 
1302
+ // src/registry/write-through-proxy.ts
1303
+ import onChange from "@rivetkit/on-change";
1304
+ function createWriteThroughProxy(value, commit, beforeChange) {
1305
+ if (!value || typeof value !== "object") {
1306
+ return value;
1307
+ }
1308
+ return onChange(
1309
+ value,
1310
+ () => {
1311
+ commit(value);
1312
+ },
1313
+ {
1314
+ // Rejection is throw-based: beforeChange throws to prevent the
1315
+ // mutation. We always return true so on-change applies the change
1316
+ // if beforeChange did not throw.
1317
+ onValidate(_path, newValue) {
1318
+ beforeChange == null ? void 0 : beforeChange(newValue);
1319
+ return true;
1320
+ }
1321
+ }
1322
+ );
1323
+ }
1324
+
1163
1325
  // src/registry/runtime.ts
1164
1326
  function normalizeRuntimeSqlExecuteResult(result) {
1165
1327
  return result;
@@ -1287,6 +1449,9 @@ var NapiCoreRuntime = class {
1287
1449
  envoyActiveActorCount: diagnostics.envoyActiveActorCount
1288
1450
  };
1289
1451
  }
1452
+ async registryActorStopThresholdMs(registry) {
1453
+ return await asNativeRegistry(registry).actorStopThresholdMs() ?? void 0;
1454
+ }
1290
1455
  async handleServerlessRequest(registry, req, onStreamEvent, cancelToken, config) {
1291
1456
  return await asNativeRegistry(registry).handleServerlessRequest(
1292
1457
  { ...req, body: toNapiBuffer(req.body) },
@@ -1407,6 +1572,9 @@ var NapiCoreRuntime = class {
1407
1572
  actorWaitUntil(ctx, promise) {
1408
1573
  asNativeActorContext(ctx).waitUntil(promise);
1409
1574
  }
1575
+ async actorWaitForTrackedShutdownWork(ctx) {
1576
+ return await asNativeActorContext(ctx).waitForTrackedShutdownWork();
1577
+ }
1410
1578
  actorKeepAwake(ctx, promise) {
1411
1579
  asNativeActorContext(ctx).keepAwake(promise);
1412
1580
  }
@@ -1974,6 +2142,12 @@ var WasmCoreRuntime = class {
1974
2142
  actorWaitUntil(ctx, promise) {
1975
2143
  callHandle(asWasmActorContext(ctx), "waitUntil", promise);
1976
2144
  }
2145
+ async actorWaitForTrackedShutdownWork(ctx) {
2146
+ return await callHandle(
2147
+ asWasmActorContext(ctx),
2148
+ "waitForTrackedShutdownWork"
2149
+ );
2150
+ }
1977
2151
  actorKeepAwake(ctx, promise) {
1978
2152
  const wasmCtx = asWasmActorContext(ctx);
1979
2153
  const regionId = callHandle(wasmCtx, "beginKeepAwake");
@@ -2368,6 +2542,14 @@ function databaseNotConfiguredError() {
2368
2542
  { public: true }
2369
2543
  );
2370
2544
  }
2545
+ function databaseClientNotReadyError() {
2546
+ return new RivetError(
2547
+ "actor",
2548
+ "database_client_not_ready",
2549
+ "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.",
2550
+ { public: true }
2551
+ );
2552
+ }
2371
2553
  function stateNotEnabledError() {
2372
2554
  return new RivetError(
2373
2555
  "actor",
@@ -2420,20 +2602,24 @@ function clearNativeRuntimeState(runtime, ctx) {
2420
2602
  callNativeSync(() => runtime.actorClearRuntimeState(ctx));
2421
2603
  }
2422
2604
  async function cleanupNativeSleepRuntimeState(runtime, ctx) {
2605
+ const waitStarted = Date.now();
2606
+ const drained = await runtime.actorWaitForTrackedShutdownWork(ctx);
2607
+ const waitMs = Date.now() - waitStarted;
2608
+ if (drained) {
2609
+ logger2().debug({
2610
+ msg: "sleep cleanup: tracked shutdown work drained",
2611
+ waitMs
2612
+ });
2613
+ } else {
2614
+ logger2().warn({
2615
+ msg: "sleep cleanup: shutdown deadline reached before tracked work drained; closing DB anyway",
2616
+ waitMs
2617
+ });
2618
+ }
2423
2619
  await closeNativeDatabaseClient(runtime, ctx);
2424
2620
  await closeNativeSqlDatabase(runtime, ctx);
2425
2621
  clearNativeRuntimeState(runtime, ctx);
2426
2622
  }
2427
- async function cleanupDeferredNativeSleepRuntimeState(runtime, ctx, runtimeState) {
2428
- runtimeState.deferSleepCleanupUntilKeepAwakeIdle = false;
2429
- const actorCtx = runtimeState.deferredSleepCleanupActorCtx;
2430
- runtimeState.deferredSleepCleanupActorCtx = void 0;
2431
- try {
2432
- await cleanupNativeSleepRuntimeState(runtime, ctx);
2433
- } finally {
2434
- await (actorCtx == null ? void 0 : actorCtx.dispose());
2435
- }
2436
- }
2437
2623
  function closeNativeSqlDatabase(runtime, ctx) {
2438
2624
  const runtimeState = getNativeRuntimeState(runtime, ctx);
2439
2625
  const database = runtimeState.sql;
@@ -2570,27 +2756,7 @@ function isStructuredBridgeError(error) {
2570
2756
  return isRivetErrorLike(error) && "__type" in error && (error.__type === "RivetError" || error.__type === "ActorError");
2571
2757
  }
2572
2758
  function encodeNativeCallbackError(error) {
2573
- const structuredError = isStructuredBridgeError(error) ? error : deconstructError(error, logger2(), {
2574
- bridge: "native_callback"
2575
- });
2576
- let stack;
2577
- if (error instanceof Error) {
2578
- try {
2579
- stack = error.stack;
2580
- } catch {
2581
- stack = void 0;
2582
- }
2583
- }
2584
- logger2().warn({
2585
- msg: "native callback error encoded for bridge",
2586
- group: structuredError.group,
2587
- code: structuredError.code,
2588
- message: structuredError.message,
2589
- metadata: structuredError.metadata,
2590
- originalError: stringifyError(error),
2591
- stack,
2592
- bridge: "native_callback"
2593
- });
2759
+ const structuredError = isStructuredBridgeError(error) ? error : deconstructError(error, true);
2594
2760
  const bridgeError = new Error(encodeBridgeRivetError(structuredError), {
2595
2761
  cause: error instanceof Error ? error : void 0
2596
2762
  });
@@ -2829,44 +2995,6 @@ function decodeArgs(value) {
2829
2995
  const decoded = decodeValue(value);
2830
2996
  return Array.isArray(decoded) ? decoded : decoded === void 0 ? [] : [decoded];
2831
2997
  }
2832
- function createWriteThroughProxy(value, commit, beforeChange) {
2833
- if (!value || typeof value !== "object") {
2834
- return value;
2835
- }
2836
- const proxies = /* @__PURE__ */ new WeakMap();
2837
- const wrap = (target) => {
2838
- const cached = proxies.get(target);
2839
- if (cached) {
2840
- return cached;
2841
- }
2842
- const proxy = new Proxy(target, {
2843
- get(innerTarget, property, receiver) {
2844
- const result = Reflect.get(innerTarget, property, receiver);
2845
- return result && typeof result === "object" ? wrap(result) : result;
2846
- },
2847
- set(innerTarget, property, nextValue, receiver) {
2848
- beforeChange == null ? void 0 : beforeChange();
2849
- const updated = Reflect.set(
2850
- innerTarget,
2851
- property,
2852
- nextValue,
2853
- receiver
2854
- );
2855
- commit(value);
2856
- return updated;
2857
- },
2858
- deleteProperty(innerTarget, property) {
2859
- beforeChange == null ? void 0 : beforeChange();
2860
- const updated = Reflect.deleteProperty(innerTarget, property);
2861
- commit(value);
2862
- return updated;
2863
- }
2864
- });
2865
- proxies.set(target, proxy);
2866
- return proxy;
2867
- };
2868
- return wrap(value);
2869
- }
2870
2998
  function buildRequest(init) {
2871
2999
  const url = init.uri.startsWith("http") ? init.uri : new URL(init.uri, "http://127.0.0.1").toString();
2872
3000
  const body = init.body && init.body.length > 0 ? runtimeBytesToArrayBuffer(init.body) : void 0;
@@ -2919,13 +3047,19 @@ var NativeConnAdapter = class {
2919
3047
  decodeValue(this.#runtime.connParams(this.#conn))
2920
3048
  );
2921
3049
  }
3050
+ [RAW_STATE_SYMBOL]() {
3051
+ return this.#readState();
3052
+ }
2922
3053
  get state() {
2923
3054
  const nextState = this.#readState();
2924
3055
  return createWriteThroughProxy(nextState, (nextValue) => {
2925
3056
  this.#writeState(nextValue, { writeNative: true });
3057
+ }, (newValue) => {
3058
+ assertJsonCompatValue(newValue);
2926
3059
  });
2927
3060
  }
2928
3061
  set state(value) {
3062
+ assertJsonCompatValue(value);
2929
3063
  this.#writeState(value, { writeNative: true });
2930
3064
  }
2931
3065
  initializeState(value) {
@@ -3749,6 +3883,70 @@ var TrackedWebSocketHandleAdapter = class {
3749
3883
  return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
3750
3884
  }
3751
3885
  };
3886
+ var NativeConnectionMap = class {
3887
+ #runtime;
3888
+ #ctx;
3889
+ #schemas;
3890
+ constructor(runtime, ctx, schemas) {
3891
+ this.#runtime = runtime;
3892
+ this.#ctx = ctx;
3893
+ this.#schemas = schemas;
3894
+ }
3895
+ #connToAdapter(conn) {
3896
+ return new NativeConnAdapter(
3897
+ this.#runtime,
3898
+ conn,
3899
+ this.#schemas,
3900
+ this.#ctx,
3901
+ (connId) => callNativeSync(
3902
+ () => this.#runtime.actorQueueHibernationRemoval(
3903
+ this.#ctx,
3904
+ connId
3905
+ )
3906
+ )
3907
+ );
3908
+ }
3909
+ get size() {
3910
+ return callNativeSync(() => this.#runtime.actorConns(this.#ctx)).length;
3911
+ }
3912
+ get(key) {
3913
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
3914
+ const conn = conns.find(
3915
+ (c) => this.#runtime.connId(c) === key
3916
+ );
3917
+ if (!conn) return void 0;
3918
+ return this.#connToAdapter(conn);
3919
+ }
3920
+ has(key) {
3921
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
3922
+ return conns.some((c) => this.#runtime.connId(c) === key);
3923
+ }
3924
+ keys() {
3925
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
3926
+ return conns.map((c) => this.#runtime.connId(c))[Symbol.iterator]();
3927
+ }
3928
+ values() {
3929
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
3930
+ return conns.map((c) => this.#connToAdapter(c))[Symbol.iterator]();
3931
+ }
3932
+ entries() {
3933
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
3934
+ return conns.map(
3935
+ (c) => [this.#runtime.connId(c), this.#connToAdapter(c)]
3936
+ )[Symbol.iterator]();
3937
+ }
3938
+ forEach(callback, thisArg) {
3939
+ const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
3940
+ for (const conn of conns) {
3941
+ const id = this.#runtime.connId(conn);
3942
+ callback.call(thisArg, this.#connToAdapter(conn), id, this);
3943
+ }
3944
+ }
3945
+ [Symbol.iterator]() {
3946
+ return this.entries();
3947
+ }
3948
+ [Symbol.toStringTag] = "NativeConnectionMap";
3949
+ };
3752
3950
  var ActorContextHandleAdapter = class {
3753
3951
  #runtime;
3754
3952
  #ctx;
@@ -3757,9 +3955,9 @@ var ActorContextHandleAdapter = class {
3757
3955
  #abortSignalCleanup;
3758
3956
  #client;
3759
3957
  #clientFactory;
3958
+ #connMap;
3760
3959
  #databaseProvider;
3761
3960
  #db;
3762
- #dbProxy;
3763
3961
  #dispatchCancelToken;
3764
3962
  #kv;
3765
3963
  #queue;
@@ -3802,30 +4000,22 @@ var ActorContextHandleAdapter = class {
3802
4000
  if (!this.#databaseProvider) {
3803
4001
  throw databaseNotConfiguredError();
3804
4002
  }
3805
- if (!this.#dbProxy) {
3806
- this.#dbProxy = new Proxy(
3807
- {},
3808
- {
3809
- get: (_target, property) => {
3810
- if (property === "then") {
3811
- return void 0;
3812
- }
3813
- return async (...args) => {
3814
- const client = await this.ensureDatabaseClient();
3815
- const value = Reflect.get(
3816
- client,
3817
- property
3818
- );
3819
- if (typeof value !== "function") {
3820
- return value;
3821
- }
3822
- return await value.apply(client, args);
3823
- };
3824
- }
3825
- }
3826
- );
4003
+ if (this.#db) {
4004
+ return this.#db;
3827
4005
  }
3828
- return this.#dbProxy;
4006
+ const runtimeState = getNativeRuntimeState(this.#runtime, this.#ctx);
4007
+ const cachedClient = runtimeState.databaseClient;
4008
+ if (cachedClient) {
4009
+ this.#db = cachedClient.client;
4010
+ return this.#db;
4011
+ }
4012
+ throw databaseClientNotReadyError();
4013
+ }
4014
+ [RAW_STATE_SYMBOL]() {
4015
+ if (!this.#stateEnabled) {
4016
+ throw stateNotEnabledError();
4017
+ }
4018
+ return this.#readState();
3829
4019
  }
3830
4020
  get state() {
3831
4021
  if (!this.#stateEnabled) {
@@ -3837,8 +4027,9 @@ var ActorContextHandleAdapter = class {
3837
4027
  (nextValue) => {
3838
4028
  this.#writeState(nextValue, { scheduleSave: true });
3839
4029
  },
3840
- () => {
4030
+ (newValue) => {
3841
4031
  this.#assertCanMutateState();
4032
+ assertJsonCompatValue(newValue);
3842
4033
  }
3843
4034
  );
3844
4035
  }
@@ -3847,6 +4038,7 @@ var ActorContextHandleAdapter = class {
3847
4038
  throw stateNotEnabledError();
3848
4039
  }
3849
4040
  this.#assertCanMutateState();
4041
+ assertJsonCompatValue(value);
3850
4042
  this.#writeState(value, { scheduleSave: true });
3851
4043
  }
3852
4044
  initializeState(value) {
@@ -3903,25 +4095,10 @@ var ActorContextHandleAdapter = class {
3903
4095
  return callNativeSync(() => this.#runtime.actorRegion(this.#ctx));
3904
4096
  }
3905
4097
  get conns() {
3906
- return new Map(
3907
- callNativeSync(() => this.#runtime.actorConns(this.#ctx)).map(
3908
- (conn) => [
3909
- this.#runtime.connId(conn),
3910
- new NativeConnAdapter(
3911
- this.#runtime,
3912
- conn,
3913
- this.#schemas,
3914
- this.#ctx,
3915
- (connId) => callNativeSync(
3916
- () => this.#runtime.actorQueueHibernationRemoval(
3917
- this.#ctx,
3918
- connId
3919
- )
3920
- )
3921
- )
3922
- ]
3923
- )
3924
- );
4098
+ if (!this.#connMap) {
4099
+ this.#connMap = new NativeConnectionMap(this.#runtime, this.#ctx, this.#schemas);
4100
+ }
4101
+ return this.#connMap;
3925
4102
  }
3926
4103
  get log() {
3927
4104
  return logger2();
@@ -4119,43 +4296,39 @@ var ActorContextHandleAdapter = class {
4119
4296
  });
4120
4297
  }
4121
4298
  keepAwake(promise) {
4122
- const runtimeState = getNativeRuntimeState(this.#runtime, this.#ctx);
4123
- runtimeState.keepAwakeCount = (runtimeState.keepAwakeCount ?? 0) + 1;
4124
- let registered = false;
4125
- const trackedPromise = Promise.resolve(promise).catch((error) => {
4126
- logger2().warn({
4127
- msg: "keepAwake promise rejected",
4128
- error: stringifyError(error)
4129
- });
4130
- }).finally(async () => {
4131
- if (!registered) {
4132
- return;
4133
- }
4134
- runtimeState.keepAwakeCount = Math.max(
4135
- (runtimeState.keepAwakeCount ?? 1) - 1,
4136
- 0
4137
- );
4138
- if (runtimeState.keepAwakeCount === 0 && runtimeState.deferSleepCleanupUntilKeepAwakeIdle) {
4139
- await cleanupDeferredNativeSleepRuntimeState(
4140
- this.#runtime,
4141
- this.#ctx,
4142
- runtimeState
4143
- );
4299
+ const startedAt = Date.now();
4300
+ logger2().debug({
4301
+ msg: "keepAwake registered",
4302
+ at: startedAt
4303
+ });
4304
+ const trackedPromise = Promise.resolve(promise).then(
4305
+ () => {
4306
+ logger2().debug({
4307
+ msg: "keepAwake promise resolved",
4308
+ durationMs: Date.now() - startedAt
4309
+ });
4310
+ },
4311
+ (error) => {
4312
+ logger2().warn({
4313
+ msg: "keepAwake promise rejected",
4314
+ durationMs: Date.now() - startedAt,
4315
+ error: stringifyError(error)
4316
+ });
4144
4317
  }
4145
- }).then(() => null);
4318
+ ).then(() => null);
4146
4319
  try {
4147
4320
  callNativeSync(
4148
4321
  () => this.#runtime.actorKeepAwake(this.#ctx, trackedPromise)
4149
4322
  );
4150
- registered = true;
4151
4323
  } catch (error) {
4152
- runtimeState.keepAwakeCount = Math.max(
4153
- (runtimeState.keepAwakeCount ?? 1) - 1,
4154
- 0
4155
- );
4156
- if (!isClosedTaskRegistrationError(error)) {
4157
- throw error;
4324
+ if (isClosedTaskRegistrationError(error)) {
4325
+ logger2().warn({
4326
+ msg: "keepAwake registration dropped (teardown already started); promise will not delay grace",
4327
+ error: stringifyError(error)
4328
+ });
4329
+ return promise;
4158
4330
  }
4331
+ throw error;
4159
4332
  }
4160
4333
  return promise;
4161
4334
  }
@@ -4459,39 +4632,6 @@ function withConnContext(runtime, ctx, conn, clientFactory, schemas = {}, databa
4459
4632
  }
4460
4633
  );
4461
4634
  }
4462
- function buildNativeRequestErrorResponse(encoding, path, error) {
4463
- const { statusCode, group, code, message, metadata } = deconstructError(
4464
- error,
4465
- logger2(),
4466
- {
4467
- path,
4468
- runtime: "native"
4469
- },
4470
- false
4471
- );
4472
- const body = serializeWithEncoding(
4473
- encoding,
4474
- { group, code, message, metadata },
4475
- HTTP_RESPONSE_ERROR_VERSIONED,
4476
- CURRENT_VERSION,
4477
- HttpResponseErrorSchema,
4478
- (value) => value,
4479
- (value) => ({
4480
- group: value.group,
4481
- code: value.code,
4482
- message: value.message,
4483
- metadata: value.metadata === void 0 ? null : runtimeBytesToArrayBuffer(
4484
- encodeCborCompat(value.metadata)
4485
- )
4486
- })
4487
- );
4488
- return new Response(body, {
4489
- status: statusCode,
4490
- headers: {
4491
- "Content-Type": contentTypeForEncoding(encoding)
4492
- }
4493
- });
4494
- }
4495
4635
  function buildActorConfig(definition, registryConfig) {
4496
4636
  const config = definition.config;
4497
4637
  const options = config.options ?? {};
@@ -4712,6 +4852,10 @@ function buildNativeFactory(runtime, registryConfig, definition) {
4712
4852
  isWorkflowEnabled: getNativeWorkflowInspector(ctx) !== void 0
4713
4853
  });
4714
4854
  } catch (error) {
4855
+ logger2().error({
4856
+ msg: "error replaying workflow history",
4857
+ error
4858
+ });
4715
4859
  return errorResponse(error);
4716
4860
  }
4717
4861
  }
@@ -4863,6 +5007,10 @@ function buildNativeFactory(runtime, registryConfig, definition) {
4863
5007
  );
4864
5008
  return jsonResponse({ output });
4865
5009
  } catch (error) {
5010
+ logger2().error({
5011
+ msg: "Error handling inspector action request",
5012
+ error
5013
+ });
4866
5014
  return errorResponse(error);
4867
5015
  }
4868
5016
  }
@@ -4876,6 +5024,10 @@ function buildNativeFactory(runtime, registryConfig, definition) {
4876
5024
  { status: 404 }
4877
5025
  );
4878
5026
  } catch (error) {
5027
+ logger2().error({
5028
+ msg: "Error handling inspector request",
5029
+ error
5030
+ });
4879
5031
  return errorResponse(error);
4880
5032
  } finally {
4881
5033
  await actorCtx.dispose();
@@ -5014,12 +5166,9 @@ function buildNativeFactory(runtime, registryConfig, definition) {
5014
5166
  }
5015
5167
  }
5016
5168
  } finally {
5017
- const runtimeState = getNativeRuntimeState(runtime, ctx);
5018
- if ((runtimeState.keepAwakeCount ?? 0) > 0) {
5019
- runtimeState.deferSleepCleanupUntilKeepAwakeIdle = true;
5020
- runtimeState.deferredSleepCleanupActorCtx = actorCtx;
5021
- } else {
5169
+ try {
5022
5170
  await cleanupNativeSleepRuntimeState(runtime, ctx);
5171
+ } finally {
5023
5172
  await actorCtx.dispose();
5024
5173
  }
5025
5174
  }
@@ -5260,17 +5409,6 @@ function buildNativeFactory(runtime, registryConfig, definition) {
5260
5409
  );
5261
5410
  }
5262
5411
  return await toRuntimeHttpResponse(response);
5263
- } catch (error2) {
5264
- const encodingHeader = jsRequest.headers.get(HEADER_ENCODING);
5265
- const encoding = encodingHeader === "cbor" || encodingHeader === "bare" ? encodingHeader : "json";
5266
- const path = new URL(jsRequest.url).pathname;
5267
- return await toRuntimeHttpResponse(
5268
- buildNativeRequestErrorResponse(
5269
- encoding,
5270
- path,
5271
- error2
5272
- )
5273
- );
5274
5412
  } finally {
5275
5413
  await (requestCtx == null ? void 0 : requestCtx.dispose());
5276
5414
  if (conn) {
@@ -5504,6 +5642,10 @@ async function buildRegistryWithRuntime(config, runtime) {
5504
5642
  }
5505
5643
  async function buildConfiguredRegistry(config) {
5506
5644
  const runtime = await loadConfiguredRuntime(config);
5645
+ if (runtime.kind === "napi") {
5646
+ const { startProcessMetrics } = await import("./process-metrics-NW754INA.js");
5647
+ startProcessMetrics();
5648
+ }
5507
5649
  return buildRegistryWithRuntime(
5508
5650
  normalizeRuntimeConfig(config, runtime),
5509
5651
  runtime
@@ -5511,6 +5653,20 @@ async function buildConfiguredRegistry(config) {
5511
5653
  }
5512
5654
 
5513
5655
  // src/registry/index.ts
5656
+ function signalExitCode(signal) {
5657
+ switch (signal) {
5658
+ case "SIGINT":
5659
+ return 130;
5660
+ case "SIGTERM":
5661
+ return 143;
5662
+ }
5663
+ }
5664
+ function finishShutdownSignal(signal) {
5665
+ if (process.pid === 1) {
5666
+ process.exit(signalExitCode(signal));
5667
+ }
5668
+ process.kill(process.pid, signal);
5669
+ }
5514
5670
  var Registry = class {
5515
5671
  #config;
5516
5672
  get config() {
@@ -5721,6 +5877,33 @@ var Registry = class {
5721
5877
  fetch: (request) => this.handler(request)
5722
5878
  };
5723
5879
  }
5880
+ /**
5881
+ * Starts an HTTP server that dispatches every request through the
5882
+ * serverless handler. Uses `crossPlatformServe` to pick the right
5883
+ * runtime (Node, Bun, Deno).
5884
+ *
5885
+ * @param opts.port Port to listen on. Defaults to 3000.
5886
+ * @param opts.publicDir If set, serves static files from this directory
5887
+ * before falling through to the registry handler.
5888
+ *
5889
+ * @example
5890
+ * ```ts
5891
+ * await registry.listen();
5892
+ * await registry.listen({ port: 8080, publicDir: "./public" });
5893
+ * ```
5894
+ */
5895
+ async listen(opts = {}) {
5896
+ const port = opts.port ?? 3e3;
5897
+ const config = this.parseConfig();
5898
+ const runtime = detectRuntime();
5899
+ const app = new Hono();
5900
+ if (opts.publicDir) {
5901
+ const serveStatic = await loadRuntimeServeStatic(runtime);
5902
+ app.use("*", serveStatic({ root: opts.publicDir }));
5903
+ }
5904
+ app.all("*", (c) => this.handler(c.req.raw));
5905
+ await crossPlatformServe(config, port, app, runtime);
5906
+ }
5724
5907
  async diagnostics() {
5725
5908
  var _a;
5726
5909
  const candidates = [
@@ -5745,8 +5928,8 @@ var Registry = class {
5745
5928
  this.#runtimeServeConfiguredPromise = configuredRegistryPromise;
5746
5929
  this.#runtimeServePromise = configuredRegistryPromise.then(async ({ runtime, registry, serveConfig }) => {
5747
5930
  await runtime.serveRegistry(registry, serveConfig);
5748
- }).catch((err) => {
5749
- logger2().warn({ err }, "runtime registry serve errored");
5931
+ }).catch((error) => {
5932
+ logger2().warn({ error }, "runtime registry serve errored");
5750
5933
  });
5751
5934
  this.#installSignalHandlers(config, configuredRegistryPromise);
5752
5935
  }
@@ -5777,29 +5960,29 @@ var Registry = class {
5777
5960
  #onShutdownSignal(signal, config, configuredRegistryPromise) {
5778
5961
  if (this.#shutdownInFlight !== null) {
5779
5962
  this.#removeSignalHandlers();
5780
- process.kill(process.pid, signal);
5963
+ finishShutdownSignal(signal);
5781
5964
  return;
5782
5965
  }
5783
5966
  this.#shutdownInFlight = this.#runShutdown(
5784
5967
  signal,
5785
5968
  config,
5786
5969
  configuredRegistryPromise
5787
- ).catch((err) => {
5788
- logger2().warn({ err }, "shutdown error");
5970
+ ).catch((error) => {
5971
+ logger2().warn({ error }, "shutdown error");
5789
5972
  });
5790
5973
  }
5791
5974
  async #runShutdown(signal, config, configuredRegistryPromise) {
5792
5975
  var _a;
5793
- const gracePeriodMs = ((_a = config.shutdown) == null ? void 0 : _a.gracePeriodMs) ?? 3e4;
5976
+ const gracePeriodMs = ((_a = config.shutdown) == null ? void 0 : _a.gracePeriodMs) ?? await this.#actorStopThresholdMs(configuredRegistryPromise) ?? 30 * 60 * 1e3;
5794
5977
  const drain = async () => {
5795
5978
  const registries = [
5796
5979
  (async () => {
5797
5980
  try {
5798
5981
  const { runtime, registry } = await configuredRegistryPromise;
5799
5982
  await runtime.shutdownRegistry(registry);
5800
- } catch (err) {
5983
+ } catch (error) {
5801
5984
  logger2().warn(
5802
- { err },
5985
+ { error },
5803
5986
  "runtime registry shutdown errored (mode A)"
5804
5987
  );
5805
5988
  }
@@ -5814,7 +5997,7 @@ var Registry = class {
5814
5997
  await runtime.shutdownRegistry(registry);
5815
5998
  } catch (err) {
5816
5999
  logger2().warn(
5817
- { err },
6000
+ { error: err },
5818
6001
  "runtime registry shutdown errored (mode B)"
5819
6002
  );
5820
6003
  }
@@ -5837,7 +6020,23 @@ var Registry = class {
5837
6020
  )
5838
6021
  ]);
5839
6022
  this.#removeSignalHandlers();
5840
- process.kill(process.pid, signal);
6023
+ finishShutdownSignal(signal);
6024
+ }
6025
+ async #actorStopThresholdMs(configuredRegistryPromise) {
6026
+ var _a;
6027
+ try {
6028
+ const { runtime, registry } = await configuredRegistryPromise;
6029
+ const thresholdMs = await ((_a = runtime.registryActorStopThresholdMs) == null ? void 0 : _a.call(runtime, registry));
6030
+ if (thresholdMs !== void 0 && Number.isFinite(thresholdMs) && thresholdMs > 0) {
6031
+ return thresholdMs;
6032
+ }
6033
+ } catch (err) {
6034
+ logger2().warn(
6035
+ { err },
6036
+ "failed to read actor stop threshold for shutdown grace"
6037
+ );
6038
+ }
6039
+ return void 0;
5841
6040
  }
5842
6041
  #removeSignalHandlers() {
5843
6042
  for (const [signal, handler] of Object.entries(