@voltro/cli 0.31.0 → 0.33.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 (81) hide show
  1. package/CHANGELOG.md +368 -0
  2. package/THIRD-PARTY-NOTICES.md +1 -29
  3. package/dist/apiBuild-C-x9YacA.js +2 -0
  4. package/dist/{apiBuild-CLPt-pX6.js → apiBuild-h9VHtnlw.js} +2 -2
  5. package/dist/bin.js +3 -3
  6. package/dist/checkCommand-DRovTKza.js +2 -0
  7. package/dist/{checkCommand-D7r6_pk7.js → checkCommand-xGhRFFg2.js} +330 -290
  8. package/dist/{commands-CNVVv03h.js → commands-CJfepbm4.js} +139 -13
  9. package/dist/{dbCommand-BH8GAYuf.js → dbCommand-DTLKAfbA.js} +431 -263
  10. package/dist/dbCommand-b1gum4td.js +2 -0
  11. package/dist/{dev-DdQEn2Ia.js → dev-C_P8FLSx.js} +2141 -2081
  12. package/dist/{dev-DOZVMVfi.js → dev-iiMtlkfs.js} +1 -1
  13. package/dist/index.js +1 -1
  14. package/dist/{inspectMetrics-BeEAnjqw.js → inspectMetrics-1xzTKAFx.js} +750 -685
  15. package/dist/{sdkgen-v9WV8zRi.js → sdkgen-C81QIkiL.js} +1 -1
  16. package/dist/serveCommand-DdaM4Hup.js +1608 -0
  17. package/dist/serveEntry.js +2 -2
  18. package/dist/{start-CI2QdKy9.js → start-C0koT0UO.js} +1 -1
  19. package/dist/startEntry.js +2 -2
  20. package/package.json +431 -18
  21. package/templates/AGENTS.md +1 -1
  22. package/templates/agent-docs/_index.md +1 -1
  23. package/templates/agent-docs/database/misc.md +37 -0
  24. package/templates/agent-docs/database/schema.md +4 -2
  25. package/templates/agent-docs/deployment.md +87 -1
  26. package/templates/agent-docs/plugins/audit.md +24 -0
  27. package/templates/agent-docs/plugins.md +50 -0
  28. package/templates/agent-docs/scheduling.md +4 -1
  29. package/templates/agent-docs/security.md +31 -1
  30. package/templates/agent-docs/whats-new.md +149 -59
  31. package/templates/apps/api-ai/package.json +7 -7
  32. package/templates/apps/api-auth/package.json +8 -8
  33. package/templates/apps/api-backend/package.json +7 -7
  34. package/templates/apps/api-backend-deactivation/package.json +7 -7
  35. package/templates/apps/api-backend-mail/package.json +8 -8
  36. package/templates/apps/api-backend-mariadb/package.json +9 -9
  37. package/templates/apps/api-backend-sqlite/package.json +8 -8
  38. package/templates/apps/api-backend-storage/package.json +8 -8
  39. package/templates/apps/api-cms/package.json +10 -10
  40. package/templates/apps/api-collab/package.json +8 -8
  41. package/templates/apps/api-data-advanced/package.json +8 -8
  42. package/templates/apps/api-durable/package.json +8 -8
  43. package/templates/apps/api-feature-flags/package.json +9 -9
  44. package/templates/apps/api-governance/package.json +8 -8
  45. package/templates/apps/api-kv/package.json +8 -8
  46. package/templates/apps/api-moderation/package.json +8 -8
  47. package/templates/apps/api-observability/package.json +8 -8
  48. package/templates/apps/api-ratelimit/package.json +8 -8
  49. package/templates/apps/api-rbac/package.json +8 -8
  50. package/templates/apps/api-rest/package.json +7 -7
  51. package/templates/apps/api-saas/package.json +11 -11
  52. package/templates/apps/api-saas-starter/package.json +10 -10
  53. package/templates/apps/api-search/package.json +8 -8
  54. package/templates/apps/api-status/package.json +8 -8
  55. package/templates/apps/api-versioning/package.json +8 -8
  56. package/templates/apps/api-webhooks/package.json +9 -9
  57. package/templates/apps/changelog/package.json +6 -6
  58. package/templates/apps/edge-functions/package.json +2 -2
  59. package/templates/apps/frontend-admin/package.json +8 -8
  60. package/templates/apps/frontend-app/package.json +8 -8
  61. package/templates/apps/frontend-auth/package.json +8 -8
  62. package/templates/apps/frontend-blank/package.json +7 -7
  63. package/templates/apps/frontend-cms/package.json +9 -9
  64. package/templates/apps/frontend-collab/package.json +9 -9
  65. package/templates/apps/frontend-contact/package.json +7 -7
  66. package/templates/apps/frontend-dashboard/package.json +7 -7
  67. package/templates/apps/frontend-docs/package.json +7 -7
  68. package/templates/apps/frontend-i18n/package.json +6 -6
  69. package/templates/apps/frontend-landing/package.json +7 -7
  70. package/templates/apps/frontend-portal/package.json +8 -8
  71. package/templates/apps/frontend-saas/package.json +8 -8
  72. package/templates/apps/frontend-spa/package.json +7 -7
  73. package/templates/apps/frontend-ssr/package.json +7 -7
  74. package/templates/apps/frontend-ssr-api/package.json +8 -8
  75. package/templates/apps/frontend-static-blog/package.json +6 -6
  76. package/templates/apps/frontend-status/package.json +8 -8
  77. package/templates/apps/mobile-app/package.json +2 -2
  78. package/dist/apiBuild-BOqL1dlg.js +0 -2
  79. package/dist/checkCommand-ClRvH_SN.js +0 -2
  80. package/dist/dbCommand-BwQ_Jl98.js +0 -2
  81. package/dist/serveCommand-KsKXXWn4.js +0 -1578
@@ -0,0 +1,1608 @@
1
+ import { _t as e, ht as t, ot as n, t as r } from "./inspectMetrics-1xzTKAFx.js";
2
+ import { n as i, s as a, t as o } from "./seedRunner-Bqxgp7HZ.js";
3
+ import { r as s, t as c } from "./appModuleLoader-C9r9mxZt.js";
4
+ import { $ as l, $t as u, A as d, At as f, B as p, Bt as ee, C as te, Ct as ne, D as m, Dt as h, E as g, Et as re, F as _, Ft as v, G as ie, H as ae, Ht as oe, I as se, It as ce, J as y, Jt as b, K as le, L as ue, Lt as x, M as de, Mt as fe, N as pe, Nt as me, O as he, Ot as ge, P as _e, Pt as ve, Q as ye, Qt as be, R as xe, S as Se, St as S, T as C, Tt as Ce, U as we, V as Te, Vt as Ee, W as w, X as De, Xt as T, Y as Oe, Yt as ke, Z as Ae, Zt as je, _ as Me, _t as Ne, at as Pe, b as Fe, bt as Ie, c as E, cn as Le, ct as Re, d as ze, dt as D, en as Be, et as Ve, ft as He, g as Ue, gt as We, h as Ge, ht as Ke, i as qe, in as Je, it as Ye, j as Xe, jt as Ze, k as O, kt as Qe, lt as $e, mt as et, nn as tt, nt, o as k, on as rt, ot as A, pt as it, q as at, r as j, rn as M, rt as ot, sn as st, st as ct, t as lt, tn as ut, tt as dt, u as ft, ut as pt, v as mt, vt as ht, w as gt, wt as _t, x as vt, xt as yt, y as N, yt as bt, zt as xt } from "./dev-C_P8FLSx.js";
5
+ import { b as P, f as F, g as St, h as Ct, m as wt, r as Tt, y as Et } from "./frameworkTableAssembly-BwIrO5nv.js";
6
+ import { S as Dt, c as Ot, n as kt, p as I, s as At } from "./fileConventions-Cof68_BL.js";
7
+ import { m as jt } from "./inspect-BUUjt773.js";
8
+ import { n as Mt, t as Nt } from "./startupRunner-DPGFchOa.js";
9
+ import { r as Pt, u as L } from "./apiBuild-h9VHtnlw.js";
10
+ import { t as Ft } from "./bootTiming-BdyP9nYw.js";
11
+ import { n as R } from "./cliArgs-qdZSElM3.js";
12
+ import { basename as z, join as It } from "node:path";
13
+ import { pathToFileURL as Lt } from "node:url";
14
+ import { Cause as Rt, Effect as B, Layer as V, ManagedRuntime as zt } from "effect";
15
+ import { createLogger as H } from "@voltro/logger";
16
+ import { existsSync as Bt } from "node:fs";
17
+ import { AggregateRegistry as Vt, CostRegistry as Ht, Dispatcher as Ut, ExpectationRegistry as Wt, ExperimentRegistry as Gt, apiKeyManagementRoutes as Kt, attachAnalyticsMirror as qt, attachExpectations as Jt, attachExperiments as Yt, attachFinops as Xt, awaitServerListening as Zt, bindMutation as U, bindStream as Qt, bindSubscription as W, buildTracingLayer as $t, cancelWakeup as en, compileCron as tn, dataStoreApiKeyStore as nn, dataStoreIdempotencyStore as rn, formatServerOnlyLeaks as an, formatUnresolvedSources as on, frameworkApiKeyStrategy as sn, getCredentialExpiry as cn, installPolicyGuardResolver as ln, loadResourceTuples as un, makeActionRunner as dn, makeAdvisoryLockCoordinator as fn, makeApiKeyService as pn, makeApiKeyUsageBuffer as mn, makeApiKeyUsageFlusher as hn, makeAsyncKv as gn, makeCoordinatedScheduler as _n, makeEffectStoreLayer as vn, makeLazyWorkflowFacade as yn, makeMutationOutputCodec as bn, makeMutationRunner as xn, makeOneShotQueryRunner as Sn, makeQueryDescriptorProducer as Cn, makeQueryFinalizer as wn, makeQueryReauthorizer as Tn, makeQuerySubscriber as En, makeSchemaRegistry as Dn, makeWorkflowFacade as On, makeWorkflowFacadeWithCallerContext as kn, makeWorkflowLayers as An, noopKv as jn, onProcessShutdown as Mn, recordCredentialExpiry as Nn, recordSubscriptionDelivery as Pn, recordWorkflowRun as G, registerWakeup as Fn, resolveSecretsBackend as In, runProvidedEffect as Ln, setSecretsBackend as Rn, setSystemStoreHandle as zn, setTupleSource as Bn, singleCoordinator as Vn, startRpcServer as Hn, startScheduler as Un, stripForbiddenForWire as Wn, unresolvedSources as Gn, workflowToRpc as Kn, wrapStoreWithBootCodec as qn } from "@voltro/runtime";
18
+ import { RpcGroup as Jn } from "@effect/rpc";
19
+ import { SqlClient as Yn } from "@effect/sql";
20
+ import { allRegisteredTables as Xn, and as Zn, ensureTableRegistered as Qn, eq as K, or as $n } from "@voltro/database";
21
+ import { appStorageProvider as er, fromNodeReadable as tr, getObjectStream as nr, putObjectStream as rr, toNodeReadable as ir } from "@voltro/plugin-storage";
22
+ import { AuthMiddleware as ar, ConnectionInfoMiddleware as or, actionToRpc as q, anonymousSubject as sr, isWireReachable as cr, mutationToRpc as lr, queryToRpc as J, streamToRpc as Y, workflowCancelDescriptor as X, workflowDomainEventsQueryDescriptor as ur, workflowEventDeliveriesQueryDescriptor as Z, workflowResumeDescriptor as dr, workflowRunEventsQueryDescriptor as fr, workflowRunQueryDescriptor as pr, workflowRunStepsQueryDescriptor as mr, workflowRunsQueryDescriptor as hr, workflowSignalDescriptor as gr, workflowUpdateDescriptor as _r } from "@voltro/protocol";
23
+ import { isEnvContract as vr } from "@voltro/env";
24
+ import { assertProductionSessionSecret as yr, sessionExpiryFromHeaders as br } from "@voltro/protocol/session";
25
+ import { createHash as xr, timingSafeEqual as Sr } from "node:crypto";
26
+ import { declaredSnapshot as Cr, describeOutcome as wr, runPlannedMigrations as Tr } from "@voltro/database/sql";
27
+ import { buildDeliverWebhookExecute as Er, buildWebhooksService as Dr, defaultIncomingPath as Or, deliverWebhookWorkflow as kr, makeDeferredEmitHandler as Ar, mountIncomingWebhook as jr } from "@voltro/plugin-webhooks";
28
+ import { getAuthSessionStrategy as Mr } from "@voltro/plugin-auth";
29
+ import { collectPublicApiRoutes as Nr, restRoutesToHttpRoutes as Pr } from "@voltro/protocol/rest";
30
+ import { registerEmailTemplates as Fr } from "@voltro/plugin-mail";
31
+ import { channelFor as Ir, getBroadcastPlugin as Lr } from "@voltro/plugin-broadcast";
32
+ import { packBundle as Rr, runExport as zr, runImport as Br, storageBlobSink as Vr, storageRefsBlobSource as Hr, unpackBundle as Ur, unpackBundleToDir as Wr } from "@voltro/data-transfer";
33
+ //#region src/dbPoolReport.ts
34
+ var Gr = (e, t, n = []) => {
35
+ let r = n.length, i = e === void 0 ? void 0 : e + r, a = i !== void 0 && t !== void 0 ? i * t : void 0, o = r === 0 ? " No connections outside the pool in this process." : ` PLUS ${r} outside the pool (${n.map((e) => e.reason).join("; ")}) — those do not come out of the pool budget, they come out of the DATABASE's.`;
36
+ return e === void 0 ? "db pool: max per replica UNSET (DB_MAX_CONNECTIONS) — each replica opens the driver's default pool, so the fleet total is that default × replicas. Set DB_MAX_CONNECTIONS so the total stays under your database's connection limit; the pool scales with replicaCount and the database does not." + o : `db pool: max=${e} per replica (DB_MAX_CONNECTIONS)` + (r === 0 ? "" : ` + ${r} = ${i}`) + (a === void 0 ? ` — the fleet opens up to ${r === 0 ? "max" : `(max + ${r})`} × replicas connections. Check that against your database's limit before raising replicaCount.` : ` × ${t} replicas = up to ${a} connections. Check that against your database's limit.`) + o;
37
+ }, Kr = (e = process.env) => {
38
+ let t = e.REPLICA_COUNT;
39
+ if (t === void 0 || t === "") return;
40
+ let n = Number(t);
41
+ return Number.isInteger(n) && n > 0 ? n : void 0;
42
+ }, qr = "/_voltro/admin/import", Jr = "/_voltro/admin/export", Q = (e, t) => ({
43
+ status: e,
44
+ contentType: "application/json; charset=utf-8",
45
+ body: JSON.stringify(t)
46
+ }), Yr = (e) => {
47
+ let t = e.authorization ?? e.Authorization, n = t ? /^Bearer\s+(.+)$/i.exec(t) : null;
48
+ return n ? n[1] : null;
49
+ }, Xr = (e, t) => Sr(xr("sha256").update(e).digest(), xr("sha256").update(t).digest()), Zr = (e, t) => {
50
+ if (e.method.toUpperCase() !== "POST") return Q(405, { error: "method not allowed" });
51
+ if (!t || t.length < 16) return Q(503, { error: "data transfer misconfigured (no/weak secret)" });
52
+ let n = Yr(e.headers);
53
+ return !n || !Xr(n, t) ? Q(401, { error: "unauthorized" }) : null;
54
+ }, Qr = H({ scope: "voltro:admin-import" }), $r = "VBUNDLE2", ei = async function* (e) {
55
+ yield e;
56
+ }, ti = (e) => async (t) => {
57
+ let n = Zr(t, e.secret);
58
+ if (n) return n;
59
+ let r = t.headers["x-import-mode"], i = t.headers["x-import-on-conflict"], a = t.headers["x-import-atomic"] === "1" || t.headers["x-import-atomic"] === "true", o = t.headers["x-import-force"] === "1" || t.headers["x-import-force"] === "true", s = t.rawBody.byteLength >= 8 && Buffer.from(t.rawBody.subarray(0, 8)).toString("latin1") === $r, c, l;
60
+ if (s) c = ei(t.rawBody), l = "upload";
61
+ else {
62
+ let n;
63
+ try {
64
+ n = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
65
+ } catch {
66
+ return Q(400, { error: "body must be a packed bundle archive or { bundleKey } JSON" });
67
+ }
68
+ if (typeof n.bundleKey != "string" || !n.bundleKey) return Q(400, { error: "body.bundleKey (string) is required for the storage transport" });
69
+ if (!e.openArchive) return Q(501, { error: "storage transport not configured on this instance" });
70
+ c = e.openArchive(n.bundleKey), l = "storage";
71
+ }
72
+ let u = await import("node:os"), d = await import("node:fs/promises"), f = await import("node:path"), p = await d.mkdtemp(f.join(u.tmpdir(), "voltro-admin-import-"));
73
+ try {
74
+ e.assetSink ? await Ur(c, {
75
+ dir: p,
76
+ blobs: e.assetSink
77
+ }) : await Wr(c, p);
78
+ let t = await B.runPromiseExit(Br({
79
+ store: e.store,
80
+ bundleDir: p,
81
+ ...r ? { mode: r } : {},
82
+ ...i ? { onConflict: i } : {},
83
+ ...a ? { atomic: a } : {},
84
+ ...e.snapshot ? { targetSnapshot: e.snapshot } : {},
85
+ force: o,
86
+ onWarn: (e) => Qr.warn("admin.import", { message: e }),
87
+ ...e.assetSink ? { assetsAlreadyRestored: !0 } : {}
88
+ }));
89
+ if (t._tag === "Failure") {
90
+ let e = t.cause._tag === "Fail" ? t.cause.error : void 0;
91
+ if (e && e._tag === "SchemaDriftError") {
92
+ let t = e;
93
+ return Qr.warn("admin.import refused (schema drift)", {
94
+ transport: l,
95
+ bundle: t.bundleFingerprint.slice(0, 16),
96
+ target: t.targetFingerprint.slice(0, 16)
97
+ }), Q(409, {
98
+ error: "schema drift",
99
+ bundleFingerprint: t.bundleFingerprint,
100
+ targetFingerprint: t.targetFingerprint,
101
+ diff: t.diff,
102
+ hint: "re-export against the current schema, or resend with x-import-force: 1"
103
+ });
104
+ }
105
+ throw Error(String(e?.message ?? e ?? "import failed"));
106
+ }
107
+ let n = t.value, s = n.tables.reduce((e, t) => e + t.rowCount, 0);
108
+ return Qr.info("admin.import", {
109
+ transport: l,
110
+ tables: n.tables.length,
111
+ rows: s,
112
+ mode: r ?? "upsert",
113
+ atomic: a
114
+ }), Q(200, {
115
+ tables: n.tables.length,
116
+ rows: s,
117
+ transport: l
118
+ });
119
+ } catch (e) {
120
+ return Qr.warn("admin.import failed", {
121
+ transport: l,
122
+ error: e?.message ?? String(e)
123
+ }), Q(500, {
124
+ error: "import failed",
125
+ message: e?.message ?? String(e)
126
+ });
127
+ } finally {
128
+ await d.rm(p, {
129
+ recursive: !0,
130
+ force: !0
131
+ });
132
+ }
133
+ }, ni = H({ scope: "voltro:admin-export" }), ri = async (e) => {
134
+ let t = [];
135
+ for await (let n of e) t.push(Buffer.from(n));
136
+ return new Uint8Array(Buffer.concat(t));
137
+ }, ii = (e) => typeof e.tenant == "string" && e.tenant ? {
138
+ kind: "tenant",
139
+ tenantId: e.tenant
140
+ } : Array.isArray(e.tables) && e.tables.length ? {
141
+ kind: "tables",
142
+ tables: e.tables.filter((e) => typeof e == "string")
143
+ } : { kind: "all" }, ai = (e) => async (t) => {
144
+ let n = Zr(t, e.secret);
145
+ if (n) return n;
146
+ let r;
147
+ try {
148
+ r = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
149
+ } catch {
150
+ return Q(400, { error: "body must be JSON: { profile?, tenant?, tables?, consistency?, compression?, bundleKey? }" });
151
+ }
152
+ let i = {};
153
+ if (typeof r.profile == "string" && r.profile) {
154
+ if (!e.loadProfile) return Q(501, { error: "server-side profiles not configured on this instance" });
155
+ try {
156
+ i = await e.loadProfile(r.profile);
157
+ } catch (e) {
158
+ return Q(400, {
159
+ error: `profile '${r.profile}' could not be loaded`,
160
+ message: e?.message ?? String(e)
161
+ });
162
+ }
163
+ }
164
+ let a = r.consistency === "snapshot" ? "snapshot" : i.consistency ?? "live", o = (typeof r.compression == "string" ? r.compression : void 0) ?? i.compression, s = i.scope ?? ii(r), c = typeof r.bundleKey == "string" && r.bundleKey.length > 0, l = r.assets === !0 && e.assetSource ? { blobs: e.assetSource } : {}, u = await import("node:os"), d = await import("node:fs/promises"), f = await import("node:path"), p = await d.mkdtemp(f.join(u.tmpdir(), "voltro-admin-export-"));
165
+ try {
166
+ let t = await B.runPromise(zr({
167
+ store: e.store,
168
+ snapshot: e.snapshot,
169
+ dialect: e.dialect,
170
+ outDir: p,
171
+ ...i.subset ? { subset: i.subset } : {
172
+ scope: s,
173
+ ...e.tenantTables && e.tenantTables.length > 0 ? { tenantTables: e.tenantTables } : {}
174
+ },
175
+ consistency: a,
176
+ ...o ? { compression: o } : {},
177
+ ...i.masking ? { masking: i.masking } : {}
178
+ })), n = t.tables.reduce((e, t) => e + t.rowCount, 0), u = t.masking?.transformed.length ?? 0;
179
+ if (c) {
180
+ if (!e.putArchive) return Q(501, { error: "storage transport not configured on this instance" });
181
+ let i = r.bundleKey;
182
+ return await e.putArchive(i, () => Rr({
183
+ dir: p,
184
+ ...l
185
+ })), ni.info("admin.export", {
186
+ transport: "storage",
187
+ tables: t.tables.length,
188
+ rows: n,
189
+ masked: u,
190
+ bundleKey: i
191
+ }), Q(200, {
192
+ bundleKey: i,
193
+ tables: t.tables.length,
194
+ rows: n,
195
+ masked: u,
196
+ transport: "storage"
197
+ });
198
+ }
199
+ let d = await ri(Rr({
200
+ dir: p,
201
+ ...l
202
+ }));
203
+ return ni.info("admin.export", {
204
+ transport: "download",
205
+ tables: t.tables.length,
206
+ rows: n,
207
+ masked: u,
208
+ bytes: d.byteLength
209
+ }), {
210
+ status: 200,
211
+ contentType: "application/octet-stream",
212
+ body: d,
213
+ headers: {
214
+ "x-export-tables": String(t.tables.length),
215
+ "x-export-rows": String(n),
216
+ "x-export-masked": String(u)
217
+ }
218
+ };
219
+ } catch (e) {
220
+ return ni.warn("admin.export failed", { error: e?.message ?? String(e) }), Q(500, {
221
+ error: "export failed",
222
+ message: e?.message ?? String(e)
223
+ });
224
+ } finally {
225
+ await d.rm(p, {
226
+ recursive: !0,
227
+ force: !0
228
+ });
229
+ }
230
+ }, oi = async (e) => {
231
+ let { resolve: t } = await import("node:path"), { existsSync: n } = await import("node:fs"), r = [
232
+ e,
233
+ `${e}.profile.ts`,
234
+ `data-profiles/${e}.ts`,
235
+ `data-profiles/${e}.profile.ts`
236
+ ].map((e) => t(process.cwd(), e)), i = r.find((e) => n(e));
237
+ if (!i) throw Error(`data profile '${e}' not found (looked for: ${r.join(", ")})`);
238
+ let a = await import(i), o = a.default ?? a.profile;
239
+ if (!o) throw Error(`data profile '${i}' has no default export`);
240
+ return o;
241
+ }, si = (e, t, n = {}) => (async function* () {
242
+ let r = await ir((await B.runPromise(nr(e, t).pipe(B.timeout(n.openTimeout ?? "30 seconds")))).stream), i = n.stallMs ?? 12e4, a, o = () => {
243
+ a && clearTimeout(a), a = setTimeout(() => r.destroy(/* @__PURE__ */ Error(`storage read stalled for ${i}ms reading '${t}'`)), i);
244
+ };
245
+ try {
246
+ o();
247
+ for await (let e of r) o(), yield e instanceof Uint8Array ? e : new Uint8Array(e);
248
+ } finally {
249
+ a && clearTimeout(a), r.destroy();
250
+ }
251
+ })(), ci = {
252
+ get: async () => void 0,
253
+ set: async () => {},
254
+ setWithTags: async () => {},
255
+ remove: async () => !1,
256
+ has: async () => !1,
257
+ clear: async () => {},
258
+ invalidateTag: async () => 0,
259
+ wrap: async (e, t, n) => n()
260
+ }, li = async (e) => {
261
+ zn({
262
+ dataStore: e.store,
263
+ schemaRegistry: e.schemaRegistry
264
+ });
265
+ let t = (e.discovered.budgets?.length ?? 0) > 0, n, i = new Ut({
266
+ store: e.store,
267
+ ...e.snapshotCache ? { cache: e.snapshotCache } : {},
268
+ ...t ? { recordCost: (e) => n?.record(e) } : {},
269
+ recordDelivery: (e) => Pn({
270
+ label: e.label,
271
+ kind: e.kind,
272
+ durationMs: e.durationMs,
273
+ rowCount: e.rowCount
274
+ })
275
+ }), a = e.cache ?? ci, o = e.kv ?? jn, s, c = () => void 0, l, d, f, ee, te, ne, m, g = /* @__PURE__ */ new Map(), ie = () => `wfctx_${globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`}`, oe = async (t, n, r) => {
276
+ let i = {
277
+ ...r,
278
+ source: r.source ?? `workflow:${t}`
279
+ };
280
+ g.set(n, i);
281
+ try {
282
+ let r = await e.store.query({
283
+ table: "_voltro_workflow_start_contexts",
284
+ order: [],
285
+ predicate: K("executionId", n),
286
+ projection: ["id"],
287
+ skip: void 0,
288
+ take: 1
289
+ }), a = {
290
+ workflowName: t,
291
+ executionId: n,
292
+ subject: i.subject ?? null,
293
+ traceId: i.traceId ?? null,
294
+ source: i.source ?? null,
295
+ parentExecutionId: i.parentExecutionId ?? null,
296
+ parentClosePolicy: i.parentClosePolicy ?? null,
297
+ createdAt: /* @__PURE__ */ new Date()
298
+ };
299
+ r[0] === void 0 ? await e.store.insert("_voltro_workflow_start_contexts", {
300
+ id: ie(),
301
+ ...a
302
+ }) : await e.store.update("_voltro_workflow_start_contexts", r[0].id, a);
303
+ } catch (e) {
304
+ process.stderr.write(`[workflow] failed to persist start context for ${t}/${n}: ${e?.message ?? String(e)}\n`);
305
+ }
306
+ }, ue = async (t, n) => {
307
+ let r = g.get(n);
308
+ if (r !== void 0) return r;
309
+ try {
310
+ let t = (await e.store.query({
311
+ table: "_voltro_workflow_start_contexts",
312
+ order: [],
313
+ predicate: K("executionId", n),
314
+ projection: void 0,
315
+ skip: void 0,
316
+ take: 1
317
+ }))[0];
318
+ if (t === void 0) return;
319
+ let r = {
320
+ ...t.subject === null ? {} : { subject: t.subject },
321
+ ...t.traceId === null ? {} : { traceId: t.traceId },
322
+ ...t.source === null ? {} : { source: t.source },
323
+ ...t.parentExecutionId === null ? {} : { parentExecutionId: t.parentExecutionId },
324
+ ...t.parentClosePolicy === null ? {} : { parentClosePolicy: t.parentClosePolicy }
325
+ };
326
+ return g.set(n, r), r;
327
+ } catch (e) {
328
+ process.stderr.write(`[workflow] failed to load start context for ${n}: ${e?.message ?? String(e)}\n`);
329
+ return;
330
+ }
331
+ }, x = (e.discovered.workflows?.length ?? 0) > 0 ? yn(() => s) : void 0, he = (e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.eventTriggers?.length ?? 0) > 0, ge = he || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster", ve = e.tenantIsolation === "namespace", ye = (e.log ?? H({ scope: "voltro:serve" })).child("webhooks"), xe, Se, C = e.discovered.webhooks;
332
+ if (C && C.outgoing.length > 0 && e.workflowEngineLayer !== void 0) {
333
+ e.workflowEngineLayer;
334
+ let t = u({
335
+ store: e.store,
336
+ schemaRegistry: e.schemaRegistry,
337
+ cache: a,
338
+ kv: o
339
+ }), n = C.outgoing.map((e) => e.descriptor);
340
+ Se = kr.toLayer(Er(t, { events: n })), xe = Dr(t, async (e) => {
341
+ let t = f;
342
+ if (t === void 0) {
343
+ 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.", {
344
+ deliveryId: e.deliveryId,
345
+ targetId: e.targetId
346
+ });
347
+ return;
348
+ }
349
+ t.runPromise(kr.execute(e)).catch((t) => {
350
+ ye.error("deliverWebhook workflow crashed", {
351
+ deliveryId: e.deliveryId,
352
+ targetId: e.targetId
353
+ }, t);
354
+ });
355
+ }, { events: n });
356
+ }
357
+ let Ce = /* @__PURE__ */ new Map();
358
+ if (C) for (let e of C.incoming) {
359
+ let t = e.descriptor.path ?? Or(e.descriptor.id), n = `VOLTRO_WEBHOOK_SECRET_${e.descriptor.id.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, r = jr(e.descriptor, {
360
+ resolveSecret: async () => process.env[n] ?? null,
361
+ resolveWorkflows: () => x === void 0 ? void 0 : kn(x, {
362
+ traceId: `incoming:${e.descriptor.id}`,
363
+ source: `incoming:${e.descriptor.id}`
364
+ }),
365
+ log: (e) => {
366
+ let t = {
367
+ webhookId: e.webhookId,
368
+ status: e.status,
369
+ signatureOk: String(e.signatureOk),
370
+ idempotency: e.idempotency,
371
+ durationMs: e.durationMs
372
+ };
373
+ e.status >= 500 ? ye.error("incoming delivery failed", t) : e.status >= 400 ? ye.warn("incoming delivery rejected", t) : ye.info("incoming delivery handled", t);
374
+ }
375
+ });
376
+ Ce.set(t, { handle: r });
377
+ }
378
+ ln(), Bn((t) => un(e.store, t.subjectId, t.resourceType, t.resourceId));
379
+ let Ee = [...e.discovered.outboxHandlers ?? [], ...He((C?.outgoing.length ?? 0) + (C?.incoming.length ?? 0) + (C?.providers.length ?? 0), []) ? [{
380
+ file: "<framework>/webhooks",
381
+ id: "voltro-webhook-emit",
382
+ definition: Ar(() => xe)
383
+ }] : []], De = Ee.length > 0 ? v({
384
+ handlers: Ee,
385
+ store: e.store,
386
+ log: (e.log ?? H({ scope: "voltro:serve" })).child("outbox")
387
+ }) : void 0, T = me({
388
+ definitions: (e.discovered.connections ?? []).map((e) => e.definition),
389
+ store: e.store,
390
+ publicUrl: fe(e.port ?? 4e3),
391
+ log: (e.log ?? H({ scope: "voltro:serve" })).child("connections")
392
+ });
393
+ de({
394
+ events: e.discovered.events ?? [],
395
+ rpcTags: [
396
+ ...e.discovered.queries.map((e) => e.descriptor.name),
397
+ ...e.discovered.mutations.map((e) => e.descriptor.name),
398
+ ...e.discovered.actions.map((e) => e.descriptor.name),
399
+ ...(e.discovered.streams ?? []).map((e) => e.descriptor.name)
400
+ ]
401
+ });
402
+ let ke = (e.log ?? H({ scope: "voltro:serve" })).child("events"), Ae = e.broadcastNamespace ?? mt(e.plugins, void 0), Me = N(e.plugins, Ae, ke), Pe = e.membership?.instanceId ?? process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, Ie = e.membership ?? Fe(e.plugins, {
403
+ instanceId: Pe,
404
+ namespace: Ae,
405
+ meta: { mode: "serve" },
406
+ logger: ke
407
+ }), E = pe({
408
+ events: e.discovered.events ?? [],
409
+ origin: Pe,
410
+ ...Me.publishRemote === void 0 ? {} : { publishRemote: Me.publishRemote }
411
+ }), ze = (e.discovered.events ?? []).length > 0 ? await Me.attach(E.bus) : null, D = be({
412
+ store: e.store,
413
+ schemaRegistry: e.schemaRegistry,
414
+ cache: a,
415
+ kv: o,
416
+ ...xe === void 0 ? {} : { webhooksService: xe },
417
+ ...x === void 0 ? {} : { workflowsProxy: x },
418
+ eventTriggers: e.discovered.eventTriggers ?? [],
419
+ namespaceIsolationOn: ve,
420
+ ...De === void 0 ? {} : { outbox: { nudge: De.nudge } },
421
+ ...T.active ? { connections: { registry: T.registry } } : {},
422
+ eventBus: E.bus
423
+ }), Be = V.succeed(Vt, S), Ue = V.succeed(Wt, We), Ge = V.succeed(Ht, Ke), qe = V.succeed(Gt, Ne), Je = (t, n) => {
424
+ let r = t.pipe(B.provide(vn(n)));
425
+ return (e.baseLayer ? r.pipe(B.provide(e.baseLayer)) : r).pipe(B.provide(Be)).pipe(B.provide(Ue)).pipe(B.provide(Ge)).pipe(B.provide(qe));
426
+ }, Xe = (e, t) => Ln(Je(e, t)), Ze = r(), O = le(e.plugins ?? [], Ze), Qe = w(e.plugins ?? [], Ze), $e = xn({
427
+ store: e.store,
428
+ recordMetric: (e) => {
429
+ Ze.record(e);
430
+ },
431
+ ...O.mutation === void 0 ? {} : { interceptor: O.mutation },
432
+ buildContext: (e, t, n) => D(e, t, n),
433
+ runEffect: Xe,
434
+ undoCapture: Oe()
435
+ }), et = y(), tt = dn({
436
+ buildContext: (e) => D(e),
437
+ runEffect: Xe,
438
+ recordMetric: (e) => {
439
+ Ze.record(e);
440
+ },
441
+ ...O.action === void 0 ? {} : { interceptor: O.action }
442
+ }), k = wn({
443
+ tenantScopedTables: e.tenantScopedTables,
444
+ softDeleteScopedTables: e.softDeleteScopedTables
445
+ }), rt = {
446
+ buildContext: (e) => D(e),
447
+ finalize: (e, t) => k(e, t.subject),
448
+ provideEffect: Je,
449
+ ...O.query === void 0 ? {} : { interceptor: O.query }
450
+ }, A = Cn(rt), it = Sn({
451
+ ...rt,
452
+ queryRows: (t, n) => e.store.query(t).then((e) => Wn(t.table, e, n.subject))
453
+ }), at = En({
454
+ ...rt,
455
+ subscribeDescriptor: (e, t, n) => i.subscribe(e, t, n),
456
+ subscribeComputed: (e, t, n) => i.subscribeComputed(e, t, n)
457
+ }), j = (e) => e.filter((e) => cr(e.descriptor)), M = {};
458
+ for (let t of [
459
+ ...j(e.discovered.queries),
460
+ ...et.queries,
461
+ ...T.queries
462
+ ]) M[t.descriptor.name] = (e) => W(A(t, e), i, `subscription.${t.descriptor.name}`, void 0, void 0, Tn(t, e));
463
+ for (let t of [
464
+ ...j(e.discovered.mutations),
465
+ ...et.mutations,
466
+ ...T.mutations
467
+ ]) {
468
+ let n = bn(t.descriptor.output);
469
+ M[t.descriptor.name] = (r) => U(async (e, n) => $e(t, e, n), r, `mutation.${t.descriptor.name}`, n, e.idempotency, t.descriptor.error);
470
+ }
471
+ for (let t of [...j(e.discovered.actions), ...T.actions]) {
472
+ let n = bn(t.descriptor.output);
473
+ M[t.descriptor.name] = (r) => U(async (e, n) => tt(t, e, n), r, `action.${t.descriptor.name}`, n, e.idempotency, t.descriptor.error);
474
+ }
475
+ let st = () => `public-${Math.random().toString(36).slice(2, 10)}`, ct = [
476
+ ...e.discovered.queries.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
477
+ descriptor: e.descriptor,
478
+ invoke: (t, n) => it(e, t, {
479
+ subject: n.subject,
480
+ traceId: st()
481
+ }),
482
+ subscribe: (t, n, r) => at(e, t, {
483
+ subject: n.subject,
484
+ traceId: st()
485
+ }, r)
486
+ })),
487
+ ...e.discovered.mutations.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
488
+ descriptor: e.descriptor,
489
+ invoke: (t, n) => $e(e, t, {
490
+ subject: n.subject,
491
+ traceId: st()
492
+ })
493
+ })),
494
+ ...e.discovered.actions.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
495
+ descriptor: e.descriptor,
496
+ invoke: (t, n) => tt(e, t, {
497
+ subject: n.subject,
498
+ traceId: st()
499
+ })
500
+ }))
501
+ ], lt = ct.length > 0 ? Pr(Nr(ct), {
502
+ store: e.store,
503
+ resolveSubject: (t) => e.resolveSubject(t, -1)
504
+ }) : [], ut = e.dataTransferSecret ?? process.env.VOLTRO_DATA_TRANSFER_SECRET, ft = ut && ut.length >= 16 ? [{
505
+ method: "POST",
506
+ path: qr,
507
+ handle: ti({
508
+ secret: ut,
509
+ store: e.store,
510
+ ...e.dataTransferSnapshot ? { snapshot: e.dataTransferSnapshot } : {},
511
+ assetSink: Vr(er()),
512
+ openArchive: (e) => si(er(), e)
513
+ })
514
+ }, {
515
+ method: "POST",
516
+ path: Jr,
517
+ handle: ai({
518
+ secret: ut,
519
+ store: e.store,
520
+ snapshot: e.dataTransferSnapshot ?? { tables: [] },
521
+ dialect: e.dataTransferDialect ?? "memory",
522
+ tenantTables: [...e.tenantScopedTables],
523
+ loadProfile: oi,
524
+ assetSource: Hr(er(), e.store),
525
+ putArchive: async (e, t) => {
526
+ let { Readable: n } = await import("node:stream"), r = er(), i = tr("storage", () => n.from(t()));
527
+ await B.runPromise(rr(r, e, i, { contentType: "application/octet-stream" }));
528
+ }
529
+ })
530
+ }] : [], pt = [
531
+ ...e.httpRoutes ?? [],
532
+ ...lt,
533
+ ...ft,
534
+ ...T.httpRoutes
535
+ ];
536
+ Object.assign(M, E.handlers);
537
+ for (let t of j(e.discovered.streams ?? [])) M[t.descriptor.name] = (n) => Qt((r) => {
538
+ let i = D(r), a = t.executor(n, i);
539
+ if (B.isEffect(a)) {
540
+ let t = a.pipe(B.provide(vn(i.store)));
541
+ return (e.baseLayer ? t.pipe(B.provide(e.baseLayer)) : t).pipe(B.provide(Be)).pipe(B.provide(Ue)).pipe(B.provide(Ge)).pipe(B.provide(qe));
542
+ }
543
+ return typeof a == "object" && a && typeof a.then == "function" ? B.promise(() => a) : a;
544
+ }, `stream.${t.descriptor.name}`);
545
+ for (let t of e.discovered.workflows ?? []) M[t.definition.name] = (e) => U(async (e, n) => {
546
+ let r = n;
547
+ return kn(x, {
548
+ subject: r.subject,
549
+ traceId: r.traceId,
550
+ source: "workflow-rpc"
551
+ }).start(t.definition.name, e);
552
+ }, e, `workflow.${t.definition.name}`);
553
+ he && (M[pr.name] = (e) => W(A({
554
+ descriptor: pr,
555
+ executor: (e) => {
556
+ let t = e.id;
557
+ return {
558
+ table: "_voltro_workflow_runs",
559
+ order: [{
560
+ column: "startedAt",
561
+ direction: "desc"
562
+ }],
563
+ predicate: $n(K("id", t), K("executionId", t)),
564
+ take: 1,
565
+ skip: void 0,
566
+ projection: void 0
567
+ };
568
+ }
569
+ }, e), i, `subscription.${pr.name}`), M[hr.name] = (e) => W(A({
570
+ descriptor: hr,
571
+ executor: (e) => {
572
+ let t = e, n = [...t.tag === void 0 ? [] : [K("tag", t.tag)], ...t.status === void 0 ? [] : [K("status", t.status)]], r = Number.isFinite(t.limit) && t.limit !== void 0 ? Math.min(Math.max(Math.floor(t.limit), 1), 500) : 100;
573
+ return {
574
+ table: "_voltro_workflow_runs",
575
+ order: [{
576
+ column: "startedAt",
577
+ direction: "desc"
578
+ }],
579
+ predicate: n.length === 0 ? void 0 : n.length === 1 ? n[0] : Zn(...n),
580
+ take: r,
581
+ skip: void 0,
582
+ projection: void 0
583
+ };
584
+ }
585
+ }, e), i, `subscription.${hr.name}`), M[mr.name] = (e) => W(A({
586
+ descriptor: mr,
587
+ executor: (e) => {
588
+ let t = e.runId;
589
+ return {
590
+ table: "_voltro_workflow_run_steps",
591
+ order: [{
592
+ column: "startedAt",
593
+ direction: "asc"
594
+ }],
595
+ predicate: K("runId", t),
596
+ take: 1e3,
597
+ skip: void 0,
598
+ projection: void 0
599
+ };
600
+ }
601
+ }, e), i, `subscription.${mr.name}`), M[fr.name] = (e) => W(A({
602
+ descriptor: fr,
603
+ executor: (e) => {
604
+ let t = e.runId;
605
+ return {
606
+ table: "_voltro_workflow_run_events",
607
+ order: [{
608
+ column: "occurredAt",
609
+ direction: "asc"
610
+ }],
611
+ predicate: K("runId", t),
612
+ take: 1e3,
613
+ skip: void 0,
614
+ projection: void 0
615
+ };
616
+ }
617
+ }, e), i, `subscription.${fr.name}`), M[ur.name] = (e) => W(A({
618
+ descriptor: ur,
619
+ executor: (e) => {
620
+ let t = e;
621
+ return {
622
+ table: "_voltro_workflow_events",
623
+ order: [{
624
+ column: "occurredAt",
625
+ direction: "desc"
626
+ }],
627
+ predicate: t.name === void 0 ? void 0 : K("name", t.name),
628
+ take: Math.max(1, Math.min(500, t.limit ?? 100)),
629
+ skip: void 0,
630
+ projection: void 0
631
+ };
632
+ }
633
+ }, e), i, `subscription.${ur.name}`), M[Z.name] = (e) => W(A({
634
+ descriptor: Z,
635
+ executor: (e) => {
636
+ let t = e.eventId;
637
+ return {
638
+ table: "_voltro_workflow_event_deliveries",
639
+ order: [{
640
+ column: "createdAt",
641
+ direction: "asc"
642
+ }],
643
+ predicate: K("eventId", t),
644
+ take: 500,
645
+ skip: void 0,
646
+ projection: void 0
647
+ };
648
+ }
649
+ }, e), i, `subscription.${Z.name}`), M[X.name] = (t) => U(async (t, n) => {
650
+ let r = t;
651
+ return await je(e.store, n.subject, { executionId: r.executionId }), await x.cancel(r.workflowName, r.executionId), await Ct(r.workflowName, r.executionId, "workflow.cancel"), { ok: !0 };
652
+ }, t, `action.${X.name}`), M[dr.name] = (t) => U(async (t, n) => {
653
+ let r = t;
654
+ return await je(e.store, n.subject, { executionId: r.executionId }), await x.resume(r.workflowName, r.executionId), { ok: !0 };
655
+ }, t, `action.${dr.name}`), M[gr.name] = (t) => U(async (t, n) => {
656
+ let r = t;
657
+ return await je(e.store, n.subject, { id: r.id }), x.signal({ id: r.id }, r.signalName, r.payload);
658
+ }, t, `action.${gr.name}`), M[_r.name] = (t) => U(async (t, n) => {
659
+ let r = t;
660
+ return await je(e.store, n.subject, { id: r.id }), x.update({ id: r.id }, r.updateName, r.payload, r.timeoutMs === void 0 ? void 0 : { timeoutMs: r.timeoutMs });
661
+ }, t, `action.${_r.name}`));
662
+ let ht = [
663
+ ...j(e.discovered.queries).map((e) => J(e.descriptor)),
664
+ ...j(e.discovered.mutations).map((e) => lr(e.descriptor)),
665
+ ...j(e.discovered.actions).map((e) => q(e.descriptor)),
666
+ ...et.queries.map((e) => J(e.descriptor)),
667
+ ...et.mutations.map((e) => lr(e.descriptor)),
668
+ ...T.queries.map((e) => J(e.descriptor)),
669
+ ...T.mutations.map((e) => lr(e.descriptor)),
670
+ ...T.actions.map((e) => q(e.descriptor)),
671
+ ...j(e.discovered.streams ?? []).map((e) => Y(e.descriptor)),
672
+ ...E.rpcs,
673
+ ...(e.discovered.workflows ?? []).map((e) => Kn(e.definition)),
674
+ ...he ? [
675
+ J(pr),
676
+ J(hr),
677
+ J(mr),
678
+ J(fr),
679
+ J(ur),
680
+ J(Z),
681
+ q(X),
682
+ q(dr),
683
+ q(gr),
684
+ q(_r)
685
+ ] : []
686
+ ], gt = Jn.make(...ht).middleware(ar).middleware(or), _t = V.succeed(ar, ar.of(({ headers: t, clientId: n }) => B.promise(() => e.resolveSubject(t, n)))), vt = V.succeed(or, or.of(({ headers: e, clientId: t }) => B.sync(() => {
687
+ let n = cn(t) ?? br(e);
688
+ return {
689
+ clientId: t,
690
+ ...e["idempotency-key"] ? { idempotencyKey: e["idempotency-key"] } : {},
691
+ ...n === void 0 ? {} : { credentialExpiresAt: n }
692
+ };
693
+ }))), bt = e.dormancyTenantId ?? "default", xt = e.dormancy === "sleep" ? {
694
+ register: (t, n, r) => Fn(e.store, {
695
+ tenantId: r ?? bt,
696
+ kind: "workflow",
697
+ refId: t,
698
+ wakeAt: n
699
+ }),
700
+ cancel: (t, n) => en(e.store, {
701
+ tenantId: n ?? bt,
702
+ kind: "workflow",
703
+ refId: t
704
+ }).then(() => {})
705
+ } : void 0, P = ge ? await import("@voltro/workflow") : void 0, F = P?.makeWorkflowRunRecorder({
706
+ store: e.store,
707
+ ...xt === void 0 ? {} : { wakeups: xt }
708
+ }), St = async (t, n) => {
709
+ await P.closeWorkflowChildrenForParent({
710
+ store: e.store,
711
+ parentExecutionId: t,
712
+ parentStatus: n,
713
+ recorder: F,
714
+ log: { warn: (e, t) => {
715
+ process.stderr.write(`[workflow] ${e} ${t ? JSON.stringify(t) : ""}\n`);
716
+ } },
717
+ interruptChild: async (t, n) => {
718
+ let r = (e.discovered.workflows ?? []).find((e) => e.definition.name === t);
719
+ if (!r) throw Error(`Unknown child workflow: ${t}`);
720
+ if (!f) throw Error("Workflow runtime is not ready");
721
+ await f.runPromise(r.definition.interrupt(n));
722
+ }
723
+ });
724
+ }, Ct = async (t, n, r) => {
725
+ let i = (await e.store.query({
726
+ table: "_voltro_workflow_runs",
727
+ order: [],
728
+ predicate: K("executionId", n),
729
+ projection: void 0,
730
+ skip: void 0,
731
+ take: 1
732
+ }))[0];
733
+ if (i === void 0) return;
734
+ let a = await e.store.update("_voltro_workflow_runs", i.id, {
735
+ status: "cancelled",
736
+ cancelled: !0,
737
+ completedAt: /* @__PURE__ */ new Date()
738
+ }), o = i.subject?.tenantId ?? void 0;
739
+ a && await F.recordEvent({
740
+ runId: i.id,
741
+ eventType: "run-cancelled",
742
+ payload: {
743
+ reason: r,
744
+ workflowName: t,
745
+ executionId: n,
746
+ ...o == null ? {} : { tenantId: o }
747
+ }
748
+ }), a && await St(n, "cancelled");
749
+ }, wt = [
750
+ ...An(e.discovered.workflows ?? [], {
751
+ buildContext: (t, n) => e.buildContextForWorkflow?.(t, n) ?? D({
752
+ subject: t.subject,
753
+ traceId: t.traceId
754
+ }, e.store, void 0, `workflow:${n.workflowName}`, { parentExecutionId: n.executionId }),
755
+ resolveStartContext: ue
756
+ }, (t, n, r) => {
757
+ let i = P.getWorkflowVersionMetadata(t.definition);
758
+ return P.wrapWorkflowExecuteWithRunRecording({
759
+ name: t.definition.name,
760
+ store: e.store,
761
+ subject: r.subject,
762
+ source: r.source ?? null,
763
+ traceId: r.traceId,
764
+ workflowVersion: i.version,
765
+ workflowCompatibleVersions: i.compatibleWith,
766
+ workflowPatches: i.patches,
767
+ parentExecutionId: r?.parentExecutionId ?? null,
768
+ parentClosePolicy: r?.parentClosePolicy ?? null,
769
+ onParentClose: ({ executionId: e, status: t }) => St(e, t),
770
+ ...dt(t.definition),
771
+ onTerminal: async ({ executionId: e }) => {
772
+ await d?.gate.release(e);
773
+ },
774
+ recorder: F,
775
+ pluginWorkflowStepLayer: Qe,
776
+ recordRun: G
777
+ }, n);
778
+ }),
779
+ ...e.discovered.workflowWorkers ?? [],
780
+ ...Se === void 0 ? [] : [Se]
781
+ ], Tt = [...(e.discovered.workflows ?? []).map((e) => e.definition.name).filter(Boolean), ...Se === void 0 ? [] : ["voltro.deliverWebhook"]], Et = wt.length > 0 ? V.mergeAll(...wt) : V.empty;
782
+ if (((e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster" || Se !== void 0) && e.workflowEngineLayer !== void 0) {
783
+ let t = Et.pipe(V.provideMerge(e.workflowEngineLayer));
784
+ f = zt.make(e.baseLayer === void 0 ? t : t.pipe(V.provideMerge(e.baseLayer))), await f.runPromise(B.void), (e.log ?? H({ scope: "voltro:serve" })).child("workflow").info(`workflow runtime ready — ${Tt.length} entity type(s) registered`, { entities: Tt });
785
+ let n = await import("@voltro/workflow/cluster"), r = (e) => f.runPromise(n.redriveFailedRun(e)), i = (e) => f.runPromise(n.resumeRunFromStep(e));
786
+ ne = await Le({
787
+ provider: Lr(e.plugins ?? [])?.broadcast?.provider,
788
+ crossReplica: Lr(e.plugins ?? [])?.broadcast?.crossReplica ?? !1,
789
+ namespace: Ae,
790
+ replicaId: crypto.randomUUID(),
791
+ pollStorage: () => f.runPromise(n.pollWorkflowStorage),
792
+ log: (e.log ?? H({ scope: "voltro:serve" })).child("workflow")
793
+ }), ee = async (t) => {
794
+ let n = await Te({
795
+ store: e.store,
796
+ workflows: e.discovered.workflows ?? [],
797
+ runRedrive: r
798
+ }, t.runId);
799
+ return n.statusReset && await F.recordEvent({
800
+ runId: t.runId,
801
+ eventType: "run-redriven",
802
+ payload: {
803
+ reason: "inspect.redrive",
804
+ activitiesReset: n.outcome.activitiesReset
805
+ }
806
+ }), {
807
+ redriven: n.outcome.redriven,
808
+ activitiesReset: n.outcome.activitiesReset,
809
+ reason: n.outcome.reason
810
+ };
811
+ }, te = async (t) => {
812
+ let n = await ae({
813
+ store: e.store,
814
+ workflows: e.discovered.workflows ?? [],
815
+ runResume: i
816
+ }, t.runId, t.step);
817
+ return n.statusReset && await F.recordEvent({
818
+ runId: t.runId,
819
+ eventType: "run-redriven",
820
+ payload: {
821
+ reason: "inspect.resume-from-step",
822
+ step: n.stepName,
823
+ activitiesReset: n.outcome.activitiesReset
824
+ }
825
+ }), {
826
+ redriven: n.outcome.redriven,
827
+ stepName: n.stepName,
828
+ activitiesReset: n.outcome.activitiesReset,
829
+ reason: n.outcome.reason
830
+ };
831
+ };
832
+ let a = _n({
833
+ coordinator: (e.scheduleCoordination ?? "single") === "advisoryLock" ? fn(e.store, e.scheduleReplicaId ?? `pid-${process.pid}`) : Vn,
834
+ replicaId: e.scheduleReplicaId ?? `pid-${process.pid}`
835
+ }), o = {
836
+ info: (e, t) => {
837
+ process.stdout.write(`[flow-control] ${e} ${t ? JSON.stringify(t) : ""}\n`);
838
+ },
839
+ warn: (e, t) => {
840
+ process.stderr.write(`[flow-control] ${e} ${t ? JSON.stringify(t) : ""}\n`);
841
+ },
842
+ error: (e, t) => {
843
+ process.stderr.write(`[flow-control] ERROR ${e} ${t ? JSON.stringify(t) : ""}\n`);
844
+ }
845
+ }, u, m = () => {
846
+ if (u !== void 0) return u;
847
+ if (!(s === void 0 || F === void 0)) return u = _({
848
+ store: e.store,
849
+ log: L,
850
+ workflows: e.discovered.workflows ?? [],
851
+ workflowsProxy: s,
852
+ workflowRuntime: f,
853
+ workflowRunRecorder: F,
854
+ closeChildrenForParent: St
855
+ }), u;
856
+ };
857
+ c = m, d = Re({
858
+ store: e.store,
859
+ onChange: (t) => e.store.onChange((e) => t({
860
+ table: e.table,
861
+ op: e.op
862
+ })),
863
+ ...e.scheduling === void 0 ? {} : {
864
+ disarmWhenIdle: e.scheduling.disarmWhenIdle,
865
+ drainIntervalMs: e.scheduling.admissionDrainMs,
866
+ cancelSweepIntervalMs: e.scheduling.cancelSweepMs
867
+ },
868
+ workflows: e.discovered.workflows ?? [],
869
+ facade: () => s,
870
+ cancelRunWithReason: m,
871
+ scheduleCoordinated: a,
872
+ onAbandoned: async (t) => {
873
+ await Ve({
874
+ workflows: e.discovered.workflows ?? [],
875
+ facade: () => s,
876
+ log: o,
877
+ ...t
878
+ });
879
+ },
880
+ log: o
881
+ });
882
+ let h = d;
883
+ h !== void 0 && Mn(() => h.stop()), l = Ye({
884
+ store: e.store,
885
+ onChange: (t) => e.store.onChange((e) => t({
886
+ table: e.table,
887
+ op: e.op
888
+ })),
889
+ ...e.scheduling === void 0 ? {} : {
890
+ disarmWhenIdle: e.scheduling.disarmWhenIdle,
891
+ tickIntervalMs: e.scheduling.inferenceTickMs
892
+ },
893
+ enabled: (e.discovered.workflows?.length ?? 0) > 0,
894
+ resumeSignal: () => f === void 0 || P === void 0 ? void 0 : async ({ executionId: t, workflowName: n, signalName: r, payload: i }) => {
895
+ await f.runPromise(P.completeSuspendingSignal({
896
+ store: e.store,
897
+ target: ot(t, n),
898
+ signalName: r,
899
+ payload: i
900
+ }));
901
+ },
902
+ runEffect: (e) => f.runPromise(e),
903
+ scheduleCoordinated: a,
904
+ log: o
905
+ });
906
+ let g = l;
907
+ g !== void 0 && Mn(() => g.stop()), s = (e.discovered.workflows?.length ?? 0) > 0 ? On({
908
+ workflows: e.discovered.workflows ?? [],
909
+ runEffect: (e) => f.runPromise(e),
910
+ onEnqueue: () => ne?.publishWake(),
911
+ ...h === void 0 ? {} : {
912
+ admitStart: h.gate.admitStart,
913
+ startPayloadSchema: h.gate.startPayloadSchema
914
+ },
915
+ rememberStartContext: oe,
916
+ signal: async (t, n, r) => {
917
+ let i = await P.sendWorkflowSignal({
918
+ store: e.store,
919
+ recorder: F,
920
+ target: t,
921
+ signalName: n,
922
+ payload: r
923
+ });
924
+ return await f.runPromise(P.completeSuspendingSignal({
925
+ store: e.store,
926
+ target: t,
927
+ signalName: n,
928
+ payload: r
929
+ })).catch(() => {}), i;
930
+ },
931
+ update: (t, n, r, i) => P.sendWorkflowUpdate({
932
+ store: e.store,
933
+ recorder: F,
934
+ target: t,
935
+ updateName: n,
936
+ payload: r,
937
+ ...i === void 0 ? {} : { options: i }
938
+ }),
939
+ listRuns: (t) => p(e.store, t),
940
+ retry: (t, n) => we({
941
+ store: e.store,
942
+ workflows: e.discovered.workflows ?? [],
943
+ runPromise: (e) => f.runPromise(e)
944
+ }, t, n),
945
+ redrive: (t) => Te({
946
+ store: e.store,
947
+ workflows: e.discovered.workflows ?? [],
948
+ runRedrive: r
949
+ }, t).then((e) => e.outcome)
950
+ }) : void 0;
951
+ }
952
+ let Dt = V.mergeAll(gt.toLayer(M), _t, vt), Ot = b(M, e.discovered.queries.map((e) => e.descriptor.name), he), kt = V.mergeAll(gt.toLayer(Ot), _t, vt), I = e.observability, At = await $t({
953
+ ...e.appName === void 0 ? {} : { serviceName: e.appName },
954
+ ...I && I.spanProcessors.length > 0 ? { extraSpanProcessors: I.spanProcessors } : {},
955
+ ...I && I.metricReaders.length > 0 ? { extraMetricReaders: I.metricReaders } : {},
956
+ ...I && Object.keys(I.resourceAttributes).length > 0 ? { resourceAttributes: I.resourceAttributes } : {},
957
+ ...I && I.sampler !== void 0 ? { sampler: I.sampler } : {}
958
+ }), jt = !1, Mt = e.store.ping ? () => e.store.ping().then(() => !0).catch(() => !1) : void 0, { server: Nt, shutdown: Pt } = Hn({
959
+ group: gt,
960
+ handlersLayer: Dt,
961
+ httpHandlersLayer: kt,
962
+ port: e.port ?? 4e3,
963
+ ...e.host === void 0 ? {} : { host: e.host },
964
+ path: e.path ?? "/ws",
965
+ tracerLayer: At.layer,
966
+ healthCheck: {
967
+ isReady: () => jt,
968
+ ...Mt ? { ping: Mt } : {}
969
+ },
970
+ ...pt.length > 0 ? { httpRoutes: pt } : {},
971
+ ...e.getStore === void 0 ? {} : { getStore: e.getStore },
972
+ ...Ce.size > 0 ? { webhookRoutes: Ce } : {},
973
+ ...e.inspectRoute === void 0 ? {} : { inspectRoute: e.inspectRoute }
974
+ });
975
+ if (await Zt(Nt), (e.discovered.schedules?.length ?? 0) > 0) {
976
+ let t = (e.scheduleCoordination ?? "single") === "advisoryLock" ? fn(e.store, e.scheduleReplicaId ?? `pid-${process.pid}`) : Vn;
977
+ m = await Un(e.discovered.schedules ?? [], {
978
+ store: e.store,
979
+ coordinator: t,
980
+ defaultTrigger: e.scheduleDefaultTrigger ?? "self",
981
+ replicaId: e.scheduleReplicaId ?? `pid-${process.pid}`,
982
+ armSelf: e.scheduleArmSelf ?? !0,
983
+ dormancy: e.dormancy ?? "always-on",
984
+ ...e.dormancyTenantId === void 0 ? {} : { dormancyTenantId: e.dormancyTenantId },
985
+ buildContext: ({ traceId: t, scheduleName: n, subject: r }) => D({
986
+ subject: r,
987
+ traceId: t
988
+ }, e.store, void 0, `schedule:${n}`),
989
+ log: {
990
+ info: (e, t) => {
991
+ process.stdout.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
992
+ },
993
+ warn: (e, t) => {
994
+ process.stderr.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
995
+ },
996
+ error: (e, t) => {
997
+ process.stderr.write(`[schedule] ERROR ${e} ${t ? JSON.stringify(t) : ""}\n`);
998
+ },
999
+ debug: () => {}
1000
+ },
1001
+ ...e.scheduleFireInterceptor === void 0 ? {} : { interceptFire: e.scheduleFireInterceptor },
1002
+ ...e.onScheduleRunEvent === void 0 ? {} : { onRunEvent: e.onScheduleRunEvent }
1003
+ }), e.onSchedulerReady?.(m);
1004
+ }
1005
+ let L = e.log ?? H({ scope: "voltro:serve" }), Ft, R;
1006
+ if ((e.discovered.subscribers?.length ?? 0) > 0 && (Ft = ce(e.discovered.subscribers ?? [], e.store, L.child("subscribe"), e.schemaRegistry, E.bus)), (e.discovered.reactions?.length ?? 0) > 0) {
1007
+ let t = L.child("reaction"), n = async (n, r) => {
1008
+ if (n.kind === "workflow") {
1009
+ if (x === void 0) {
1010
+ t.warn("reaction workflow act skipped — no workflow engine in this app", { workflow: n.workflow });
1011
+ return;
1012
+ }
1013
+ let e = n.payload === void 0 ? r.new ?? r.old ?? {} : n.payload(r);
1014
+ await kn(x, {
1015
+ traceId: `reaction:${n.workflow}`,
1016
+ source: `reaction:${n.workflow}`
1017
+ }).start(n.workflow, e);
1018
+ return;
1019
+ }
1020
+ await h(n.agent, r, {
1021
+ findAgentSend: (t) => e.discovered.actions.find((e) => e.descriptor.name === `${t}.send`),
1022
+ runAction: (e, t, n) => Promise.resolve(tt(e, t, n)),
1023
+ makeSubject: (e) => sr(e),
1024
+ now: () => Date.now(),
1025
+ log: t
1026
+ });
1027
+ }, r = async (n, r) => {
1028
+ try {
1029
+ let { requireAiBudget: t } = await import("@voltro/ai");
1030
+ return (await B.runPromise(B.either(t(e.store, {
1031
+ tenantId: n,
1032
+ limitUsd: r
1033
+ }))))._tag === "Right";
1034
+ } catch (e) {
1035
+ return t.warn("reaction budget check failed — refusing the act", { tenantId: n }, e), !1;
1036
+ }
1037
+ }, i = nt(e.store, { onError: (e) => t.warn("reaction: rate-slot claim failed; refusing the act", { cause: String(e) }) });
1038
+ R = re(e.discovered.reactions ?? [], e.store, {
1039
+ runAct: n,
1040
+ checkBudget: r,
1041
+ claimRateSlot: (e) => i.claim(e)
1042
+ }, t);
1043
+ }
1044
+ let z;
1045
+ (e.discovered.aggregates?.length ?? 0) > 0 && (z = await yt({
1046
+ discovered: e.discovered.aggregates ?? [],
1047
+ store: e.store,
1048
+ log: L.child("aggregate"),
1049
+ ...e.analytics === void 0 ? {} : { analytics: e.analytics },
1050
+ ...e.aggregateStorage === void 0 ? {} : { storage: e.aggregateStorage },
1051
+ ...e.aggregateCoordinator === void 0 ? {} : { coordinator: e.aggregateCoordinator }
1052
+ }), Be = V.succeed(Vt, z.registry));
1053
+ let It;
1054
+ (e.discovered.expectations?.length ?? 0) > 0 && (It = Jt({
1055
+ discovered: e.discovered.expectations ?? [],
1056
+ store: e.store,
1057
+ log: L.child("expectation")
1058
+ }), Ue = V.succeed(Wt, It.registry)), (e.discovered.budgets?.length ?? 0) > 0 && (n = Xt({
1059
+ discovered: e.discovered.budgets ?? [],
1060
+ log: L.child("finops")
1061
+ }), Ge = V.succeed(Ht, n.registry));
1062
+ let Lt;
1063
+ return (e.discovered.experiments?.length ?? 0) > 0 && (Lt = Yt({
1064
+ discovered: e.discovered.experiments ?? [],
1065
+ store: e.store,
1066
+ log: L.child("experiment")
1067
+ }), qe = V.succeed(Gt, Lt.registry)), jt = !0, e.bootTiming?.mark("ready"), {
1068
+ dispatcher: i,
1069
+ server: Nt,
1070
+ scheduler: m,
1071
+ eventsSnapshot: _e(E.bus, E.declared),
1072
+ membersSnapshot: () => ({
1073
+ members: Ie.membership.list(),
1074
+ capturedAt: Date.now()
1075
+ }),
1076
+ rpcMetrics: () => Ze,
1077
+ webhooksService: () => xe,
1078
+ runCanceller: () => c(),
1079
+ flowControlHealth: () => d?.cancelHealth(),
1080
+ inferenceHealth: () => l?.health(),
1081
+ workflowWriteActions: () => x === void 0 || F === void 0 ? void 0 : se({
1082
+ store: e.store,
1083
+ log: L,
1084
+ workflows: e.discovered.workflows ?? [],
1085
+ workflowsProxy: s,
1086
+ workflowRuntime: f,
1087
+ workflowRunRecorder: F,
1088
+ closeChildrenForParent: St
1089
+ }),
1090
+ redriveWorkflowRun: (e) => ee ? ee(e) : Promise.reject(/* @__PURE__ */ Error("redrive: this app registers no workflows")),
1091
+ resumeWorkflowRunFromStep: (e) => te ? te(e) : Promise.reject(/* @__PURE__ */ Error("resume-from-step: this app registers no workflows")),
1092
+ close: async () => {
1093
+ jt = !1, await ze?.detach(), await Ie.detach(), z?.detach(), It?.detach(), n?.detach(), Lt?.detach(), R?.(), Ft?.(), await m?.shutdown(), i.close(), await ne?.detach(), await f?.dispose(), await new Promise((e) => Nt.close(() => e())), await Pt();
1094
+ }
1095
+ };
1096
+ }, $ = H({ scope: "voltro:serve" }), ui = (e, t, n) => (e === "production" || e === "staging") && t !== "memory" && n !== "0", di = R, fi = async (e) => {
1097
+ let t = L(process.cwd());
1098
+ if (Bt(t)) {
1099
+ let n;
1100
+ try {
1101
+ let e = await import(Lt(t).href);
1102
+ typeof e.runServe == "function" ? n = e.runServe : $.warn("serve bundle has no runServe export — using the standard serve path");
1103
+ } catch (e) {
1104
+ $.warn("serve bundle failed to load — using the standard serve path", {}, e);
1105
+ }
1106
+ if (n) return $.info("serve: booting from the precompiled serve bundle"), n(e);
1107
+ }
1108
+ return pi(e);
1109
+ }, pi = async (u) => {
1110
+ let p = Ft();
1111
+ process.env.NODE_ENV || (process.env.NODE_ENV = "production");
1112
+ try {
1113
+ yr();
1114
+ } catch (e) {
1115
+ throw n(e instanceof Error ? e.message : String(e));
1116
+ }
1117
+ let h = process.cwd(), re = Number(process.env.PORT ?? di(u, "--port") ?? 4e3), _ = await E(h);
1118
+ Rn(In(_?.secrets)), await e({
1119
+ rawEnv: _?.env,
1120
+ appType: "api",
1121
+ root: h,
1122
+ log: $,
1123
+ generateTypes: !1
1124
+ }), p.mark("config");
1125
+ let v = (process.env.DB_DIALECT ?? _?.store ?? "memory").toLowerCase(), ae = (v === "mariadb" || v === "postgres" || v === "mssql") && (process.env.CDC ?? "1") !== "0", se = v === "mariadb" ? "mariadb" : v === "mssql" ? "mssql" : void 0, ce = Pt(h);
1126
+ if (!c() && Bt(ce)) try {
1127
+ let e = await import(Lt(ce).href);
1128
+ if (e.modules) {
1129
+ let t = {};
1130
+ for (let [n, r] of Object.entries(e.modules)) t[It(h, n)] = r;
1131
+ s(t), $.info("precompiled api bundle loaded", { modules: Object.keys(t).length });
1132
+ }
1133
+ } catch (e) {
1134
+ $.warn("precompiled api bundle failed to load — falling back to source", {}, e);
1135
+ }
1136
+ let y = await Ge(h), b = await ft(y, { cdc: ae && se !== void 0 });
1137
+ {
1138
+ let e = /* @__PURE__ */ new Set([
1139
+ ...b.queries.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name),
1140
+ ...b.mutations.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name),
1141
+ ...b.actions.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name)
1142
+ ]);
1143
+ Et(P(_?.plugins ?? []), [
1144
+ ...b.queries.map((e) => e.descriptor.name),
1145
+ ...b.mutations.map((e) => e.descriptor.name),
1146
+ ...b.actions.map((e) => e.descriptor.name),
1147
+ ...b.streams.map((e) => e.descriptor.name)
1148
+ ], e);
1149
+ let t = Ze(b.serverOnlyLeaks, f(process.env, "strict"), an, "`voltro serve`");
1150
+ if (t.action === "fail") throw n(t.message ?? "");
1151
+ t.action === "warn" && $.warn(t.message ?? "");
1152
+ }
1153
+ let le = y.filter((e) => D.test(e)), de = le.length > 0 ? await it(le, $.child("webhooks")) : {
1154
+ outgoing: [],
1155
+ incoming: [],
1156
+ providers: []
1157
+ }, fe = et(b.events), pe = de.outgoing.length + de.incoming.length + de.providers.length + fe.length === 0 ? void 0 : {
1158
+ ...de,
1159
+ outgoing: [...de.outgoing, ...fe]
1160
+ }, me = Tt({
1161
+ mix: b.featureMix,
1162
+ plugins: _?.plugins ?? [],
1163
+ cdc: ae && se !== void 0,
1164
+ ...se ? { cdcDialect: se } : {}
1165
+ }), _e = _?.analytics !== void 0 && _.analytics.kind !== "noop" && v !== "memory" ? (await a(v)).makeSqlLayer(k()) : void 0, be = await ee({
1166
+ spec: _?.analytics,
1167
+ sqlLayer: _e,
1168
+ log: $
1169
+ }), S = (() => {
1170
+ let e = new Set(b.tables.map((e) => e.tableName)), t = [...b.tables];
1171
+ for (let n of [...me, ...be.tables]) e.has(n.tableName) || (e.add(n.tableName), t.push(n));
1172
+ return t;
1173
+ })();
1174
+ for (let e of S) Qn(e);
1175
+ {
1176
+ let e = on(Gn(b.queries.map((e) => ({
1177
+ name: e.descriptor.name,
1178
+ source: e.descriptor.source
1179
+ })), new Set(S.flatMap((e) => {
1180
+ let t = e.tableName;
1181
+ return t === void 0 ? [] : [t];
1182
+ }))));
1183
+ e !== void 0 && $.warn(e);
1184
+ }
1185
+ let we = (process.env.NODE_ENV ?? "").toLowerCase();
1186
+ if (ui(we, v, process.env.VOLTRO_AUTO_MIGRATE)) {
1187
+ let e = (await a(v)).makeSqlLayer(k()), t = await B.runPromise(Yn.SqlClient.pipe(B.flatMap((e) => Tr(e, S, {
1188
+ appliedBy: `serve:${we}`,
1189
+ environment: "prod",
1190
+ dialectId: v
1191
+ })), B.provide(e)));
1192
+ t.kind === "prod-mismatch" && ($.error(wr(t, v)), $.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(wr(t, v));
1193
+ }
1194
+ let Te = Dn(S);
1195
+ p.mark("discover");
1196
+ let w = await qe(_, void 0), Oe = qn(w, v);
1197
+ for (let e of Je({
1198
+ dialect: String(_?.store ?? process.env.DB_DIALECT ?? "postgres"),
1199
+ changeStrategy: (process.env.CDC ?? "1") === "0" ? "inline" : "cdc",
1200
+ dbUrl: process.env.DB_URL,
1201
+ tables: b.tables.map((e) => ({
1202
+ tableName: e.tableName,
1203
+ isReactive: e.isReactive === !0
1204
+ })),
1205
+ querySources: b.queries.flatMap((e) => {
1206
+ let t = e.descriptor.source;
1207
+ return t === void 0 ? [] : typeof t == "string" ? [t] : [...t];
1208
+ })
1209
+ })) e.level === "warn" ? $.warn(e.message) : $.info(e.message);
1210
+ {
1211
+ let e = M(tt({
1212
+ tables: Xn().map((e) => ({ tableName: e.tableName })),
1213
+ queries: b.queries.map((e) => ({
1214
+ name: e.descriptor.name,
1215
+ source: e.descriptor.source
1216
+ }))
1217
+ }));
1218
+ e !== void 0 && $.warn(e);
1219
+ }
1220
+ _?.cache && !process.env.CACHE_BACKEND && (process.env.CACHE_BACKEND = _.cache), _?.cacheRedisUrl && !process.env.CACHE_REDIS_URL && (process.env.CACHE_REDIS_URL = _.cacheRedisUrl), _?.cacheRedisDriver && !process.env.CACHE_REDIS_DRIVER && (process.env.CACHE_REDIS_DRIVER = _.cacheRedisDriver), _?.cacheKeyPrefix && !process.env.CACHE_KEY_PREFIX && (process.env.CACHE_KEY_PREFIX = _.cacheKeyPrefix);
1221
+ let { service: je, invalidationBus: Ne, snapshotCache: Le, cache: Re, semantic: Ve, evictSource: He, backend: We, stats: Ke, dispose: Ye } = await ut({
1222
+ env: process.env,
1223
+ semantic: _?.cacheSemantic ?? !1
1224
+ });
1225
+ Ve !== void 0 && $.info("semantic cache enabled — reactive eviction on live writes"), $.info(`cache backend resolved: ${We}` + (We === "redis" ? ` (driver ${process.env.CACHE_REDIS_DRIVER ?? "resp"})` : " — in-process, not cross-instance")), w.onChange((e) => {
1226
+ if (B.runFork(Ne.publish(e.table)), He !== void 0) {
1227
+ let t = (e.new ?? e.old)?.id;
1228
+ He({
1229
+ table: e.table,
1230
+ op: e.op,
1231
+ ...t === void 0 ? {} : { id: t }
1232
+ });
1233
+ }
1234
+ }), _?.kv && !process.env.KV_BACKEND && (process.env.KV_BACKEND = _.kv), _?.kvRedisUrl && !process.env.KV_REDIS_URL && (process.env.KV_REDIS_URL = _.kvRedisUrl), _?.kvKeyPrefix && !process.env.KV_KEY_PREFIX && (process.env.KV_KEY_PREFIX = _.kvKeyPrefix);
1235
+ let { kv: nt, service: ot } = await gn({ store: w });
1236
+ $.info(Gr(ze(), Kr(), v === "postgres" && (process.env.CDC ?? "1") !== "0" ? [{ reason: "CDC LISTEN consumer" }] : [])), p.mark("store");
1237
+ let dt = qt({
1238
+ store: w,
1239
+ sink: be.sink,
1240
+ log: $
1241
+ }), yt = Be({
1242
+ store: w,
1243
+ dialect: v,
1244
+ log: { info: (e) => $.info(e) }
1245
+ }), N = _?.plugins ?? [], L = process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, R, H;
1246
+ v !== "memory" && (R = zt.make((await a(v)).makeSqlLayer(k())), H = await R.runPromise(Yn.SqlClient));
1247
+ let Vt = [
1248
+ "postgres",
1249
+ "mariadb",
1250
+ "mysql",
1251
+ "mssql"
1252
+ ].includes(v) ? fn(w, L, $) : Vn, Ht = pt(_?.scheduling), Ut = _n({
1253
+ maxIdleIntervalMs: Ht.pollCeilingMs,
1254
+ coordinator: Vt,
1255
+ replicaId: L,
1256
+ log: $
1257
+ }), Wt = [], Gt = process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, Jt = Lr(_?.plugins ?? [])?.broadcast?.provider, Yt = mt(_?.plugins, _?.name ?? z(h));
1258
+ {
1259
+ let e = Me(_?.plugins, _?.name ?? z(h));
1260
+ e !== void 0 && $.warn(e);
1261
+ }
1262
+ let Xt = Fe(_?.plugins, {
1263
+ instanceId: Gt,
1264
+ namespace: Yt,
1265
+ meta: { mode: "serve" },
1266
+ logger: $
1267
+ }), Zt = {
1268
+ ...H ? { sql: H } : {},
1269
+ instanceId: Gt,
1270
+ membership: Xt.membership,
1271
+ ...Jt === void 0 ? {} : { broadcast: Jt },
1272
+ broadcastChannels: { presence: Ir(Yt, "presence") },
1273
+ scheduleCoordinated: (e, t, n) => {
1274
+ let r = Ut(e, t, n);
1275
+ return Wt.push(r), r;
1276
+ }
1277
+ };
1278
+ for (let e of N) e.bindDataStore?.(w, Zt);
1279
+ Xe({
1280
+ store: w,
1281
+ ...d(),
1282
+ log: $
1283
+ });
1284
+ let U = N.filter((e) => typeof e.onChangeEvent == "function");
1285
+ if (U.length > 0) {
1286
+ let e = w.changeScope ?? "local";
1287
+ w.onChange((t) => {
1288
+ let n = Qe(t, e);
1289
+ for (let e of U) B.runFork(e.onChangeEvent(n).pipe(B.catchAllCause((t) => B.sync(() => $.warn(`plugin ${e.name} onChangeEvent failed`, { error: Rt.pretty(t) })))));
1290
+ });
1291
+ }
1292
+ let Qt = at({
1293
+ plugins: N,
1294
+ appName: _?.name ?? "voltro-api",
1295
+ appType: "api",
1296
+ voltroVersion: process.env.npm_package_version ?? "0.0.0",
1297
+ log: $
1298
+ });
1299
+ N.length && await Qt.activate(), p.mark("plugins");
1300
+ let W = await Qt.gatherObservability(), $t = {
1301
+ info: (e, t) => process.stdout.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
1302
+ warn: (e, t) => process.stderr.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
1303
+ debug: () => {}
1304
+ }, en, cn = await Ue(w, _, v, Yt, $t, (e, t) => {
1305
+ en?.refreshAll(`broadcast gap: missed ${t} change(s) from ${e}`);
1306
+ }), ln = _?.apiKeys, un = (typeof ln == "object" ? ln.prefix : void 0) ?? "voltro_", dn = ln ? nn(w) : void 0, vn = dn ? mn({ flush: hn(dn) }) : void 0;
1307
+ vn && Mn(() => vn.shutdown());
1308
+ let yn = dn ? pn(dn, {
1309
+ prefix: un,
1310
+ ...vn ? { usage: vn } : {}
1311
+ }) : void 0, bn = yn ? [sn(yn, { prefix: un })] : [], xn = j([..._?.auth?.strategies ?? [], ...bn], Mr(_?.plugins ?? []), _?.auth?.anonymousTenantRequired ?? !1, _?.auth?.resolveScopes, () => Oe), Sn = [..._?.restRoutes ?? [], ...yn ? Kt(yn, (typeof ln == "object" ? ln.managementPath : void 0) ?? "/v1/api-keys") : []], Cn = _?.idempotency, wn = Cn ? {
1312
+ store: rn(w),
1313
+ header: (typeof Cn == "object" ? Cn.header : void 0) ?? "Idempotency-Key",
1314
+ ttlMs: (typeof Cn == "object" ? Cn.ttlMs : void 0) ?? 864e5
1315
+ } : void 0, Tn = Sn.length > 0 ? Pr(Sn, {
1316
+ store: w,
1317
+ resolveSubject: async (e) => (await xn({
1318
+ headers: e,
1319
+ clientId: -1
1320
+ })).subject,
1321
+ ...wn ? { idempotency: wn } : {}
1322
+ }) : [], En = N.map((e) => e.services).filter((e) => e !== void 0), On = V.mergeAll(T({
1323
+ analyticsLayer: be.layer,
1324
+ cacheService: je,
1325
+ kvService: ot,
1326
+ ...Ve === void 0 ? {} : { semanticCache: Ve },
1327
+ pluginServices: En,
1328
+ userLayers: _?.layers ?? []
1329
+ }), ke(_?.http ?? {})), kn = _?.scheduling ?? {}, An = kn.trigger ?? "self", jn = /* @__PURE__ */ new Set([
1330
+ "postgres",
1331
+ "mysql",
1332
+ "mariadb",
1333
+ "mssql"
1334
+ ]), Pn = kn.coordination ?? (jn.has(v) ? "advisoryLock" : "single"), G = Pn === "cluster" && jn.has(v), Fn = G ? "cluster" : Pn === "advisoryLock" && jn.has(v) ? "advisoryLock" : "single";
1335
+ Pn === "cluster" && !G && $.warn("scheduling.coordination=cluster needs a sql-backed store except sqlite — falling back to single"), Pn === "advisoryLock" && !jn.has(v) && $.warn("scheduling.coordination=advisoryLock needs a SQL store (the claim-row gate) — falling back to single");
1336
+ let Ln, zn = b.workflows.length > 0 || b.workflowWorkers.length > 0 || b.eventTriggers.length > 0 || (pe?.outgoing.length ?? 0) > 0 || G, Bn;
1337
+ if (zn) {
1338
+ if (v === "mssql") {
1339
+ let e = await xt(process.cwd());
1340
+ e && $.warn(e);
1341
+ }
1342
+ let [{ WorkflowEngine: e }, { makeClusterCronLayer: t, workflowEngineLayer: n, resolveRunnerStorage: r, resolveFailoverTuning: i }] = await Promise.all([import("@effect/workflow"), import("@voltro/workflow/cluster")]), o = G ? b.schedules.filter((e) => (e.trigger ?? An) === "self").map((e) => t({
1343
+ name: e.name,
1344
+ cron: tn(e),
1345
+ execute: async () => {
1346
+ await Ln?.fireFromCluster(e.name);
1347
+ }
1348
+ })) : [];
1349
+ Bn = v === "memory" ? e.layerMemory : await (async () => {
1350
+ let e = await a(v), t = r({ sqliteFamily: e.id === "sqlite" || e.id === "turso" });
1351
+ 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({
1352
+ sqlClientLayer: e.makeSqlLayer(k()),
1353
+ runnerStorage: t,
1354
+ dialectId: e.id,
1355
+ ...process.env.VOLTRO_WORKFLOW_RUNNER_PORT ? { runnerListenPort: Number(process.env.VOLTRO_WORKFLOW_RUNNER_PORT) } : {},
1356
+ ...i(),
1357
+ ...o.length > 0 ? { extraShardingLayers: o } : {}
1358
+ });
1359
+ })();
1360
+ }
1361
+ let Hn = ie(N, r()), Un = y.filter((e) => /\.subscribe\.tsx?$/.test(e)), Wn = Un.length > 0 ? await x(Un, $) : [], Kn = y.filter((e) => /\.reaction\.tsx?$/.test(e)), Jn = Kn.length > 0 ? await ge(Kn, $) : [], Zn = y.filter((e) => I.test(e)), K = Zn.length > 0 ? await ve(Zn, $) : [], $n = y.filter((e) => /\.aggregate\.tsx?$/.test(e)), er = $n.length > 0 ? await ne($n, $) : [], tr = _t();
1362
+ if (er.length > 0 && v !== "memory") try {
1363
+ tr = Ce((await a(v)).makeSqlLayer(k()));
1364
+ } catch (e) {
1365
+ $.warn("aggregate: SQL storage init failed — falling back to in-process", { err: String(e) });
1366
+ }
1367
+ let nr = v === "memory" ? Vn : fn(w, `aggregate@${process.pid}`, $), rr = y.filter((e) => At.test(e)), ir = rr.length > 0 ? await bt(rr, $) : [], ar = y.filter((e) => kt.test(e)), or = ar.length > 0 ? await ht(ar, $) : [], q = y.filter((e) => Ot.test(e)), sr = q.length > 0 ? await Ie(q, $) : [], cr = [], lr = [], J = y.filter((e) => F.test(e));
1368
+ if (J.length > 0) {
1369
+ let e = $.child("agent"), t = y.filter((e) => wt.test(e));
1370
+ t.length > 0 && await St(t, e);
1371
+ let n = await Ct(J, e);
1372
+ for (let e of n.agents) for (let t of De(e)) (t.kind === "action" ? cr : lr).push({
1373
+ file: t.file,
1374
+ descriptor: t.descriptor,
1375
+ executor: t.executor
1376
+ });
1377
+ n.agents.length > 0 && e.info("synthesized agent routes", { agents: n.agents.map((e) => e.descriptor.name) });
1378
+ }
1379
+ p.mark("workflow");
1380
+ let Y = () => {
1381
+ let e = Z.workflowWriteActions();
1382
+ if (e === void 0) throw Error("workflow actions: this app registers no workflows");
1383
+ return e;
1384
+ }, X = await Ae({
1385
+ files: y,
1386
+ store: w,
1387
+ log: $,
1388
+ seedPolicy: "report",
1389
+ seedPattern: o,
1390
+ loadSeedFiles: i,
1391
+ startupPattern: Dt,
1392
+ loadStartupFiles: Nt,
1393
+ runStartups: Mt,
1394
+ emailPattern: ye,
1395
+ loadEmailFiles: l,
1396
+ registerEmailTemplates: Fr
1397
+ });
1398
+ (X.startupCount > 0 || X.emailCount > 0) && $.info("boot lifecycle", {
1399
+ startups: X.startupCount,
1400
+ emailTemplates: X.emailCount
1401
+ }), X.startups !== void 0 && Mn(async () => {
1402
+ await X.startups.stop();
1403
+ });
1404
+ let ur = {
1405
+ kind: "api",
1406
+ meta: {
1407
+ name: _?.name ?? "voltro-api",
1408
+ voltroVersion: lt,
1409
+ port: re,
1410
+ mode: "start",
1411
+ store: v,
1412
+ cdc: ae ? "on" : "off"
1413
+ },
1414
+ rpc: rt(b, h),
1415
+ workflows: st(b, h),
1416
+ events: () => Z.eventsSnapshot(),
1417
+ members: () => Z.membersSnapshot(),
1418
+ inspectFireSchedule: async ({ name: e, trigger: t }) => {
1419
+ if (!Ln) throw Error("scheduler not started — this app registers no self-triggered schedules (all schedules are trigger:'external', or there are none).");
1420
+ return { runId: await Ln.fireNow(e, t) ?? null };
1421
+ },
1422
+ ...pe === void 0 ? {} : { webhooks: () => O({
1423
+ store: w,
1424
+ discoveredWebhooks: pe
1425
+ }) },
1426
+ plugins: () => ({
1427
+ plugins: Qt.snapshot(),
1428
+ capturedAt: Date.now()
1429
+ }),
1430
+ env: () => t(_?.name ?? z(h), {
1431
+ ..._?.env !== void 0 && vr(_.env) ? { contract: _.env } : {},
1432
+ plugins: _?.plugins ?? []
1433
+ }),
1434
+ dataCache: () => Se({
1435
+ stats: Ke,
1436
+ backendKind: We
1437
+ }),
1438
+ subscriptions: () => te(() => en),
1439
+ inspectTables: () => ue(b.tables),
1440
+ inspectRows: xe({
1441
+ store: w,
1442
+ tables: b.tables,
1443
+ mask: !0
1444
+ }),
1445
+ metrics: (e) => Z.rpcMetrics().snapshot(e),
1446
+ cluster: () => vt({
1447
+ store: w,
1448
+ dialect: v,
1449
+ useClusterCron: G,
1450
+ scheduleCoordChoice: Pn
1451
+ }),
1452
+ inspectSchedules: () => m({
1453
+ schedules: b.schedules,
1454
+ defaultTrigger: An,
1455
+ coordination: Fn
1456
+ }),
1457
+ inspectScheduleRuns: (e) => g(w, e),
1458
+ ...C(w, {
1459
+ controls: ct(b.workflows ?? []),
1460
+ active: (b.workflows?.length ?? 0) > 0,
1461
+ cancellation: () => Z.flowControlHealth()
1462
+ }),
1463
+ webhookActions: gt(() => Z.webhooksService()),
1464
+ inspectStartWorkflow: (e) => Y().inspectStartWorkflow(e),
1465
+ inspectCancelWorkflowRun: (e) => Y().inspectCancelWorkflowRun(e),
1466
+ inspectSuspendWorkflowRun: (e) => Y().inspectSuspendWorkflowRun(e),
1467
+ inspectResumeWorkflowRun: (e) => Y().inspectResumeWorkflowRun(e),
1468
+ inspectDiscardWorkflowRun: (e) => Y().inspectDiscardWorkflowRun(e),
1469
+ inspectRetryWorkflowRun: (e) => Y().inspectRetryWorkflowRun(e),
1470
+ inspectSignalWorkflowRun: (e) => Y().inspectSignalWorkflowRun(e),
1471
+ inspectUpdateWorkflowRun: (e) => Y().inspectUpdateWorkflowRun(e),
1472
+ inspectInferences: (e) => Pe({
1473
+ store: w,
1474
+ active: (b.workflows?.length ?? 0) > 0,
1475
+ dispatcher: () => Z.inferenceHealth()
1476
+ }, e.limit === void 0 ? {} : { limit: e.limit }),
1477
+ ...A({
1478
+ store: w,
1479
+ cancelRun: async (e) => await Z.runCanceller()?.(e) ?? !1,
1480
+ retryRun: async (e) => Y().inspectRetryWorkflowRun({ runId: e }),
1481
+ redriveRun: async (e) => Z.redriveWorkflowRun({ runId: e }),
1482
+ log: $
1483
+ }),
1484
+ inspectRedriveWorkflowRun: (e) => Z.redriveWorkflowRun(e),
1485
+ inspectResumeWorkflowRunFromStep: (e) => Z.resumeWorkflowRunFromStep(e)
1486
+ }, Z = await li({
1487
+ bootTiming: p,
1488
+ broadcastNamespace: Yt,
1489
+ scheduling: (() => {
1490
+ let e = Ht;
1491
+ return {
1492
+ admissionDrainMs: e.admissionDrainMs,
1493
+ inferenceTickMs: e.inferenceTickMs,
1494
+ cancelSweepMs: e.cancelSweepMs,
1495
+ disarmWhenIdle: $e({
1496
+ changeScope: w.changeScope,
1497
+ broadcastAttached: cn !== void 0
1498
+ })
1499
+ };
1500
+ })(),
1501
+ membership: {
1502
+ ...Xt,
1503
+ instanceId: Gt
1504
+ },
1505
+ ..._?.plugins === void 0 ? {} : { plugins: _.plugins },
1506
+ ...wn ? { idempotency: {
1507
+ store: wn.store,
1508
+ ttlMs: wn.ttlMs
1509
+ } } : {},
1510
+ discovered: {
1511
+ queries: [...b.queries, ...lr],
1512
+ mutations: b.mutations,
1513
+ actions: [...b.actions, ...cr],
1514
+ streams: b.streams,
1515
+ events: b.events,
1516
+ workflows: b.workflows,
1517
+ workflowWorkers: b.workflowWorkers,
1518
+ eventTriggers: b.eventTriggers,
1519
+ schedules: b.schedules,
1520
+ subscribers: Wn,
1521
+ outboxHandlers: K,
1522
+ connections: b.connections,
1523
+ reactions: Jn,
1524
+ aggregates: er,
1525
+ expectations: ir,
1526
+ budgets: or,
1527
+ experiments: sr,
1528
+ ...pe === void 0 ? {} : { webhooks: pe }
1529
+ },
1530
+ log: $,
1531
+ analytics: be.sink,
1532
+ aggregateStorage: tr,
1533
+ aggregateCoordinator: nr,
1534
+ store: w,
1535
+ kv: nt,
1536
+ cache: Re,
1537
+ snapshotCache: Le,
1538
+ schemaRegistry: Te,
1539
+ tenantScopedTables: b.tenantScopedTables,
1540
+ softDeleteScopedTables: b.softDeleteScopedTables,
1541
+ dataTransferSnapshot: Cr(S),
1542
+ dataTransferDialect: v,
1543
+ tenantIsolation: (process.env.VOLTRO_TENANT_ISOLATION ?? _?.tenancy?.isolation) === "namespace" ? "namespace" : "shared-schema",
1544
+ resolveSubject: async (e, t) => {
1545
+ let n = await xn({
1546
+ headers: e,
1547
+ clientId: t
1548
+ });
1549
+ return Nn(t, n.credentialExpiresAt), n.subject;
1550
+ },
1551
+ httpRoutes: [...N.flatMap((e) => e.httpRoutes ?? []), ...Tn],
1552
+ getStore: () => Oe,
1553
+ ...On ? { baseLayer: On } : {},
1554
+ ...Bn === void 0 ? {} : { workflowEngineLayer: Bn },
1555
+ scheduleDefaultTrigger: An,
1556
+ scheduleCoordination: Fn,
1557
+ scheduleArmSelf: !G,
1558
+ dormancy: process.env.VOLTRO_DORMANCY === "sleep" || process.env.VOLTRO_DORMANCY === "always-on" ? process.env.VOLTRO_DORMANCY : _?.dormancy ?? "always-on",
1559
+ scheduleReplicaId: process.env.HOSTNAME ?? `pid-${process.pid}`,
1560
+ ...Hn === void 0 ? {} : { scheduleFireInterceptor: Hn },
1561
+ onSchedulerReady: (e) => {
1562
+ Ln = e;
1563
+ },
1564
+ inspectRoute: { handle: async (e, t, n, r) => await he(e, ur, t, {
1565
+ method: n,
1566
+ ...r === void 0 ? {} : { body: r }
1567
+ }) || (jt(e, ur, t, {
1568
+ method: n,
1569
+ ...r === void 0 ? {} : { body: r }
1570
+ }) ?? {
1571
+ status: 404,
1572
+ contentType: "application/json",
1573
+ body: JSON.stringify({ error: "not an inspect route" })
1574
+ }) },
1575
+ ..._?.name === void 0 ? {} : { appName: _.name },
1576
+ observability: W,
1577
+ port: re,
1578
+ ..._?.transport?.wsPath ? { path: _.transport.wsPath } : {}
1579
+ });
1580
+ return en = Z.dispatcher, oe(Ee([
1581
+ b.queries,
1582
+ b.mutations,
1583
+ b.actions,
1584
+ b.streams
1585
+ ]), (e) => {
1586
+ $.warn(e);
1587
+ }), $.info(`API listening on :${re}`, {
1588
+ dialect: v,
1589
+ queries: b.queries.length,
1590
+ mutations: b.mutations.length,
1591
+ actions: b.actions.length,
1592
+ streams: b.streams.length,
1593
+ workflows: b.workflows.length,
1594
+ workflowWorkers: b.workflowWorkers.length,
1595
+ schedules: b.schedules.length,
1596
+ scheduleCoordination: Fn
1597
+ }), p.finish($), Mn(async () => {
1598
+ for (let e of Wt) e.stop();
1599
+ dt.detach(), yt.stop(), Ye(), R?.dispose();
1600
+ try {
1601
+ await Qt.deactivate(), await cn?.close(), await be.dispose(), await Z.close(), await w.close?.();
1602
+ } catch (e) {
1603
+ console.error("serve: shutdown step failed, exiting anyway:", e);
1604
+ }
1605
+ }), await new Promise(() => {}), 0;
1606
+ };
1607
+ //#endregion
1608
+ export { fi as n, oi as r, pi as t };