rivetkit 2.3.0-rc.6 → 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 (122) hide show
  1. package/dist/browser/client.d.ts +37 -8
  2. package/dist/browser/client.js +64 -34
  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 +2 -2
  7. package/dist/tsup/actor/errors.js +1 -1
  8. package/dist/tsup/agent-os/index.cjs +7 -5
  9. package/dist/tsup/agent-os/index.cjs.map +1 -1
  10. package/dist/tsup/agent-os/index.d.cts +26 -5
  11. package/dist/tsup/agent-os/index.d.ts +26 -5
  12. package/dist/tsup/agent-os/index.js +7 -5
  13. package/dist/tsup/agent-os/index.js.map +1 -1
  14. package/dist/tsup/{chunk-2G64KSZQ.cjs → chunk-2H4ISA4Y.cjs} +10 -10
  15. package/dist/tsup/chunk-2H4ISA4Y.cjs.map +1 -0
  16. package/dist/tsup/{chunk-ZI5QJMKO.js → chunk-4DJMFOSU.js} +2 -2
  17. package/dist/tsup/{chunk-RTC2AZGB.js → chunk-4LTY5TOO.js} +132 -4
  18. package/dist/tsup/chunk-4LTY5TOO.js.map +1 -0
  19. package/dist/tsup/{chunk-DEO7MMWQ.js → chunk-52TPEKEC.js} +2 -2
  20. package/dist/tsup/{chunk-HTR4YLNT.cjs → chunk-55E7IR6D.cjs} +4 -4
  21. package/dist/tsup/{chunk-HTR4YLNT.cjs.map → chunk-55E7IR6D.cjs.map} +1 -1
  22. package/dist/tsup/{chunk-QAZLM4WT.cjs → chunk-63WNTDRC.cjs} +3 -3
  23. package/dist/tsup/{chunk-QAZLM4WT.cjs.map → chunk-63WNTDRC.cjs.map} +1 -1
  24. package/dist/tsup/{chunk-EMO6E3PJ.js → chunk-CMV6N5OX.js} +3 -3
  25. package/dist/tsup/{chunk-T6YVRM4K.js → chunk-D5G75T7J.js} +3 -1
  26. package/dist/tsup/chunk-D5G75T7J.js.map +1 -0
  27. package/dist/tsup/{chunk-LIXXFXVR.cjs → chunk-FEOG44WH.cjs} +137 -9
  28. package/dist/tsup/chunk-FEOG44WH.cjs.map +1 -0
  29. package/dist/tsup/{chunk-M5C7YNI5.cjs → chunk-G5HUSWP4.cjs} +8 -8
  30. package/dist/tsup/{chunk-M5C7YNI5.cjs.map → chunk-G5HUSWP4.cjs.map} +1 -1
  31. package/dist/tsup/{chunk-6S25NVAP.js → chunk-HERL2VQ2.js} +7 -5
  32. package/dist/tsup/chunk-HERL2VQ2.js.map +1 -0
  33. package/dist/tsup/{chunk-JALSAX7Z.cjs → chunk-SJLPZEA3.cjs} +3 -3
  34. package/dist/tsup/{chunk-JALSAX7Z.cjs.map → chunk-SJLPZEA3.cjs.map} +1 -1
  35. package/dist/tsup/{chunk-WQ4HNA4W.cjs → chunk-SRNOPUC6.cjs} +4 -2
  36. package/dist/tsup/chunk-SRNOPUC6.cjs.map +1 -0
  37. package/dist/tsup/{chunk-KIWH5H3K.js → chunk-TMLOKTRB.js} +3 -3
  38. package/dist/tsup/chunk-TMLOKTRB.js.map +1 -0
  39. package/dist/tsup/{chunk-CAF6JDJE.js → chunk-VFIY6GWO.js} +4 -4
  40. package/dist/tsup/chunk-VFIY6GWO.js.map +1 -0
  41. package/dist/tsup/{chunk-FLODVLYW.js → chunk-VJ4Y4WBT.js} +10 -34
  42. package/dist/tsup/chunk-VJ4Y4WBT.js.map +1 -0
  43. package/dist/tsup/{chunk-K5BA2LEO.cjs → chunk-X6HIFXNK.cjs} +14 -12
  44. package/dist/tsup/chunk-X6HIFXNK.cjs.map +1 -0
  45. package/dist/tsup/{chunk-ENK7C66G.cjs → chunk-ZGPX6KAH.cjs} +169 -193
  46. package/dist/tsup/chunk-ZGPX6KAH.cjs.map +1 -0
  47. package/dist/tsup/client/mod.cjs +7 -7
  48. package/dist/tsup/client/mod.d.cts +2 -2
  49. package/dist/tsup/client/mod.d.ts +2 -2
  50. package/dist/tsup/client/mod.js +6 -6
  51. package/dist/tsup/common/log.cjs +3 -3
  52. package/dist/tsup/common/log.js +2 -2
  53. package/dist/tsup/common/websocket.cjs +4 -4
  54. package/dist/tsup/common/websocket.js +3 -3
  55. package/dist/tsup/{config-0Ta55UV0.d.ts → config-Ak1lv4gF.d.ts} +27 -6
  56. package/dist/tsup/{config-Ca8dN4cS.d.cts → config-DU_xj4qZ.d.cts} +27 -6
  57. package/dist/tsup/{context-B_IWbWne.d.ts → context-DAAp4Lpg.d.ts} +1 -1
  58. package/dist/tsup/{context-CUrQ9MHc.d.cts → context-Dt_L55q8.d.cts} +1 -1
  59. package/dist/tsup/inspector/mod.cjs +6 -6
  60. package/dist/tsup/inspector/mod.js +5 -5
  61. package/dist/tsup/mod.cjs +470 -316
  62. package/dist/tsup/mod.cjs.map +1 -1
  63. package/dist/tsup/mod.d.cts +3 -3
  64. package/dist/tsup/mod.d.ts +3 -3
  65. package/dist/tsup/mod.js +391 -237
  66. package/dist/tsup/mod.js.map +1 -1
  67. package/dist/tsup/process-metrics-NW754INA.js +118 -0
  68. package/dist/tsup/process-metrics-NW754INA.js.map +1 -0
  69. package/dist/tsup/process-metrics-TYAGKCEJ.cjs +118 -0
  70. package/dist/tsup/process-metrics-TYAGKCEJ.cjs.map +1 -0
  71. package/dist/tsup/test/mod.cjs +10 -10
  72. package/dist/tsup/test/mod.d.cts +1 -1
  73. package/dist/tsup/test/mod.d.ts +1 -1
  74. package/dist/tsup/test/mod.js +6 -6
  75. package/dist/tsup/utils.cjs +3 -3
  76. package/dist/tsup/utils.js +2 -2
  77. package/dist/tsup/workflow/mod.cjs +41 -16
  78. package/dist/tsup/workflow/mod.cjs.map +1 -1
  79. package/dist/tsup/workflow/mod.d.cts +3 -3
  80. package/dist/tsup/workflow/mod.d.ts +3 -3
  81. package/dist/tsup/workflow/mod.js +35 -10
  82. package/dist/tsup/workflow/mod.js.map +1 -1
  83. package/package.json +11 -10
  84. package/src/actor/config.ts +3 -0
  85. package/src/actor/errors.ts +2 -2
  86. package/src/agent-os/actor/session.ts +2 -2
  87. package/src/client/actor-conn.ts +6 -34
  88. package/src/client/actor-handle.ts +2 -1
  89. package/src/client/queue.ts +2 -1
  90. package/src/client/utils.ts +0 -1
  91. package/src/common/encoding.ts +243 -5
  92. package/src/common/inline-websocket-adapter.ts +12 -12
  93. package/src/common/log.ts +1 -0
  94. package/src/common/router.ts +2 -2
  95. package/src/common/utils.ts +0 -148
  96. package/src/drivers/engine/actor-driver.ts +11 -11
  97. package/src/engine-client/actor-websocket-client.ts +2 -1
  98. package/src/engine-client/mod.ts +3 -2
  99. package/src/registry/index.ts +46 -109
  100. package/src/registry/napi-runtime.ts +11 -34
  101. package/src/registry/native.ts +193 -104
  102. package/src/registry/process-metrics.ts +183 -0
  103. package/src/registry/runtime.ts +5 -12
  104. package/src/registry/wasm-runtime.ts +2 -13
  105. package/src/registry/write-through-proxy.ts +40 -0
  106. package/src/serde.ts +2 -2
  107. package/src/workflow/context.ts +32 -5
  108. package/src/workflow/inspector.ts +2 -1
  109. package/dist/tsup/chunk-2G64KSZQ.cjs.map +0 -1
  110. package/dist/tsup/chunk-6S25NVAP.js.map +0 -1
  111. package/dist/tsup/chunk-CAF6JDJE.js.map +0 -1
  112. package/dist/tsup/chunk-ENK7C66G.cjs.map +0 -1
  113. package/dist/tsup/chunk-FLODVLYW.js.map +0 -1
  114. package/dist/tsup/chunk-K5BA2LEO.cjs.map +0 -1
  115. package/dist/tsup/chunk-KIWH5H3K.js.map +0 -1
  116. package/dist/tsup/chunk-LIXXFXVR.cjs.map +0 -1
  117. package/dist/tsup/chunk-RTC2AZGB.js.map +0 -1
  118. package/dist/tsup/chunk-T6YVRM4K.js.map +0 -1
  119. package/dist/tsup/chunk-WQ4HNA4W.cjs.map +0 -1
  120. /package/dist/tsup/{chunk-ZI5QJMKO.js.map → chunk-4DJMFOSU.js.map} +0 -0
  121. /package/dist/tsup/{chunk-DEO7MMWQ.js.map → chunk-52TPEKEC.js.map} +0 -0
  122. /package/dist/tsup/{chunk-EMO6E3PJ.js.map → chunk-CMV6N5OX.js.map} +0 -0
package/dist/tsup/mod.js CHANGED
@@ -2,13 +2,14 @@ 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-DEO7MMWQ.js";
12
+ } from "./chunk-52TPEKEC.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-FLODVLYW.js";
22
+ } from "./chunk-VJ4Y4WBT.js";
22
23
  import {
23
24
  KEYS,
24
25
  makePrefixedKey,
@@ -28,16 +29,18 @@ import {
28
29
  workflowStoragePrefix
29
30
  } from "./chunk-3YY5S6TV.js";
30
31
  import {
32
+ assertJsonCompatValue,
31
33
  decodeCborCompat,
32
34
  decodeCborJsonCompat,
33
35
  encodeCborCompat
34
- } from "./chunk-RTC2AZGB.js";
36
+ } from "./chunk-4LTY5TOO.js";
35
37
  import "./chunk-PCBNKI2J.js";
36
- import "./chunk-ZI5QJMKO.js";
38
+ import "./chunk-4DJMFOSU.js";
37
39
  import {
38
40
  LogLevelSchema,
39
41
  VERSION,
40
42
  deconstructError,
43
+ detectRuntime,
41
44
  getEnvUniversal,
42
45
  getLogger,
43
46
  getNodeEnv,
@@ -57,7 +60,7 @@ import {
57
60
  noopNext,
58
61
  stringifyError,
59
62
  toUint8Array
60
- } from "./chunk-6S25NVAP.js";
63
+ } from "./chunk-HERL2VQ2.js";
61
64
  import {
62
65
  INTERNAL_ERROR_CODE,
63
66
  RivetError,
@@ -68,7 +71,7 @@ import {
68
71
  isRivetErrorLike,
69
72
  toRivetError,
70
73
  unsupportedFeature
71
- } from "./chunk-KIWH5H3K.js";
74
+ } from "./chunk-TMLOKTRB.js";
72
75
 
73
76
  // src/actor/log.ts
74
77
  function loggerWithoutContext() {
@@ -314,24 +317,24 @@ var InlineWebSocketAdapter = class {
314
317
  this.#close(1011, "Internal error during initialization");
315
318
  }
316
319
  }
317
- #handleError(err) {
318
- console.error("INLINE_WEBSOCKET_ADAPTER_ERROR", err);
320
+ #handleError(error) {
321
+ console.error("INLINE_WEBSOCKET_ADAPTER_ERROR", error);
319
322
  logger().error({
320
323
  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
324
+ error,
325
+ errorMessage: error instanceof Error ? error.message : String(error),
326
+ stack: error instanceof Error ? error.stack : void 0
324
327
  });
325
328
  try {
326
- this.#handler.onError(err, this.#wsContext);
327
- } catch (handlerErr) {
329
+ this.#handler.onError(error, this.#wsContext);
330
+ } catch (error2) {
328
331
  logger().error({
329
332
  msg: "error in onError handler",
330
- error: handlerErr
333
+ error: error2
331
334
  });
332
335
  }
333
- this.#clientWs.triggerError(err);
334
- this.#actorWs.triggerError(err);
336
+ this.#clientWs.triggerError(error);
337
+ this.#actorWs.triggerError(error);
335
338
  }
336
339
  #close(code, reason) {
337
340
  if (this.#readyState === 3 || this.#readyState === 2) {
@@ -344,8 +347,8 @@ var InlineWebSocketAdapter = class {
344
347
  { code, reason, wasClean: true },
345
348
  this.#wsContext
346
349
  );
347
- } catch (err) {
348
- logger().error({ msg: "error closing websocket", error: err });
350
+ } catch (error) {
351
+ logger().error({ msg: "error closing websocket", error });
349
352
  } finally {
350
353
  this.#readyState = 3;
351
354
  this.#clientWs.triggerClose(code, reason);
@@ -354,6 +357,9 @@ var InlineWebSocketAdapter = class {
354
357
  }
355
358
  };
356
359
 
360
+ // src/registry/index.ts
361
+ import { Hono } from "hono";
362
+
357
363
  // src/common/engine.ts
358
364
  var ENGINE_PORT = 6420;
359
365
  var ENGINE_ENDPOINT = `http://127.0.0.1:${ENGINE_PORT}`;
@@ -450,6 +456,145 @@ async function configureServerlessPool(config) {
450
456
  throw lastError;
451
457
  }
452
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
+
453
598
  // src/registry/config/index.ts
454
599
  import { z as z3 } from "zod";
455
600
 
@@ -1154,6 +1299,29 @@ function lastInsertRowIdColumnName(sql) {
1154
1299
  return alias;
1155
1300
  }
1156
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
+
1157
1325
  // src/registry/runtime.ts
1158
1326
  function normalizeRuntimeSqlExecuteResult(result) {
1159
1327
  return result;
@@ -1274,32 +1442,15 @@ var NapiCoreRuntime = class {
1274
1442
  async shutdownRegistry(registry) {
1275
1443
  await asNativeRegistry(registry).shutdown();
1276
1444
  }
1277
- async registryActorStopThresholdMs(registry) {
1278
- return await asNativeRegistry(registry).actorStopThresholdMs() ?? void 0;
1279
- }
1280
- async registryHealth(registry) {
1281
- const response = await asNativeRegistry(registry).health();
1445
+ async registryDiagnostics(registry) {
1446
+ const diagnostics = await asNativeRegistry(registry).diagnostics();
1282
1447
  return {
1283
- status: response.status,
1284
- headers: response.headers,
1285
- body: response.body
1448
+ mode: diagnostics.mode,
1449
+ envoyActiveActorCount: diagnostics.envoyActiveActorCount
1286
1450
  };
1287
1451
  }
1288
- async registryMetadata(registry) {
1289
- const response = asNativeRegistry(registry).metadata();
1290
- return {
1291
- status: response.status,
1292
- headers: response.headers,
1293
- body: response.body
1294
- };
1295
- }
1296
- async registryMetrics(registry) {
1297
- const response = asNativeRegistry(registry).metrics();
1298
- return {
1299
- status: response.status,
1300
- headers: response.headers,
1301
- body: response.body
1302
- };
1452
+ async registryActorStopThresholdMs(registry) {
1453
+ return await asNativeRegistry(registry).actorStopThresholdMs() ?? void 0;
1303
1454
  }
1304
1455
  async handleServerlessRequest(registry, req, onStreamEvent, cancelToken, config) {
1305
1456
  return await asNativeRegistry(registry).handleServerlessRequest(
@@ -1841,18 +1992,8 @@ var WasmCoreRuntime = class {
1841
1992
  async shutdownRegistry(registry) {
1842
1993
  await callWasm(() => asWasmRegistry(registry).shutdown());
1843
1994
  }
1844
- async registryHealth() {
1845
- return {
1846
- status: 200,
1847
- headers: { "content-type": "application/json" },
1848
- body: new TextEncoder().encode(
1849
- JSON.stringify({
1850
- status: "ok",
1851
- runtime: "rivetkit",
1852
- version: "wasm"
1853
- })
1854
- )
1855
- };
1995
+ async registryDiagnostics() {
1996
+ return { mode: "wasm", envoyActiveActorCount: null };
1856
1997
  }
1857
1998
  async handleServerlessRequest(registry, req, onStreamEvent, cancelToken, config) {
1858
1999
  return await callHandleAsync(
@@ -2401,6 +2542,14 @@ function databaseNotConfiguredError() {
2401
2542
  { public: true }
2402
2543
  );
2403
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
+ }
2404
2553
  function stateNotEnabledError() {
2405
2554
  return new RivetError(
2406
2555
  "actor",
@@ -2453,7 +2602,20 @@ function clearNativeRuntimeState(runtime, ctx) {
2453
2602
  callNativeSync(() => runtime.actorClearRuntimeState(ctx));
2454
2603
  }
2455
2604
  async function cleanupNativeSleepRuntimeState(runtime, ctx) {
2456
- await runtime.actorWaitForTrackedShutdownWork(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
+ }
2457
2619
  await closeNativeDatabaseClient(runtime, ctx);
2458
2620
  await closeNativeSqlDatabase(runtime, ctx);
2459
2621
  clearNativeRuntimeState(runtime, ctx);
@@ -2833,44 +2995,6 @@ function decodeArgs(value) {
2833
2995
  const decoded = decodeValue(value);
2834
2996
  return Array.isArray(decoded) ? decoded : decoded === void 0 ? [] : [decoded];
2835
2997
  }
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);
2873
- }
2874
2998
  function buildRequest(init) {
2875
2999
  const url = init.uri.startsWith("http") ? init.uri : new URL(init.uri, "http://127.0.0.1").toString();
2876
3000
  const body = init.body && init.body.length > 0 ? runtimeBytesToArrayBuffer(init.body) : void 0;
@@ -2923,13 +3047,19 @@ var NativeConnAdapter = class {
2923
3047
  decodeValue(this.#runtime.connParams(this.#conn))
2924
3048
  );
2925
3049
  }
3050
+ [RAW_STATE_SYMBOL]() {
3051
+ return this.#readState();
3052
+ }
2926
3053
  get state() {
2927
3054
  const nextState = this.#readState();
2928
3055
  return createWriteThroughProxy(nextState, (nextValue) => {
2929
3056
  this.#writeState(nextValue, { writeNative: true });
3057
+ }, (newValue) => {
3058
+ assertJsonCompatValue(newValue);
2930
3059
  });
2931
3060
  }
2932
3061
  set state(value) {
3062
+ assertJsonCompatValue(value);
2933
3063
  this.#writeState(value, { writeNative: true });
2934
3064
  }
2935
3065
  initializeState(value) {
@@ -3753,6 +3883,70 @@ var TrackedWebSocketHandleAdapter = class {
3753
3883
  return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
3754
3884
  }
3755
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
+ };
3756
3950
  var ActorContextHandleAdapter = class {
3757
3951
  #runtime;
3758
3952
  #ctx;
@@ -3761,9 +3955,9 @@ var ActorContextHandleAdapter = class {
3761
3955
  #abortSignalCleanup;
3762
3956
  #client;
3763
3957
  #clientFactory;
3958
+ #connMap;
3764
3959
  #databaseProvider;
3765
3960
  #db;
3766
- #dbProxy;
3767
3961
  #dispatchCancelToken;
3768
3962
  #kv;
3769
3963
  #queue;
@@ -3806,30 +4000,22 @@ var ActorContextHandleAdapter = class {
3806
4000
  if (!this.#databaseProvider) {
3807
4001
  throw databaseNotConfiguredError();
3808
4002
  }
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
- );
4003
+ if (this.#db) {
4004
+ return this.#db;
4005
+ }
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;
3831
4011
  }
3832
- return this.#dbProxy;
4012
+ throw databaseClientNotReadyError();
4013
+ }
4014
+ [RAW_STATE_SYMBOL]() {
4015
+ if (!this.#stateEnabled) {
4016
+ throw stateNotEnabledError();
4017
+ }
4018
+ return this.#readState();
3833
4019
  }
3834
4020
  get state() {
3835
4021
  if (!this.#stateEnabled) {
@@ -3841,8 +4027,9 @@ var ActorContextHandleAdapter = class {
3841
4027
  (nextValue) => {
3842
4028
  this.#writeState(nextValue, { scheduleSave: true });
3843
4029
  },
3844
- () => {
4030
+ (newValue) => {
3845
4031
  this.#assertCanMutateState();
4032
+ assertJsonCompatValue(newValue);
3846
4033
  }
3847
4034
  );
3848
4035
  }
@@ -3851,6 +4038,7 @@ var ActorContextHandleAdapter = class {
3851
4038
  throw stateNotEnabledError();
3852
4039
  }
3853
4040
  this.#assertCanMutateState();
4041
+ assertJsonCompatValue(value);
3854
4042
  this.#writeState(value, { scheduleSave: true });
3855
4043
  }
3856
4044
  initializeState(value) {
@@ -3907,25 +4095,10 @@ var ActorContextHandleAdapter = class {
3907
4095
  return callNativeSync(() => this.#runtime.actorRegion(this.#ctx));
3908
4096
  }
3909
4097
  get conns() {
3910
- return new Map(
3911
- callNativeSync(() => this.#runtime.actorConns(this.#ctx)).map(
3912
- (conn) => [
3913
- this.#runtime.connId(conn),
3914
- new NativeConnAdapter(
3915
- this.#runtime,
3916
- conn,
3917
- this.#schemas,
3918
- this.#ctx,
3919
- (connId) => callNativeSync(
3920
- () => this.#runtime.actorQueueHibernationRemoval(
3921
- this.#ctx,
3922
- connId
3923
- )
3924
- )
3925
- )
3926
- ]
3927
- )
3928
- );
4098
+ if (!this.#connMap) {
4099
+ this.#connMap = new NativeConnectionMap(this.#runtime, this.#ctx, this.#schemas);
4100
+ }
4101
+ return this.#connMap;
3929
4102
  }
3930
4103
  get log() {
3931
4104
  return logger2();
@@ -4123,20 +4296,39 @@ var ActorContextHandleAdapter = class {
4123
4296
  });
4124
4297
  }
4125
4298
  keepAwake(promise) {
4126
- const trackedPromise = Promise.resolve(promise).catch((error) => {
4127
- logger2().warn({
4128
- msg: "keepAwake promise rejected",
4129
- error: stringifyError(error)
4130
- });
4131
- }).then(() => null);
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
+ });
4317
+ }
4318
+ ).then(() => null);
4132
4319
  try {
4133
4320
  callNativeSync(
4134
4321
  () => this.#runtime.actorKeepAwake(this.#ctx, trackedPromise)
4135
4322
  );
4136
4323
  } catch (error) {
4137
- if (!isClosedTaskRegistrationError(error)) {
4138
- 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;
4139
4330
  }
4331
+ throw error;
4140
4332
  }
4141
4333
  return promise;
4142
4334
  }
@@ -4660,6 +4852,10 @@ function buildNativeFactory(runtime, registryConfig, definition) {
4660
4852
  isWorkflowEnabled: getNativeWorkflowInspector(ctx) !== void 0
4661
4853
  });
4662
4854
  } catch (error) {
4855
+ logger2().error({
4856
+ msg: "error replaying workflow history",
4857
+ error
4858
+ });
4663
4859
  return errorResponse(error);
4664
4860
  }
4665
4861
  }
@@ -4811,6 +5007,10 @@ function buildNativeFactory(runtime, registryConfig, definition) {
4811
5007
  );
4812
5008
  return jsonResponse({ output });
4813
5009
  } catch (error) {
5010
+ logger2().error({
5011
+ msg: "Error handling inspector action request",
5012
+ error
5013
+ });
4814
5014
  return errorResponse(error);
4815
5015
  }
4816
5016
  }
@@ -4824,6 +5024,10 @@ function buildNativeFactory(runtime, registryConfig, definition) {
4824
5024
  { status: 404 }
4825
5025
  );
4826
5026
  } catch (error) {
5027
+ logger2().error({
5028
+ msg: "Error handling inspector request",
5029
+ error
5030
+ });
4827
5031
  return errorResponse(error);
4828
5032
  } finally {
4829
5033
  await actorCtx.dispose();
@@ -5438,6 +5642,10 @@ async function buildRegistryWithRuntime(config, runtime) {
5438
5642
  }
5439
5643
  async function buildConfiguredRegistry(config) {
5440
5644
  const runtime = await loadConfiguredRuntime(config);
5645
+ if (runtime.kind === "napi") {
5646
+ const { startProcessMetrics } = await import("./process-metrics-NW754INA.js");
5647
+ startProcessMetrics();
5648
+ }
5441
5649
  return buildRegistryWithRuntime(
5442
5650
  normalizeRuntimeConfig(config, runtime),
5443
5651
  runtime
@@ -5461,7 +5669,6 @@ function finishShutdownSignal(signal) {
5461
5669
  }
5462
5670
  var Registry = class {
5463
5671
  #config;
5464
- routes;
5465
5672
  get config() {
5466
5673
  return this.#config;
5467
5674
  }
@@ -5478,11 +5685,6 @@ var Registry = class {
5478
5685
  #signalHandlers = {};
5479
5686
  constructor(config) {
5480
5687
  this.#config = config;
5481
- this.routes = {
5482
- health: () => this.#healthRoute(),
5483
- metadata: () => this.#metadataRoute(),
5484
- prometheusMetrics: (request) => this.#prometheusMetricsRoute(request)
5485
- };
5486
5688
  }
5487
5689
  #ensureServerlessPoolConfigured(config) {
5488
5690
  if (!config.configurePool) return void 0;
@@ -5676,88 +5878,46 @@ var Registry = class {
5676
5878
  };
5677
5879
  }
5678
5880
  /**
5679
- * Returns a health response suitable for mounting in a user-owned router.
5680
- */
5681
- async #healthRoute() {
5682
- const configured = await this.#activeConfiguredRegistry();
5683
- if (!configured) {
5684
- return jsonRouteResponse(503, {
5685
- status: "not_started",
5686
- runtime: "rivetkit",
5687
- version: VERSION
5688
- });
5689
- }
5690
- const { runtime, registry } = configured;
5691
- if (!runtime.registryHealth) {
5692
- return jsonRouteResponse(501, {
5693
- status: "unsupported",
5694
- runtime: "rivetkit",
5695
- version: VERSION
5696
- });
5697
- }
5698
- const response = await runtime.registryHealth(registry);
5699
- return new Response(new Uint8Array(response.body), {
5700
- status: response.status,
5701
- headers: response.headers
5702
- });
5703
- }
5704
- /**
5705
- * Returns serverless metadata suitable for mounting in a user-owned router.
5706
- */
5707
- async #metadataRoute() {
5708
- const configured = await this.#activeConfiguredRegistry();
5709
- if (!configured) {
5710
- return new Response("registry not started\n", {
5711
- status: 503,
5712
- headers: { "content-type": "text/plain; charset=utf-8" }
5713
- });
5714
- }
5715
- const { runtime, registry } = configured;
5716
- if (!runtime.registryMetadata) {
5717
- return new Response("metadata is not supported by this runtime\n", {
5718
- status: 501,
5719
- headers: { "content-type": "text/plain; charset=utf-8" }
5720
- });
5721
- }
5722
- const response = await runtime.registryMetadata(registry);
5723
- return new Response(new Uint8Array(response.body), {
5724
- status: response.status,
5725
- headers: response.headers
5726
- });
5727
- }
5728
- /**
5729
- * Returns a Prometheus metrics response suitable for mounting in a user-owned router.
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
+ * ```
5730
5894
  */
5731
- async #prometheusMetricsRoute(_request) {
5732
- const configured = await this.#activeConfiguredRegistry();
5733
- if (!configured) {
5734
- return new Response("registry not started\n", {
5735
- status: 503,
5736
- headers: { "content-type": "text/plain; charset=utf-8" }
5737
- });
5738
- }
5739
- const { runtime, registry } = configured;
5740
- if (!runtime.registryMetrics) {
5741
- return new Response("metrics are not supported by this runtime\n", {
5742
- status: 501,
5743
- headers: { "content-type": "text/plain; charset=utf-8" }
5744
- });
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 }));
5745
5903
  }
5746
- const response = await runtime.registryMetrics(registry);
5747
- return new Response(new Uint8Array(response.body), {
5748
- status: response.status,
5749
- headers: response.headers
5750
- });
5904
+ app.all("*", (c) => this.handler(c.req.raw));
5905
+ await crossPlatformServe(config, port, app, runtime);
5751
5906
  }
5752
- async #activeConfiguredRegistry() {
5907
+ async diagnostics() {
5908
+ var _a;
5753
5909
  const candidates = [
5754
5910
  this.#runtimeServerlessPromise,
5755
5911
  this.#runtimeServeConfiguredPromise
5756
5912
  ].filter(
5757
5913
  (candidate) => candidate !== void 0
5758
5914
  );
5759
- if (candidates.length === 0) return void 0;
5760
- return await candidates[0];
5915
+ for (const candidate of candidates) {
5916
+ const { runtime, registry } = await candidate;
5917
+ const diagnostics = await ((_a = runtime.registryDiagnostics) == null ? void 0 : _a.call(runtime, registry));
5918
+ if (diagnostics) return diagnostics;
5919
+ }
5920
+ return { mode: "not_started", envoyActiveActorCount: null };
5761
5921
  }
5762
5922
  /**
5763
5923
  * Starts an actor envoy for standalone server deployments.
@@ -5768,8 +5928,8 @@ var Registry = class {
5768
5928
  this.#runtimeServeConfiguredPromise = configuredRegistryPromise;
5769
5929
  this.#runtimeServePromise = configuredRegistryPromise.then(async ({ runtime, registry, serveConfig }) => {
5770
5930
  await runtime.serveRegistry(registry, serveConfig);
5771
- }).catch((err) => {
5772
- logger2().warn({ err }, "runtime registry serve errored");
5931
+ }).catch((error) => {
5932
+ logger2().warn({ error }, "runtime registry serve errored");
5773
5933
  });
5774
5934
  this.#installSignalHandlers(config, configuredRegistryPromise);
5775
5935
  }
@@ -5807,8 +5967,8 @@ var Registry = class {
5807
5967
  signal,
5808
5968
  config,
5809
5969
  configuredRegistryPromise
5810
- ).catch((err) => {
5811
- logger2().warn({ err }, "shutdown error");
5970
+ ).catch((error) => {
5971
+ logger2().warn({ error }, "shutdown error");
5812
5972
  });
5813
5973
  }
5814
5974
  async #runShutdown(signal, config, configuredRegistryPromise) {
@@ -5820,9 +5980,9 @@ var Registry = class {
5820
5980
  try {
5821
5981
  const { runtime, registry } = await configuredRegistryPromise;
5822
5982
  await runtime.shutdownRegistry(registry);
5823
- } catch (err) {
5983
+ } catch (error) {
5824
5984
  logger2().warn(
5825
- { err },
5985
+ { error },
5826
5986
  "runtime registry shutdown errored (mode A)"
5827
5987
  );
5828
5988
  }
@@ -5837,7 +5997,7 @@ var Registry = class {
5837
5997
  await runtime.shutdownRegistry(registry);
5838
5998
  } catch (err) {
5839
5999
  logger2().warn(
5840
- { err },
6000
+ { error: err },
5841
6001
  "runtime registry shutdown errored (mode B)"
5842
6002
  );
5843
6003
  }
@@ -5939,12 +6099,6 @@ function isServerlessMetadataRequest(request, basePath) {
5939
6099
  const normalizedBase = basePath === "/" ? "" : `/${basePath.replace(/^\/+|\/+$/g, "")}`;
5940
6100
  return parsed.pathname === `${normalizedBase}/metadata`;
5941
6101
  }
5942
- function jsonRouteResponse(status, body) {
5943
- return new Response(JSON.stringify(body), {
5944
- status,
5945
- headers: { "content-type": "application/json" }
5946
- });
5947
- }
5948
6102
  function setup(input) {
5949
6103
  return new Registry(input);
5950
6104
  }