@voltro/cli 0.48.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/dist/apiBuild-BWo8KI6n.js +2 -0
  3. package/dist/{apiBuild-Dz8TJSxp.js → apiBuild-CFYXo06U.js} +1 -1
  4. package/dist/bin.js +1 -1
  5. package/dist/{build-DLme2ppa.js → build-CnSH-zru.js} +6 -6
  6. package/dist/{checkCommand-Dals7g-I.js → checkCommand-Do3SQbLx.js} +3 -3
  7. package/dist/{checkCommand-BUBqPBlI.js → checkCommand-OL41BMIb.js} +1 -1
  8. package/dist/{codegenCommand-L6vacVRW.js → codegenCommand-BJzaRz6q.js} +39 -47
  9. package/dist/{codemodRunner-DSZjgyCL.js → codemodRunner-De3k0pRd.js} +859 -629
  10. package/dist/{commands-CAxFLqG4.js → commands-By23Ljny.js} +68 -60
  11. package/dist/{dashboardCommand-CJC8Kg-s.js → dashboardCommand-DN1rAABE.js} +1 -1
  12. package/dist/dataCommand-B93TUBIx.js +1306 -0
  13. package/dist/dataProfile-Du3ztYxv.js +51 -0
  14. package/dist/{dbCommand-ZGNItjoJ.js → dbCommand-Bf7Cy0mn.js} +2 -2
  15. package/dist/dbCommand-Bnl7MSGC.js +2 -0
  16. package/dist/{dev-lvnVq5RD.js → dev-1yu42ubu.js} +2 -2
  17. package/dist/{dev-cGGsLNn6.js → dev-BWwE0QjK.js} +1 -1
  18. package/dist/doctorCommand-BmovAwb7.js +2 -0
  19. package/dist/{doctorCommand-BK0qu7eD.js → doctorCommand-y-EbP8st.js} +12 -12
  20. package/dist/{dormancyCommand-CyIk-zq4.js → dormancyCommand-Dc7KRNCG.js} +1 -1
  21. package/dist/{embeddingsCommand-D7TLklps.js → embeddingsCommand-kPs132bB.js} +1 -1
  22. package/dist/{envCommand-BHxKkGXq.js → envCommand-E12zSt51.js} +1 -1
  23. package/dist/{evolveCommand-CQh6dw21.js → evolveCommand-B3nagPVc.js} +2 -2
  24. package/dist/{frameworkTableAssembly-BNod_DKN.js → frameworkTableAssembly-BwJVEKLr.js} +3 -3
  25. package/dist/frameworkTableAssembly-CVDB2hCq.js +2 -0
  26. package/dist/index.js +1 -1
  27. package/dist/{infoCommand-CuNl9cbh.js → infoCommand-Cq0Yz98u.js} +1 -1
  28. package/dist/{interruptedReplace-C1ZI84xi.js → interruptedReplace-C3O3M1MM.js} +2 -1
  29. package/dist/interruptedReplace-CvmiAM9K.js +2 -0
  30. package/dist/{migrate-CL5Ed01M.js → migrate-D3MK9BpK.js} +2 -2
  31. package/dist/{runtimeTrace-C0SlIoQY.js → runtimeTrace-BpLUcrfy.js} +1 -1
  32. package/dist/{sdkgen-BXm7zx7F.js → sdkgen-dl4-WKF6.js} +1 -1
  33. package/dist/serveCommand-8CTzQCY0.js +2362 -0
  34. package/dist/serveCommand-C_WI4TTG.js +2 -0
  35. package/dist/serveEntry.js +5 -5
  36. package/dist/{subcommandNames-CKG5Dz3a.js → subcommandNames-DpYs3DXr.js} +12 -2
  37. package/dist/updateCommand-D91-TZ7E.js +2 -0
  38. package/dist/{updateCommand-BlyXavoG.js → updateCommand-i8JbrLAA.js} +2 -1
  39. package/dist/{webhooksCommand-QlAk_tED.js → webhooksCommand-B0bdyuQ4.js} +1 -1
  40. package/package.json +47 -17
  41. package/templates/AGENTS.md +1 -1
  42. package/templates/agent-docs/_index.md +1 -1
  43. package/templates/agent-docs/cli.md +124 -16
  44. package/templates/agent-docs/whats-new.md +30 -52
  45. package/templates/apps/api-ai/package.json +7 -7
  46. package/templates/apps/api-auth/package.json +8 -8
  47. package/templates/apps/api-backend/package.json +7 -7
  48. package/templates/apps/api-backend-deactivation/package.json +7 -7
  49. package/templates/apps/api-backend-mail/package.json +8 -8
  50. package/templates/apps/api-backend-mariadb/package.json +9 -9
  51. package/templates/apps/api-backend-sqlite/package.json +8 -8
  52. package/templates/apps/api-backend-storage/package.json +8 -8
  53. package/templates/apps/api-cms/package.json +10 -10
  54. package/templates/apps/api-collab/package.json +8 -8
  55. package/templates/apps/api-data-advanced/package.json +8 -8
  56. package/templates/apps/api-durable/package.json +8 -8
  57. package/templates/apps/api-feature-flags/package.json +9 -9
  58. package/templates/apps/api-governance/package.json +8 -8
  59. package/templates/apps/api-kv/package.json +8 -8
  60. package/templates/apps/api-moderation/package.json +8 -8
  61. package/templates/apps/api-observability/package.json +8 -8
  62. package/templates/apps/api-ratelimit/package.json +8 -8
  63. package/templates/apps/api-rbac/package.json +8 -8
  64. package/templates/apps/api-rest/package.json +7 -7
  65. package/templates/apps/api-saas/package.json +11 -11
  66. package/templates/apps/api-saas-starter/package.json +10 -10
  67. package/templates/apps/api-search/package.json +8 -8
  68. package/templates/apps/api-status/package.json +8 -8
  69. package/templates/apps/api-versioning/package.json +8 -8
  70. package/templates/apps/api-webhooks/package.json +9 -9
  71. package/templates/apps/changelog/package.json +6 -6
  72. package/templates/apps/edge-functions/package.json +2 -2
  73. package/templates/apps/frontend-admin/package.json +8 -8
  74. package/templates/apps/frontend-app/package.json +9 -9
  75. package/templates/apps/frontend-auth/package.json +8 -8
  76. package/templates/apps/frontend-blank/package.json +7 -7
  77. package/templates/apps/frontend-cms/package.json +9 -9
  78. package/templates/apps/frontend-collab/package.json +10 -10
  79. package/templates/apps/frontend-contact/package.json +7 -7
  80. package/templates/apps/frontend-dashboard/package.json +7 -7
  81. package/templates/apps/frontend-docs/package.json +7 -7
  82. package/templates/apps/frontend-i18n/package.json +6 -6
  83. package/templates/apps/frontend-landing/package.json +7 -7
  84. package/templates/apps/frontend-portal/package.json +8 -8
  85. package/templates/apps/frontend-saas/package.json +8 -8
  86. package/templates/apps/frontend-spa/package.json +7 -7
  87. package/templates/apps/frontend-ssr/package.json +7 -7
  88. package/templates/apps/frontend-ssr-api/package.json +8 -8
  89. package/templates/apps/frontend-static-blog/package.json +6 -6
  90. package/templates/apps/frontend-status/package.json +8 -8
  91. package/templates/apps/mobile-app/package.json +4 -4
  92. package/dist/apiBuild-DOnvi2zm.js +0 -2
  93. package/dist/dataCommand-hIaq2iKY.js +0 -1052
  94. package/dist/dataProfile-Cm0YVKSy.js +0 -18
  95. package/dist/dbCommand-D1Q33ktl.js +0 -2
  96. package/dist/doctorCommand-CWgUPye-.js +0 -2
  97. package/dist/frameworkTableAssembly-Rft-DPUg.js +0 -2
  98. package/dist/interruptedReplace-DNJ7MKph.js +0 -2
  99. package/dist/serveCommand-CV3YO9L3.js +0 -2035
  100. package/dist/serveCommand-ZP_Cb-yz.js +0 -2
  101. package/dist/updateCommand-CT5AvVg7.js +0 -2
@@ -0,0 +1,2362 @@
1
+ import { t as e } from "./nodeEnvironment-cGFAj1J8.js";
2
+ import { t } from "./frameworkInspectState-CX2250XB.js";
3
+ import { r as n, t as r } from "./appModuleLoader-C9r9mxZt.js";
4
+ import { t as i } from "./bootRefusal-pgvDxlrU.js";
5
+ import { n as a, r as o } from "./startupRunner-CEqQq7ax.js";
6
+ import { t as s } from "./interruptedReplace-C3O3M1MM.js";
7
+ import { $ as c, $t as l, A as u, At as d, Bt as f, C as ee, Cn as te, Ct as ne, D as p, Dt as m, E as h, En as re, Et as g, F as ie, Ft as ae, G as oe, Gt as se, H as _, Ht as ce, I as le, It as ue, J as de, Jt as v, K as y, Kt as fe, L as b, Lt as pe, M as me, Mt as he, N as ge, Nt as _e, O as ve, Ot as ye, P as be, Pt as xe, Q as Se, Qt as Ce, R as x, Rt as we, S as Te, St as Ee, T as De, Tn as Oe, Tt as S, U as ke, V as Ae, W as je, Wt as Me, X as Ne, Xt as Pe, Y as Fe, Yt as C, Z as Ie, Zt as Le, _ as w, _n as Re, _t as T, an as ze, at as Be, b as Ve, bn as He, bt as Ue, c as We, cn as Ge, ct as Ke, dn as qe, dt as Je, en as Ye, et as Xe, f as Ze, fn as Qe, ft as $e, g as et, gt as tt, h as nt, hn as rt, ht as it, i as at, in as ot, it as st, j as ct, jt as lt, k as ut, kt as dt, ln as ft, lt as pt, m as mt, mn as ht, mt as gt, nn as _t, nt as E, o as D, on as vt, ot as O, p as k, pn as yt, pt as bt, q as xt, qt as St, r as Ct, rn as A, rt as wt, sn as j, st as Tt, t as Et, tn as Dt, tt as Ot, u as kt, un as At, ut as jt, v as Mt, vn as Nt, vt as M, w as N, wn as Pt, wt as Ft, x as It, xn as Lt, xt as Rt, y as zt, yn as Bt, yt as Vt, zt as Ht } from "./dev-1yu42ubu.js";
8
+ import { n as Ut } from "./cliArgs-D4p8n7EE.js";
9
+ import { r as P } from "./appPort-B_HpJ_ck.js";
10
+ import { ht as Wt, pt as Gt } from "./webDev-B4IEMB0n.js";
11
+ import { r as F } from "./dialectDriver-czCHYpeH.js";
12
+ import { i as Kt, n as qt } from "./connectionConfig-Bk9IC7D0.js";
13
+ import { c as Jt, n as I, o as Yt } from "./seedRunner-Dgsiwk_e.js";
14
+ import { b as Xt, d as Zt, h as Qt, m as $t, p as en, r as tn, y as nn } from "./frameworkTableAssembly-BwJVEKLr.js";
15
+ import { n as rn, r as an, t as on } from "./declaredSchemaGates-BlcwObhb.js";
16
+ import { S as sn, c as cn, n as ln, p as un, s as dn, x as fn } from "./fileConventions-Cof68_BL.js";
17
+ import { h as pn, o as mn } from "./inspect-B7U7Cl_Z.js";
18
+ import { n as hn } from "./mssqlClusterPatch-_4cE_nun.js";
19
+ import { i as gn, n as _n, r as vn, t as yn } from "./webhookDiscovery-CphsQe59.js";
20
+ import { t as bn } from "./inspectMetrics-CfdKLh6t.js";
21
+ import { r as xn, u as Sn } from "./apiBuild-CFYXo06U.js";
22
+ import { t as Cn } from "./bootTiming-BdyP9nYw.js";
23
+ import { a as wn, o as Tn, t as En } from "./dataProfile-Du3ztYxv.js";
24
+ import L, { basename as Dn, join as On } from "node:path";
25
+ import { createWriteStream as kn, existsSync as An } from "node:fs";
26
+ import { pathToFileURL as jn } from "node:url";
27
+ import { createLogger as R } from "@voltro/logger";
28
+ import { AuthMiddleware as Mn, ConnectionInfoMiddleware as Nn, actionToRpc as Pn, anonymousSubject as Fn, isWireReachable as In, mutationToRpc as Ln, queryToRpc as z, streamToRpc as Rn, wireErrorUnion as zn, workflowCancelDescriptor as Bn, workflowDomainEventsQueryDescriptor as B, workflowEventDeliveriesQueryDescriptor as Vn, workflowResumeDescriptor as Hn, workflowRunEventsQueryDescriptor as Un, workflowRunQueryDescriptor as Wn, workflowRunStepsQueryDescriptor as Gn, workflowRunsQueryDescriptor as Kn, workflowSignalDescriptor as V, workflowUpdateDescriptor as H } from "@voltro/protocol";
29
+ import { DATA_TRANSFERS_TABLE as U, _voltroDataTransfersTable as qn, allRegisteredTables as Jn, and as Yn, connectionIdentity as Xn, derivedRowId as Zn, describeTransferRun as Qn, ensureTableRegistered as $n, eq as W, or as er } from "@voltro/database";
30
+ import { Cause as tr, Effect as G, Layer as K, ManagedRuntime as nr } from "effect";
31
+ import { SqlClient as rr } from "@effect/sql";
32
+ import { declaredSnapshot as ir, describeOutcome as ar, pendingFileMigrationIds as or, runPlannedMigrations as sr } from "@voltro/database/sql";
33
+ import { AggregateRegistry as cr, CostRegistry as lr, DORMANCY_WAKEUP_TENANT as ur, Dispatcher as dr, ExpectationRegistry as fr, ExperimentRegistry as pr, apiKeyManagementRoutes as mr, attachAnalyticsMirror as hr, attachExpectations as gr, attachExperiments as _r, attachFinops as vr, awaitServerListening as yr, bindMutation as q, bindStream as br, bindSubscription as xr, buildTracingLayer as Sr, cancelWakeup as Cr, compileCron as wr, dataStoreApiKeyStore as Tr, formatServerOnlyLeaks as Er, formatUnresolvedSources as Dr, frameworkApiKeyStrategy as Or, getResourcePolicy as kr, installPolicyGuardResolver as Ar, loadResourceTuples as jr, makeActionRunner as Mr, makeAdvisoryLockCoordinator as Nr, makeApiKeyService as Pr, makeApiKeyUsageBuffer as Fr, makeApiKeyUsageFlusher as Ir, makeAsyncKv as Lr, makeAuthMiddlewareLayers as Rr, makeCoordinatedScheduler as zr, makeEffectStoreLayer as Br, makeLazyWorkflowFacade as Vr, makeMutationOutputCodec as Hr, makeMutationRunner as J, makeOneShotQueryRunner as Ur, makeQueryDescriptorProducer as Wr, makeQueryFinalizer as Gr, makeQueryReauthorizer as Kr, makeQuerySubscriber as qr, makeSchemaRegistry as Jr, makeWorkflowFacade as Yr, makeWorkflowFacadeWithCallerContext as Xr, makeWorkflowLayers as Y, noopKv as Zr, onProcessShutdown as Qr, recordSubscriptionDelivery as $r, recordWorkflowRun as ei, registerDefaultTupleSource as ti, registerWakeup as ni, resolveSecretsBackend as ri, runProvidedEffect as ii, setSecretsBackend as ai, setSystemStoreHandle as oi, shutdownGraceMsFromEnv as si, singleCoordinator as ci, startRpcServer as li, startScheduler as ui, stripForbiddenForWire as di, undoCaptureEnabled as fi, unresolvedSources as pi, withScopedRequest as mi, workflowToRpc as hi, wrapStoreWithBootCodec as gi } from "@voltro/runtime";
34
+ import _i, { tmpdir as vi } from "node:os";
35
+ import { RpcGroup as yi } from "@effect/rpc";
36
+ import { appStorageProvider as bi, durabilityNotice as xi, fromNodeReadable as Si, getObjectStream as Ci, putObjectStream as wi, toNodeReadable as Ti } from "@voltro/plugin-storage";
37
+ import { isEnvContract as Ei } from "@voltro/env";
38
+ import { assertProductionSessionSecret as Di } from "@voltro/protocol/session";
39
+ import X from "node:fs/promises";
40
+ import { createHash as Oi, timingSafeEqual as ki } from "node:crypto";
41
+ import { buildDeliverWebhookExecute as Ai, buildWebhooksService as ji, defaultIncomingPath as Mi, deliverWebhookWorkflow as Ni, makeDeferredEmitHandler as Pi, mountIncomingWebhook as Fi } from "@voltro/plugin-webhooks";
42
+ import { getAuthSessionStrategy as Ii } from "@voltro/plugin-auth";
43
+ import { registerEmailTemplates as Li } from "@voltro/plugin-mail";
44
+ import { channelFor as Ri, getBroadcastPlugin as zi } from "@voltro/plugin-broadcast";
45
+ import { checkSchemaDrift as Bi, decideStaging as Vi, isEnvironmentLocal as Hi, packBundle as Ui, peekBundle as Wi, runExport as Gi, runImport as Ki, storageBlobSink as qi, storageRefsBlobSource as Ji, unpackBundle as Yi, unpackBundleToDir as Xi } from "@voltro/data-transfer";
46
+ //#region \0rolldown/runtime.js
47
+ var Zi = /* @__PURE__ */ ((e) => typeof require < "u" ? require : typeof Proxy < "u" ? new Proxy(e, { get: (e, t) => (typeof require < "u" ? require : e)[t] }) : e)(function(e) {
48
+ if (typeof require < "u") return require.apply(this, arguments);
49
+ throw Error("Calling `require` for \"" + e + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
50
+ }), Qi = () => Math.max(500, Math.floor(si() * .6)), $i = (e) => new Promise((t) => setTimeout(t, e)), ea = (e) => {
51
+ let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), r = 0;
52
+ e.on("connection", (e) => {
53
+ t.add(e), e.once("close", () => {
54
+ t.delete(e), n.delete(e);
55
+ });
56
+ }), e.on("upgrade", (e, t) => {
57
+ n.add(t);
58
+ }), e.on("request", (e, t) => {
59
+ r += 1, t.once("close", () => {
60
+ --r;
61
+ });
62
+ });
63
+ let i, a = async (t = {}) => {
64
+ let n = t.budgetMs ?? Qi();
65
+ i ??= new Promise((t) => {
66
+ e.close(() => {
67
+ t();
68
+ });
69
+ }), e.closeIdleConnections();
70
+ let a = Date.now() + n;
71
+ for (; r > 0 && Date.now() < a;) await $i(25), e.closeIdleConnections();
72
+ e.closeIdleConnections();
73
+ }, o = async () => {
74
+ i ??= new Promise((t) => {
75
+ e.close(() => {
76
+ t();
77
+ });
78
+ });
79
+ for (let e of t) if (n.has(e)) try {
80
+ e.write(Buffer.from([
81
+ 136,
82
+ 2,
83
+ 3,
84
+ 233
85
+ ]));
86
+ } catch {}
87
+ else e.destroy();
88
+ for (let e = 0; t.size > 0 && e < 250; e += 25) await $i(25);
89
+ for (let e of t) e.destroy();
90
+ await i;
91
+ };
92
+ return {
93
+ activeRequests: () => r,
94
+ drainRequests: a,
95
+ finish: o,
96
+ drain: async (e = {}) => {
97
+ await a(e), await o();
98
+ }
99
+ };
100
+ }, ta = "/_voltro/admin/import", na = "/_voltro/admin/import/start", ra = "/_voltro/admin/export", ia = "/_voltro/admin/export/download", aa = "/_voltro/admin/transfers", Z = (e, t) => ({
101
+ status: e,
102
+ contentType: "application/json; charset=utf-8",
103
+ body: JSON.stringify(t)
104
+ }), oa = (e) => {
105
+ let t = e.authorization ?? e.Authorization, n = t ? /^Bearer\s+(.+)$/i.exec(t) : null;
106
+ return n ? n[1] : null;
107
+ }, sa = (e, t) => ki(Oi("sha256").update(e).digest(), Oi("sha256").update(t).digest()), ca = (e, t, n = "POST") => {
108
+ if (e.method.toUpperCase() !== n) return Z(405, { error: "method not allowed" });
109
+ if (!t || t.length < 16) return Z(503, { error: "data transfer misconfigured (no/weak secret)" });
110
+ let r = oa(e.headers);
111
+ return !r || !sa(r, t) ? Z(401, { error: "unauthorized" }) : null;
112
+ }, la = /^[A-Za-z0-9_-]{8,64}$/, ua = (e) => la.test(e), da = () => process.env.VOLTRO_IMPORT_UPLOAD_DIR ?? L.join(_i.tmpdir(), "voltro-import-uploads"), fa = (e) => L.join(da(), e), pa = (e) => L.join(fa(e), "archive.bin"), ma = (e) => L.join(fa(e), "meta.json"), ha = async (e = Date.now()) => {
113
+ let t = 0;
114
+ try {
115
+ for (let n of await X.readdir(da())) {
116
+ if (n === ".runs") continue;
117
+ let r = await X.stat(fa(n)).catch(() => null);
118
+ r !== null && (e - r.mtimeMs <= 864e5 || (await X.rm(fa(n), {
119
+ recursive: !0,
120
+ force: !0
121
+ }).catch(() => void 0), t++));
122
+ }
123
+ } catch {}
124
+ return t;
125
+ }, ga = async (e) => {
126
+ if (!ua(e)) return {
127
+ bytes: 0,
128
+ key: null,
129
+ runId: null
130
+ };
131
+ let t = await X.stat(pa(e)).catch(() => null);
132
+ if (t === null) return {
133
+ bytes: 0,
134
+ key: null,
135
+ runId: null
136
+ };
137
+ let n = await _a(e);
138
+ return {
139
+ bytes: t.size,
140
+ key: n.key ?? null,
141
+ runId: n.runId ?? null
142
+ };
143
+ }, _a = async (e) => {
144
+ try {
145
+ let t = await X.readFile(ma(e), "utf8");
146
+ return JSON.parse(t);
147
+ } catch {
148
+ return {};
149
+ }
150
+ }, va = async (e, t) => {
151
+ let n = ma(e), r = `${n}.${process.pid}.${Math.random().toString(36).slice(2, 8)}.tmp`;
152
+ await X.writeFile(r, JSON.stringify(t)), await X.rename(r, n);
153
+ }, ya = async (e, t, n) => {
154
+ if (!ua(e)) return t;
155
+ await X.mkdir(fa(e), { recursive: !0 });
156
+ let r = await _a(e), i = typeof r.runId == "string" && r.runId.length > 0 ? r.runId : null;
157
+ return i !== null && n?.takeOver !== !0 ? i : (await va(e, {
158
+ ...r,
159
+ runId: t
160
+ }), t);
161
+ }, ba = async (e) => {
162
+ if (!ua(e)) return;
163
+ let t = await _a(e);
164
+ if (t.runId === void 0) return;
165
+ let { runId: n, ...r } = t;
166
+ await va(e, r).catch(() => void 0);
167
+ }, xa = async (e, t, n) => (await X.mkdir(fa(e), { recursive: !0 }), await X.writeFile(pa(e), Buffer.from(t)), await va(e, {
168
+ ...await _a(e),
169
+ key: n,
170
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
171
+ }), t.byteLength), Sa = (e) => `up-${Oi("sha256").update(e).digest("hex").slice(0, 32)}`, Ca = async (e) => {
172
+ if (!ua(e.id)) return {
173
+ reason: "bad-id",
174
+ message: `upload id must match ${String(la)}`
175
+ };
176
+ let t = await ga(e.id);
177
+ if (t.key !== null && t.key !== e.key) return {
178
+ reason: "key-mismatch",
179
+ message: "this upload id already holds a different bundle. Use a new upload id, or delete the partial upload."
180
+ };
181
+ if (e.offset !== t.bytes) return {
182
+ reason: "offset-mismatch",
183
+ message: `chunk starts at ${e.offset} but the server holds ${t.bytes} byte(s)`,
184
+ expectedOffset: t.bytes
185
+ };
186
+ if (await X.mkdir(fa(e.id), { recursive: !0 }), t.key === null) {
187
+ let t = await _a(e.id);
188
+ await va(e.id, {
189
+ ...t,
190
+ key: e.key,
191
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
192
+ });
193
+ }
194
+ return await new Promise((t, n) => {
195
+ let r = kn(pa(e.id), { flags: "a" });
196
+ r.on("error", n), r.on("finish", () => t()), r.end(Buffer.from(e.bytes));
197
+ }), { total: t.bytes + e.bytes.byteLength };
198
+ }, wa = async (e) => {
199
+ let t = await X.stat(pa(e));
200
+ return {
201
+ path: pa(e),
202
+ bytes: t.size
203
+ };
204
+ }, Ta = () => L.join(da(), ".runs"), Ea = (e) => L.join(Ta(), `${e}.bin`), Da = async (e, t) => {
205
+ if (!ua(e)) return null;
206
+ let n = pa(e), r = await X.stat(n).catch(() => null);
207
+ if (r === null || r.size === 0) return null;
208
+ await X.mkdir(Ta(), { recursive: !0 });
209
+ let i = Ea(t);
210
+ return await X.rename(n, i), i;
211
+ }, Oa = async (e) => {
212
+ await X.rm(Ea(e), { force: !0 }).catch(() => void 0);
213
+ }, Q = R({ scope: "voltro:admin-import" }), ka = "VBUNDLE2", Aa = (e) => {
214
+ let t = e.req.headers["x-import-rollback-key"];
215
+ if (e.mode !== "replace") return { options: {} };
216
+ if (typeof t != "string" || t.length === 0) return Q.warn("admin.import: no rollback capture — this run empties the target first, and nothing was asked to be kept. Send `x-import-rollback-key: <storage key>` (voltro data import --rollback-key <key>) to have the instance store the target's current rows before deleting them."), { options: {} };
217
+ if (e.deps.putArchive === void 0) return {
218
+ options: {},
219
+ refusal: Z(409, {
220
+ error: "rollback capture requested but this instance has no object storage configured",
221
+ hint: "A capture written to the pod would not survive the failure it exists for. Configure storage (the same one the storage-push export uses), or re-send without `x-import-rollback-key` to accept that a run which does not finish can leave the target emptied. Note that CONFIGURED is not the same question as SURVIVES: a `filesystem` provider pointed at a container directory with no volume behind it passes this check and dies with the pod. The run says so when it can observe it — the capture path being on the same filesystem as `/`."
222
+ })
223
+ };
224
+ let n = On(vi(), `voltro-rollback-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`), r = e.deps.putArchive;
225
+ return {
226
+ key: t,
227
+ options: {
228
+ rollbackDir: n,
229
+ onRollbackCaptured: async () => {
230
+ let e = xi(n);
231
+ e !== void 0 && Q.warn(`admin.import: ${e}`), await r(t, () => Ui({ dir: n })), Q.info("admin.import: rollback capture stored", { bundleKey: t });
232
+ }
233
+ }
234
+ };
235
+ }, ja = (e) => {
236
+ let t = e["x-import-mode"], n = e["x-import-atomic"];
237
+ return {
238
+ mode: t,
239
+ onConflict: e["x-import-on-conflict"],
240
+ atomic: n === "0" || n === "false" ? !1 : n === "1" || n === "true" || t === "replace",
241
+ force: e["x-import-force"] === "1" || e["x-import-force"] === "true",
242
+ dryRun: e["x-import-dry-run"] === "1" || e["x-import-dry-run"] === "true",
243
+ tables: (e["x-import-tables"] ?? "").split(",").map((e) => e.trim()).filter(Boolean)
244
+ };
245
+ }, Ma = async (e, t) => {
246
+ if (typeof t.bundleKey == "string" && t.bundleKey !== "") {
247
+ if (!e.openArchive) return { refusal: Z(501, { error: "storage transport not configured on this instance" }) };
248
+ let n = e.openArchive, r = t.bundleKey;
249
+ return {
250
+ source: () => n(r),
251
+ transport: "storage",
252
+ uploadId: Sa(r)
253
+ };
254
+ }
255
+ let n = t.uploadId;
256
+ if (typeof n != "string" || !ua(n)) return { refusal: Z(400, { error: "start needs { uploadId } from an upload, or { bundleKey } for the storage transport" }) };
257
+ let r = await wa(n).catch(() => null);
258
+ return r === null || r.bytes === 0 ? { refusal: Z(409, {
259
+ error: "no such upload",
260
+ message: `this instance holds no bytes for upload '${n}'. Upload the bundle first, or re-upload if it has expired.`
261
+ }) } : {
262
+ source: () => Na(r.path),
263
+ transport: "upload",
264
+ uploadId: n
265
+ };
266
+ }, Na = (e) => {
267
+ let { createReadStream: t } = Zi("node:fs");
268
+ return t(e);
269
+ }, Pa = (e) => async (t) => {
270
+ let n = ca(t, e.secret);
271
+ if (n) return n;
272
+ let r = ja(t.headers), i = Aa({
273
+ req: t,
274
+ mode: r.mode,
275
+ deps: e
276
+ });
277
+ if (i.refusal !== void 0) return i.refusal;
278
+ if (t.headers["x-import-preflight"] === "1" || t.headers["x-import-preflight"] === "true") {
279
+ let n;
280
+ try {
281
+ n = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
282
+ } catch {
283
+ return Z(400, { error: "a preflight body must be JSON: { tables: string[] } or { bundleKey: string }" });
284
+ }
285
+ let a = Array.isArray(n.tables) ? n.tables.filter((e) => typeof e == "string") : [];
286
+ if (a.length === 0 && typeof n.bundleKey == "string" && n.bundleKey !== "" && e.openArchive && (a = [...await Fa(e.openArchive(n.bundleKey))]), a.length === 0) return Z(400, {
287
+ error: "a preflight needs { tables: string[] } — the bundle's table names, so the staging decision can be made against them",
288
+ hint: "or { bundleKey } on an instance with storage configured, where this endpoint reads the table list out of the archive itself"
289
+ });
290
+ let o = Vi({
291
+ mode: r.mode ?? "upsert",
292
+ ...e.dialect === void 0 ? {} : { targetDialect: e.dialect },
293
+ ...e.snapshot === void 0 ? {} : { targetSnapshot: e.snapshot },
294
+ bundleTables: a,
295
+ isSkipped: Hi,
296
+ canRunSql: !0
297
+ });
298
+ return Z(200, {
299
+ preflight: !0,
300
+ mode: r.mode ?? "upsert",
301
+ atomic: r.atomic,
302
+ staged: o.active,
303
+ ...o.blocker === void 0 ? {} : { reason: o.blocker },
304
+ stagedTables: o.tables.length,
305
+ rollback: i.key === void 0 ? { taken: !1 } : {
306
+ taken: !0,
307
+ key: i.key
308
+ },
309
+ dialect: e.dialect ?? null
310
+ });
311
+ }
312
+ let a = t.headers["x-import-upload-id"];
313
+ if (a !== void 0 && a !== "") {
314
+ if (ha(), t.headers["x-import-probe"] === "1") {
315
+ let e = await ga(a);
316
+ return Z(200, {
317
+ uploadId: a,
318
+ bytes: e.bytes,
319
+ ...e.runId === null ? {} : { runId: e.runId }
320
+ });
321
+ }
322
+ let e = t.headers["x-import-upload-key"] ?? "", n = Number(t.headers["x-import-chunk-offset"] ?? "0");
323
+ if (e === "" || !Number.isFinite(n) || n < 0) return Z(400, { error: "a chunked upload needs x-import-upload-key and a numeric x-import-chunk-offset" });
324
+ let r = await Ca({
325
+ id: a,
326
+ key: e,
327
+ offset: n,
328
+ bytes: t.rawBody
329
+ });
330
+ if ("reason" in r) return Q.warn("admin.import chunk refused", {
331
+ uploadId: a,
332
+ reason: r.reason
333
+ }), Z(409, {
334
+ error: "chunk refused",
335
+ reason: r.reason,
336
+ message: r.message,
337
+ ...r.expectedOffset === void 0 ? {} : { expectedOffset: r.expectedOffset }
338
+ });
339
+ let i = t.headers["x-import-chunk-final"] === "1";
340
+ return Z(202, {
341
+ uploadId: a,
342
+ bytes: r.total,
343
+ complete: i
344
+ });
345
+ }
346
+ if (t.rawBody.byteLength >= 8 && Buffer.from(t.rawBody.subarray(0, 8)).toString("latin1") === ka) {
347
+ ha();
348
+ let e = Oi("sha256").update(Buffer.from(t.rawBody)).digest("hex"), n = Sa(e);
349
+ return Z(202, {
350
+ uploadId: n,
351
+ bytes: await xa(n, t.rawBody, e),
352
+ complete: !0
353
+ });
354
+ }
355
+ let o;
356
+ try {
357
+ o = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
358
+ } catch {
359
+ return Z(400, { error: "body must be a packed bundle archive or { bundleKey } JSON" });
360
+ }
361
+ return typeof o.bundleKey != "string" || !o.bundleKey ? Z(400, { error: "body.bundleKey (string) is required for the storage transport" }) : e.openArchive ? Z(202, {
362
+ uploadId: Sa(o.bundleKey),
363
+ bundleKey: o.bundleKey,
364
+ complete: !0
365
+ }) : Z(501, { error: "storage transport not configured on this instance" });
366
+ }, Fa = async (e) => {
367
+ let t = await Wi(e, ["manifest.json"]).then((e) => e.get("manifest.json"), () => void 0);
368
+ if (t === void 0) return [];
369
+ try {
370
+ return (JSON.parse(Buffer.from(t).toString("utf8")).tables ?? []).map((e) => e.name).filter((e) => typeof e == "string");
371
+ } catch {
372
+ return [];
373
+ }
374
+ }, Ia = (e) => async (t) => {
375
+ let n = ca(t, e.secret);
376
+ if (n) return n;
377
+ let r = ja(t.headers), i = Aa({
378
+ req: t,
379
+ mode: r.mode,
380
+ deps: e
381
+ });
382
+ if (i.refusal !== void 0) return i.refusal;
383
+ let a;
384
+ try {
385
+ a = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
386
+ } catch {
387
+ return Z(400, { error: "body must be JSON: { uploadId } or { bundleKey }" });
388
+ }
389
+ let o = typeof a.bundleKey == "string" && a.bundleKey !== "" ? Sa(a.bundleKey) : typeof a.uploadId == "string" ? a.uploadId : "";
390
+ if (!ua(o)) return Z(400, { error: "start needs { uploadId } from an upload, or { bundleKey } for the storage transport" });
391
+ let s = Zn("dimp", `${o}-${Date.now()}-${Math.random()}`), c = await ya(o, s);
392
+ if (c !== s) {
393
+ let t = await wn(e.store, c);
394
+ if (Tn(t) === void 0 && t !== null) return Q.info("admin.import start: already running", {
395
+ uploadId: o,
396
+ runId: c
397
+ }), Z(202, {
398
+ runId: c,
399
+ uploadId: o,
400
+ alreadyStarted: !0
401
+ });
402
+ Q.info("admin.import start: taking over a claim whose run is not running", {
403
+ uploadId: o,
404
+ staleRunId: c,
405
+ outcome: Tn(t) ?? "no record"
406
+ }), c = await ya(o, s, { takeOver: !0 });
407
+ }
408
+ let l = async (e) => (await ba(o).catch(() => void 0), e), u = await Ma(e, {
409
+ ...typeof a.uploadId == "string" ? { uploadId: a.uploadId } : {},
410
+ ...typeof a.bundleKey == "string" ? { bundleKey: a.bundleKey } : {}
411
+ });
412
+ if ("refusal" in u) return l(u.refusal);
413
+ if (e.snapshot !== void 0 && !r.force) {
414
+ let t = await La(u.source());
415
+ if (t !== null) {
416
+ let n = Bi(t.source?.schemaFingerprint ?? "", e.snapshot, Ra(t));
417
+ if (n.drifted) return Q.warn("admin.import refused (schema drift)", {
418
+ transport: u.transport,
419
+ bundle: n.bundleFingerprint.slice(0, 16),
420
+ target: n.targetFingerprint.slice(0, 16)
421
+ }), l(Z(409, {
422
+ error: "schema drift",
423
+ bundleFingerprint: n.bundleFingerprint,
424
+ targetFingerprint: n.targetFingerprint,
425
+ diff: n.diff,
426
+ hint: "each line above would break the load: a table or column the bundle carries that the target cannot take, or a column the target requires that the bundle has no value for. Fix the target schema, re-export against it, or resend with x-import-force: 1 to write anyway."
427
+ }));
428
+ }
429
+ }
430
+ let d = null;
431
+ if (u.transport === "upload" && (d = await Da(u.uploadId, c), d === null)) return l(Z(409, {
432
+ error: "no such upload",
433
+ message: `the bytes for upload '${u.uploadId}' are gone. Re-upload the bundle.`
434
+ }));
435
+ let f = await za(e.store, {
436
+ runId: c,
437
+ mode: r.mode ?? "upsert",
438
+ via: "api",
439
+ bundle: u.transport === "storage" ? String(a.bundleKey) : u.uploadId
440
+ });
441
+ return Ba({
442
+ deps: e,
443
+ opts: r,
444
+ rollback: i,
445
+ runId: c,
446
+ traced: f,
447
+ resolved: d === null ? u : {
448
+ ...u,
449
+ source: () => Na(d)
450
+ }
451
+ }), Q.info("admin.import started", {
452
+ runId: c,
453
+ uploadId: u.uploadId,
454
+ transport: u.transport,
455
+ mode: r.mode ?? "upsert",
456
+ atomic: r.atomic,
457
+ dryRun: r.dryRun
458
+ }), Z(202, {
459
+ runId: c,
460
+ uploadId: u.uploadId,
461
+ transport: u.transport,
462
+ mode: r.mode ?? "upsert",
463
+ atomic: r.atomic,
464
+ ...r.dryRun ? { dryRun: !0 } : {},
465
+ recorded: f,
466
+ outcome: "poll /_voltro/admin/transfers for this runId — a 202 means started, not finished"
467
+ });
468
+ }, La = async (e) => {
469
+ let t = await Wi(e, ["manifest.json"]).then((e) => e.get("manifest.json"), () => null);
470
+ if (t == null) return null;
471
+ try {
472
+ return JSON.parse(Buffer.from(t).toString("utf8"));
473
+ } catch {
474
+ return null;
475
+ }
476
+ }, Ra = (e) => ({ tables: (e.tables ?? []).map((e) => ({
477
+ name: e.name,
478
+ indexes: [],
479
+ columns: Object.entries(e.columnTypes ?? {}).map(([e, t]) => ({
480
+ name: e,
481
+ type: t,
482
+ nullable: !0,
483
+ unique: !1,
484
+ hasDefault: !1
485
+ }))
486
+ })) }), za = async (e, t) => {
487
+ try {
488
+ return $n(qn), await e.insert(U, {
489
+ id: t.runId,
490
+ direction: "import",
491
+ startedAt: /* @__PURE__ */ new Date(),
492
+ finishedAt: null,
493
+ failure: null,
494
+ mode: t.mode,
495
+ via: t.via,
496
+ bundle: t.bundle,
497
+ sourceFingerprint: null,
498
+ tablesWritten: 0,
499
+ rowsWritten: 0,
500
+ staged: null
501
+ }), !0;
502
+ } catch (e) {
503
+ return Q.warn("admin.import: the run could not be recorded", {
504
+ runId: t.runId,
505
+ error: e?.message ?? String(e)
506
+ }), !1;
507
+ }
508
+ }, Ba = async (e) => {
509
+ let { deps: t, opts: n, rollback: r, resolved: i, runId: a } = e, o = await import("node:os"), s = await import("node:fs/promises"), c = await import("node:path"), l = await s.mkdtemp(c.join(o.tmpdir(), "voltro-admin-import-")), u = async (n) => {
510
+ Q.warn("admin.import failed", {
511
+ runId: a,
512
+ transport: i.transport,
513
+ error: n
514
+ }), e.traced && await t.store.update(U, a, {
515
+ failure: n,
516
+ finishedAt: null
517
+ }).then(() => void 0, () => void 0);
518
+ };
519
+ try {
520
+ t.assetSink ? await Yi(i.source(), {
521
+ dir: l,
522
+ blobs: t.assetSink
523
+ }) : await Xi(i.source(), l);
524
+ let o = await G.runPromiseExit(Ki({
525
+ store: t.store,
526
+ bundleDir: l,
527
+ ...n.mode ? { mode: n.mode } : {},
528
+ ...n.onConflict ? { onConflict: n.onConflict } : {},
529
+ atomic: n.atomic,
530
+ ...r.options,
531
+ recordInterruption: !0,
532
+ via: "api",
533
+ ...e.traced ? { traceId: a } : {},
534
+ ...n.dryRun ? { dryRun: n.dryRun } : {},
535
+ ...n.tables.length > 0 ? { tables: [...n.tables] } : {},
536
+ ...t.snapshot ? { targetSnapshot: t.snapshot } : {},
537
+ ...t.dialect ? { targetDialect: t.dialect } : {},
538
+ force: n.force,
539
+ onWarn: (e) => Q.warn("admin.import", {
540
+ runId: a,
541
+ message: e
542
+ }),
543
+ ...t.assetSink ? { assetsAlreadyRestored: !0 } : {}
544
+ }));
545
+ if (o._tag === "Failure") {
546
+ let e = o.cause._tag === "Fail" ? o.cause.error : void 0, t = typeof e?.reason == "string" ? e.reason : void 0, n = e?.diff;
547
+ await u(t ?? (Array.isArray(n) ? `schema drift: ${n.join("; ")}` : void 0) ?? String(e?.message ?? e ?? "import failed"));
548
+ return;
549
+ }
550
+ let s = o.value;
551
+ Q.info(n.dryRun ? "admin.import (dry run — nothing written)" : "admin.import complete", {
552
+ runId: a,
553
+ transport: i.transport,
554
+ tables: s.tablesWritten,
555
+ rows: s.rowsWritten,
556
+ mode: n.mode ?? "upsert",
557
+ atomic: n.atomic,
558
+ ...s.tablesSkipped > 0 ? {
559
+ skippedTables: s.tablesSkipped,
560
+ skippedRows: s.rowsSkipped
561
+ } : {}
562
+ }), n.dryRun || t.refreshSubscriptions?.(`data import: ${s.tablesWritten} table(s), mode ${n.mode ?? "upsert"}`);
563
+ } catch (e) {
564
+ await u(e?.message ?? String(e));
565
+ } finally {
566
+ await s.rm(l, {
567
+ recursive: !0,
568
+ force: !0
569
+ }).catch(() => void 0), await Oa(a).catch(() => void 0), await ba(i.uploadId).catch(() => void 0);
570
+ }
571
+ }, Va = /^[A-Za-z0-9_-]{8,64}$/, Ha = (e) => Va.test(e), Ua = () => process.env.VOLTRO_EXPORT_ARTIFACT_DIR ?? L.join(_i.tmpdir(), "voltro-export-artifacts"), Wa = (e) => L.join(Ua(), e), Ga = (e) => L.join(Wa(e), "archive.bin"), Ka = async (e = Date.now()) => {
572
+ let t = 0;
573
+ try {
574
+ for (let n of await X.readdir(Ua())) {
575
+ let r = await X.stat(Wa(n)).catch(() => null);
576
+ r !== null && (e - r.mtimeMs <= 864e5 || (await X.rm(Wa(n), {
577
+ recursive: !0,
578
+ force: !0
579
+ }).catch(() => void 0), t++));
580
+ }
581
+ } catch {}
582
+ return t;
583
+ }, qa = async (e, t) => {
584
+ if (!Ha(e)) throw Error(`invalid run id: ${e}`);
585
+ await X.mkdir(Wa(e), { recursive: !0 });
586
+ let { createWriteStream: n } = await import("node:fs"), r = n(Ga(e)), i = 0;
587
+ try {
588
+ for await (let e of t) i += e.byteLength, r.write(Buffer.from(e)) || await new Promise((e, t) => {
589
+ r.once("drain", e), r.once("error", t);
590
+ });
591
+ } finally {
592
+ await new Promise((e, t) => {
593
+ r.end(() => e()), r.once("error", t);
594
+ });
595
+ }
596
+ return i;
597
+ }, Ja = async (e) => {
598
+ if (!Ha(e)) return null;
599
+ let t = await X.stat(Ga(e)).catch(() => null);
600
+ return t === null ? null : t.size;
601
+ }, Ya = async (e, t, n) => {
602
+ let r = await Ja(e);
603
+ if (r === null) return null;
604
+ if (t >= r) return {
605
+ bytes: Buffer.alloc(0),
606
+ total: r
607
+ };
608
+ let i = await X.open(Ga(e), "r");
609
+ try {
610
+ let e = Math.max(0, Math.min(n, r - t)), a = Buffer.alloc(e);
611
+ return await i.read(a, 0, e, t), {
612
+ bytes: a,
613
+ total: r
614
+ };
615
+ } finally {
616
+ await i.close();
617
+ }
618
+ }, Xa = async (e) => {
619
+ Ha(e) && await X.rm(Wa(e), {
620
+ recursive: !0,
621
+ force: !0
622
+ }).catch(() => void 0);
623
+ }, Za = R({ scope: "voltro:admin-export" }), Qa = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], $a = (e) => {
624
+ if (typeof e.tenant == "string" && e.tenant) return {
625
+ kind: "tenant",
626
+ tenantId: e.tenant
627
+ };
628
+ if (Array.isArray(e.tables) && e.tables.length) return {
629
+ kind: "tables",
630
+ tables: Qa(e.tables)
631
+ };
632
+ let t = Qa(e.exclude);
633
+ return t.length > 0 ? {
634
+ kind: "all",
635
+ exclude: t
636
+ } : { kind: "all" };
637
+ }, eo = (e) => async (t) => {
638
+ let n = ca(t, e.secret);
639
+ if (n) return n;
640
+ let r;
641
+ try {
642
+ r = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
643
+ } catch {
644
+ return Z(400, { error: "body must be JSON: { profile?, tenant?, tables?, consistency?, compression?, bundleKey? }" });
645
+ }
646
+ let i = {};
647
+ if (typeof r.profile == "string" && r.profile) {
648
+ if (!e.loadProfile) return Z(501, { error: "server-side profiles not configured on this instance" });
649
+ try {
650
+ i = await e.loadProfile(r.profile);
651
+ } catch (e) {
652
+ return Z(400, {
653
+ error: `profile '${r.profile}' could not be loaded`,
654
+ message: e?.message ?? String(e)
655
+ });
656
+ }
657
+ }
658
+ let a = r.consistency === "snapshot" ? "snapshot" : i.consistency ?? "live", o = (typeof r.compression == "string" ? r.compression : void 0) ?? i.compression, s = i.scope ?? $a(r), c = typeof r.bundleKey == "string" && r.bundleKey.length > 0, l = r.assets === !0 && e.assetSource ? { blobs: e.assetSource } : {}, u = Zn("dexp", `${Date.now()}-${Math.random()}`), d = await to(e.store, {
659
+ runId: u,
660
+ mode: i.subset ? "subset" : s.kind,
661
+ bundle: c ? String(r.bundleKey) : null
662
+ });
663
+ return no({
664
+ deps: e,
665
+ runId: u,
666
+ recorded: d,
667
+ profile: i,
668
+ scope: s,
669
+ consistency: a,
670
+ blobs: l,
671
+ ...o ? { compression: o } : {},
672
+ ...c ? { bundleKey: String(r.bundleKey) } : {}
673
+ }), Ka(), Za.info("admin.export started", {
674
+ runId: u,
675
+ scope: s.kind,
676
+ storage: c
677
+ }), Z(202, {
678
+ runId: u,
679
+ transport: c ? "storage" : "download",
680
+ ...c ? { bundleKey: r.bundleKey } : {},
681
+ recorded: d,
682
+ outcome: "poll /_voltro/admin/transfers for this runId; fetch the bytes from /_voltro/admin/export/download"
683
+ });
684
+ }, to = async (e, t) => {
685
+ try {
686
+ return $n(qn), await e.insert(U, {
687
+ id: t.runId,
688
+ direction: "export",
689
+ startedAt: /* @__PURE__ */ new Date(),
690
+ finishedAt: null,
691
+ failure: null,
692
+ mode: t.mode,
693
+ via: "api",
694
+ bundle: t.bundle,
695
+ sourceFingerprint: null,
696
+ tablesWritten: 0,
697
+ rowsWritten: 0,
698
+ staged: null
699
+ }), !0;
700
+ } catch (e) {
701
+ return Za.warn("admin.export: the run could not be recorded", {
702
+ runId: t.runId,
703
+ error: e?.message ?? String(e)
704
+ }), !1;
705
+ }
706
+ }, no = async (e) => {
707
+ let { deps: t, runId: n } = e, r = await import("node:os"), i = await import("node:fs/promises"), a = await import("node:path"), o = await i.mkdtemp(a.join(r.tmpdir(), "voltro-admin-export-")), s = async (r) => {
708
+ e.recorded && await t.store.update(U, n, r).then(() => void 0, () => void 0);
709
+ };
710
+ try {
711
+ let r = await G.runPromise(Gi({
712
+ store: t.store,
713
+ snapshot: t.snapshot,
714
+ dialect: t.dialect,
715
+ outDir: o,
716
+ ...e.profile.subset ? { subset: e.profile.subset } : {
717
+ scope: e.scope,
718
+ ...t.tenantTables && t.tenantTables.length > 0 ? { tenantTables: t.tenantTables } : {}
719
+ },
720
+ consistency: e.consistency,
721
+ ...e.compression ? { compression: e.compression } : {},
722
+ ...e.profile.masking ? { masking: e.profile.masking } : {}
723
+ })), i = r.tables.reduce((e, t) => e + t.rowCount, 0), a = r.masking?.transformed.length ?? 0;
724
+ if (e.bundleKey !== void 0) {
725
+ if (!t.putArchive) throw Error("storage transport not configured on this instance");
726
+ await t.putArchive(e.bundleKey, () => Ui({
727
+ dir: o,
728
+ ...e.blobs
729
+ }));
730
+ }
731
+ let c = await qa(n, Ui({
732
+ dir: o,
733
+ ...e.blobs
734
+ }));
735
+ Za.info("admin.export complete", {
736
+ runId: n,
737
+ tables: r.tables.length,
738
+ rows: i,
739
+ masked: a,
740
+ bytes: c,
741
+ ...e.bundleKey === void 0 ? {} : { bundleKey: e.bundleKey }
742
+ }), await s({
743
+ finishedAt: /* @__PURE__ */ new Date(),
744
+ failure: null,
745
+ tablesWritten: r.tables.length,
746
+ rowsWritten: i,
747
+ sourceFingerprint: r.source?.schemaFingerprint ?? null
748
+ });
749
+ } catch (e) {
750
+ let t = e?.message ?? String(e);
751
+ Za.warn("admin.export failed", {
752
+ runId: n,
753
+ error: t
754
+ }), await s({
755
+ failure: t,
756
+ finishedAt: null
757
+ }), await Xa(n);
758
+ } finally {
759
+ await i.rm(o, {
760
+ recursive: !0,
761
+ force: !0
762
+ }).catch(() => void 0);
763
+ }
764
+ }, ro = (e) => async (t) => {
765
+ let n = ca(t, e.secret, "GET");
766
+ if (n) return n;
767
+ let r = new URLSearchParams(t.query ?? ""), i = r.get("runId") ?? "";
768
+ if (!Ha(i)) return Z(400, { error: "download needs ?runId=<id> from the 202 the export answered with" });
769
+ let a = Math.max(0, Number(r.get("offset") ?? "0") || 0), o = Number(r.get("length") ?? "8388608"), s = await Ya(i, a, Number.isFinite(o) && o > 0 ? Math.min(o, ao) : io);
770
+ return s === null ? Z(404, {
771
+ error: "no artefact",
772
+ message: `this instance holds no produced bundle for run '${i}'. It may have expired, or the export may still be running — poll the run first.`
773
+ }) : {
774
+ status: 200,
775
+ contentType: "application/octet-stream",
776
+ body: new Uint8Array(s.bytes),
777
+ headers: {
778
+ "x-export-total-bytes": String(s.total),
779
+ "x-export-offset": String(a),
780
+ "x-export-length": String(s.bytes.byteLength)
781
+ }
782
+ };
783
+ }, io = 8388608, ao = 33554432, oo = async (e, t) => await e.query({
784
+ table: U,
785
+ order: [{
786
+ column: "startedAt",
787
+ direction: "desc"
788
+ }],
789
+ predicate: void 0,
790
+ projection: void 0,
791
+ skip: 0,
792
+ take: t
793
+ }), so = (e) => {
794
+ let t = new Date(e);
795
+ return Number.isFinite(t.getTime()) ? t : /* @__PURE__ */ new Date(0);
796
+ }, co = (e) => ({
797
+ ...e,
798
+ startedAt: so(e.startedAt),
799
+ finishedAt: e.finishedAt === null || e.finishedAt === void 0 ? null : so(e.finishedAt)
800
+ }), lo = (e) => async (t) => {
801
+ let n = ca(t, e.secret, "GET");
802
+ if (n) return n;
803
+ let r = Number(new URLSearchParams(t.query ?? "").get("limit") ?? "20"), i = Number.isFinite(r) ? Math.max(1, Math.min(200, Math.trunc(r))) : 20, a;
804
+ try {
805
+ a = (await oo(e.store, i)).map(co);
806
+ } catch (e) {
807
+ return Z(409, {
808
+ error: "no import history",
809
+ message: `this instance has no \`${U}\` table, so no import has been recorded. Run \`voltro db apply\` against it; imports themselves are unaffected.`,
810
+ detail: e?.message ?? String(e)
811
+ });
812
+ }
813
+ return Z(200, {
814
+ running: a.filter((e) => e.finishedAt === null && e.failure === null).length,
815
+ runs: a.map((e) => ({
816
+ id: e.id,
817
+ startedAt: e.startedAt.toISOString(),
818
+ finishedAt: e.finishedAt === null ? null : e.finishedAt.toISOString(),
819
+ mode: e.mode,
820
+ via: e.via,
821
+ bundle: e.bundle,
822
+ sourceFingerprint: e.sourceFingerprint,
823
+ tablesWritten: e.tablesWritten,
824
+ rowsWritten: e.rowsWritten,
825
+ direction: e.direction,
826
+ failure: e.failure,
827
+ staged: e.staged,
828
+ line: Qn(e)
829
+ }))
830
+ });
831
+ }, uo = (e, t, n = {}) => (async function* () {
832
+ let r = await G.runPromise(Ci(e, t).pipe(G.timeout(n.openTimeout ?? "30 seconds"))), i = await Ti(r.stream), a = n.stallMs ?? 12e4, o, s = () => {
833
+ o && clearTimeout(o), o = setTimeout(() => i.destroy(/* @__PURE__ */ Error(`storage read stalled for ${a}ms reading '${t}'`)), a);
834
+ };
835
+ try {
836
+ s();
837
+ for await (let e of i) s(), yield e instanceof Uint8Array ? e : new Uint8Array(e);
838
+ } finally {
839
+ o && clearTimeout(o), i.destroy();
840
+ }
841
+ })(), fo = {
842
+ get: async () => void 0,
843
+ set: async () => {},
844
+ setWithTags: async () => {},
845
+ remove: async () => !1,
846
+ has: async () => !1,
847
+ clear: async () => {},
848
+ invalidateTag: async () => 0,
849
+ wrap: async (e, t, n) => n()
850
+ }, po = async (e) => {
851
+ f(e.appProcedures ?? e.discovered, {
852
+ defaultDeny: e.security?.defaultDeny ?? !0,
853
+ commandHint: "`voltro serve`"
854
+ }), oi({
855
+ dataStore: e.store,
856
+ schemaRegistry: e.schemaRegistry
857
+ });
858
+ let t = (e.discovered.budgets?.length ?? 0) > 0, n, r = new dr({
859
+ store: e.store,
860
+ ...e.snapshotCache ? { cache: e.snapshotCache } : {},
861
+ ...e.reactive === void 0 ? {} : { reactive: e.reactive },
862
+ ...t ? { recordCost: (e) => n?.record(e) } : {},
863
+ recordDelivery: (e) => $r({
864
+ label: e.label,
865
+ kind: e.kind,
866
+ durationMs: e.durationMs,
867
+ rowCount: e.rowCount
868
+ })
869
+ }), i = e.cache ?? fo, a = e.kv ?? Zr, o, s = () => void 0, l, u, d, ee, te, ne, p, h = fe({
870
+ store: e.store,
871
+ warn: (e, t) => {
872
+ process.stderr.write(`[workflow] ${e} ${JSON.stringify(t)}\n`);
873
+ }
874
+ }), re = h.remember, se = h.resolve, ce = St({
875
+ authority: e.authority,
876
+ getStore: () => e.store
877
+ }), b = (e.discovered.workflows?.length ?? 0) > 0 ? Vr(() => o) : void 0, pe = (e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.eventTriggers?.length ?? 0) > 0, _e = pe || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster", ve = e.tenantIsolation === "namespace", ye = (e.log ?? R({ scope: "voltro:serve" })).child("webhooks"), be, xe, x = e.discovered.webhooks;
878
+ if (x && x.outgoing.length > 0 && e.workflowEngineLayer !== void 0) {
879
+ e.workflowEngineLayer;
880
+ let t = ft({
881
+ store: e.store,
882
+ schemaRegistry: e.schemaRegistry,
883
+ cache: i,
884
+ kv: a
885
+ }), n = x.outgoing.map((e) => e.descriptor);
886
+ xe = Ni.toLayer(Ai(t, { events: n })), be = ji(t, async (e) => {
887
+ let t = d;
888
+ if (t === void 0) {
889
+ ye.error("webhook delivery skipped — the workflow runtime was never built. This is a framework defect, not a configuration problem: report it with your engine setting. Deliveries are NOT queued and will not be retried.", {
890
+ deliveryId: e.deliveryId,
891
+ targetId: e.targetId
892
+ });
893
+ return;
894
+ }
895
+ t.runPromise(Ni.execute(e)).catch((t) => {
896
+ ye.error("deliverWebhook workflow crashed", {
897
+ deliveryId: e.deliveryId,
898
+ targetId: e.targetId
899
+ }, t);
900
+ });
901
+ }, { events: n });
902
+ }
903
+ let we = /* @__PURE__ */ new Map();
904
+ if (x) for (let e of x.incoming) {
905
+ let t = e.descriptor.path ?? Mi(e.descriptor.id), n = `VOLTRO_WEBHOOK_SECRET_${e.descriptor.id.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, r = Fi(e.descriptor, {
906
+ resolveSecret: async () => process.env[n] ?? null,
907
+ resolveWorkflows: () => b === void 0 ? void 0 : Xr(b, {
908
+ traceId: `incoming:${e.descriptor.id}`,
909
+ source: `incoming:${e.descriptor.id}`
910
+ }),
911
+ log: (e) => {
912
+ let t = {
913
+ webhookId: e.webhookId,
914
+ status: e.status,
915
+ signatureOk: String(e.signatureOk),
916
+ idempotency: e.idempotency,
917
+ durationMs: e.durationMs
918
+ };
919
+ e.status >= 500 ? ye.error("incoming delivery failed", t) : e.status >= 400 ? ye.warn("incoming delivery rejected", t) : ye.info("incoming delivery handled", t);
920
+ }
921
+ });
922
+ we.set(t, { handle: r });
923
+ }
924
+ Ar(), ti((t) => jr(e.store, t.subjectId, t.resourceType, t.resourceId)) || R({ scope: "voltro:serve" }).info("policy guards: using the app-registered tuple source");
925
+ let Te = [], De = [...e.discovered.outboxHandlers ?? [], ..._n((x?.outgoing.length ?? 0) + (x?.incoming.length ?? 0) + (x?.providers.length ?? 0), []) ? [{
926
+ file: "<framework>/webhooks",
927
+ id: "voltro-webhook-emit",
928
+ definition: Pi(() => be)
929
+ }] : []], Oe = De.length > 0 ? Le({
930
+ handlers: De,
931
+ store: e.store,
932
+ log: (e.log ?? R({ scope: "voltro:serve" })).child("outbox"),
933
+ onChange: (t) => e.store.onChange((e) => t({
934
+ table: e.table,
935
+ op: e.op
936
+ })),
937
+ onShutdown: (e) => {
938
+ Te.push(e);
939
+ }
940
+ }) : void 0, S = C({
941
+ definitions: (e.discovered.connections ?? []).map((e) => e.definition),
942
+ store: e.store,
943
+ publicUrl: v(e.port ?? 4e3),
944
+ log: (e.log ?? R({ scope: "voltro:serve" })).child("connections")
945
+ });
946
+ ct({
947
+ events: e.discovered.events ?? [],
948
+ rpcTags: [
949
+ ...e.discovered.queries.map((e) => e.descriptor.name),
950
+ ...e.discovered.mutations.map((e) => e.descriptor.name),
951
+ ...e.discovered.actions.map((e) => e.descriptor.name),
952
+ ...(e.discovered.streams ?? []).map((e) => e.descriptor.name)
953
+ ]
954
+ });
955
+ let Me = (e.log ?? R({ scope: "voltro:serve" })).child("events"), Ne = e.broadcastNamespace ?? et(e.plugins, void 0), Pe = w(e.plugins, Ne, Me), Fe = e.membership?.instanceId ?? process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, Re = e.membership ?? Mt(e.plugins, {
956
+ instanceId: Fe,
957
+ namespace: Ne,
958
+ meta: { mode: "serve" },
959
+ logger: Me
960
+ }), T = me({
961
+ events: e.discovered.events ?? [],
962
+ origin: Fe,
963
+ ...Pe.publishRemote === void 0 ? {} : { publishRemote: Pe.publishRemote }
964
+ }), ze = (e.discovered.events ?? []).length > 0 ? await Pe.attach(T.bus) : null, Be = Ge({
965
+ store: e.store,
966
+ schemaRegistry: e.schemaRegistry,
967
+ cache: i,
968
+ kv: a,
969
+ ...be === void 0 ? {} : { webhooksService: be },
970
+ ...b === void 0 ? {} : { workflowsProxy: b },
971
+ eventTriggers: e.discovered.eventTriggers ?? [],
972
+ namespaceIsolationOn: ve,
973
+ ...e.ensureTenantProvisioned === void 0 ? {} : { ensureTenantProvisioned: e.ensureTenantProvisioned },
974
+ ...e.resolveResidentStore === void 0 ? {} : { resolveResidentStore: e.resolveResidentStore },
975
+ ...Oe === void 0 ? {} : { outbox: { nudge: Oe.nudge } },
976
+ ...S.active ? { connections: { registry: S.registry } } : {},
977
+ eventBus: T.bus
978
+ }), Ve = K.succeed(cr, m), He = K.succeed(fr, Rt), We = K.succeed(lr, Ue), qe = K.succeed(pr, Ee), Ye = (t, n) => {
979
+ let r = t.pipe(G.provide(Br(n)));
980
+ return (e.baseLayer ? r.pipe(G.provide(e.baseLayer)) : r).pipe(G.provide(Ve)).pipe(G.provide(He)).pipe(G.provide(We)).pipe(G.provide(qe));
981
+ }, Ze = (e, t) => {
982
+ let n = Ye(e, t);
983
+ return ii(n);
984
+ }, Qe = bn(), nt = de(e.plugins ?? [], Qe), rt = Ae({
985
+ plugins: e.plugins ?? [],
986
+ metrics: Qe,
987
+ log: e.log ?? R({ scope: "voltro:serve" })
988
+ }), it = y(e.plugins ?? [], Qe), at = e.security?.defaultDeny ?? !0, st = J({
989
+ store: e.store,
990
+ defaultDeny: at,
991
+ recordMetric: (e) => {
992
+ Qe.record(e);
993
+ },
994
+ ...nt.mutation === void 0 ? {} : { interceptor: nt.mutation },
995
+ buildContext: (e, t, n) => Be(e, t, n),
996
+ runEffect: Ze,
997
+ undoCapture: c()
998
+ }), ut = Se();
999
+ {
1000
+ let t = Xe();
1001
+ t !== void 0 && (e.log ?? R({ scope: "voltro:serve" })).info(t);
1002
+ }
1003
+ let dt = Ie({
1004
+ store: e.store,
1005
+ ...e.approvals === void 0 ? {} : { defaultExpiryMs: e.approvals.defaultExpiryMs }
1006
+ }), mt = Mr({
1007
+ defaultDeny: at,
1008
+ buildContext: (e) => Be(e),
1009
+ runEffect: Ze,
1010
+ recordMetric: (e) => {
1011
+ Qe.record(e);
1012
+ },
1013
+ ...nt.action === void 0 ? {} : { interceptor: nt.action }
1014
+ }), ht = Gr({
1015
+ tenantScopedTables: e.tenantScopedTables,
1016
+ softDeleteScopedTables: e.softDeleteScopedTables
1017
+ }), gt = {
1018
+ defaultDeny: at,
1019
+ buildContext: (e) => Be(e),
1020
+ finalize: (e, t) => ht(e, t.subject),
1021
+ provideEffect: Ye,
1022
+ ...nt.query === void 0 ? {} : { interceptor: nt.query }
1023
+ }, E = Wr(gt), D = Ur({
1024
+ ...gt,
1025
+ queryRows: (t, n) => e.store.query(t).then((e) => di(t.table, e, n.subject))
1026
+ }), vt = qr({
1027
+ ...gt,
1028
+ subscribeDescriptor: (e, t, n) => r.subscribe(e, t, n),
1029
+ subscribeComputed: (e, t, n) => r.subscribeComputed(e, t, n)
1030
+ }), O = (e) => e.filter((e) => In(e.descriptor)), k = {};
1031
+ for (let t of [
1032
+ ...O(e.discovered.queries),
1033
+ ...ut.queries,
1034
+ ...dt.queries,
1035
+ ...S.queries
1036
+ ]) k[t.descriptor.name] = (e) => xr(E(t, e), r, `subscription.${t.descriptor.name}`, void 0, void 0, Kr(t, e));
1037
+ for (let t of [
1038
+ ...O(e.discovered.mutations),
1039
+ ...ut.mutations,
1040
+ ...dt.mutations,
1041
+ ...S.mutations
1042
+ ]) {
1043
+ let n = Hr(t.descriptor.output);
1044
+ k[t.descriptor.name] = (r) => q(async (e, n) => st(t, e, n), r, `mutation.${t.descriptor.name}`, n, e.idempotency, zn(t.descriptor, "mutation"));
1045
+ }
1046
+ for (let t of [...O(e.discovered.actions), ...S.actions]) {
1047
+ let n = Hr(t.descriptor.output);
1048
+ k[t.descriptor.name] = (r) => q(async (e, n) => mt(t, e, n), r, `action.${t.descriptor.name}`, n, e.idempotency, zn(t.descriptor, "action"));
1049
+ }
1050
+ let yt = () => `public-${Math.random().toString(36).slice(2, 10)}`, bt = [
1051
+ ...e.discovered.queries.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
1052
+ descriptor: e.descriptor,
1053
+ invoke: (t, n) => D(e, t, {
1054
+ subject: n.subject,
1055
+ traceId: yt()
1056
+ }),
1057
+ subscribe: (t, n, r) => vt(e, t, {
1058
+ subject: n.subject,
1059
+ traceId: yt()
1060
+ }, r)
1061
+ })),
1062
+ ...e.discovered.mutations.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
1063
+ descriptor: e.descriptor,
1064
+ invoke: (t, n) => st(e, t, {
1065
+ subject: n.subject,
1066
+ traceId: yt()
1067
+ })
1068
+ })),
1069
+ ...e.discovered.actions.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
1070
+ descriptor: e.descriptor,
1071
+ invoke: (t, n) => mt(e, t, {
1072
+ subject: n.subject,
1073
+ traceId: yt()
1074
+ })
1075
+ }))
1076
+ ], xt = {
1077
+ candidates: ue({
1078
+ queries: e.discovered.queries,
1079
+ mutations: e.discovered.mutations,
1080
+ actions: e.discovered.actions,
1081
+ descriptorOf: (e) => e.descriptor,
1082
+ runQuery: (e, t, n) => Promise.resolve(D(e, t, n)),
1083
+ runMutation: (e, t, n) => Promise.resolve(st(e, t, n)),
1084
+ runAction: (e, t, n) => Promise.resolve(mt(e, t, n))
1085
+ }),
1086
+ policy: e.agents?.tools ?? {},
1087
+ mcpEnabled: e.agents?.mcp === !0,
1088
+ resolveSubject: (t) => e.resolveSubject(t, -1).then((e) => e.subject)
1089
+ }, Ct = _t({
1090
+ ...e.restRoutes === void 0 ? {} : { restRoutes: e.restRoutes },
1091
+ publicApiEntries: bt,
1092
+ store: e.store,
1093
+ resolveSubject: (t) => e.resolveSubject(t, -1).then((e) => e.subject),
1094
+ ...e.idempotency === void 0 ? {} : { idempotency: e.idempotency },
1095
+ log: e.log ?? R({ scope: "voltro:serve" })
1096
+ }), A = e.dataTransferSecret ?? process.env.VOLTRO_DATA_TRANSFER_SECRET, wt = async (e, t) => {
1097
+ let { Readable: n } = await import("node:stream"), r = bi(), i = Si("storage", () => n.from(t()));
1098
+ await G.runPromise(wi(r, e, i, { contentType: "application/octet-stream" }));
1099
+ }, Tt = A && A.length >= 16 ? [
1100
+ {
1101
+ method: "POST",
1102
+ path: ta,
1103
+ handle: Pa({
1104
+ secret: A,
1105
+ store: e.store,
1106
+ ...e.dataTransferSnapshot ? { snapshot: e.dataTransferSnapshot } : {},
1107
+ ...e.dataTransferDialect ? { dialect: e.dataTransferDialect } : {},
1108
+ assetSink: qi(bi()),
1109
+ openArchive: (e) => uo(bi(), e),
1110
+ refreshSubscriptions: (e) => {
1111
+ r.refreshAll(e);
1112
+ },
1113
+ putArchive: wt,
1114
+ ...e.dataTransferDialect ? { dialect: e.dataTransferDialect } : {}
1115
+ })
1116
+ },
1117
+ {
1118
+ method: "POST",
1119
+ path: na,
1120
+ handle: Ia({
1121
+ secret: A,
1122
+ store: e.store,
1123
+ ...e.dataTransferSnapshot ? { snapshot: e.dataTransferSnapshot } : {},
1124
+ ...e.dataTransferDialect ? { dialect: e.dataTransferDialect } : {},
1125
+ assetSink: qi(bi()),
1126
+ openArchive: (e) => uo(bi(), e),
1127
+ refreshSubscriptions: (e) => {
1128
+ r.refreshAll(e);
1129
+ },
1130
+ putArchive: wt
1131
+ })
1132
+ },
1133
+ {
1134
+ method: "GET",
1135
+ path: aa,
1136
+ handle: lo({
1137
+ secret: A,
1138
+ store: e.store
1139
+ })
1140
+ },
1141
+ {
1142
+ method: "GET",
1143
+ path: ia,
1144
+ handle: ro({ secret: A })
1145
+ },
1146
+ {
1147
+ method: "POST",
1148
+ path: ra,
1149
+ handle: eo({
1150
+ secret: A,
1151
+ store: e.store,
1152
+ snapshot: e.dataTransferSnapshot ?? { tables: [] },
1153
+ dialect: e.dataTransferDialect ?? "memory",
1154
+ tenantTables: [...e.tenantScopedTables],
1155
+ loadProfile: En,
1156
+ assetSource: Ji(bi(), e.store),
1157
+ putArchive: wt
1158
+ })
1159
+ }
1160
+ ] : [], Et = [
1161
+ ...e.httpRoutes ?? [],
1162
+ ...Ct.httpRoutes,
1163
+ ...Tt,
1164
+ ...S.httpRoutes
1165
+ ];
1166
+ Object.assign(k, T.handlers);
1167
+ for (let t of O(e.discovered.streams ?? [])) k[t.descriptor.name] = (n) => br((r) => mi(r, (r) => {
1168
+ let i = Be(r), a = t.executor(n, i);
1169
+ if (G.isEffect(a)) {
1170
+ let t = a.pipe(G.provide(Br(i.store)));
1171
+ return (e.baseLayer ? t.pipe(G.provide(e.baseLayer)) : t).pipe(G.provide(Ve)).pipe(G.provide(He)).pipe(G.provide(We)).pipe(G.provide(qe));
1172
+ }
1173
+ return typeof a == "object" && a && typeof a.then == "function" ? G.promise(() => a) : a;
1174
+ }), `stream.${t.descriptor.name}`);
1175
+ for (let t of e.discovered.workflows ?? []) k[t.definition.name] = (e) => q(async (e, n) => {
1176
+ let r = n;
1177
+ return Xr(b, {
1178
+ subject: r.subject,
1179
+ traceId: r.traceId,
1180
+ source: "workflow-rpc"
1181
+ }).start(t.definition.name, e);
1182
+ }, e, `workflow.${t.definition.name}`);
1183
+ pe && (k[Wn.name] = (e) => xr(E({
1184
+ descriptor: Wn,
1185
+ executor: (e) => {
1186
+ let t = e.id;
1187
+ return {
1188
+ table: "_voltro_workflow_runs",
1189
+ order: [{
1190
+ column: "startedAt",
1191
+ direction: "desc"
1192
+ }],
1193
+ predicate: er(W("id", t), W("executionId", t)),
1194
+ take: 1,
1195
+ skip: void 0,
1196
+ projection: void 0
1197
+ };
1198
+ }
1199
+ }, e), r, `subscription.${Wn.name}`), k[Kn.name] = (e) => xr(E({
1200
+ descriptor: Kn,
1201
+ executor: (e) => {
1202
+ let t = e, n = [...t.tag === void 0 ? [] : [W("tag", t.tag)], ...t.status === void 0 ? [] : [W("status", t.status)]], r = Number.isFinite(t.limit) && t.limit !== void 0 ? Math.min(Math.max(Math.floor(t.limit), 1), 500) : 100;
1203
+ return {
1204
+ table: "_voltro_workflow_runs",
1205
+ order: [{
1206
+ column: "startedAt",
1207
+ direction: "desc"
1208
+ }],
1209
+ predicate: n.length === 0 ? void 0 : n.length === 1 ? n[0] : Yn(...n),
1210
+ take: r,
1211
+ skip: void 0,
1212
+ projection: void 0
1213
+ };
1214
+ }
1215
+ }, e), r, `subscription.${Kn.name}`), k[Gn.name] = (e) => xr(E({
1216
+ descriptor: Gn,
1217
+ executor: (e) => {
1218
+ let t = e.runId;
1219
+ return {
1220
+ table: "_voltro_workflow_run_steps",
1221
+ order: [{
1222
+ column: "startedAt",
1223
+ direction: "asc"
1224
+ }],
1225
+ predicate: W("runId", t),
1226
+ take: 1e3,
1227
+ skip: void 0,
1228
+ projection: void 0
1229
+ };
1230
+ }
1231
+ }, e), r, `subscription.${Gn.name}`), k[Un.name] = (e) => xr(E({
1232
+ descriptor: Un,
1233
+ executor: (e) => {
1234
+ let t = e.runId;
1235
+ return {
1236
+ table: "_voltro_workflow_run_events",
1237
+ order: [{
1238
+ column: "occurredAt",
1239
+ direction: "asc"
1240
+ }],
1241
+ predicate: W("runId", t),
1242
+ take: 1e3,
1243
+ skip: void 0,
1244
+ projection: void 0
1245
+ };
1246
+ }
1247
+ }, e), r, `subscription.${Un.name}`), k[B.name] = (e) => xr(E({
1248
+ descriptor: B,
1249
+ executor: (e) => {
1250
+ let t = e;
1251
+ return {
1252
+ table: "_voltro_workflow_events",
1253
+ order: [{
1254
+ column: "occurredAt",
1255
+ direction: "desc"
1256
+ }],
1257
+ predicate: t.name === void 0 ? void 0 : W("name", t.name),
1258
+ take: Math.max(1, Math.min(500, t.limit ?? 100)),
1259
+ skip: void 0,
1260
+ projection: void 0
1261
+ };
1262
+ }
1263
+ }, e), r, `subscription.${B.name}`), k[Vn.name] = (e) => xr(E({
1264
+ descriptor: Vn,
1265
+ executor: (e) => {
1266
+ let t = e.eventId;
1267
+ return {
1268
+ table: "_voltro_workflow_event_deliveries",
1269
+ order: [{
1270
+ column: "createdAt",
1271
+ direction: "asc"
1272
+ }],
1273
+ predicate: W("eventId", t),
1274
+ take: 500,
1275
+ skip: void 0,
1276
+ projection: void 0
1277
+ };
1278
+ }
1279
+ }, e), r, `subscription.${Vn.name}`), k[Bn.name] = (t) => q(async (t, n) => {
1280
+ let r = t;
1281
+ return await j(e.store, n.subject, { executionId: r.executionId }), await b.cancel(r.workflowName, r.executionId), await Ft(r.workflowName, r.executionId, "workflow.cancel"), { ok: !0 };
1282
+ }, t, `action.${Bn.name}`), k[Hn.name] = (t) => q(async (t, n) => {
1283
+ let r = t;
1284
+ return await j(e.store, n.subject, { executionId: r.executionId }), await b.resume(r.workflowName, r.executionId), { ok: !0 };
1285
+ }, t, `action.${Hn.name}`), k[V.name] = (t) => q(async (t, n) => {
1286
+ let r = t;
1287
+ return await j(e.store, n.subject, { id: r.id }), b.signal({ id: r.id }, r.signalName, r.payload);
1288
+ }, t, `action.${V.name}`), k[H.name] = (t) => q(async (t, n) => {
1289
+ let r = t;
1290
+ return await j(e.store, n.subject, { id: r.id }), b.update({ id: r.id }, r.updateName, r.payload, r.timeoutMs === void 0 ? void 0 : { timeoutMs: r.timeoutMs });
1291
+ }, t, `action.${H.name}`));
1292
+ let Dt = [
1293
+ ...O(e.discovered.queries).map((e) => z(e.descriptor)),
1294
+ ...O(e.discovered.mutations).map((e) => Ln(e.descriptor)),
1295
+ ...O(e.discovered.actions).map((e) => Pn(e.descriptor)),
1296
+ ...ut.queries.map((e) => z(e.descriptor)),
1297
+ ...ut.mutations.map((e) => Ln(e.descriptor)),
1298
+ ...dt.queries.map((e) => z(e.descriptor)),
1299
+ ...dt.mutations.map((e) => Ln(e.descriptor)),
1300
+ ...S.queries.map((e) => z(e.descriptor)),
1301
+ ...S.mutations.map((e) => Ln(e.descriptor)),
1302
+ ...S.actions.map((e) => Pn(e.descriptor)),
1303
+ ...O(e.discovered.streams ?? []).map((e) => Rn(e.descriptor)),
1304
+ ...T.rpcs,
1305
+ ...(e.discovered.workflows ?? []).map((e) => hi(e.definition)),
1306
+ ...pe ? [
1307
+ z(Wn),
1308
+ z(Kn),
1309
+ z(Gn),
1310
+ z(Un),
1311
+ z(B),
1312
+ z(Vn),
1313
+ Pn(Bn),
1314
+ Pn(Hn),
1315
+ Pn(V),
1316
+ Pn(H)
1317
+ ] : []
1318
+ ], Ot = yi.make(...Dt).middleware(Mn).middleware(Nn), kt = Rr({ resolveSubject: ({ headers: t, clientId: n }) => e.resolveSubject(t, n) }), At = e.dormancyTenantId ?? ur, Nt = e.dormancy === "sleep" ? {
1319
+ register: (t, n, r) => ni(e.store, {
1320
+ tenantId: r ?? At,
1321
+ kind: "workflow",
1322
+ refId: t,
1323
+ wakeAt: n
1324
+ }),
1325
+ cancel: (t, n) => Cr(e.store, {
1326
+ tenantId: n ?? At,
1327
+ kind: "workflow",
1328
+ refId: t
1329
+ }).then(() => {})
1330
+ } : void 0, M = _e ? await import("@voltro/workflow") : void 0, N = M?.makeWorkflowRunRecorder({
1331
+ store: e.store,
1332
+ ...e.workflowRecording === void 0 ? {} : { recording: e.workflowRecording },
1333
+ ...Nt === void 0 ? {} : { wakeups: Nt }
1334
+ }), Pt = async (t, n) => {
1335
+ await M.closeWorkflowChildrenForParent({
1336
+ store: e.store,
1337
+ parentExecutionId: t,
1338
+ parentStatus: n,
1339
+ recorder: N,
1340
+ log: { warn: (e, t) => {
1341
+ process.stderr.write(`[workflow] ${e} ${t ? JSON.stringify(t) : ""}\n`);
1342
+ } },
1343
+ interruptChild: async (t, n) => {
1344
+ let r = (e.discovered.workflows ?? []).find((e) => e.definition.name === t);
1345
+ if (!r) throw Error(`Unknown child workflow: ${t}`);
1346
+ if (!d) throw Error("Workflow runtime is not ready");
1347
+ await d.runPromise(r.definition.interrupt(n));
1348
+ }
1349
+ });
1350
+ }, Ft = async (t, n, r) => {
1351
+ let i = (await e.store.query({
1352
+ table: "_voltro_workflow_runs",
1353
+ order: [],
1354
+ predicate: W("executionId", n),
1355
+ projection: void 0,
1356
+ skip: void 0,
1357
+ take: 1
1358
+ }))[0];
1359
+ if (i === void 0) return;
1360
+ let a = await e.store.update("_voltro_workflow_runs", i.id, {
1361
+ status: "cancelled",
1362
+ cancelled: !0,
1363
+ completedAt: /* @__PURE__ */ new Date()
1364
+ }), o = i.subject?.tenantId ?? void 0;
1365
+ a && await N.recordEvent({
1366
+ runId: i.id,
1367
+ eventType: "run-cancelled",
1368
+ payload: {
1369
+ reason: r,
1370
+ workflowName: t,
1371
+ executionId: n,
1372
+ ...o == null ? {} : { tenantId: o }
1373
+ }
1374
+ }), a && await Pt(n, "cancelled");
1375
+ }, It = [
1376
+ ...Y(e.discovered.workflows ?? [], {
1377
+ buildContext: (t, n) => e.buildContextForWorkflow?.(t, n) ?? Be({
1378
+ subject: t.subject,
1379
+ traceId: t.traceId
1380
+ }, e.store, void 0, `workflow:${n.workflowName}`, { parentExecutionId: n.executionId }),
1381
+ resolveStartContext: se,
1382
+ ...ce === void 0 ? {} : { resolveAuthority: ce }
1383
+ }, (t, n, r) => {
1384
+ let i = M.getWorkflowVersionMetadata(t.definition);
1385
+ return M.wrapWorkflowExecuteWithRunRecording({
1386
+ name: t.definition.name,
1387
+ store: e.store,
1388
+ subject: r.subject,
1389
+ source: r.source ?? null,
1390
+ traceId: r.traceId,
1391
+ workflowVersion: i.version,
1392
+ workflowCompatibleVersions: i.compatibleWith,
1393
+ workflowPatches: i.patches,
1394
+ parentExecutionId: r?.parentExecutionId ?? null,
1395
+ parentClosePolicy: r?.parentClosePolicy ?? null,
1396
+ onParentClose: ({ executionId: e, status: t }) => Pt(e, t),
1397
+ ...pt(t.definition),
1398
+ onTerminal: async ({ executionId: e }) => {
1399
+ await u?.gate.release(e);
1400
+ },
1401
+ recorder: N,
1402
+ pluginWorkflowStepLayer: it,
1403
+ recordRun: ei
1404
+ }, n);
1405
+ }),
1406
+ ...e.discovered.workflowWorkers ?? [],
1407
+ ...xe === void 0 ? [] : [xe]
1408
+ ], Lt = [...(e.discovered.workflows ?? []).map((e) => e.definition.name).filter(Boolean), ...xe === void 0 ? [] : ["voltro.deliverWebhook"]], zt = It.length > 0 ? K.mergeAll(...It) : K.empty;
1409
+ if (((e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster" || xe !== void 0) && e.workflowEngineLayer !== void 0) {
1410
+ let t = zt.pipe(K.provideMerge(e.workflowEngineLayer));
1411
+ d = nr.make(e.baseLayer === void 0 ? t : t.pipe(K.provideMerge(e.baseLayer))), await d.runPromise(G.void), (e.log ?? R({ scope: "voltro:serve" })).child("workflow").info(`workflow runtime ready — ${Lt.length} entity type(s) registered`, { entities: Lt });
1412
+ let n = await import("@voltro/workflow/cluster"), r = (e) => d.runPromise(n.redriveFailedRun(e)), i = (e) => d.runPromise(n.resumeRunFromStep(e));
1413
+ ne = await Bt({
1414
+ provider: zi(e.plugins ?? [])?.broadcast?.provider,
1415
+ crossReplica: zi(e.plugins ?? [])?.broadcast?.crossReplica ?? !1,
1416
+ namespace: Ne,
1417
+ replicaId: crypto.randomUUID(),
1418
+ pollStorage: () => d.runPromise(n.pollWorkflowStorage),
1419
+ onChange: (t) => e.store.onChange((e) => t({
1420
+ table: e.table,
1421
+ op: e.op,
1422
+ ...e.origin === void 0 ? {} : { origin: e.origin }
1423
+ })),
1424
+ log: (e.log ?? R({ scope: "voltro:serve" })).child("workflow")
1425
+ }), ee = async (t) => {
1426
+ let n = await ke({
1427
+ store: e.store,
1428
+ workflows: e.discovered.workflows ?? [],
1429
+ runRedrive: r
1430
+ }, t.runId);
1431
+ return n.statusReset && await N.recordEvent({
1432
+ runId: t.runId,
1433
+ eventType: "run-redriven",
1434
+ payload: {
1435
+ reason: "inspect.redrive",
1436
+ activitiesReset: n.outcome.activitiesReset
1437
+ }
1438
+ }), {
1439
+ redriven: n.outcome.redriven,
1440
+ activitiesReset: n.outcome.activitiesReset,
1441
+ reason: n.outcome.reason
1442
+ };
1443
+ }, te = async (t) => {
1444
+ let n = await je({
1445
+ store: e.store,
1446
+ workflows: e.discovered.workflows ?? [],
1447
+ runResume: i
1448
+ }, t.runId, t.step);
1449
+ return n.statusReset && await N.recordEvent({
1450
+ runId: t.runId,
1451
+ eventType: "run-redriven",
1452
+ payload: {
1453
+ reason: "inspect.resume-from-step",
1454
+ step: n.stepName,
1455
+ activitiesReset: n.outcome.activitiesReset
1456
+ }
1457
+ }), {
1458
+ redriven: n.outcome.redriven,
1459
+ stepName: n.stepName,
1460
+ activitiesReset: n.outcome.activitiesReset,
1461
+ reason: n.outcome.reason
1462
+ };
1463
+ };
1464
+ let a = (e.scheduleCoordination ?? "single") === "advisoryLock" ? Nr(e.store, e.scheduleReplicaId ?? `pid-${process.pid}`) : ci, c = zr({
1465
+ coordinator: a,
1466
+ replicaId: e.scheduleReplicaId ?? `pid-${process.pid}`
1467
+ }), f = {
1468
+ info: (e, t) => {
1469
+ process.stdout.write(`[flow-control] ${e} ${t ? JSON.stringify(t) : ""}\n`);
1470
+ },
1471
+ warn: (e, t) => {
1472
+ process.stderr.write(`[flow-control] ${e} ${t ? JSON.stringify(t) : ""}\n`);
1473
+ },
1474
+ error: (e, t) => {
1475
+ process.stderr.write(`[flow-control] ERROR ${e} ${t ? JSON.stringify(t) : ""}\n`);
1476
+ }
1477
+ }, p, m = () => {
1478
+ if (p !== void 0) return p;
1479
+ if (o !== void 0 && N !== void 0) return p = ie({
1480
+ store: e.store,
1481
+ log: I,
1482
+ workflows: e.discovered.workflows ?? [],
1483
+ workflowsProxy: o,
1484
+ workflowRuntime: d,
1485
+ workflowRunRecorder: N,
1486
+ closeChildrenForParent: Pt
1487
+ }), p;
1488
+ };
1489
+ s = m, u = tt({
1490
+ store: e.store,
1491
+ onChange: (t) => e.store.onChange((e) => t({
1492
+ table: e.table,
1493
+ op: e.op
1494
+ })),
1495
+ ...e.scheduling === void 0 ? {} : {
1496
+ disarmWhenIdle: e.scheduling.disarmWhenIdle,
1497
+ drainIntervalMs: e.scheduling.admissionDrainMs,
1498
+ cancelSweepIntervalMs: e.scheduling.cancelSweepMs,
1499
+ stalenessSweepIntervalMs: e.scheduling.stalenessSweepMs
1500
+ },
1501
+ workflows: e.discovered.workflows ?? [],
1502
+ facade: () => o,
1503
+ cancelRunWithReason: m,
1504
+ recordRunEvent: () => N?.recordEvent,
1505
+ ...e.workflowStaleness === void 0 ? {} : { staleness: e.workflowStaleness },
1506
+ ...e.workflowSuspendSignalHintMs === void 0 ? {} : { suspendSignalHintMs: e.workflowSuspendSignalHintMs },
1507
+ scheduleCoordinated: c,
1508
+ onAbandoned: async (t) => {
1509
+ await Ke({
1510
+ workflows: e.discovered.workflows ?? [],
1511
+ facade: () => o,
1512
+ log: f,
1513
+ ...t
1514
+ });
1515
+ },
1516
+ log: f
1517
+ });
1518
+ let h = u;
1519
+ h !== void 0 && Qr(() => h.stop()), l = $e({
1520
+ store: e.store,
1521
+ onChange: (t) => e.store.onChange((e) => t({
1522
+ table: e.table,
1523
+ op: e.op
1524
+ })),
1525
+ ...e.scheduling === void 0 ? {} : {
1526
+ disarmWhenIdle: e.scheduling.disarmWhenIdle,
1527
+ tickIntervalMs: e.scheduling.inferenceTickMs
1528
+ },
1529
+ enabled: (e.discovered.workflows?.length ?? 0) > 0,
1530
+ resumeSignal: () => d === void 0 || M === void 0 ? void 0 : async ({ executionId: t, workflowName: n, signalName: r, payload: i }) => {
1531
+ await d.runPromise(M.completeSuspendingSignal({
1532
+ store: e.store,
1533
+ target: Je(t, n),
1534
+ signalName: r,
1535
+ payload: i
1536
+ }));
1537
+ },
1538
+ runEffect: (e) => d.runPromise(e),
1539
+ scheduleCoordinated: c,
1540
+ log: f
1541
+ });
1542
+ let g = l;
1543
+ g !== void 0 && Qr(() => g.stop()), o = (e.discovered.workflows?.length ?? 0) > 0 ? Yr({
1544
+ workflows: e.discovered.workflows ?? [],
1545
+ runEffect: (e) => d.runPromise(e),
1546
+ onEnqueue: () => ne?.publishWake(),
1547
+ ...h === void 0 ? {} : {
1548
+ admitStart: h.gate.admitStart,
1549
+ startPayloadSchema: h.gate.startPayloadSchema,
1550
+ parkDelayedStart: h.gate.parkDelayed
1551
+ },
1552
+ rememberStartContext: re,
1553
+ signal: async (t, n, r) => {
1554
+ let i = await M.sendWorkflowSignal({
1555
+ store: e.store,
1556
+ recorder: N,
1557
+ target: t,
1558
+ signalName: n,
1559
+ payload: r
1560
+ });
1561
+ return await d.runPromise(M.completeSuspendingSignal({
1562
+ store: e.store,
1563
+ target: t,
1564
+ signalName: n,
1565
+ payload: r
1566
+ })).catch(() => {}), i;
1567
+ },
1568
+ update: (t, n, r, i) => M.sendWorkflowUpdate({
1569
+ store: e.store,
1570
+ recorder: N,
1571
+ target: t,
1572
+ updateName: n,
1573
+ payload: r,
1574
+ ...i === void 0 ? {} : { options: i }
1575
+ }),
1576
+ listRuns: (t) => _(e.store, t),
1577
+ retry: (t, n) => oe({
1578
+ store: e.store,
1579
+ workflows: e.discovered.workflows ?? [],
1580
+ runPromise: (e) => d.runPromise(e)
1581
+ }, t, n),
1582
+ redrive: (t) => ke({
1583
+ store: e.store,
1584
+ workflows: e.discovered.workflows ?? [],
1585
+ runRedrive: r
1586
+ }, t).then((e) => e.outcome)
1587
+ }) : void 0;
1588
+ }
1589
+ let Vt = K.mergeAll(Ot.toLayer(k), kt), Ht = ot(k, e.discovered.queries.map((e) => e.descriptor.name), pe), Ut = K.mergeAll(Ot.toLayer(Ht), kt), P = e.observability, Wt = await Sr({
1590
+ ...e.appName === void 0 ? {} : { serviceName: e.appName },
1591
+ ...P && P.spanProcessors.length > 0 ? { extraSpanProcessors: P.spanProcessors } : {},
1592
+ ...P && P.metricReaders.length > 0 ? { extraMetricReaders: P.metricReaders } : {},
1593
+ ...P && Object.keys(P.resourceAttributes).length > 0 ? { resourceAttributes: P.resourceAttributes } : {},
1594
+ ...P && P.sampler !== void 0 ? { sampler: P.sampler } : {}
1595
+ }), Gt = !1, F = e.store.ping ? () => e.store.ping().then(() => !0).catch(() => !1) : void 0, { server: Kt, shutdown: qt } = li({
1596
+ group: Ot,
1597
+ handlersLayer: Vt,
1598
+ httpHandlersLayer: Ut,
1599
+ port: e.port ?? 4e3,
1600
+ ...e.host === void 0 ? {} : { host: e.host },
1601
+ path: e.path ?? "/ws",
1602
+ tracerLayer: Wt.layer,
1603
+ security: ae(e),
1604
+ ...rt,
1605
+ healthCheck: {
1606
+ isReady: () => Gt,
1607
+ ...F ? { ping: F } : {}
1608
+ },
1609
+ ...Et.length > 0 ? { httpRoutes: Et } : {},
1610
+ ...e.getStore === void 0 ? {} : { getStore: e.getStore },
1611
+ ...we.size > 0 ? { webhookRoutes: we } : {},
1612
+ ...e.inspectRoute === void 0 ? {} : { inspectRoute: e.inspectRoute }
1613
+ }), Jt = ea(Kt);
1614
+ if (await yr(Kt), (e.discovered.schedules?.length ?? 0) > 0) {
1615
+ let t = (e.scheduleCoordination ?? "single") === "advisoryLock" ? Nr(e.store, e.scheduleReplicaId ?? `pid-${process.pid}`) : ci;
1616
+ p = await ui(e.discovered.schedules ?? [], {
1617
+ store: e.store,
1618
+ coordinator: t,
1619
+ defaultTrigger: e.scheduleDefaultTrigger ?? "self",
1620
+ replicaId: e.scheduleReplicaId ?? `pid-${process.pid}`,
1621
+ armSelf: e.scheduleArmSelf ?? !0,
1622
+ dormancy: e.dormancy ?? "always-on",
1623
+ ...e.dormancyTenantId === void 0 ? {} : { dormancyTenantId: e.dormancyTenantId },
1624
+ buildContext: ({ traceId: t, scheduleName: n, subject: r }) => Be({
1625
+ subject: r,
1626
+ traceId: t
1627
+ }, e.store, void 0, `schedule:${n}`),
1628
+ log: {
1629
+ info: (e, t) => {
1630
+ process.stdout.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
1631
+ },
1632
+ warn: (e, t) => {
1633
+ process.stderr.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
1634
+ },
1635
+ error: (e, t) => {
1636
+ process.stderr.write(`[schedule] ERROR ${e} ${t ? JSON.stringify(t) : ""}\n`);
1637
+ },
1638
+ debug: () => {}
1639
+ },
1640
+ ...e.scheduleFireInterceptor === void 0 ? {} : { interceptFire: e.scheduleFireInterceptor },
1641
+ ...e.onScheduleRunEvent === void 0 ? {} : { onRunEvent: e.onScheduleRunEvent }
1642
+ }), e.onSchedulerReady?.(p);
1643
+ }
1644
+ let I = e.log ?? R({ scope: "voltro:serve" }), Yt, Xt;
1645
+ if ((e.discovered.subscribers?.length ?? 0) > 0 && (Yt = Ce(e.discovered.subscribers ?? [], e.store, I.child("subscribe"), e.schemaRegistry, T.bus)), (e.discovered.reactions?.length ?? 0) > 0) {
1646
+ let t = I.child("reaction"), n = async (n, r) => {
1647
+ if (n.kind === "workflow") {
1648
+ if (b === void 0) {
1649
+ t.warn("reaction workflow act skipped — no workflow engine in this app", { workflow: n.workflow });
1650
+ return;
1651
+ }
1652
+ let e = n.payload === void 0 ? r.new ?? r.old ?? {} : n.payload(r);
1653
+ await Xr(b, {
1654
+ traceId: `reaction:${n.workflow}`,
1655
+ source: `reaction:${n.workflow}`
1656
+ }).start(n.workflow, e);
1657
+ return;
1658
+ }
1659
+ await he(n.agent, r, {
1660
+ findAgentSend: (t) => e.discovered.actions.find((e) => e.descriptor.name === `${t}.send`),
1661
+ runAction: (e, t, n) => Promise.resolve(mt(e, t, n)),
1662
+ makeSubject: (e) => Fn(e),
1663
+ now: () => Date.now(),
1664
+ log: t
1665
+ });
1666
+ }, r = async (n, r) => {
1667
+ try {
1668
+ let { requireAiBudget: t } = await import("@voltro/ai");
1669
+ return (await G.runPromise(G.either(t(e.store, {
1670
+ tenantId: n,
1671
+ limitUsd: r
1672
+ }))))._tag === "Right";
1673
+ } catch (e) {
1674
+ return t.warn("reaction budget check failed — refusing the act", { tenantId: n }, e), !1;
1675
+ }
1676
+ }, i = jt(e.store, { onError: (e) => t.warn("reaction: rate-slot claim failed; refusing the act", { cause: String(e) }) });
1677
+ Xt = lt(e.discovered.reactions ?? [], e.store, {
1678
+ runAct: n,
1679
+ checkBudget: r,
1680
+ claimRateSlot: (e) => i.claim(e)
1681
+ }, t);
1682
+ }
1683
+ let Zt;
1684
+ (e.discovered.aggregates?.length ?? 0) > 0 && (Zt = await g({
1685
+ discovered: e.discovered.aggregates ?? [],
1686
+ store: e.store,
1687
+ log: I.child("aggregate"),
1688
+ ...e.analytics === void 0 ? {} : { analytics: e.analytics },
1689
+ ...e.aggregateStorage === void 0 ? {} : { storage: e.aggregateStorage },
1690
+ ...e.aggregateCoordinator === void 0 ? {} : { coordinator: e.aggregateCoordinator }
1691
+ }), Ve = K.succeed(cr, Zt.registry));
1692
+ let Qt;
1693
+ (e.discovered.expectations?.length ?? 0) > 0 && (Qt = gr({
1694
+ discovered: e.discovered.expectations ?? [],
1695
+ store: e.store,
1696
+ log: I.child("expectation")
1697
+ }), He = K.succeed(fr, Qt.registry)), (e.discovered.budgets?.length ?? 0) > 0 && (n = vr({
1698
+ discovered: e.discovered.budgets ?? [],
1699
+ log: I.child("finops")
1700
+ }), We = K.succeed(lr, n.registry));
1701
+ let $t;
1702
+ return (e.discovered.experiments?.length ?? 0) > 0 && ($t = _r({
1703
+ discovered: e.discovered.experiments ?? [],
1704
+ store: e.store,
1705
+ log: I.child("experiment")
1706
+ }), qe = K.succeed(pr, $t.registry)), Gt = !0, e.bootTiming?.mark("ready"), {
1707
+ dispatcher: r,
1708
+ server: Kt,
1709
+ scheduler: p,
1710
+ eventsSnapshot: ge(T.bus, T.declared),
1711
+ membersSnapshot: () => ({
1712
+ members: Re.membership.list(),
1713
+ capturedAt: Date.now()
1714
+ }),
1715
+ agentTools: () => xt,
1716
+ rpcMetrics: () => Qe,
1717
+ webhooksService: () => be,
1718
+ runCanceller: () => s(),
1719
+ flowControlHealth: () => u?.cancelHealth(),
1720
+ inferenceHealth: () => l?.health(),
1721
+ workflowWriteActions: () => b === void 0 || N === void 0 ? void 0 : le({
1722
+ store: e.store,
1723
+ log: I,
1724
+ workflows: e.discovered.workflows ?? [],
1725
+ workflowsProxy: o,
1726
+ workflowRuntime: d,
1727
+ workflowRunRecorder: N,
1728
+ closeChildrenForParent: Pt
1729
+ }),
1730
+ redriveWorkflowRun: (e) => ee ? ee(e) : Promise.reject(/* @__PURE__ */ Error("redrive: this app registers no workflows")),
1731
+ resumeWorkflowRunFromStep: (e) => te ? te(e) : Promise.reject(/* @__PURE__ */ Error("resume-from-step: this app registers no workflows")),
1732
+ close: async () => {
1733
+ Gt = !1, await Jt.drainRequests();
1734
+ for (let e of Te) try {
1735
+ await e();
1736
+ } catch (e) {
1737
+ I.warn("serve: teardown step failed", {}, e);
1738
+ }
1739
+ await ze?.detach(), await Re.detach(), Zt?.detach(), Qt?.detach(), n?.detach(), $t?.detach(), Xt?.(), Yt?.(), await p?.shutdown(), r.close(), await ne?.detach(), await d?.dispose(), await qt(), await Jt.finish();
1740
+ }
1741
+ };
1742
+ }, $ = R({ scope: "voltro:serve" }), mo = (e, t, n) => (e === "production" || e === "staging") && t !== "memory" && n !== "0", ho = Ut, go = async (e) => {
1743
+ let t = Sn(process.cwd());
1744
+ if (An(t)) {
1745
+ let n;
1746
+ try {
1747
+ let e = await import(jn(t).href);
1748
+ typeof e.runServe == "function" ? n = e.runServe : $.warn("serve bundle has no runServe export — using the standard serve path");
1749
+ } catch (e) {
1750
+ $.warn("serve bundle failed to load — using the standard serve path", {}, e);
1751
+ }
1752
+ if (n) return $.info("serve: booting from the precompiled serve bundle"), n(e);
1753
+ }
1754
+ return _o(e);
1755
+ }, _o = async (c) => {
1756
+ let f = Cn();
1757
+ e("serve");
1758
+ try {
1759
+ Di();
1760
+ } catch (e) {
1761
+ throw i(e instanceof Error ? e.message : String(e));
1762
+ }
1763
+ let m = process.cwd(), g = await We(m), ie = P({
1764
+ kind: "api",
1765
+ configPort: g?.port,
1766
+ env: process.env,
1767
+ flagPort: ho(c, "--port")
1768
+ });
1769
+ for (let e of ie.warnings) $.warn(e);
1770
+ let oe = ie.port;
1771
+ ai(ri(g?.secrets)), await Wt({
1772
+ rawEnv: g?.env,
1773
+ appType: "api",
1774
+ root: m,
1775
+ log: $,
1776
+ generateTypes: !1
1777
+ }), f.mark("config");
1778
+ let _ = (process.env.DB_DIALECT ?? g?.store ?? "memory").toLowerCase(), le = (_ === "mariadb" || _ === "postgres" || _ === "mssql") && (process.env.CDC ?? "1") !== "0", ue = _ === "mariadb" ? "mariadb" : _ === "mssql" ? "mssql" : void 0, de = xn(m);
1779
+ if (!r() && An(de)) try {
1780
+ let e = await import(jn(de).href);
1781
+ if (e.modules) {
1782
+ let t = {};
1783
+ for (let [n, r] of Object.entries(e.modules)) t[On(m, n)] = r;
1784
+ n(t), $.info("precompiled api bundle loaded", { modules: Object.keys(t).length });
1785
+ }
1786
+ } catch (e) {
1787
+ $.warn("precompiled api bundle failed to load — falling back to source", {}, e);
1788
+ }
1789
+ let v = await Ze(m), y = await kt(v, { cdc: le && ue !== void 0 }), fe = Ht(y);
1790
+ {
1791
+ let e = /* @__PURE__ */ new Set([
1792
+ ...y.queries.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name),
1793
+ ...y.mutations.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name),
1794
+ ...y.actions.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name)
1795
+ ]);
1796
+ nn(Xt(g?.plugins ?? []), [
1797
+ ...y.queries.map((e) => e.descriptor.name),
1798
+ ...y.mutations.map((e) => e.descriptor.name),
1799
+ ...y.actions.map((e) => e.descriptor.name),
1800
+ ...y.streams.map((e) => e.descriptor.name)
1801
+ ], e);
1802
+ let t = se(y.serverOnlyLeaks, Me(process.env, "strict"), Er, "`voltro serve`");
1803
+ if (t.action === "fail") throw i(t.message ?? "");
1804
+ t.action === "warn" && $.warn(t.message ?? "");
1805
+ }
1806
+ let me = v.filter((e) => yn.test(e)), he = me.length > 0 ? await vn(me, $.child("webhooks")) : {
1807
+ outgoing: [],
1808
+ incoming: [],
1809
+ providers: []
1810
+ }, ge = gn(y.events), Se = he.outgoing.length + he.incoming.length + he.providers.length + ge.length === 0 ? void 0 : {
1811
+ ...he,
1812
+ outgoing: [...he.outgoing, ...ge]
1813
+ }, Ce = rn({
1814
+ nodeEnv: process.env.NODE_ENV,
1815
+ cdcDialect: ue,
1816
+ declared: g?.schema
1817
+ }), Ee = an({
1818
+ gates: Ce,
1819
+ runtime: {
1820
+ traces: be(),
1821
+ undo: fi()
1822
+ }
1823
+ });
1824
+ if (Ee !== void 0) throw i(`serve: ${Ee}`);
1825
+ let ke = tn({
1826
+ mix: y.featureMix,
1827
+ plugins: g?.plugins ?? [],
1828
+ gates: Ce,
1829
+ ...ue ? { cdcDialect: ue } : {}
1830
+ }), Ae = g?.analytics !== void 0 && g.analytics.kind !== "noop" && _ !== "memory" ? (await F(_)).makeSqlLayer(D()) : void 0, je = await Ye({
1831
+ spec: g?.analytics,
1832
+ sqlLayer: Ae,
1833
+ log: $
1834
+ }), C = (() => {
1835
+ let e = new Set(y.tables.map((e) => e.tableName)), t = [...y.tables];
1836
+ for (let n of [...ke, ...je.tables]) e.has(n.tableName) || (e.add(n.tableName), t.push(n));
1837
+ return t;
1838
+ })();
1839
+ for (let e of C) $n(e);
1840
+ {
1841
+ let e = Dr(pi(He(y), Lt(C)));
1842
+ e !== void 0 && $.warn(e);
1843
+ }
1844
+ let Ie = (process.env.NODE_ENV ?? "").toLowerCase();
1845
+ if (mo(Ie, _, process.env.VOLTRO_AUTO_MIGRATE)) {
1846
+ let e = (await F(_)).makeSqlLayer(D()), t = await G.runPromise(rr.SqlClient.pipe(G.flatMap((e) => or(e, m)), G.provide(e), G.catchAll(() => G.succeed([]))));
1847
+ t.length > 0 && ($.error(`serve: refusing to boot — ${t.length} pending file-based migration(s) have never run against this database. They perform the changes a schema diff cannot infer (data moves, backfills, table splits), so the declarative fingerprint check below cannot see them and would have let this process serve un-migrated data.`, { pending: t }), $.error("Run them from your pre-deploy job — `voltro db migrate .` (schema + files) or `voltro db files .` (files alone) — or set VOLTRO_AUTO_MIGRATE=0 to bypass every boot schema check. `voltro serve` never applies them itself: a rolling deploy would start N replicas and each would try."), process.exit(1));
1848
+ let n = await G.runPromise(rr.SqlClient.pipe(G.flatMap((e) => sr(e, C, {
1849
+ appliedBy: `serve:${Ie}`,
1850
+ environment: "prod",
1851
+ dialectId: _
1852
+ })), G.provide(e)));
1853
+ n.kind === "prod-mismatch" && ($.error(ar(n, _)), $.error(on({
1854
+ gates: Ce,
1855
+ nodeEnv: process.env.NODE_ENV,
1856
+ cdcDialect: ue,
1857
+ declared: g?.schema
1858
+ })), $.error("serve: refusing to boot — apply the schema first (voltro db apply in a pre-deploy step), or set VOLTRO_AUTO_MIGRATE=0 to bypass this check."), process.exit(1)), $.info(ar(n, _));
1859
+ }
1860
+ await Yt({
1861
+ dialectId: _,
1862
+ tables: C,
1863
+ mode: Jt(g?.reactiveTriggers),
1864
+ lockSchema: D().schema,
1865
+ makeLayer: async () => (await F(_)).makeSqlLayer(D()),
1866
+ log: {
1867
+ info: (e, t) => $.info(e, t ?? {}),
1868
+ warn: (e, t) => $.warn(e, t ?? {})
1869
+ }
1870
+ });
1871
+ let Le = Jr(C);
1872
+ f.mark("discover");
1873
+ let w = await at(g, void 0);
1874
+ {
1875
+ let e = await s(w);
1876
+ if (e !== void 0) throw i(`serve: ${e}`);
1877
+ }
1878
+ let Ue = gi(w, _);
1879
+ for (let e of rt({
1880
+ dialect: String(g?.store ?? process.env.DB_DIALECT ?? "postgres"),
1881
+ changeStrategy: (process.env.CDC ?? "1") === "0" ? "inline" : "cdc",
1882
+ dbUrl: process.env.DB_URL,
1883
+ crossReplicaBus: zi(g?.plugins ?? [])?.broadcast.crossReplica === !0,
1884
+ tables: y.tables.map((e) => ({
1885
+ tableName: e.tableName,
1886
+ isReactive: e.isReactive === !0
1887
+ })),
1888
+ querySources: y.queries.flatMap((e) => {
1889
+ let t = e.descriptor.source;
1890
+ return t === void 0 ? [] : typeof t == "string" ? [t] : [...t];
1891
+ })
1892
+ })) e.level === "warn" ? $.warn(e.message) : $.info(e.message);
1893
+ {
1894
+ let e = yt({
1895
+ tables: Jn().map((e) => ({ tableName: e.tableName })),
1896
+ queries: y.queries.map((e) => ({
1897
+ name: e.descriptor.name,
1898
+ source: e.descriptor.source
1899
+ }))
1900
+ }), t = ht(e);
1901
+ t !== void 0 && $.warn(t);
1902
+ }
1903
+ g?.cache && !process.env.CACHE_BACKEND && (process.env.CACHE_BACKEND = g.cache), g?.cacheRedisUrl && !process.env.CACHE_REDIS_URL && (process.env.CACHE_REDIS_URL = g.cacheRedisUrl), g?.cacheRedisDriver && !process.env.CACHE_REDIS_DRIVER && (process.env.CACHE_REDIS_DRIVER = g.cacheRedisDriver), g?.cacheKeyPrefix && !process.env.CACHE_KEY_PREFIX && (process.env.CACHE_KEY_PREFIX = g.cacheKeyPrefix);
1904
+ let { service: Ge, invalidationBus: Ke, snapshotCache: Je, cache: Xe, semantic: $e, evictSource: tt, backend: ot, stats: ct, dispose: lt } = await Qe({
1905
+ env: process.env,
1906
+ semantic: g?.cacheSemantic ?? !1
1907
+ });
1908
+ $e !== void 0 && $.info("semantic cache enabled — reactive eviction on live writes"), $.info(`cache backend resolved: ${ot}` + (ot === "redis" ? ` (driver ${process.env.CACHE_REDIS_DRIVER ?? "resp"})` : " — in-process, not cross-instance")), w.onChange((e) => {
1909
+ if (G.runFork(Ke.publish(e.table)), tt !== void 0) {
1910
+ let t = (e.new ?? e.old)?.id;
1911
+ tt({
1912
+ table: e.table,
1913
+ op: e.op,
1914
+ ...t === void 0 ? {} : { id: t }
1915
+ });
1916
+ }
1917
+ }), g?.kv && !process.env.KV_BACKEND && (process.env.KV_BACKEND = g.kv), g?.kvRedisUrl && !process.env.KV_REDIS_URL && (process.env.KV_REDIS_URL = g.kvRedisUrl), g?.kvKeyPrefix && !process.env.KV_KEY_PREFIX && (process.env.KV_KEY_PREFIX = g.kvKeyPrefix);
1918
+ let { kv: ft, service: pt } = await Lr({ store: w });
1919
+ Pt({
1920
+ log: $,
1921
+ max: qt(),
1922
+ outOfPool: te(_, (process.env.CDC ?? "1") !== "0"),
1923
+ readPools: t.replicationSnapshot()?.replicaCount ?? 0,
1924
+ always: !0
1925
+ }), f.mark("store");
1926
+ let _t = hr({
1927
+ store: w,
1928
+ sink: je.sink,
1929
+ log: $
1930
+ }), St = qe({
1931
+ store: w,
1932
+ dialect: _,
1933
+ log: { info: (e) => $.info(e) }
1934
+ }), j = g?.plugins ?? [], jt = process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, Rt, Bt;
1935
+ _ !== "memory" && (Rt = nr.make((await F(_)).makeSqlLayer(D())), Bt = await Rt.runPromise(rr.SqlClient));
1936
+ let Ut = [
1937
+ "postgres",
1938
+ "mariadb",
1939
+ "mysql",
1940
+ "mssql"
1941
+ ].includes(_) ? Nr(w, jt, $) : ci, _n = M(g?.scheduling), Sn = zr({
1942
+ maxIdleIntervalMs: _n.pollCeilingMs,
1943
+ coordinator: Ut,
1944
+ replicaId: jt,
1945
+ log: $
1946
+ }), wn = [], Tn = process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, En = zi(g?.plugins ?? [])?.broadcast?.provider, L = et(g?.plugins, g?.name ?? Dn(m));
1947
+ {
1948
+ let e = nt(g?.plugins, g?.name ?? Dn(m));
1949
+ e !== void 0 && $.warn(e);
1950
+ }
1951
+ let kn = Mt(g?.plugins, {
1952
+ instanceId: Tn,
1953
+ namespace: L,
1954
+ meta: { mode: "serve" },
1955
+ logger: $
1956
+ }), R = {
1957
+ ...Bt ? { sql: Bt } : {},
1958
+ instanceId: Tn,
1959
+ membership: kn.membership,
1960
+ ...En === void 0 ? {} : { broadcast: En },
1961
+ broadcastChannels: { presence: Ri(L, "presence") },
1962
+ scheduleCoordinated: (e, t, n) => {
1963
+ let r = Sn(e, t, n);
1964
+ return wn.push(r), r;
1965
+ }
1966
+ };
1967
+ for (let e of j) e.bindDataStore?.(Ue, R);
1968
+ u({
1969
+ store: w,
1970
+ ...ut(),
1971
+ log: $
1972
+ });
1973
+ let Mn = j.filter((e) => typeof e.onChangeEvent == "function");
1974
+ if (Mn.length > 0) {
1975
+ let e = w.changeScope ?? "local";
1976
+ w.onChange((t) => {
1977
+ let n = xe(t, e);
1978
+ for (let e of Mn) G.runFork(e.onChangeEvent(n).pipe(G.catchAllCause((t) => G.sync(() => $.warn(`plugin ${e.name} onChangeEvent failed`, { error: tr.pretty(t) })))));
1979
+ });
1980
+ }
1981
+ let Nn = Fe({
1982
+ plugins: j,
1983
+ appName: g?.name ?? "voltro-api",
1984
+ appType: "api",
1985
+ voltroVersion: process.env.npm_package_version ?? "0.0.0",
1986
+ log: $
1987
+ });
1988
+ j.length && await Nn.activate(), f.mark("plugins");
1989
+ let Pn = await Nn.gatherObservability(), Fn = {
1990
+ info: (e, t) => process.stdout.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
1991
+ warn: (e, t) => process.stderr.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
1992
+ debug: () => {}
1993
+ }, In, Ln = await k(w, g, _, L, Fn, (e, t) => {
1994
+ In?.refreshAll(`broadcast gap: missed ${t} change(s) from ${e}`);
1995
+ }), z = g?.apiKeys, Rn = (typeof z == "object" ? z.prefix : void 0) ?? "voltro_", zn = z ? Tr(w) : void 0, Bn = zn ? Fr({ flush: Ir(zn) }) : void 0;
1996
+ Bn && Qr(() => Bn.shutdown());
1997
+ let B = zn ? Pr(zn, {
1998
+ prefix: Rn,
1999
+ ...Bn ? { usage: Bn } : {}
2000
+ }) : void 0, Vn = B ? [Or(B, { prefix: Rn })] : [], Hn = Ct([...g?.auth?.strategies ?? [], ...Vn], Ii(g?.plugins ?? []), g?.auth?.anonymousTenantRequired ?? !1, g?.auth, () => Ue), Un = [...g?.restRoutes ?? [], ...B ? mr(B, (typeof z == "object" ? z.managementPath : void 0) ?? "/v1/api-keys") : []], Wn = A(g?.idempotency, w), Gn = j.map((e) => e.services).filter((e) => e !== void 0), Kn = K.mergeAll(vt({
2001
+ analyticsLayer: je.layer,
2002
+ cacheService: Ge,
2003
+ kvService: pt,
2004
+ ...$e === void 0 ? {} : { semanticCache: $e },
2005
+ pluginServices: Gn,
2006
+ userLayers: g?.layers ?? []
2007
+ }), ze(g?.http ?? {})), V = await Be({
2008
+ files: v,
2009
+ store: w,
2010
+ log: $,
2011
+ seedPolicy: "report",
2012
+ seedPattern: fn,
2013
+ loadSeedFiles: I,
2014
+ startupPattern: sn,
2015
+ loadStartupFiles: a,
2016
+ runStartups: o,
2017
+ emailPattern: O,
2018
+ loadEmailFiles: Tt,
2019
+ registerEmailTemplates: Li
2020
+ });
2021
+ (V.startupCount > 0 || V.emailCount > 0) && $.info("boot lifecycle", {
2022
+ startups: V.startupCount,
2023
+ emailTemplates: V.emailCount
2024
+ }), V.startups !== void 0 && Qr(async () => {
2025
+ await V.startups.stop();
2026
+ }), pe({
2027
+ demands: we(fe),
2028
+ isRegistered: (e) => kr(e) !== void 0
2029
+ });
2030
+ let H = wt({
2031
+ schedules: st({
2032
+ schedules: y.schedules,
2033
+ seeds: V.seeds,
2034
+ store: w,
2035
+ log: $.child("seeds")
2036
+ }),
2037
+ workflows: y.workflows ?? [],
2038
+ log: $.child("workflow-schedules")
2039
+ }), U = g?.scheduling ?? {}, qn = U.trigger ?? "self", Yn = /* @__PURE__ */ new Set([
2040
+ "postgres",
2041
+ "mysql",
2042
+ "mariadb",
2043
+ "mssql"
2044
+ ]), Zn = U.coordination ?? (Yn.has(_) ? "advisoryLock" : "single"), Qn = Zn === "cluster" && Yn.has(_), W = Qn ? "cluster" : Zn === "advisoryLock" && Yn.has(_) ? "advisoryLock" : "single";
2045
+ Zn === "cluster" && !Qn && $.warn("scheduling.coordination=cluster needs a sql-backed store except sqlite — falling back to single"), Zn === "advisoryLock" && !Yn.has(_) && $.warn("scheduling.coordination=advisoryLock needs a SQL store (the claim-row gate) — falling back to single");
2046
+ let er, cr = y.workflows.length > 0 || y.workflowWorkers.length > 0 || y.eventTriggers.length > 0 || (Se?.outgoing.length ?? 0) > 0 || Qn, lr;
2047
+ if (cr) {
2048
+ if (_ === "mssql") {
2049
+ let e = await hn(process.cwd());
2050
+ e && $.warn(e);
2051
+ }
2052
+ let [{ WorkflowEngine: e }, { makeClusterCronLayer: t, workflowEngineLayer: n, resolveRunnerStorage: r, resolveFailoverTuning: i }] = await Promise.all([import("@effect/workflow"), import("@voltro/workflow/cluster")]), a = Qn ? H.filter((e) => (e.trigger ?? qn) === "self").map((e) => t({
2053
+ name: e.name,
2054
+ cron: wr(e),
2055
+ execute: async () => {
2056
+ await er?.fireFromCluster(e.name);
2057
+ }
2058
+ })) : [];
2059
+ lr = _ === "memory" ? e.layerMemory : await (async () => {
2060
+ let e = await F(_), t = r({ sqliteFamily: e.id === "sqlite" || e.id === "turso" });
2061
+ return $.info(`workflow engine: cluster-${t}, dialect=${e.id}` + (t === "memory" ? " — single-process durable replay, no cross-pod shard handoff" + (e.id !== "sqlite" && e.id !== "turso" ? " (VOLTRO_WORKFLOW_RUNNER_STORAGE=memory: SqlRunnerStorage/cluster_runners + GET_LOCK skipped)" : "") : "")), n({
2062
+ sqlClientLayer: e.makeSqlLayer(D()),
2063
+ runnerStorage: t,
2064
+ dialectId: e.id,
2065
+ ...process.env.VOLTRO_WORKFLOW_RUNNER_PORT ? { runnerListenPort: Number(process.env.VOLTRO_WORKFLOW_RUNNER_PORT) } : {},
2066
+ ...i(),
2067
+ ...a.length > 0 ? { extraShardingLayers: a } : {}
2068
+ });
2069
+ })();
2070
+ }
2071
+ let ur = xt(j, bn()), dr = v.filter((e) => /\.subscribe\.tsx?$/.test(e)), fr = dr.length > 0 ? await l(dr, $) : [], pr = v.filter((e) => /\.reaction\.tsx?$/.test(e)), gr = pr.length > 0 ? await _e(pr, $) : [], _r = v.filter((e) => un.test(e)), vr = _r.length > 0 ? await Pe(_r, $) : [], yr = v.filter((e) => /\.aggregate\.tsx?$/.test(e)), q = yr.length > 0 ? await ye(yr, $) : [];
2072
+ {
2073
+ let e = Dr(pi(He({ aggregates: q.map((e) => e.definition) }), Lt(C)));
2074
+ e !== void 0 && $.warn(e);
2075
+ }
2076
+ let br = dt();
2077
+ if (q.length > 0 && _ !== "memory") try {
2078
+ let e = (await F(_)).makeSqlLayer(D());
2079
+ br = d(e);
2080
+ } catch (e) {
2081
+ $.warn("aggregate: SQL storage init failed — falling back to in-process", { err: String(e) });
2082
+ }
2083
+ let xr = _ === "memory" ? ci : Nr(w, `aggregate@${process.pid}`, $), Sr = v.filter((e) => dn.test(e)), Cr = Sr.length > 0 ? await Ft(Sr, $) : [], Ar = v.filter((e) => ln.test(e)), jr = Ar.length > 0 ? await ne(Ar, $) : [], Mr = v.filter((e) => cn.test(e)), Rr = Mr.length > 0 ? await S(Mr, $) : [], Br = [], Vr = [], Hr = v.filter((e) => Zt.test(e));
2084
+ if (Hr.length > 0) {
2085
+ let e = $.child("agent"), t = v.filter((e) => en.test(e));
2086
+ t.length > 0 && await Qt(t, e);
2087
+ let n = await $t(Hr, e);
2088
+ for (let e of n.agents) for (let t of Ot(e)) (t.kind === "action" ? Br : Vr).push({
2089
+ file: t.file,
2090
+ descriptor: t.descriptor,
2091
+ executor: t.executor
2092
+ });
2093
+ n.agents.length > 0 && e.info("synthesized agent routes", { agents: n.agents.map((e) => e.descriptor.name) });
2094
+ }
2095
+ f.mark("workflow");
2096
+ let J = () => {
2097
+ let e = Y.workflowWriteActions();
2098
+ if (e === void 0) throw Error("workflow actions: this app registers no workflows");
2099
+ return e;
2100
+ }, Ur = Xn({
2101
+ dialect: _,
2102
+ ...D()
2103
+ }), Wr = _ === "memory" ? void 0 : (await F(_)).makeSqlLayer(D()), Gr = async () => E({
2104
+ sqlLayer: Wr,
2105
+ declared: C,
2106
+ log: $
2107
+ }), Kr = {
2108
+ kind: "api",
2109
+ meta: {
2110
+ name: g?.name ?? "voltro-api",
2111
+ voltroVersion: Et,
2112
+ port: oe,
2113
+ mode: "start",
2114
+ store: _,
2115
+ cdc: le ? "on" : "off",
2116
+ ...Ur === void 0 ? {} : { databaseId: Ur }
2117
+ },
2118
+ rpc: Re(y, m),
2119
+ workflows: Nt(y, m),
2120
+ migrations: Gr,
2121
+ events: () => Y.eventsSnapshot(),
2122
+ agentTools: () => Y.agentTools(),
2123
+ invariantChecks: () => ({
2124
+ mode: "serve",
2125
+ accessGate: fe,
2126
+ config: g,
2127
+ serverOnlyLeaks: y.serverOnlyLeaks,
2128
+ migrations: Gr
2129
+ }),
2130
+ members: () => Y.membersSnapshot(),
2131
+ inspectFireSchedule: async ({ name: e, trigger: t }) => {
2132
+ if (!er) throw Error("scheduler not started — this app registers no self-triggered schedules (all schedules are trigger:'external', or there are none).");
2133
+ return { runId: await er.fireNow(e, t) ?? null };
2134
+ },
2135
+ inspectBackfillSchedule: h({
2136
+ getHandle: () => er,
2137
+ getSchedules: () => H
2138
+ }),
2139
+ ...Se === void 0 ? {} : { webhooks: () => ve({
2140
+ store: w,
2141
+ discoveredWebhooks: Se
2142
+ }) },
2143
+ plugins: () => ({
2144
+ plugins: Nn.snapshot(),
2145
+ capturedAt: Date.now()
2146
+ }),
2147
+ env: () => Gt(g?.name ?? Dn(m), {
2148
+ ...g?.env !== void 0 && Ei(g.env) ? { contract: g.env } : {},
2149
+ plugins: g?.plugins ?? []
2150
+ }),
2151
+ dataCache: () => Ve({
2152
+ stats: ct,
2153
+ backendKind: ot
2154
+ }),
2155
+ subscriptions: () => It(() => In),
2156
+ inspectTables: () => b(y.tables),
2157
+ inspectRows: x({
2158
+ store: w,
2159
+ tables: y.tables,
2160
+ mask: !0
2161
+ }),
2162
+ metrics: (e) => Y.rpcMetrics().snapshot(e),
2163
+ cluster: () => zt({
2164
+ store: w,
2165
+ dialect: _,
2166
+ useClusterCron: Qn,
2167
+ scheduleCoordChoice: Zn
2168
+ }),
2169
+ inspectSchedules: () => De({
2170
+ schedules: H,
2171
+ defaultTrigger: qn,
2172
+ coordination: W
2173
+ }),
2174
+ inspectScheduleRuns: (e) => N(w, e),
2175
+ ...ee(w, {
2176
+ controls: it(y.workflows ?? []),
2177
+ active: (y.workflows?.length ?? 0) > 0,
2178
+ cancellation: () => Y.flowControlHealth()
2179
+ }),
2180
+ webhookActions: Te(() => Y.webhooksService()),
2181
+ inspectStartWorkflow: (e) => J().inspectStartWorkflow(e),
2182
+ inspectCancelWorkflowRun: (e) => J().inspectCancelWorkflowRun(e),
2183
+ inspectSuspendWorkflowRun: (e) => J().inspectSuspendWorkflowRun(e),
2184
+ inspectResumeWorkflowRun: (e) => J().inspectResumeWorkflowRun(e),
2185
+ inspectDiscardWorkflowRun: (e) => J().inspectDiscardWorkflowRun(e),
2186
+ inspectRetryWorkflowRun: (e) => J().inspectRetryWorkflowRun(e),
2187
+ inspectSignalWorkflowRun: (e) => J().inspectSignalWorkflowRun(e),
2188
+ inspectUpdateWorkflowRun: (e) => J().inspectUpdateWorkflowRun(e),
2189
+ inspectInferences: (e) => bt({
2190
+ store: w,
2191
+ active: (y.workflows?.length ?? 0) > 0,
2192
+ dispatcher: () => Y.inferenceHealth()
2193
+ }, e.limit === void 0 ? {} : { limit: e.limit }),
2194
+ ...gt({
2195
+ store: w,
2196
+ cancelRun: async (e) => await Y.runCanceller()?.(e) ?? !1,
2197
+ retryRun: async (e) => J().inspectRetryWorkflowRun({ runId: e }),
2198
+ redriveRun: async (e) => Y.redriveWorkflowRun({ runId: e }),
2199
+ log: $
2200
+ }),
2201
+ inspectRedriveWorkflowRun: (e) => Y.redriveWorkflowRun(e),
2202
+ inspectResumeWorkflowRunFromStep: (e) => Y.resumeWorkflowRunFromStep(e)
2203
+ }, qr = (process.env.VOLTRO_TENANT_ISOLATION ?? g?.tenancy?.isolation) === "namespace", Yr = qr && _ !== "memory" ? await (async () => {
2204
+ let e = await F(_);
2205
+ return At({
2206
+ tables: C,
2207
+ sqlLayer: e.makeSqlLayer(D()),
2208
+ dialect: _,
2209
+ options: { retryFilter: e.retryFilter },
2210
+ log: {
2211
+ info: (e, t) => $.info(e, t),
2212
+ error: (e, t, n) => $.error(e, t ?? {}, n)
2213
+ }
2214
+ });
2215
+ })() : void 0, Xr = await mt({
2216
+ input: g?.tenancy?.residency,
2217
+ namespaceIsolationOn: qr,
2218
+ makeStoreForUrl: (e, t) => at(g, void 0, Kt(D(), t)),
2219
+ log: {
2220
+ info: (e, t) => $.info(e, t),
2221
+ warn: (e, t) => $.warn(e, t)
2222
+ }
2223
+ });
2224
+ Xr !== void 0 && Qr(async () => {
2225
+ await Xr.close();
2226
+ });
2227
+ let Y = await po({
2228
+ bootTiming: f,
2229
+ broadcastNamespace: L,
2230
+ scheduling: (() => {
2231
+ let e = _n;
2232
+ return {
2233
+ admissionDrainMs: e.admissionDrainMs,
2234
+ inferenceTickMs: e.inferenceTickMs,
2235
+ cancelSweepMs: e.cancelSweepMs,
2236
+ stalenessSweepMs: e.stalenessSweepMs,
2237
+ disarmWhenIdle: T({
2238
+ changeScope: w.changeScope,
2239
+ broadcastAttached: Ln !== void 0
2240
+ })
2241
+ };
2242
+ })(),
2243
+ ...g?.workflows?.staleness === void 0 ? {} : { workflowStaleness: g.workflows.staleness },
2244
+ ...g?.workflows?.suspendSignalHintMs === void 0 ? {} : { workflowSuspendSignalHintMs: g.workflows.suspendSignalHintMs },
2245
+ workflowRecording: Vt(g?.workflows?.recording),
2246
+ membership: {
2247
+ ...kn,
2248
+ instanceId: Tn
2249
+ },
2250
+ security: {
2251
+ defaultDeny: ce(g),
2252
+ ...ae(g)
2253
+ },
2254
+ approvals: { defaultExpiryMs: Ne(g) },
2255
+ ...g?.plugins === void 0 ? {} : { plugins: g.plugins },
2256
+ ...Wn ? { idempotency: Wn } : {},
2257
+ restRoutes: Un,
2258
+ appProcedures: fe,
2259
+ discovered: {
2260
+ queries: [...y.queries, ...Vr],
2261
+ mutations: y.mutations,
2262
+ actions: [...y.actions, ...Br],
2263
+ streams: y.streams,
2264
+ events: y.events,
2265
+ workflows: y.workflows,
2266
+ workflowWorkers: y.workflowWorkers,
2267
+ eventTriggers: y.eventTriggers,
2268
+ schedules: H,
2269
+ subscribers: fr,
2270
+ outboxHandlers: vr,
2271
+ connections: y.connections,
2272
+ reactions: gr,
2273
+ aggregates: q,
2274
+ expectations: Cr,
2275
+ budgets: jr,
2276
+ experiments: Rr,
2277
+ ...Se === void 0 ? {} : { webhooks: Se }
2278
+ },
2279
+ log: $,
2280
+ analytics: je.sink,
2281
+ aggregateStorage: br,
2282
+ aggregateCoordinator: xr,
2283
+ store: w,
2284
+ kv: ft,
2285
+ cache: Xe,
2286
+ snapshotCache: Je,
2287
+ ...g?.reactive === void 0 ? {} : { reactive: g.reactive },
2288
+ schemaRegistry: Le,
2289
+ tenantScopedTables: y.tenantScopedTables,
2290
+ softDeleteScopedTables: y.softDeleteScopedTables,
2291
+ dataTransferSnapshot: ir(C, _),
2292
+ dataTransferDialect: _,
2293
+ ...Yr === void 0 ? {} : { ensureTenantProvisioned: Yr.ensure },
2294
+ ...Xr === void 0 ? {} : { resolveResidentStore: Xr.resolveStore },
2295
+ tenantIsolation: (process.env.VOLTRO_TENANT_ISOLATION ?? g?.tenancy?.isolation) === "namespace" ? "namespace" : "shared-schema",
2296
+ resolveSubject: (e, t) => Hn({
2297
+ headers: e,
2298
+ clientId: t
2299
+ }),
2300
+ ...g?.auth === void 0 ? {} : { authority: g.auth },
2301
+ ...g?.agents === void 0 ? {} : { agents: g.agents },
2302
+ httpRoutes: j.flatMap((e) => e.httpRoutes ?? []),
2303
+ getStore: () => Ue,
2304
+ ...Kn ? { baseLayer: Kn } : {},
2305
+ ...lr === void 0 ? {} : { workflowEngineLayer: lr },
2306
+ scheduleDefaultTrigger: qn,
2307
+ scheduleCoordination: W,
2308
+ scheduleArmSelf: !Qn,
2309
+ dormancy: process.env.VOLTRO_DORMANCY === "sleep" || process.env.VOLTRO_DORMANCY === "always-on" ? process.env.VOLTRO_DORMANCY : g?.dormancy ?? "always-on",
2310
+ scheduleReplicaId: process.env.HOSTNAME ?? `pid-${process.pid}`,
2311
+ ...ur === void 0 ? {} : { scheduleFireInterceptor: ur },
2312
+ onSchedulerReady: (e) => {
2313
+ er = e;
2314
+ },
2315
+ inspectRoute: { handle: async (e, t, n, r) => await p(e, Kr, t, {
2316
+ method: n,
2317
+ ...r === void 0 ? {} : { body: r }
2318
+ }) || ((n === "GET" ? await mn(e, Kr, t, { method: n }) : null) ?? pn(e, Kr, t, {
2319
+ method: n,
2320
+ ...r === void 0 ? {} : { body: r }
2321
+ }) ?? {
2322
+ status: 404,
2323
+ contentType: "application/json",
2324
+ body: JSON.stringify({ error: "not an inspect route" })
2325
+ }) },
2326
+ ...g?.name === void 0 ? {} : { appName: g.name },
2327
+ observability: Pn,
2328
+ port: oe,
2329
+ ...g?.transport?.wsPath ? { path: g.transport.wsPath } : {}
2330
+ });
2331
+ return In = Y.dispatcher, re(Oe([
2332
+ y.queries,
2333
+ y.mutations,
2334
+ y.actions,
2335
+ y.streams
2336
+ ]), (e) => {
2337
+ $.warn(e);
2338
+ }), $.info(`API listening on :${oe}`, {
2339
+ dialect: _,
2340
+ queries: y.queries.length,
2341
+ mutations: y.mutations.length,
2342
+ actions: y.actions.length,
2343
+ streams: y.streams.length,
2344
+ workflows: y.workflows.length,
2345
+ workflowWorkers: y.workflowWorkers.length,
2346
+ schedules: H.length,
2347
+ scheduleCoordination: W
2348
+ }), f.finish($), Qr(async () => {
2349
+ for (let e of wn) e.stop();
2350
+ St.stop();
2351
+ try {
2352
+ await Y.close(), lt(), Rt?.dispose(), await Nn.deactivate(), await Ln?.close(), await Dt({
2353
+ mirror: _t,
2354
+ log: $
2355
+ }), await je.dispose(), await w.close?.();
2356
+ } catch (e) {
2357
+ console.error("serve: shutdown step failed, exiting anyway:", e);
2358
+ }
2359
+ }), await new Promise(() => {}), 0;
2360
+ };
2361
+ //#endregion
2362
+ export { go as n, mo as r, _o as t };