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