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
@@ -0,0 +1,118 @@
1
+ // src/registry/process-metrics.ts
2
+ import { monitorEventLoopDelay, performance, PerformanceObserver } from "perf_hooks";
3
+ import { getHeapStatistics } from "v8";
4
+ import * as napi from "@rivetkit/rivetkit-napi";
5
+ function callIfFn(fn, ...args) {
6
+ if (typeof fn === "function") {
7
+ fn(...args);
8
+ }
9
+ }
10
+ var SCRAPE_INTERVAL_MS = 5e3;
11
+ var HEARTBEAT_INTERVAL_MS = 100;
12
+ var EVENTLOOP_DELAY_RESOLUTION_MS = 20;
13
+ var NS_PER_SECOND = 1e9;
14
+ var US_PER_SECOND = 1e6;
15
+ var GC_KIND_NAMES = {
16
+ 1: "minor",
17
+ 2: "major",
18
+ 4: "incremental",
19
+ 8: "weakcb"
20
+ };
21
+ var state;
22
+ function startProcessMetrics() {
23
+ if (state) {
24
+ return;
25
+ }
26
+ const eventLoopHistogram = monitorEventLoopDelay({
27
+ resolution: EVENTLOOP_DELAY_RESOLUTION_MS
28
+ });
29
+ eventLoopHistogram.enable();
30
+ const gcObserver = new PerformanceObserver((list) => {
31
+ var _a;
32
+ for (const entry of list.getEntries()) {
33
+ const kind = ((_a = entry.detail) == null ? void 0 : _a.kind) ?? entry.kind;
34
+ if (typeof kind !== "number") continue;
35
+ const kindName = GC_KIND_NAMES[kind];
36
+ if (!kindName) continue;
37
+ callIfFn(napi.jsObserveGcDuration, kindName, entry.duration / 1e3);
38
+ }
39
+ });
40
+ gcObserver.observe({ entryTypes: ["gc"], buffered: false });
41
+ const lastCpuUsage = process.cpuUsage();
42
+ const lastEventLoopUtilization = performance.eventLoopUtilization();
43
+ const heartbeatInterval = setInterval(() => {
44
+ callIfFn(napi.jsSetEventloopHeartbeatTsMs, Date.now());
45
+ }, HEARTBEAT_INTERVAL_MS);
46
+ heartbeatInterval.unref();
47
+ const scrapeInterval = setInterval(() => {
48
+ try {
49
+ collectAndPush();
50
+ } catch {
51
+ }
52
+ }, SCRAPE_INTERVAL_MS);
53
+ scrapeInterval.unref();
54
+ state = {
55
+ scrapeInterval,
56
+ heartbeatInterval,
57
+ gcObserver,
58
+ eventLoopHistogram,
59
+ lastCpuUsage,
60
+ lastEventLoopUtilization
61
+ };
62
+ callIfFn(napi.jsSetEventloopHeartbeatTsMs, Date.now());
63
+ try {
64
+ collectAndPush();
65
+ } catch {
66
+ }
67
+ }
68
+ function stopProcessMetrics() {
69
+ if (!state) {
70
+ return;
71
+ }
72
+ clearInterval(state.scrapeInterval);
73
+ clearInterval(state.heartbeatInterval);
74
+ state.gcObserver.disconnect();
75
+ state.eventLoopHistogram.disable();
76
+ state = void 0;
77
+ }
78
+ function collectAndPush() {
79
+ if (!state) return;
80
+ const hist = state.eventLoopHistogram;
81
+ callIfFn(napi.jsSetEventloopLagQuantile, "p50", hist.percentile(50) / NS_PER_SECOND);
82
+ callIfFn(napi.jsSetEventloopLagQuantile, "p90", hist.percentile(90) / NS_PER_SECOND);
83
+ callIfFn(napi.jsSetEventloopLagQuantile, "p99", hist.percentile(99) / NS_PER_SECOND);
84
+ callIfFn(napi.jsSetEventloopLagQuantile, "max", hist.max / NS_PER_SECOND);
85
+ hist.reset();
86
+ const nextElu = performance.eventLoopUtilization();
87
+ const eluDelta = performance.eventLoopUtilization(nextElu, state.lastEventLoopUtilization);
88
+ state.lastEventLoopUtilization = nextElu;
89
+ callIfFn(napi.jsSetEventloopUtilization, eluDelta.utilization);
90
+ const nextCpu = process.cpuUsage();
91
+ const userDeltaUs = nextCpu.user - state.lastCpuUsage.user;
92
+ const systemDeltaUs = nextCpu.system - state.lastCpuUsage.system;
93
+ state.lastCpuUsage = nextCpu;
94
+ if (userDeltaUs > 0) {
95
+ callIfFn(napi.jsAddProcessCpuSeconds, "user", userDeltaUs / US_PER_SECOND);
96
+ }
97
+ if (systemDeltaUs > 0) {
98
+ callIfFn(napi.jsAddProcessCpuSeconds, "system", systemDeltaUs / US_PER_SECOND);
99
+ }
100
+ const mem = process.memoryUsage();
101
+ callIfFn(napi.jsSetProcessResidentMemoryBytes, mem.rss);
102
+ callIfFn(napi.jsSetHeapBytes, "used", mem.heapUsed);
103
+ callIfFn(napi.jsSetHeapBytes, "total", mem.heapTotal);
104
+ const heapLimit = getHeapStatistics().heap_size_limit;
105
+ callIfFn(napi.jsSetHeapBytes, "limit", heapLimit);
106
+ const proc = process;
107
+ if (typeof proc._getActiveHandles === "function") {
108
+ callIfFn(napi.jsSetActiveHandles, proc._getActiveHandles().length);
109
+ }
110
+ if (typeof proc._getActiveRequests === "function") {
111
+ callIfFn(napi.jsSetActiveRequests, proc._getActiveRequests().length);
112
+ }
113
+ }
114
+ export {
115
+ startProcessMetrics,
116
+ stopProcessMetrics
117
+ };
118
+ //# sourceMappingURL=process-metrics-NW754INA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/registry/process-metrics.ts"],"sourcesContent":["/**\n * Node.js runtime health metrics.\n *\n * Collects JS-internal data (event loop lag, GC, heap, libuv handles,\n * event loop utilization, CPU) using Node built-ins (`node:perf_hooks`,\n * `process`, `node:v8`, `PerformanceObserver`) and pushes them across NAPI\n * into Rust-side prometheus collectors registered with\n * `rivet_metrics::REGISTRY` so they appear on the existing `/metrics`\n * endpoint.\n *\n * All data collection happens here in TypeScript. The NAPI bridge is pure\n * type marshalling and the Rust side only registers + stores the metrics.\n */\nimport { monitorEventLoopDelay, performance, PerformanceObserver } from \"node:perf_hooks\";\nimport { getHeapStatistics } from \"node:v8\";\nimport * as napi from \"@rivetkit/rivetkit-napi\";\n\n// Some napi process-metrics symbols may be missing on older native binaries\n// (the auto-generated index.js destructures them as `undefined` if the\n// underlying `.node` was built before they were added). Guard each call so\n// the metrics collection runs as a no-op instead of throwing\n// `TypeError: napi.jsXxx is not a function` on every interval tick.\nfunction callIfFn<T extends unknown[]>(\n\tfn: ((...args: T) => void) | undefined,\n\t...args: T\n): void {\n\tif (typeof fn === \"function\") {\n\t\tfn(...args);\n\t}\n}\n\nconst SCRAPE_INTERVAL_MS = 5_000;\nconst HEARTBEAT_INTERVAL_MS = 100;\nconst EVENTLOOP_DELAY_RESOLUTION_MS = 20;\nconst NS_PER_SECOND = 1e9;\nconst US_PER_SECOND = 1e6;\n\n// V8 GC kind bitfield from Node's perf_hooks documentation. A `gc` performance\n// entry's `kind` field is one of these values.\nconst GC_KIND_NAMES: Record<number, string> = {\n\t1: \"minor\",\n\t2: \"major\",\n\t4: \"incremental\",\n\t8: \"weakcb\",\n};\n\ninterface ProcessMetricsState {\n\tscrapeInterval: NodeJS.Timeout;\n\theartbeatInterval: NodeJS.Timeout;\n\tgcObserver: PerformanceObserver;\n\teventLoopHistogram: ReturnType<typeof monitorEventLoopDelay>;\n\tlastCpuUsage: NodeJS.CpuUsage;\n\tlastEventLoopUtilization: ReturnType<typeof performance.eventLoopUtilization>;\n}\n\nlet state: ProcessMetricsState | undefined;\n\nexport function startProcessMetrics(): void {\n\tif (state) {\n\t\treturn;\n\t}\n\n\tconst eventLoopHistogram = monitorEventLoopDelay({\n\t\tresolution: EVENTLOOP_DELAY_RESOLUTION_MS,\n\t});\n\teventLoopHistogram.enable();\n\n\tconst gcObserver = new PerformanceObserver((list) => {\n\t\tfor (const entry of list.getEntries()) {\n\t\t\tconst kind =\n\t\t\t\t(entry as PerformanceEntry & { detail?: { kind?: number }; kind?: number }).detail\n\t\t\t\t\t?.kind ??\n\t\t\t\t(entry as PerformanceEntry & { kind?: number }).kind;\n\t\t\tif (typeof kind !== \"number\") continue;\n\t\t\tconst kindName = GC_KIND_NAMES[kind];\n\t\t\tif (!kindName) continue;\n\t\t\t// `entry.duration` is in milliseconds; convert to seconds.\n\t\t\tcallIfFn(napi.jsObserveGcDuration, kindName, entry.duration / 1000);\n\t\t}\n\t});\n\tgcObserver.observe({ entryTypes: [\"gc\"], buffered: false });\n\n\tconst lastCpuUsage = process.cpuUsage();\n\tconst lastEventLoopUtilization = performance.eventLoopUtilization();\n\n\tconst heartbeatInterval = setInterval(() => {\n\t\tcallIfFn(napi.jsSetEventloopHeartbeatTsMs, Date.now());\n\t}, HEARTBEAT_INTERVAL_MS);\n\theartbeatInterval.unref();\n\n\tconst scrapeInterval = setInterval(() => {\n\t\ttry {\n\t\t\tcollectAndPush();\n\t\t} catch {\n\t\t\t// Collection errors must never bring down the process; metrics\n\t\t\t// are best-effort.\n\t\t}\n\t}, SCRAPE_INTERVAL_MS);\n\tscrapeInterval.unref();\n\n\tstate = {\n\t\tscrapeInterval,\n\t\theartbeatInterval,\n\t\tgcObserver,\n\t\teventLoopHistogram,\n\t\tlastCpuUsage,\n\t\tlastEventLoopUtilization,\n\t};\n\n\t// Emit one snapshot immediately so freshly-scraped instances have data.\n\tcallIfFn(napi.jsSetEventloopHeartbeatTsMs, Date.now());\n\ttry {\n\t\tcollectAndPush();\n\t} catch {\n\t\t// As above; best-effort.\n\t}\n}\n\nexport function stopProcessMetrics(): void {\n\tif (!state) {\n\t\treturn;\n\t}\n\tclearInterval(state.scrapeInterval);\n\tclearInterval(state.heartbeatInterval);\n\tstate.gcObserver.disconnect();\n\tstate.eventLoopHistogram.disable();\n\tstate = undefined;\n}\n\nfunction collectAndPush(): void {\n\tif (!state) return;\n\n\t// Event loop delay quantiles. `monitorEventLoopDelay()` reports values in\n\t// nanoseconds; convert to seconds. Reset after reading so the next window\n\t// reflects only the new interval.\n\tconst hist = state.eventLoopHistogram;\n\tcallIfFn(napi.jsSetEventloopLagQuantile, \"p50\", hist.percentile(50) / NS_PER_SECOND);\n\tcallIfFn(napi.jsSetEventloopLagQuantile, \"p90\", hist.percentile(90) / NS_PER_SECOND);\n\tcallIfFn(napi.jsSetEventloopLagQuantile, \"p99\", hist.percentile(99) / NS_PER_SECOND);\n\tcallIfFn(napi.jsSetEventloopLagQuantile, \"max\", hist.max / NS_PER_SECOND);\n\thist.reset();\n\n\t// Event loop utilization delta over the scrape window.\n\tconst nextElu = performance.eventLoopUtilization();\n\tconst eluDelta = performance.eventLoopUtilization(nextElu, state.lastEventLoopUtilization);\n\tstate.lastEventLoopUtilization = nextElu;\n\tcallIfFn(napi.jsSetEventloopUtilization, eluDelta.utilization);\n\n\t// CPU usage delta. `process.cpuUsage()` returns microseconds.\n\tconst nextCpu = process.cpuUsage();\n\tconst userDeltaUs = nextCpu.user - state.lastCpuUsage.user;\n\tconst systemDeltaUs = nextCpu.system - state.lastCpuUsage.system;\n\tstate.lastCpuUsage = nextCpu;\n\tif (userDeltaUs > 0) {\n\t\tcallIfFn(napi.jsAddProcessCpuSeconds, \"user\", userDeltaUs / US_PER_SECOND);\n\t}\n\tif (systemDeltaUs > 0) {\n\t\tcallIfFn(napi.jsAddProcessCpuSeconds, \"system\", systemDeltaUs / US_PER_SECOND);\n\t}\n\n\t// Memory + heap.\n\tconst mem = process.memoryUsage();\n\tcallIfFn(napi.jsSetProcessResidentMemoryBytes, mem.rss);\n\tcallIfFn(napi.jsSetHeapBytes, \"used\", mem.heapUsed);\n\tcallIfFn(napi.jsSetHeapBytes, \"total\", mem.heapTotal);\n\tconst heapLimit = getHeapStatistics().heap_size_limit;\n\tcallIfFn(napi.jsSetHeapBytes, \"limit\", heapLimit);\n\n\t// libuv active handles + requests. These are unstable Node internals\n\t// guarded behind underscore-prefixed names; if a future Node release\n\t// removes them the try/catch above keeps the rest of the collection\n\t// alive.\n\tconst proc = process as unknown as {\n\t\t_getActiveHandles?: () => unknown[];\n\t\t_getActiveRequests?: () => unknown[];\n\t};\n\tif (typeof proc._getActiveHandles === \"function\") {\n\t\tcallIfFn(napi.jsSetActiveHandles, proc._getActiveHandles().length);\n\t}\n\tif (typeof proc._getActiveRequests === \"function\") {\n\t\tcallIfFn(napi.jsSetActiveRequests, proc._getActiveRequests().length);\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,118 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/registry/process-metrics.ts
2
+ var _perf_hooks = require('perf_hooks');
3
+ var _v8 = require('v8');
4
+ var _rivetkitnapi = require('@rivetkit/rivetkit-napi'); var napi = _interopRequireWildcard(_rivetkitnapi);
5
+ function callIfFn(fn, ...args) {
6
+ if (typeof fn === "function") {
7
+ fn(...args);
8
+ }
9
+ }
10
+ var SCRAPE_INTERVAL_MS = 5e3;
11
+ var HEARTBEAT_INTERVAL_MS = 100;
12
+ var EVENTLOOP_DELAY_RESOLUTION_MS = 20;
13
+ var NS_PER_SECOND = 1e9;
14
+ var US_PER_SECOND = 1e6;
15
+ var GC_KIND_NAMES = {
16
+ 1: "minor",
17
+ 2: "major",
18
+ 4: "incremental",
19
+ 8: "weakcb"
20
+ };
21
+ var state;
22
+ function startProcessMetrics() {
23
+ if (state) {
24
+ return;
25
+ }
26
+ const eventLoopHistogram = _perf_hooks.monitorEventLoopDelay.call(void 0, {
27
+ resolution: EVENTLOOP_DELAY_RESOLUTION_MS
28
+ });
29
+ eventLoopHistogram.enable();
30
+ const gcObserver = new (0, _perf_hooks.PerformanceObserver)((list) => {
31
+ var _a;
32
+ for (const entry of list.getEntries()) {
33
+ const kind = _nullishCoalesce(((_a = entry.detail) == null ? void 0 : _a.kind), () => ( entry.kind));
34
+ if (typeof kind !== "number") continue;
35
+ const kindName = GC_KIND_NAMES[kind];
36
+ if (!kindName) continue;
37
+ callIfFn(napi.jsObserveGcDuration, kindName, entry.duration / 1e3);
38
+ }
39
+ });
40
+ gcObserver.observe({ entryTypes: ["gc"], buffered: false });
41
+ const lastCpuUsage = process.cpuUsage();
42
+ const lastEventLoopUtilization = _perf_hooks.performance.eventLoopUtilization();
43
+ const heartbeatInterval = setInterval(() => {
44
+ callIfFn(napi.jsSetEventloopHeartbeatTsMs, Date.now());
45
+ }, HEARTBEAT_INTERVAL_MS);
46
+ heartbeatInterval.unref();
47
+ const scrapeInterval = setInterval(() => {
48
+ try {
49
+ collectAndPush();
50
+ } catch (e) {
51
+ }
52
+ }, SCRAPE_INTERVAL_MS);
53
+ scrapeInterval.unref();
54
+ state = {
55
+ scrapeInterval,
56
+ heartbeatInterval,
57
+ gcObserver,
58
+ eventLoopHistogram,
59
+ lastCpuUsage,
60
+ lastEventLoopUtilization
61
+ };
62
+ callIfFn(napi.jsSetEventloopHeartbeatTsMs, Date.now());
63
+ try {
64
+ collectAndPush();
65
+ } catch (e2) {
66
+ }
67
+ }
68
+ function stopProcessMetrics() {
69
+ if (!state) {
70
+ return;
71
+ }
72
+ clearInterval(state.scrapeInterval);
73
+ clearInterval(state.heartbeatInterval);
74
+ state.gcObserver.disconnect();
75
+ state.eventLoopHistogram.disable();
76
+ state = void 0;
77
+ }
78
+ function collectAndPush() {
79
+ if (!state) return;
80
+ const hist = state.eventLoopHistogram;
81
+ callIfFn(napi.jsSetEventloopLagQuantile, "p50", hist.percentile(50) / NS_PER_SECOND);
82
+ callIfFn(napi.jsSetEventloopLagQuantile, "p90", hist.percentile(90) / NS_PER_SECOND);
83
+ callIfFn(napi.jsSetEventloopLagQuantile, "p99", hist.percentile(99) / NS_PER_SECOND);
84
+ callIfFn(napi.jsSetEventloopLagQuantile, "max", hist.max / NS_PER_SECOND);
85
+ hist.reset();
86
+ const nextElu = _perf_hooks.performance.eventLoopUtilization();
87
+ const eluDelta = _perf_hooks.performance.eventLoopUtilization(nextElu, state.lastEventLoopUtilization);
88
+ state.lastEventLoopUtilization = nextElu;
89
+ callIfFn(napi.jsSetEventloopUtilization, eluDelta.utilization);
90
+ const nextCpu = process.cpuUsage();
91
+ const userDeltaUs = nextCpu.user - state.lastCpuUsage.user;
92
+ const systemDeltaUs = nextCpu.system - state.lastCpuUsage.system;
93
+ state.lastCpuUsage = nextCpu;
94
+ if (userDeltaUs > 0) {
95
+ callIfFn(napi.jsAddProcessCpuSeconds, "user", userDeltaUs / US_PER_SECOND);
96
+ }
97
+ if (systemDeltaUs > 0) {
98
+ callIfFn(napi.jsAddProcessCpuSeconds, "system", systemDeltaUs / US_PER_SECOND);
99
+ }
100
+ const mem = process.memoryUsage();
101
+ callIfFn(napi.jsSetProcessResidentMemoryBytes, mem.rss);
102
+ callIfFn(napi.jsSetHeapBytes, "used", mem.heapUsed);
103
+ callIfFn(napi.jsSetHeapBytes, "total", mem.heapTotal);
104
+ const heapLimit = _v8.getHeapStatistics.call(void 0, ).heap_size_limit;
105
+ callIfFn(napi.jsSetHeapBytes, "limit", heapLimit);
106
+ const proc = process;
107
+ if (typeof proc._getActiveHandles === "function") {
108
+ callIfFn(napi.jsSetActiveHandles, proc._getActiveHandles().length);
109
+ }
110
+ if (typeof proc._getActiveRequests === "function") {
111
+ callIfFn(napi.jsSetActiveRequests, proc._getActiveRequests().length);
112
+ }
113
+ }
114
+
115
+
116
+
117
+ exports.startProcessMetrics = startProcessMetrics; exports.stopProcessMetrics = stopProcessMetrics;
118
+ //# sourceMappingURL=process-metrics-TYAGKCEJ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/rivet/rivet/rivetkit-typescript/packages/rivetkit/dist/tsup/process-metrics-TYAGKCEJ.cjs","../../src/registry/process-metrics.ts"],"names":[],"mappings":"AAAA;ACaA,wCAAwE;AACxE,wBAAkC;AAClC,0GAAsB;AAOtB,SAAS,QAAA,CACR,EAAA,EAAA,GACG,IAAA,EACI;AACP,EAAA,GAAA,CAAI,OAAO,GAAA,IAAO,UAAA,EAAY;AAC7B,IAAA,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,EACX;AACD;AAEA,IAAM,mBAAA,EAAqB,GAAA;AAC3B,IAAM,sBAAA,EAAwB,GAAA;AAC9B,IAAM,8BAAA,EAAgC,EAAA;AACtC,IAAM,cAAA,EAAgB,GAAA;AACtB,IAAM,cAAA,EAAgB,GAAA;AAItB,IAAM,cAAA,EAAwC;AAAA,EAC7C,CAAA,EAAG,OAAA;AAAA,EACH,CAAA,EAAG,OAAA;AAAA,EACH,CAAA,EAAG,aAAA;AAAA,EACH,CAAA,EAAG;AACJ,CAAA;AAWA,IAAI,KAAA;AAEG,SAAS,mBAAA,CAAA,EAA4B;AAC3C,EAAA,GAAA,CAAI,KAAA,EAAO;AACV,IAAA,MAAA;AAAA,EACD;AAEA,EAAA,MAAM,mBAAA,EAAqB,+CAAA;AAAsB,IAChD,UAAA,EAAY;AAAA,EACb,CAAC,CAAA;AACD,EAAA,kBAAA,CAAmB,MAAA,CAAO,CAAA;AAE1B,EAAA,MAAM,WAAA,EAAa,IAAI,oCAAA,CAAoB,CAAC,IAAA,EAAA,GAAS;AAnEtD,IAAA,IAAA,EAAA;AAoEE,IAAA,IAAA,CAAA,MAAW,MAAA,GAAS,IAAA,CAAK,UAAA,CAAW,CAAA,EAAG;AACtC,MAAA,MAAM,KAAA,mBAAA,CAAA,CACJ,GAAA,EAAA,KAAA,CAA2E,MAAA,EAAA,GAA3E,KAAA,EAAA,KAAA,EAAA,EAAA,EAAA,CACE,IAAA,CAAA,UACF,KAAA,CAA+C,MAAA;AACjD,MAAA,GAAA,CAAI,OAAO,KAAA,IAAS,QAAA,EAAU,QAAA;AAC9B,MAAA,MAAM,SAAA,EAAW,aAAA,CAAc,IAAI,CAAA;AACnC,MAAA,GAAA,CAAI,CAAC,QAAA,EAAU,QAAA;AAEf,MAAA,QAAA,CAAc,IAAA,CAAA,mBAAA,EAAqB,QAAA,EAAU,KAAA,CAAM,SAAA,EAAW,GAAI,CAAA;AAAA,IACnE;AAAA,EACD,CAAC,CAAA;AACD,EAAA,UAAA,CAAW,OAAA,CAAQ,EAAE,UAAA,EAAY,CAAC,IAAI,CAAA,EAAG,QAAA,EAAU,MAAM,CAAC,CAAA;AAE1D,EAAA,MAAM,aAAA,EAAe,OAAA,CAAQ,QAAA,CAAS,CAAA;AACtC,EAAA,MAAM,yBAAA,EAA2B,uBAAA,CAAY,oBAAA,CAAqB,CAAA;AAElE,EAAA,MAAM,kBAAA,EAAoB,WAAA,CAAY,CAAA,EAAA,GAAM;AAC3C,IAAA,QAAA,CAAc,IAAA,CAAA,2BAAA,EAA6B,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA;AAAA,EACtD,CAAA,EAAG,qBAAqB,CAAA;AACxB,EAAA,iBAAA,CAAkB,KAAA,CAAM,CAAA;AAExB,EAAA,MAAM,eAAA,EAAiB,WAAA,CAAY,CAAA,EAAA,GAAM;AACxC,IAAA,IAAI;AACH,MAAA,cAAA,CAAe,CAAA;AAAA,IAChB,EAAA,UAAQ;AAAA,IAGR;AAAA,EACD,CAAA,EAAG,kBAAkB,CAAA;AACrB,EAAA,cAAA,CAAe,KAAA,CAAM,CAAA;AAErB,EAAA,MAAA,EAAQ;AAAA,IACP,cAAA;AAAA,IACA,iBAAA;AAAA,IACA,UAAA;AAAA,IACA,kBAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,EACD,CAAA;AAGA,EAAA,QAAA,CAAc,IAAA,CAAA,2BAAA,EAA6B,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA;AACrD,EAAA,IAAI;AACH,IAAA,cAAA,CAAe,CAAA;AAAA,EAChB,EAAA,WAAQ;AAAA,EAER;AACD;AAEO,SAAS,kBAAA,CAAA,EAA2B;AAC1C,EAAA,GAAA,CAAI,CAAC,KAAA,EAAO;AACX,IAAA,MAAA;AAAA,EACD;AACA,EAAA,aAAA,CAAc,KAAA,CAAM,cAAc,CAAA;AAClC,EAAA,aAAA,CAAc,KAAA,CAAM,iBAAiB,CAAA;AACrC,EAAA,KAAA,CAAM,UAAA,CAAW,UAAA,CAAW,CAAA;AAC5B,EAAA,KAAA,CAAM,kBAAA,CAAmB,OAAA,CAAQ,CAAA;AACjC,EAAA,MAAA,EAAQ,KAAA,CAAA;AACT;AAEA,SAAS,cAAA,CAAA,EAAuB;AAC/B,EAAA,GAAA,CAAI,CAAC,KAAA,EAAO,MAAA;AAKZ,EAAA,MAAM,KAAA,EAAO,KAAA,CAAM,kBAAA;AACnB,EAAA,QAAA,CAAc,IAAA,CAAA,yBAAA,EAA2B,KAAA,EAAO,IAAA,CAAK,UAAA,CAAW,EAAE,EAAA,EAAI,aAAa,CAAA;AACnF,EAAA,QAAA,CAAc,IAAA,CAAA,yBAAA,EAA2B,KAAA,EAAO,IAAA,CAAK,UAAA,CAAW,EAAE,EAAA,EAAI,aAAa,CAAA;AACnF,EAAA,QAAA,CAAc,IAAA,CAAA,yBAAA,EAA2B,KAAA,EAAO,IAAA,CAAK,UAAA,CAAW,EAAE,EAAA,EAAI,aAAa,CAAA;AACnF,EAAA,QAAA,CAAc,IAAA,CAAA,yBAAA,EAA2B,KAAA,EAAO,IAAA,CAAK,IAAA,EAAM,aAAa,CAAA;AACxE,EAAA,IAAA,CAAK,KAAA,CAAM,CAAA;AAGX,EAAA,MAAM,QAAA,EAAU,uBAAA,CAAY,oBAAA,CAAqB,CAAA;AACjD,EAAA,MAAM,SAAA,EAAW,uBAAA,CAAY,oBAAA,CAAqB,OAAA,EAAS,KAAA,CAAM,wBAAwB,CAAA;AACzF,EAAA,KAAA,CAAM,yBAAA,EAA2B,OAAA;AACjC,EAAA,QAAA,CAAc,IAAA,CAAA,yBAAA,EAA2B,QAAA,CAAS,WAAW,CAAA;AAG7D,EAAA,MAAM,QAAA,EAAU,OAAA,CAAQ,QAAA,CAAS,CAAA;AACjC,EAAA,MAAM,YAAA,EAAc,OAAA,CAAQ,KAAA,EAAO,KAAA,CAAM,YAAA,CAAa,IAAA;AACtD,EAAA,MAAM,cAAA,EAAgB,OAAA,CAAQ,OAAA,EAAS,KAAA,CAAM,YAAA,CAAa,MAAA;AAC1D,EAAA,KAAA,CAAM,aAAA,EAAe,OAAA;AACrB,EAAA,GAAA,CAAI,YAAA,EAAc,CAAA,EAAG;AACpB,IAAA,QAAA,CAAc,IAAA,CAAA,sBAAA,EAAwB,MAAA,EAAQ,YAAA,EAAc,aAAa,CAAA;AAAA,EAC1E;AACA,EAAA,GAAA,CAAI,cAAA,EAAgB,CAAA,EAAG;AACtB,IAAA,QAAA,CAAc,IAAA,CAAA,sBAAA,EAAwB,QAAA,EAAU,cAAA,EAAgB,aAAa,CAAA;AAAA,EAC9E;AAGA,EAAA,MAAM,IAAA,EAAM,OAAA,CAAQ,WAAA,CAAY,CAAA;AAChC,EAAA,QAAA,CAAc,IAAA,CAAA,+BAAA,EAAiC,GAAA,CAAI,GAAG,CAAA;AACtD,EAAA,QAAA,CAAc,IAAA,CAAA,cAAA,EAAgB,MAAA,EAAQ,GAAA,CAAI,QAAQ,CAAA;AAClD,EAAA,QAAA,CAAc,IAAA,CAAA,cAAA,EAAgB,OAAA,EAAS,GAAA,CAAI,SAAS,CAAA;AACpD,EAAA,MAAM,UAAA,EAAY,mCAAA,CAAkB,CAAE,eAAA;AACtC,EAAA,QAAA,CAAc,IAAA,CAAA,cAAA,EAAgB,OAAA,EAAS,SAAS,CAAA;AAMhD,EAAA,MAAM,KAAA,EAAO,OAAA;AAIb,EAAA,GAAA,CAAI,OAAO,IAAA,CAAK,kBAAA,IAAsB,UAAA,EAAY;AACjD,IAAA,QAAA,CAAc,IAAA,CAAA,kBAAA,EAAoB,IAAA,CAAK,iBAAA,CAAkB,CAAA,CAAE,MAAM,CAAA;AAAA,EAClE;AACA,EAAA,GAAA,CAAI,OAAO,IAAA,CAAK,mBAAA,IAAuB,UAAA,EAAY;AAClD,IAAA,QAAA,CAAc,IAAA,CAAA,mBAAA,EAAqB,IAAA,CAAK,kBAAA,CAAmB,CAAA,CAAE,MAAM,CAAA;AAAA,EACpE;AACD;ADrEA;AACE;AACA;AACF,mGAAC","file":"/home/runner/work/rivet/rivet/rivetkit-typescript/packages/rivetkit/dist/tsup/process-metrics-TYAGKCEJ.cjs","sourcesContent":[null,"/**\n * Node.js runtime health metrics.\n *\n * Collects JS-internal data (event loop lag, GC, heap, libuv handles,\n * event loop utilization, CPU) using Node built-ins (`node:perf_hooks`,\n * `process`, `node:v8`, `PerformanceObserver`) and pushes them across NAPI\n * into Rust-side prometheus collectors registered with\n * `rivet_metrics::REGISTRY` so they appear on the existing `/metrics`\n * endpoint.\n *\n * All data collection happens here in TypeScript. The NAPI bridge is pure\n * type marshalling and the Rust side only registers + stores the metrics.\n */\nimport { monitorEventLoopDelay, performance, PerformanceObserver } from \"node:perf_hooks\";\nimport { getHeapStatistics } from \"node:v8\";\nimport * as napi from \"@rivetkit/rivetkit-napi\";\n\n// Some napi process-metrics symbols may be missing on older native binaries\n// (the auto-generated index.js destructures them as `undefined` if the\n// underlying `.node` was built before they were added). Guard each call so\n// the metrics collection runs as a no-op instead of throwing\n// `TypeError: napi.jsXxx is not a function` on every interval tick.\nfunction callIfFn<T extends unknown[]>(\n\tfn: ((...args: T) => void) | undefined,\n\t...args: T\n): void {\n\tif (typeof fn === \"function\") {\n\t\tfn(...args);\n\t}\n}\n\nconst SCRAPE_INTERVAL_MS = 5_000;\nconst HEARTBEAT_INTERVAL_MS = 100;\nconst EVENTLOOP_DELAY_RESOLUTION_MS = 20;\nconst NS_PER_SECOND = 1e9;\nconst US_PER_SECOND = 1e6;\n\n// V8 GC kind bitfield from Node's perf_hooks documentation. A `gc` performance\n// entry's `kind` field is one of these values.\nconst GC_KIND_NAMES: Record<number, string> = {\n\t1: \"minor\",\n\t2: \"major\",\n\t4: \"incremental\",\n\t8: \"weakcb\",\n};\n\ninterface ProcessMetricsState {\n\tscrapeInterval: NodeJS.Timeout;\n\theartbeatInterval: NodeJS.Timeout;\n\tgcObserver: PerformanceObserver;\n\teventLoopHistogram: ReturnType<typeof monitorEventLoopDelay>;\n\tlastCpuUsage: NodeJS.CpuUsage;\n\tlastEventLoopUtilization: ReturnType<typeof performance.eventLoopUtilization>;\n}\n\nlet state: ProcessMetricsState | undefined;\n\nexport function startProcessMetrics(): void {\n\tif (state) {\n\t\treturn;\n\t}\n\n\tconst eventLoopHistogram = monitorEventLoopDelay({\n\t\tresolution: EVENTLOOP_DELAY_RESOLUTION_MS,\n\t});\n\teventLoopHistogram.enable();\n\n\tconst gcObserver = new PerformanceObserver((list) => {\n\t\tfor (const entry of list.getEntries()) {\n\t\t\tconst kind =\n\t\t\t\t(entry as PerformanceEntry & { detail?: { kind?: number }; kind?: number }).detail\n\t\t\t\t\t?.kind ??\n\t\t\t\t(entry as PerformanceEntry & { kind?: number }).kind;\n\t\t\tif (typeof kind !== \"number\") continue;\n\t\t\tconst kindName = GC_KIND_NAMES[kind];\n\t\t\tif (!kindName) continue;\n\t\t\t// `entry.duration` is in milliseconds; convert to seconds.\n\t\t\tcallIfFn(napi.jsObserveGcDuration, kindName, entry.duration / 1000);\n\t\t}\n\t});\n\tgcObserver.observe({ entryTypes: [\"gc\"], buffered: false });\n\n\tconst lastCpuUsage = process.cpuUsage();\n\tconst lastEventLoopUtilization = performance.eventLoopUtilization();\n\n\tconst heartbeatInterval = setInterval(() => {\n\t\tcallIfFn(napi.jsSetEventloopHeartbeatTsMs, Date.now());\n\t}, HEARTBEAT_INTERVAL_MS);\n\theartbeatInterval.unref();\n\n\tconst scrapeInterval = setInterval(() => {\n\t\ttry {\n\t\t\tcollectAndPush();\n\t\t} catch {\n\t\t\t// Collection errors must never bring down the process; metrics\n\t\t\t// are best-effort.\n\t\t}\n\t}, SCRAPE_INTERVAL_MS);\n\tscrapeInterval.unref();\n\n\tstate = {\n\t\tscrapeInterval,\n\t\theartbeatInterval,\n\t\tgcObserver,\n\t\teventLoopHistogram,\n\t\tlastCpuUsage,\n\t\tlastEventLoopUtilization,\n\t};\n\n\t// Emit one snapshot immediately so freshly-scraped instances have data.\n\tcallIfFn(napi.jsSetEventloopHeartbeatTsMs, Date.now());\n\ttry {\n\t\tcollectAndPush();\n\t} catch {\n\t\t// As above; best-effort.\n\t}\n}\n\nexport function stopProcessMetrics(): void {\n\tif (!state) {\n\t\treturn;\n\t}\n\tclearInterval(state.scrapeInterval);\n\tclearInterval(state.heartbeatInterval);\n\tstate.gcObserver.disconnect();\n\tstate.eventLoopHistogram.disable();\n\tstate = undefined;\n}\n\nfunction collectAndPush(): void {\n\tif (!state) return;\n\n\t// Event loop delay quantiles. `monitorEventLoopDelay()` reports values in\n\t// nanoseconds; convert to seconds. Reset after reading so the next window\n\t// reflects only the new interval.\n\tconst hist = state.eventLoopHistogram;\n\tcallIfFn(napi.jsSetEventloopLagQuantile, \"p50\", hist.percentile(50) / NS_PER_SECOND);\n\tcallIfFn(napi.jsSetEventloopLagQuantile, \"p90\", hist.percentile(90) / NS_PER_SECOND);\n\tcallIfFn(napi.jsSetEventloopLagQuantile, \"p99\", hist.percentile(99) / NS_PER_SECOND);\n\tcallIfFn(napi.jsSetEventloopLagQuantile, \"max\", hist.max / NS_PER_SECOND);\n\thist.reset();\n\n\t// Event loop utilization delta over the scrape window.\n\tconst nextElu = performance.eventLoopUtilization();\n\tconst eluDelta = performance.eventLoopUtilization(nextElu, state.lastEventLoopUtilization);\n\tstate.lastEventLoopUtilization = nextElu;\n\tcallIfFn(napi.jsSetEventloopUtilization, eluDelta.utilization);\n\n\t// CPU usage delta. `process.cpuUsage()` returns microseconds.\n\tconst nextCpu = process.cpuUsage();\n\tconst userDeltaUs = nextCpu.user - state.lastCpuUsage.user;\n\tconst systemDeltaUs = nextCpu.system - state.lastCpuUsage.system;\n\tstate.lastCpuUsage = nextCpu;\n\tif (userDeltaUs > 0) {\n\t\tcallIfFn(napi.jsAddProcessCpuSeconds, \"user\", userDeltaUs / US_PER_SECOND);\n\t}\n\tif (systemDeltaUs > 0) {\n\t\tcallIfFn(napi.jsAddProcessCpuSeconds, \"system\", systemDeltaUs / US_PER_SECOND);\n\t}\n\n\t// Memory + heap.\n\tconst mem = process.memoryUsage();\n\tcallIfFn(napi.jsSetProcessResidentMemoryBytes, mem.rss);\n\tcallIfFn(napi.jsSetHeapBytes, \"used\", mem.heapUsed);\n\tcallIfFn(napi.jsSetHeapBytes, \"total\", mem.heapTotal);\n\tconst heapLimit = getHeapStatistics().heap_size_limit;\n\tcallIfFn(napi.jsSetHeapBytes, \"limit\", heapLimit);\n\n\t// libuv active handles + requests. These are unstable Node internals\n\t// guarded behind underscore-prefixed names; if a future Node release\n\t// removes them the try/catch above keeps the rest of the collection\n\t// alive.\n\tconst proc = process as unknown as {\n\t\t_getActiveHandles?: () => unknown[];\n\t\t_getActiveRequests?: () => unknown[];\n\t};\n\tif (typeof proc._getActiveHandles === \"function\") {\n\t\tcallIfFn(napi.jsSetActiveHandles, proc._getActiveHandles().length);\n\t}\n\tif (typeof proc._getActiveRequests === \"function\") {\n\t\tcallIfFn(napi.jsSetActiveRequests, proc._getActiveRequests().length);\n\t}\n}\n"]}
@@ -1,25 +1,25 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2
2
 
3
- var _chunkM5C7YNI5cjs = require('../chunk-M5C7YNI5.cjs');
3
+ var _chunkG5HUSWP4cjs = require('../chunk-G5HUSWP4.cjs');
4
4
 
5
5
 
6
6
 
7
- var _chunkENK7C66Gcjs = require('../chunk-ENK7C66G.cjs');
7
+ var _chunkZGPX6KAHcjs = require('../chunk-ZGPX6KAH.cjs');
8
8
  require('../chunk-LD5YASJU.cjs');
9
- require('../chunk-LIXXFXVR.cjs');
9
+ require('../chunk-FEOG44WH.cjs');
10
10
  require('../chunk-2NDZ7JCR.cjs');
11
- require('../chunk-JALSAX7Z.cjs');
12
- require('../chunk-K5BA2LEO.cjs');
13
- require('../chunk-QAZLM4WT.cjs');
11
+ require('../chunk-SJLPZEA3.cjs');
12
+ require('../chunk-X6HIFXNK.cjs');
13
+ require('../chunk-63WNTDRC.cjs');
14
14
 
15
15
  // src/test/mod.ts
16
16
  var _pretry = require('p-retry'); var _pretry2 = _interopRequireDefault(_pretry);
17
17
  async function waitForRegistryReady(registry) {
18
- const clientConfig = _chunkENK7C66Gcjs.convertRegistryConfigToClientConfig.call(void 0,
18
+ const clientConfig = _chunkZGPX6KAHcjs.convertRegistryConfigToClientConfig.call(void 0,
19
19
  registry.parseConfig()
20
20
  );
21
21
  await _pretry2.default.call(void 0, async () => {
22
- await _chunkENK7C66Gcjs.getMetadata.call(void 0, clientConfig);
22
+ await _chunkZGPX6KAHcjs.getMetadata.call(void 0, clientConfig);
23
23
  }, {
24
24
  retries: 20,
25
25
  minTimeout: 50,
@@ -31,8 +31,8 @@ async function setupTest(c, registry) {
31
31
  registry.config.noWelcome = true;
32
32
  registry.start();
33
33
  await waitForRegistryReady(registry);
34
- const client = _chunkM5C7YNI5cjs.createClient.call(void 0, {
35
- ..._chunkENK7C66Gcjs.convertRegistryConfigToClientConfig.call(void 0, registry.parseConfig()),
34
+ const client = _chunkG5HUSWP4cjs.createClient.call(void 0, {
35
+ ..._chunkZGPX6KAHcjs.convertRegistryConfigToClientConfig.call(void 0, registry.parseConfig()),
36
36
  disableMetadataLookup: false
37
37
  });
38
38
  c.onTestFinished(async () => {
@@ -1,5 +1,5 @@
1
1
  import { TestContext } from 'vitest';
2
- import { ap as Registry, V as Client } from '../config-Ca8dN4cS.cjs';
2
+ import { aq as Registry, V as Client } from '../config-DU_xj4qZ.cjs';
3
3
  import 'zod/v4';
4
4
  import '@rivetkit/virtual-websocket';
5
5
  import '../config-CxjGYf4K.cjs';
@@ -1,5 +1,5 @@
1
1
  import { TestContext } from 'vitest';
2
- import { ap as Registry, V as Client } from '../config-0Ta55UV0.js';
2
+ import { aq as Registry, V as Client } from '../config-Ak1lv4gF.js';
3
3
  import 'zod/v4';
4
4
  import '@rivetkit/virtual-websocket';
5
5
  import '../config-CxjGYf4K.js';
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  createClient
3
- } from "../chunk-EMO6E3PJ.js";
3
+ } from "../chunk-CMV6N5OX.js";
4
4
  import {
5
5
  convertRegistryConfigToClientConfig,
6
6
  getMetadata
7
- } from "../chunk-FLODVLYW.js";
7
+ } from "../chunk-VJ4Y4WBT.js";
8
8
  import "../chunk-3YY5S6TV.js";
9
- import "../chunk-RTC2AZGB.js";
9
+ import "../chunk-4LTY5TOO.js";
10
10
  import "../chunk-PCBNKI2J.js";
11
- import "../chunk-ZI5QJMKO.js";
12
- import "../chunk-6S25NVAP.js";
13
- import "../chunk-KIWH5H3K.js";
11
+ import "../chunk-4DJMFOSU.js";
12
+ import "../chunk-HERL2VQ2.js";
13
+ import "../chunk-TMLOKTRB.js";
14
14
 
15
15
  // src/test/mod.ts
16
16
  import pRetry from "p-retry";
@@ -17,8 +17,8 @@
17
17
 
18
18
 
19
19
 
20
- var _chunkK5BA2LEOcjs = require('./chunk-K5BA2LEO.cjs');
21
- require('./chunk-QAZLM4WT.cjs');
20
+ var _chunkX6HIFXNKcjs = require('./chunk-X6HIFXNK.cjs');
21
+ require('./chunk-63WNTDRC.cjs');
22
22
 
23
23
 
24
24
 
@@ -38,5 +38,5 @@ require('./chunk-QAZLM4WT.cjs');
38
38
 
39
39
 
40
40
 
41
- exports.EXTRA_ERROR_LOG = _chunkK5BA2LEOcjs.EXTRA_ERROR_LOG; exports.SinglePromiseQueue = _chunkK5BA2LEOcjs.SinglePromiseQueue; exports.VERSION = _chunkK5BA2LEOcjs.VERSION; exports.arrayBuffersEqual = _chunkK5BA2LEOcjs.arrayBuffersEqual; exports.assertUnreachable = _chunkK5BA2LEOcjs.assertUnreachable; exports.bufferToArrayBuffer = _chunkK5BA2LEOcjs.bufferToArrayBuffer; exports.combineUrlPath = _chunkK5BA2LEOcjs.combineUrlPath; exports.dbg = _chunkK5BA2LEOcjs.dbg; exports.detectRuntime = _chunkK5BA2LEOcjs.detectRuntime; exports.getEnvUniversal = _chunkK5BA2LEOcjs.getEnvUniversal; exports.httpUserAgent = _chunkK5BA2LEOcjs.httpUserAgent; exports.interval = _chunkK5BA2LEOcjs.interval; exports.joinSignals = _chunkK5BA2LEOcjs.joinSignals; exports.promiseWithResolvers = _chunkK5BA2LEOcjs.promiseWithResolvers; exports.setLongTimeout = _chunkK5BA2LEOcjs.setLongTimeout; exports.sleep = _chunkK5BA2LEOcjs.sleep; exports.stringifyError = _chunkK5BA2LEOcjs.stringifyError; exports.toUint8Array = _chunkK5BA2LEOcjs.toUint8Array;
41
+ exports.EXTRA_ERROR_LOG = _chunkX6HIFXNKcjs.EXTRA_ERROR_LOG; exports.SinglePromiseQueue = _chunkX6HIFXNKcjs.SinglePromiseQueue; exports.VERSION = _chunkX6HIFXNKcjs.VERSION; exports.arrayBuffersEqual = _chunkX6HIFXNKcjs.arrayBuffersEqual; exports.assertUnreachable = _chunkX6HIFXNKcjs.assertUnreachable; exports.bufferToArrayBuffer = _chunkX6HIFXNKcjs.bufferToArrayBuffer; exports.combineUrlPath = _chunkX6HIFXNKcjs.combineUrlPath; exports.dbg = _chunkX6HIFXNKcjs.dbg; exports.detectRuntime = _chunkX6HIFXNKcjs.detectRuntime; exports.getEnvUniversal = _chunkX6HIFXNKcjs.getEnvUniversal; exports.httpUserAgent = _chunkX6HIFXNKcjs.httpUserAgent; exports.interval = _chunkX6HIFXNKcjs.interval; exports.joinSignals = _chunkX6HIFXNKcjs.joinSignals; exports.promiseWithResolvers = _chunkX6HIFXNKcjs.promiseWithResolvers; exports.setLongTimeout = _chunkX6HIFXNKcjs.setLongTimeout; exports.sleep = _chunkX6HIFXNKcjs.sleep; exports.stringifyError = _chunkX6HIFXNKcjs.stringifyError; exports.toUint8Array = _chunkX6HIFXNKcjs.toUint8Array;
42
42
  //# sourceMappingURL=utils.cjs.map
@@ -17,8 +17,8 @@ import {
17
17
  sleep,
18
18
  stringifyError,
19
19
  toUint8Array
20
- } from "./chunk-6S25NVAP.js";
21
- import "./chunk-KIWH5H3K.js";
20
+ } from "./chunk-HERL2VQ2.js";
21
+ import "./chunk-TMLOKTRB.js";
22
22
  export {
23
23
  EXTRA_ERROR_LOG,
24
24
  SinglePromiseQueue,
@@ -1,22 +1,23 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } var _class; var _class2;
2
2
 
3
- var _chunk2G64KSZQcjs = require('../chunk-2G64KSZQ.cjs');
3
+ var _chunk2H4ISA4Ycjs = require('../chunk-2H4ISA4Y.cjs');
4
4
 
5
5
 
6
6
 
7
- var _chunkWQ4HNA4Wcjs = require('../chunk-WQ4HNA4W.cjs');
8
- require('../chunk-HTR4YLNT.cjs');
7
+
8
+ var _chunkSRNOPUC6cjs = require('../chunk-SRNOPUC6.cjs');
9
+ require('../chunk-55E7IR6D.cjs');
9
10
 
10
11
 
11
12
 
12
13
  var _chunkLD5YASJUcjs = require('../chunk-LD5YASJU.cjs');
13
- require('../chunk-LIXXFXVR.cjs');
14
+ require('../chunk-FEOG44WH.cjs');
14
15
 
15
16
 
16
- var _chunkK5BA2LEOcjs = require('../chunk-K5BA2LEO.cjs');
17
+ var _chunkX6HIFXNKcjs = require('../chunk-X6HIFXNK.cjs');
17
18
 
18
19
 
19
- var _chunkQAZLM4WTcjs = require('../chunk-QAZLM4WT.cjs');
20
+ var _chunk63WNTDRCcjs = require('../chunk-63WNTDRC.cjs');
20
21
 
21
22
  // src/workflow/mod.ts
22
23
 
@@ -346,14 +347,14 @@ var ActorWorkflowContext = class _ActorWorkflowContext {
346
347
  return await this.#wrapActive(
347
348
  () => this.#inner.step(
348
349
  nameOrConfig,
349
- () => this.#withActorAccess(run)
350
+ () => this.#withActorAccessAndStateRollback(run)
350
351
  )
351
352
  );
352
353
  }
353
354
  const stepConfig = nameOrConfig;
354
355
  const config = {
355
356
  ...stepConfig,
356
- run: () => this.#withActorAccess(stepConfig.run)
357
+ run: () => this.#withActorAccessAndStateRollback(stepConfig.run)
357
358
  };
358
359
  return await this.#wrapActive(() => this.#inner.step(config));
359
360
  }
@@ -365,14 +366,14 @@ var ActorWorkflowContext = class _ActorWorkflowContext {
365
366
  return await this.#wrapActive(
366
367
  () => this.#inner.tryStep(
367
368
  nameOrConfig,
368
- () => this.#withActorAccess(run)
369
+ () => this.#withActorAccessAndStateRollback(run)
369
370
  )
370
371
  );
371
372
  }
372
373
  const stepConfig = nameOrConfig;
373
374
  const config = {
374
375
  ...stepConfig,
375
- run: () => this.#withActorAccess(stepConfig.run)
376
+ run: () => this.#withActorAccessAndStateRollback(stepConfig.run)
376
377
  };
377
378
  return await this.#wrapActive(() => this.#inner.tryStep(config));
378
379
  }
@@ -543,6 +544,30 @@ var ActorWorkflowContext = class _ActorWorkflowContext {
543
544
  }
544
545
  }
545
546
  }
547
+ async #withActorAccessAndStateRollback(run) {
548
+ let stateSnapshot = null;
549
+ try {
550
+ stateSnapshot = { state: this.#runCtx[_chunkSRNOPUC6cjs.RAW_STATE_SYMBOL]() };
551
+ } catch (error) {
552
+ this.#runCtx.log.debug({
553
+ msg: "failed to get state, likely due to being stateless workflow",
554
+ error
555
+ });
556
+ }
557
+ if (stateSnapshot) {
558
+ stateSnapshot.state = structuredClone(stateSnapshot.state);
559
+ }
560
+ const varsSnapshot = structuredClone(this.#runCtx.vars);
561
+ try {
562
+ return await this.#withActorAccess(run);
563
+ } catch (error) {
564
+ if (stateSnapshot) {
565
+ this.#runCtx.state = stateSnapshot.state;
566
+ }
567
+ this.#runCtx.vars = varsSnapshot;
568
+ throw error;
569
+ }
570
+ }
546
571
  #ensureActorAccess(feature) {
547
572
  if (!this.#allowActorAccess) {
548
573
  this.#guardViolation = true;
@@ -595,7 +620,7 @@ function shouldRethrowWorkflowError(error) {
595
620
  return true;
596
621
  }
597
622
  function workflowReplayInFlightError() {
598
- return new (0, _chunkQAZLM4WTcjs.RivetError)(
623
+ return new (0, _chunk63WNTDRCcjs.RivetError)(
599
624
  "actor",
600
625
  "workflow_in_flight",
601
626
  "Workflow replay is unavailable while the workflow is currently in flight.",
@@ -614,13 +639,13 @@ function workflow(fn, options = {}) {
614
639
  function getWorkflowInspector(actorId) {
615
640
  let workflowInspector = workflowInspectors.get(actorId);
616
641
  if (!workflowInspector) {
617
- workflowInspector = _chunk2G64KSZQcjs.createWorkflowInspectorAdapter.call(void 0, );
642
+ workflowInspector = _chunk2H4ISA4Ycjs.createWorkflowInspectorAdapter.call(void 0, );
618
643
  workflowInspectors.set(actorId, workflowInspector);
619
644
  }
620
645
  return workflowInspector;
621
646
  }
622
647
  async function run(runCtx) {
623
- const actor = runCtx[_chunkWQ4HNA4Wcjs.ACTOR_CONTEXT_INTERNAL_SYMBOL];
648
+ const actor = runCtx[_chunkSRNOPUC6cjs.ACTOR_CONTEXT_INTERNAL_SYMBOL];
624
649
  _invariant2.default.call(void 0, actor, "workflow() requires an actor instance");
625
650
  const workflowInspector = getWorkflowInspector(actor.id);
626
651
  const driver = new ActorWorkflowDriver(actor, runCtx);
@@ -680,20 +705,20 @@ function workflow(fn, options = {}) {
680
705
  if (shouldRethrowWorkflowError(error)) {
681
706
  runCtx.log.error({
682
707
  msg: "workflow run failed",
683
- error: _chunkK5BA2LEOcjs.stringifyError.call(void 0, error)
708
+ error: _chunkX6HIFXNKcjs.stringifyError.call(void 0, error)
684
709
  });
685
710
  throw error;
686
711
  }
687
712
  runCtx.log.warn({
688
713
  msg: "workflow failed and will sleep until woken",
689
- error: _chunkK5BA2LEOcjs.stringifyError.call(void 0, error)
714
+ error: _chunkX6HIFXNKcjs.stringifyError.call(void 0, error)
690
715
  });
691
716
  } finally {
692
717
  runCtx.abortSignal.removeEventListener("abort", onAbort);
693
718
  }
694
719
  }
695
720
  const runWithConfig = run;
696
- runWithConfig[_chunkWQ4HNA4Wcjs.RUN_FUNCTION_CONFIG_SYMBOL] = {
721
+ runWithConfig[_chunkSRNOPUC6cjs.RUN_FUNCTION_CONFIG_SYMBOL] = {
697
722
  icon: "diagram-project",
698
723
  inspectorFactory: (actor) => {
699
724
  const actorId = resolveWorkflowInspectorActorId(actor);