@voltro/cli 0.3.0 → 0.5.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 (72) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/{apiBuild-DdgYydVJ.js → apiBuild-CZugTK46.js} +2 -5
  3. package/dist/apiBuild-D-iBYKa3.js +2 -0
  4. package/dist/bin.js +2 -2
  5. package/dist/{commands-CXESev-z.js → commands-CJheDVOr.js} +2435 -2000
  6. package/dist/{dev-x_VqbV_8.js → dev-B71ICpXJ.js} +1993 -1823
  7. package/dist/dev-DNUetyG2.js +2 -0
  8. package/dist/index.js +1 -1
  9. package/dist/serveCommand-C0WFA396.js +1084 -0
  10. package/dist/serveEntry.js +2 -2
  11. package/package.json +17 -17
  12. package/templates/AGENTS.core.md +131 -0
  13. package/templates/AGENTS.md +131 -0
  14. package/templates/agent-docs/_manifest.json +4 -4
  15. package/templates/agent-docs/ai.md +34 -2
  16. package/templates/agent-docs/authentication.md +74 -2
  17. package/templates/agent-docs/cli.md +115 -0
  18. package/templates/agent-docs/data.md +302 -7
  19. package/templates/agent-docs/database/advancedqueries.md +25 -2
  20. package/templates/agent-docs/database/querying.md +17 -5
  21. package/templates/agent-docs/database/schema.md +5 -2
  22. package/templates/agent-docs/internationalization.md +237 -2
  23. package/templates/agent-docs/observability.md +9 -0
  24. package/templates/agent-docs/plugins.md +2 -2
  25. package/templates/agent-docs/reference.md +110 -0
  26. package/templates/agent-docs/schema-driven-ui.md +551 -2
  27. package/templates/agent-docs/templates/apibackends.md +10 -8
  28. package/templates/agent-docs/templates/overview.md +1 -1
  29. package/templates/agent-docs/testing.md +177 -3
  30. package/templates/agent-docs/workflows.md +11 -8
  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-storage/package.json +8 -8
  38. package/templates/apps/api-data-advanced/package.json +8 -8
  39. package/templates/apps/api-durable/package.json +8 -8
  40. package/templates/apps/api-feature-flags/package.json +9 -9
  41. package/templates/apps/api-governance/package.json +8 -8
  42. package/templates/apps/api-kv/package.json +8 -8
  43. package/templates/apps/api-moderation/package.json +8 -8
  44. package/templates/apps/api-observability/package.json +8 -8
  45. package/templates/apps/api-ratelimit/package.json +8 -8
  46. package/templates/apps/api-rbac/README.md +9 -4
  47. package/templates/apps/api-rbac/mutations/notes.create.mutation.server.ts +1 -1
  48. package/templates/apps/api-rbac/mutations/notes.create.mutation.ts +6 -6
  49. package/templates/apps/api-rbac/package.json +8 -8
  50. package/templates/apps/api-rbac/tests/notes.create.test.ts +8 -8
  51. package/templates/apps/api-rest/package.json +7 -7
  52. package/templates/apps/api-saas/package.json +11 -11
  53. package/templates/apps/api-search/package.json +8 -8
  54. package/templates/apps/api-versioning/package.json +8 -8
  55. package/templates/apps/api-webhooks/package.json +8 -8
  56. package/templates/apps/changelog/package.json +6 -6
  57. package/templates/apps/edge-functions/package.json +2 -2
  58. package/templates/apps/frontend-admin/package.json +8 -8
  59. package/templates/apps/frontend-app/package.json +8 -8
  60. package/templates/apps/frontend-blank/package.json +7 -7
  61. package/templates/apps/frontend-contact/package.json +7 -7
  62. package/templates/apps/frontend-dashboard/package.json +7 -7
  63. package/templates/apps/frontend-docs/package.json +7 -7
  64. package/templates/apps/frontend-i18n/package.json +6 -6
  65. package/templates/apps/frontend-landing/package.json +7 -7
  66. package/templates/apps/frontend-spa/package.json +7 -7
  67. package/templates/apps/frontend-ssr/package.json +7 -7
  68. package/templates/apps/frontend-ssr-api/package.json +8 -8
  69. package/templates/apps/frontend-static-blog/package.json +6 -6
  70. package/dist/apiBuild-cadmH8ca.js +0 -2
  71. package/dist/dev-DemiMSSl.js +0 -2
  72. package/dist/serveCommand-Dttqe5Ms.js +0 -1077
@@ -0,0 +1,1084 @@
1
+ import { $ as e, A as t, B as n, C as r, D as i, E as a, G as o, H as s, J as c, K as l, M as u, N as d, O as f, P as p, Q as ee, S as te, T as ne, U as re, V as m, W as h, X as ie, Yt as ae, _ as oe, b as se, d as g, et as ce, f as le, g as _, h as v, i as y, it as b, j as ue, k as de, m as x, n as S, o as fe, q as C, s as w, st as pe, t as me, tt as he, v as T, w as ge, x as _e, y as ve } from "./dev-B71ICpXJ.js";
2
+ import { a as ye, r as be } from "./startupRunner-DhlX9nqd.js";
3
+ import { a as xe, t as Se } from "./apiBuild-CZugTK46.js";
4
+ import { join as Ce } from "node:path";
5
+ import { pathToFileURL as we } from "node:url";
6
+ import { Cause as Te, Effect as E, Layer as D, ManagedRuntime as Ee } from "effect";
7
+ import { createLogger as O } from "@voltro/logger";
8
+ import { existsSync as De } from "node:fs";
9
+ import { AggregateRegistry as k, Dispatcher as A, apiKeyManagementRoutes as j, applySoftDeleteScope as Oe, applyTenantScope as ke, attachAnalyticsMirror as M, awaitServerListening as N, bindMutation as P, bindStream as Ae, bindSubscription as F, buildTracingLayer as je, cancelWakeup as Me, compileCron as Ne, dataStoreApiKeyStore as Pe, dataStoreIdempotencyStore as Fe, frameworkApiKeyStrategy as Ie, installPolicyGuardResolver as Le, loadResourceTuples as Re, makeActionRunner as ze, makeAdvisoryLockCoordinator as Be, makeApiKeyService as Ve, makeAsyncKv as He, makeCoordinatedScheduler as Ue, makeEffectStoreLayer as We, makeLazyWorkflowFacade as Ge, makeMutationRunner as I, makeQueryDescriptorProducer as Ke, makeQueryReauthorizer as qe, makeSchemaRegistry as L, makeWorkflowFacade as Je, makeWorkflowFacadeWithCallerContext as Ye, makeWorkflowLayers as Xe, noopKv as Ze, recordSubscriptionDelivery as Qe, registerWakeup as $e, resolveSecretsBackend as et, runProvidedEffect as tt, setSecretsBackend as nt, setTupleSource as rt, singleCoordinator as it, startRpcServer as R, startScheduler as at, workflowToRpc as z, wrapStoreWithMixinBehaviour as ot } from "@voltro/runtime";
10
+ import { createHash as B, timingSafeEqual as V } from "node:crypto";
11
+ import { assertProductionSessionSecret as st } from "@voltro/protocol/session";
12
+ import { RpcGroup as H } from "@effect/rpc";
13
+ import { SqlClient as ct } from "@effect/sql";
14
+ import { and as lt, ensureTableRegistered as ut, eq as U, or as dt } from "@voltro/database";
15
+ import { fromNodeReadable as ft, getObjectStream as pt, putObjectStream as mt, resolveStorageProvider as W, toNodeReadable as ht } from "@voltro/plugin-storage";
16
+ import { AuthMiddleware as G, ConnectionInfoMiddleware as gt, actionToRpc as K, anonymousSubject as _t, mutationToRpc as vt, queryToRpc as q, streamToRpc as yt, workflowCancelDescriptor as bt, workflowDomainEventsQueryDescriptor as J, workflowEventDeliveriesQueryDescriptor as xt, workflowResumeDescriptor as St, workflowRunEventsQueryDescriptor as Ct, workflowRunQueryDescriptor as Y, workflowRunStepsQueryDescriptor as X, workflowRunsQueryDescriptor as Z, workflowSignalDescriptor as wt, workflowUpdateDescriptor as Tt } from "@voltro/protocol";
17
+ import { declaredSnapshot as Et, describeOutcome as Dt, runPlannedMigrations as Ot } from "@voltro/database/sql";
18
+ import { getAuthSessionStrategy as kt } from "@voltro/plugin-auth";
19
+ import { collectPublicApiRoutes as At, restRoutesToHttpRoutes as jt } from "@voltro/protocol/rest";
20
+ import { buildDeliverWebhookExecute as Mt, buildWebhooksService as Nt, defaultIncomingPath as Pt, deliverWebhookWorkflow as Ft, mountIncomingWebhook as It } from "@voltro/plugin-webhooks";
21
+ import { packBundle as Lt, runExport as Rt, runImport as zt, storageBlobSink as Bt, storageRefsBlobSource as Vt, unpackBundle as Ht, unpackBundleToDir as Ut } from "@voltro/data-transfer";
22
+ //#region src/bootTiming.ts
23
+ var Wt = () => {
24
+ let e = process.env.VOLTRO_BOOT_TIMING;
25
+ return e === "1" || e === "true";
26
+ }, Gt = () => {
27
+ let e = [{
28
+ name: "modules",
29
+ at: performance.now()
30
+ }];
31
+ return {
32
+ mark: (t) => {
33
+ e.push({
34
+ name: t,
35
+ at: performance.now()
36
+ });
37
+ },
38
+ finish: (t) => {
39
+ let n = Math.round(e[e.length - 1].at);
40
+ if (!Wt()) {
41
+ t.info(`serve: ready in ${n}ms`);
42
+ return;
43
+ }
44
+ let r = {}, i = 0;
45
+ for (let t of e) r[t.name] = Math.round(t.at - i), i = t.at;
46
+ t.info(`serve: ready in ${n}ms`, {
47
+ bootMs: n,
48
+ phases: r
49
+ });
50
+ }
51
+ };
52
+ }, Kt = "/_voltro/admin/import", qt = "/_voltro/admin/export", Q = (e, t) => ({
53
+ status: e,
54
+ contentType: "application/json; charset=utf-8",
55
+ body: JSON.stringify(t)
56
+ }), Jt = (e) => {
57
+ let t = e.authorization ?? e.Authorization, n = t ? /^Bearer\s+(.+)$/i.exec(t) : null;
58
+ return n ? n[1] : null;
59
+ }, Yt = (e, t) => V(B("sha256").update(e).digest(), B("sha256").update(t).digest()), Xt = (e, t) => {
60
+ if (e.method.toUpperCase() !== "POST") return Q(405, { error: "method not allowed" });
61
+ if (!t || t.length < 16) return Q(503, { error: "data transfer misconfigured (no/weak secret)" });
62
+ let n = Jt(e.headers);
63
+ return !n || !Yt(n, t) ? Q(401, { error: "unauthorized" }) : null;
64
+ }, Zt = O({ scope: "voltro:admin-import" }), Qt = "VBUNDLE2", $t = async function* (e) {
65
+ yield e;
66
+ }, en = (e) => async (t) => {
67
+ let n = Xt(t, e.secret);
68
+ if (n) return n;
69
+ 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") === Qt, c, l;
70
+ if (s) c = $t(t.rawBody), l = "upload";
71
+ else {
72
+ let n;
73
+ try {
74
+ n = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
75
+ } catch {
76
+ return Q(400, { error: "body must be a packed bundle archive or { bundleKey } JSON" });
77
+ }
78
+ if (typeof n.bundleKey != "string" || !n.bundleKey) return Q(400, { error: "body.bundleKey (string) is required for the storage transport" });
79
+ if (!e.openArchive) return Q(501, { error: "storage transport not configured on this instance" });
80
+ c = e.openArchive(n.bundleKey), l = "storage";
81
+ }
82
+ 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-"));
83
+ try {
84
+ e.assetSink ? await Ht(c, {
85
+ dir: p,
86
+ blobs: e.assetSink
87
+ }) : await Ut(c, p);
88
+ let t = await E.runPromiseExit(zt({
89
+ store: e.store,
90
+ bundleDir: p,
91
+ ...r ? { mode: r } : {},
92
+ ...i ? { onConflict: i } : {},
93
+ ...a ? { atomic: a } : {},
94
+ ...e.snapshot ? { targetSnapshot: e.snapshot } : {},
95
+ force: o,
96
+ onWarn: (e) => Zt.warn("admin.import", { message: e }),
97
+ ...e.assetSink ? { assetsAlreadyRestored: !0 } : {}
98
+ }));
99
+ if (t._tag === "Failure") {
100
+ let e = t.cause._tag === "Fail" ? t.cause.error : void 0;
101
+ if (e && e._tag === "SchemaDriftError") {
102
+ let t = e;
103
+ return Zt.warn("admin.import refused (schema drift)", {
104
+ transport: l,
105
+ bundle: t.bundleFingerprint.slice(0, 16),
106
+ target: t.targetFingerprint.slice(0, 16)
107
+ }), Q(409, {
108
+ error: "schema drift",
109
+ bundleFingerprint: t.bundleFingerprint,
110
+ targetFingerprint: t.targetFingerprint,
111
+ diff: t.diff,
112
+ hint: "re-export against the current schema, or resend with x-import-force: 1"
113
+ });
114
+ }
115
+ throw Error(String(e?.message ?? e ?? "import failed"));
116
+ }
117
+ let n = t.value, s = n.tables.reduce((e, t) => e + t.rowCount, 0);
118
+ return Zt.info("admin.import", {
119
+ transport: l,
120
+ tables: n.tables.length,
121
+ rows: s,
122
+ mode: r ?? "upsert",
123
+ atomic: a
124
+ }), Q(200, {
125
+ tables: n.tables.length,
126
+ rows: s,
127
+ transport: l
128
+ });
129
+ } catch (e) {
130
+ return Zt.warn("admin.import failed", {
131
+ transport: l,
132
+ error: e?.message ?? String(e)
133
+ }), Q(500, {
134
+ error: "import failed",
135
+ message: e?.message ?? String(e)
136
+ });
137
+ } finally {
138
+ await d.rm(p, {
139
+ recursive: !0,
140
+ force: !0
141
+ });
142
+ }
143
+ }, tn = O({ scope: "voltro:admin-export" }), nn = async (e) => {
144
+ let t = [];
145
+ for await (let n of e) t.push(Buffer.from(n));
146
+ return new Uint8Array(Buffer.concat(t));
147
+ }, rn = (e) => typeof e.tenant == "string" && e.tenant ? {
148
+ kind: "tenant",
149
+ tenantId: e.tenant
150
+ } : Array.isArray(e.tables) && e.tables.length ? {
151
+ kind: "tables",
152
+ tables: e.tables.filter((e) => typeof e == "string")
153
+ } : { kind: "all" }, an = (e) => async (t) => {
154
+ let n = Xt(t, e.secret);
155
+ if (n) return n;
156
+ let r;
157
+ try {
158
+ r = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
159
+ } catch {
160
+ return Q(400, { error: "body must be JSON: { profile?, tenant?, tables?, consistency?, compression?, bundleKey? }" });
161
+ }
162
+ let i = {};
163
+ if (typeof r.profile == "string" && r.profile) {
164
+ if (!e.loadProfile) return Q(501, { error: "server-side profiles not configured on this instance" });
165
+ try {
166
+ i = await e.loadProfile(r.profile);
167
+ } catch (e) {
168
+ return Q(400, {
169
+ error: `profile '${r.profile}' could not be loaded`,
170
+ message: e?.message ?? String(e)
171
+ });
172
+ }
173
+ }
174
+ let a = r.consistency === "snapshot" ? "snapshot" : i.consistency ?? "live", o = (typeof r.compression == "string" ? r.compression : void 0) ?? i.compression, s = i.scope ?? rn(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-"));
175
+ try {
176
+ let t = await E.runPromise(Rt({
177
+ store: e.store,
178
+ snapshot: e.snapshot,
179
+ dialect: e.dialect,
180
+ outDir: p,
181
+ ...i.subset ? { subset: i.subset } : {
182
+ scope: s,
183
+ ...e.tenantTables && e.tenantTables.length > 0 ? { tenantTables: e.tenantTables } : {}
184
+ },
185
+ consistency: a,
186
+ ...o ? { compression: o } : {},
187
+ ...i.masking ? { masking: i.masking } : {}
188
+ })), n = t.tables.reduce((e, t) => e + t.rowCount, 0), u = t.masking?.transformed.length ?? 0;
189
+ if (c) {
190
+ if (!e.putArchive) return Q(501, { error: "storage transport not configured on this instance" });
191
+ let i = r.bundleKey;
192
+ return await e.putArchive(i, () => Lt({
193
+ dir: p,
194
+ ...l
195
+ })), tn.info("admin.export", {
196
+ transport: "storage",
197
+ tables: t.tables.length,
198
+ rows: n,
199
+ masked: u,
200
+ bundleKey: i
201
+ }), Q(200, {
202
+ bundleKey: i,
203
+ tables: t.tables.length,
204
+ rows: n,
205
+ masked: u,
206
+ transport: "storage"
207
+ });
208
+ }
209
+ let d = await nn(Lt({
210
+ dir: p,
211
+ ...l
212
+ }));
213
+ return tn.info("admin.export", {
214
+ transport: "download",
215
+ tables: t.tables.length,
216
+ rows: n,
217
+ masked: u,
218
+ bytes: d.byteLength
219
+ }), {
220
+ status: 200,
221
+ contentType: "application/octet-stream",
222
+ body: d,
223
+ headers: {
224
+ "x-export-tables": String(t.tables.length),
225
+ "x-export-rows": String(n),
226
+ "x-export-masked": String(u)
227
+ }
228
+ };
229
+ } catch (e) {
230
+ return tn.warn("admin.export failed", { error: e?.message ?? String(e) }), Q(500, {
231
+ error: "export failed",
232
+ message: e?.message ?? String(e)
233
+ });
234
+ } finally {
235
+ await d.rm(p, {
236
+ recursive: !0,
237
+ force: !0
238
+ });
239
+ }
240
+ }, on = async (e) => {
241
+ let { resolve: t } = await import("node:path"), { existsSync: n } = await import("node:fs"), r = [
242
+ e,
243
+ `${e}.profile.ts`,
244
+ `data-profiles/${e}.ts`,
245
+ `data-profiles/${e}.profile.ts`
246
+ ].map((e) => t(process.cwd(), e)), i = r.find((e) => n(e));
247
+ if (!i) throw Error(`data profile '${e}' not found (looked for: ${r.join(", ")})`);
248
+ let a = await import(i), o = a.default ?? a.profile;
249
+ if (!o) throw Error(`data profile '${i}' has no default export`);
250
+ return o;
251
+ }, sn = {
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
+ }, cn = async (e) => {
261
+ let t = new A({
262
+ store: e.store,
263
+ ...e.snapshotCache ? { cache: e.snapshotCache } : {},
264
+ recordDelivery: (e) => Qe({
265
+ label: e.label,
266
+ kind: e.kind,
267
+ durationMs: e.durationMs,
268
+ rowCount: e.rowCount
269
+ })
270
+ }), n = e.cache ?? sn, i = e.kv ?? Ze, a, c, p, ee = /* @__PURE__ */ new Map(), te = () => `wfctx_${globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`}`, ne = async (t, n, r) => {
271
+ let i = {
272
+ ...r,
273
+ source: r.source ?? `workflow:${t}`
274
+ };
275
+ ee.set(n, i);
276
+ try {
277
+ let r = await e.store.query({
278
+ table: "_voltro_workflow_start_contexts",
279
+ order: [],
280
+ predicate: U("executionId", n),
281
+ projection: ["id"],
282
+ skip: void 0,
283
+ take: 1
284
+ }), a = {
285
+ workflowName: t,
286
+ executionId: n,
287
+ subject: i.subject ?? null,
288
+ traceId: i.traceId ?? null,
289
+ source: i.source ?? null,
290
+ parentExecutionId: i.parentExecutionId ?? null,
291
+ parentClosePolicy: i.parentClosePolicy ?? null,
292
+ createdAt: /* @__PURE__ */ new Date()
293
+ };
294
+ r[0] === void 0 ? await e.store.insert("_voltro_workflow_start_contexts", {
295
+ id: te(),
296
+ ...a
297
+ }) : await e.store.update("_voltro_workflow_start_contexts", r[0].id, a);
298
+ } catch (e) {
299
+ process.stderr.write(`[workflow] failed to persist start context for ${t}/${n}: ${e?.message ?? String(e)}\n`);
300
+ }
301
+ }, re = async (t, n) => {
302
+ let r = ee.get(n);
303
+ if (r !== void 0) return r;
304
+ try {
305
+ let t = (await e.store.query({
306
+ table: "_voltro_workflow_start_contexts",
307
+ order: [],
308
+ predicate: U("executionId", n),
309
+ projection: void 0,
310
+ skip: void 0,
311
+ take: 1
312
+ }))[0];
313
+ if (t === void 0) return;
314
+ let r = {
315
+ ...t.subject === null ? {} : { subject: t.subject },
316
+ ...t.traceId === null ? {} : { traceId: t.traceId },
317
+ ...t.source === null ? {} : { source: t.source },
318
+ ...t.parentExecutionId === null ? {} : { parentExecutionId: t.parentExecutionId },
319
+ ...t.parentClosePolicy === null ? {} : { parentClosePolicy: t.parentClosePolicy }
320
+ };
321
+ return ee.set(n, r), r;
322
+ } catch (e) {
323
+ process.stderr.write(`[workflow] failed to load start context for ${n}: ${e?.message ?? String(e)}\n`);
324
+ return;
325
+ }
326
+ }, m = (e.discovered.workflows?.length ?? 0) > 0 ? Ge(() => a) : void 0, h = (e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.eventTriggers?.length ?? 0) > 0, ie = h || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster", ae = e.tenantIsolation === "namespace", oe = (e.log ?? O({ scope: "voltro:serve" })).child("webhooks"), se, g = e.discovered.webhooks;
327
+ if (g && g.outgoing.length > 0 && e.workflowEngineLayer !== void 0) {
328
+ let t = e.workflowEngineLayer, r = {
329
+ store: ot(e.store, {
330
+ subject: _t(null),
331
+ schemaRegistry: e.schemaRegistry
332
+ }),
333
+ request: {
334
+ subject: _t(null),
335
+ traceId: "webhooks:trigger"
336
+ },
337
+ cache: n,
338
+ kv: i
339
+ }, a = g.outgoing.map((e) => e.descriptor);
340
+ se = Nt(r, async (e) => {
341
+ let n = Ft.execute(e).pipe(E.provide(Ft.toLayer(Mt(r, { events: a })).pipe(D.provideMerge(t))));
342
+ E.runPromise(n).catch((t) => {
343
+ oe.error("deliverWebhook workflow crashed", {
344
+ deliveryId: e.deliveryId,
345
+ targetId: e.targetId
346
+ }, t);
347
+ });
348
+ }, { events: a });
349
+ }
350
+ let ce = /* @__PURE__ */ new Map();
351
+ if (g) for (let e of g.incoming) {
352
+ let t = e.descriptor.path ?? Pt(e.descriptor.id), n = `VOLTRO_WEBHOOK_SECRET_${e.descriptor.id.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, r = It(e.descriptor, {
353
+ resolveSecret: async () => process.env[n] ?? null,
354
+ resolveWorkflows: () => m === void 0 ? void 0 : Ye(m, {
355
+ traceId: `incoming:${e.descriptor.id}`,
356
+ source: `incoming:${e.descriptor.id}`
357
+ }),
358
+ log: (e) => {
359
+ let t = {
360
+ webhookId: e.webhookId,
361
+ status: e.status,
362
+ signatureOk: String(e.signatureOk),
363
+ idempotency: e.idempotency,
364
+ durationMs: e.durationMs
365
+ };
366
+ e.status >= 500 ? oe.error("incoming delivery failed", t) : e.status >= 400 ? oe.warn("incoming delivery rejected", t) : oe.info("incoming delivery handled", t);
367
+ }
368
+ });
369
+ ce.set(t, { handle: r });
370
+ }
371
+ Le(), rt((t) => Re(e.store, t.subjectId, t.resourceType, t.resourceId));
372
+ let le = (e.discovered.outboxHandlers?.length ?? 0) > 0 ? u({
373
+ handlers: e.discovered.outboxHandlers ?? [],
374
+ store: e.store,
375
+ log: (e.log ?? O({ scope: "voltro:serve" })).child("outbox")
376
+ }) : void 0, _ = l({
377
+ store: e.store,
378
+ schemaRegistry: e.schemaRegistry,
379
+ cache: n,
380
+ kv: i,
381
+ ...se === void 0 ? {} : { webhooksService: se },
382
+ ...m === void 0 ? {} : { workflowsProxy: m },
383
+ eventTriggers: e.discovered.eventTriggers ?? [],
384
+ namespaceIsolationOn: ae,
385
+ ...le === void 0 ? {} : { outbox: { nudge: le.nudge } }
386
+ }), y = D.succeed(k, ge), b = (t, n) => {
387
+ let r = t.pipe(E.provide(We(n)));
388
+ return tt((e.baseLayer ? r.pipe(E.provide(e.baseLayer)) : r).pipe(E.provide(y)));
389
+ }, ue = I({
390
+ store: e.store,
391
+ buildContext: (e, t, n) => _(e, t, n),
392
+ runEffect: b,
393
+ undoCapture: ve()
394
+ }), S = T(), fe = ze({
395
+ buildContext: (e) => _(e),
396
+ runEffect: b
397
+ }), C = Ke({
398
+ buildContext: (e) => _(e),
399
+ finalize: (t, n) => Oe(ke(t, e.tenantScopedTables, n.subject.tenantId), e.softDeleteScopedTables),
400
+ provideEffect: (e, t) => e.pipe(E.provide(We(t)))
401
+ }), w = {};
402
+ for (let n of [...e.discovered.queries, ...S.queries]) w[n.descriptor.name] = (e) => F(C(n, e), t, `subscription.${n.descriptor.name}`, void 0, void 0, qe(n, e));
403
+ for (let t of [...e.discovered.mutations, ...S.mutations]) w[t.descriptor.name] = (e) => P(async (e, n) => ue(t, e, n), e, `mutation.${t.descriptor.name}`);
404
+ for (let t of e.discovered.actions) w[t.descriptor.name] = (e) => P(async (e, n) => fe(t, e, n), e, `action.${t.descriptor.name}`);
405
+ let pe = () => `public-${Math.random().toString(36).slice(2, 10)}`, me = [...e.discovered.mutations.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
406
+ descriptor: e.descriptor,
407
+ invoke: (t, n) => ue(e, t, {
408
+ subject: n.subject,
409
+ traceId: pe()
410
+ })
411
+ })), ...e.discovered.actions.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
412
+ descriptor: e.descriptor,
413
+ invoke: (t, n) => fe(e, t, {
414
+ subject: n.subject,
415
+ traceId: pe()
416
+ })
417
+ }))], he = me.length > 0 ? jt(At(me), {
418
+ store: e.store,
419
+ resolveSubject: (t) => e.resolveSubject(t, -1)
420
+ }) : [], _e = e.dataTransferSecret ?? process.env.VOLTRO_DATA_TRANSFER_SECRET, ye = _e && _e.length >= 16 ? [{
421
+ method: "POST",
422
+ path: Kt,
423
+ handle: en({
424
+ secret: _e,
425
+ store: e.store,
426
+ ...e.dataTransferSnapshot ? { snapshot: e.dataTransferSnapshot } : {},
427
+ assetSink: Bt(W({})),
428
+ openArchive: (e) => (async function* () {
429
+ let t = W({}), n = await ht((await E.runPromise(pt(t, e))).stream);
430
+ for await (let e of n) yield e instanceof Uint8Array ? e : new Uint8Array(e);
431
+ })()
432
+ })
433
+ }, {
434
+ method: "POST",
435
+ path: qt,
436
+ handle: an({
437
+ secret: _e,
438
+ store: e.store,
439
+ snapshot: e.dataTransferSnapshot ?? { tables: [] },
440
+ dialect: e.dataTransferDialect ?? "memory",
441
+ tenantTables: [...e.tenantScopedTables],
442
+ loadProfile: on,
443
+ assetSource: Vt(W({}), e.store),
444
+ putArchive: async (e, t) => {
445
+ let { Readable: n } = await import("node:stream"), r = W({}), i = ft("storage", () => n.from(t()));
446
+ await E.runPromise(mt(r, e, i, { contentType: "application/octet-stream" }));
447
+ }
448
+ })
449
+ }] : [], be = [
450
+ ...e.httpRoutes ?? [],
451
+ ...he,
452
+ ...ye
453
+ ];
454
+ for (let t of e.discovered.streams ?? []) w[t.descriptor.name] = (n) => Ae((r) => {
455
+ let i = _(r), a = t.executor(n, i);
456
+ if (E.isEffect(a)) {
457
+ let t = a.pipe(E.provide(We(i.store)));
458
+ return (e.baseLayer ? t.pipe(E.provide(e.baseLayer)) : t).pipe(E.provide(y));
459
+ }
460
+ return typeof a == "object" && a && typeof a.then == "function" ? E.promise(() => a) : a;
461
+ }, `stream.${t.descriptor.name}`);
462
+ for (let t of e.discovered.workflows ?? []) w[t.definition.name] = (e) => P(async (e, n) => {
463
+ let r = n;
464
+ return Ye(m, {
465
+ subject: r.subject,
466
+ traceId: r.traceId,
467
+ source: "workflow-rpc"
468
+ }).start(t.definition.name, e);
469
+ }, e, `workflow.${t.definition.name}`);
470
+ h && (w[Y.name] = (e) => F(C({
471
+ descriptor: Y,
472
+ executor: (e) => {
473
+ let t = e.id;
474
+ return {
475
+ table: "_voltro_workflow_runs",
476
+ order: [{
477
+ column: "startedAt",
478
+ direction: "desc"
479
+ }],
480
+ predicate: dt(U("id", t), U("executionId", t)),
481
+ take: 1,
482
+ skip: void 0,
483
+ projection: void 0
484
+ };
485
+ }
486
+ }, e), t, `subscription.${Y.name}`), w[Z.name] = (e) => F(C({
487
+ descriptor: Z,
488
+ executor: (e) => {
489
+ 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;
490
+ return {
491
+ table: "_voltro_workflow_runs",
492
+ order: [{
493
+ column: "startedAt",
494
+ direction: "desc"
495
+ }],
496
+ predicate: n.length === 0 ? void 0 : n.length === 1 ? n[0] : lt(...n),
497
+ take: r,
498
+ skip: void 0,
499
+ projection: void 0
500
+ };
501
+ }
502
+ }, e), t, `subscription.${Z.name}`), w[X.name] = (e) => F(C({
503
+ descriptor: X,
504
+ executor: (e) => {
505
+ let t = e.runId;
506
+ return {
507
+ table: "_voltro_workflow_run_steps",
508
+ order: [{
509
+ column: "startedAt",
510
+ direction: "asc"
511
+ }],
512
+ predicate: U("runId", t),
513
+ take: 1e3,
514
+ skip: void 0,
515
+ projection: void 0
516
+ };
517
+ }
518
+ }, e), t, `subscription.${X.name}`), w[Ct.name] = (e) => F(C({
519
+ descriptor: Ct,
520
+ executor: (e) => {
521
+ let t = e.runId;
522
+ return {
523
+ table: "_voltro_workflow_run_events",
524
+ order: [{
525
+ column: "occurredAt",
526
+ direction: "asc"
527
+ }],
528
+ predicate: U("runId", t),
529
+ take: 1e3,
530
+ skip: void 0,
531
+ projection: void 0
532
+ };
533
+ }
534
+ }, e), t, `subscription.${Ct.name}`), w[J.name] = (e) => F(C({
535
+ descriptor: J,
536
+ executor: (e) => {
537
+ let t = e;
538
+ return {
539
+ table: "_voltro_workflow_events",
540
+ order: [{
541
+ column: "occurredAt",
542
+ direction: "desc"
543
+ }],
544
+ predicate: t.name === void 0 ? void 0 : U("name", t.name),
545
+ take: Math.max(1, Math.min(500, t.limit ?? 100)),
546
+ skip: void 0,
547
+ projection: void 0
548
+ };
549
+ }
550
+ }, e), t, `subscription.${J.name}`), w[xt.name] = (e) => F(C({
551
+ descriptor: xt,
552
+ executor: (e) => {
553
+ let t = e.eventId;
554
+ return {
555
+ table: "_voltro_workflow_event_deliveries",
556
+ order: [{
557
+ column: "createdAt",
558
+ direction: "asc"
559
+ }],
560
+ predicate: U("eventId", t),
561
+ take: 500,
562
+ skip: void 0,
563
+ projection: void 0
564
+ };
565
+ }
566
+ }, e), t, `subscription.${xt.name}`), w[bt.name] = (t) => P(async (t, n) => {
567
+ let r = t;
568
+ return await o(e.store, n.subject, { executionId: r.executionId }), await m.cancel(r.workflowName, r.executionId), await Pe(r.workflowName, r.executionId, "workflow.cancel"), { ok: !0 };
569
+ }, t, `action.${bt.name}`), w[St.name] = (t) => P(async (t, n) => {
570
+ let r = t;
571
+ return await o(e.store, n.subject, { executionId: r.executionId }), await m.resume(r.workflowName, r.executionId), { ok: !0 };
572
+ }, t, `action.${St.name}`), w[wt.name] = (t) => P(async (t, n) => {
573
+ let r = t;
574
+ return await o(e.store, n.subject, { id: r.id }), m.signal({ id: r.id }, r.signalName, r.payload);
575
+ }, t, `action.${wt.name}`), w[Tt.name] = (t) => P(async (t, n) => {
576
+ let r = t;
577
+ return await o(e.store, n.subject, { id: r.id }), m.update({ id: r.id }, r.updateName, r.payload, r.timeoutMs === void 0 ? void 0 : { timeoutMs: r.timeoutMs });
578
+ }, t, `action.${Tt.name}`));
579
+ let xe = [
580
+ ...e.discovered.queries.map((e) => q(e.descriptor)),
581
+ ...e.discovered.mutations.map((e) => vt(e.descriptor)),
582
+ ...e.discovered.actions.map((e) => K(e.descriptor)),
583
+ ...S.queries.map((e) => q(e.descriptor)),
584
+ ...S.mutations.map((e) => vt(e.descriptor)),
585
+ ...(e.discovered.streams ?? []).map((e) => yt(e.descriptor)),
586
+ ...(e.discovered.workflows ?? []).map((e) => z(e.definition)),
587
+ ...h ? [
588
+ q(Y),
589
+ q(Z),
590
+ q(X),
591
+ q(Ct),
592
+ q(J),
593
+ q(xt),
594
+ K(bt),
595
+ K(St),
596
+ K(wt),
597
+ K(Tt)
598
+ ] : []
599
+ ], Se = H.make(...xe).middleware(G).middleware(gt), Ce = D.succeed(G, G.of(({ headers: t, clientId: n }) => E.promise(() => e.resolveSubject(t, n)))), we = D.succeed(gt, gt.of(({ clientId: e }) => E.succeed({ clientId: e }))), Te = e.dormancyTenantId ?? "default", De = e.dormancy === "sleep" ? {
600
+ register: (t, n, r) => $e(e.store, {
601
+ tenantId: r ?? Te,
602
+ kind: "workflow",
603
+ refId: t,
604
+ wakeAt: n
605
+ }),
606
+ cancel: (t, n) => Me(e.store, {
607
+ tenantId: n ?? Te,
608
+ kind: "workflow",
609
+ refId: t
610
+ }).then(() => {})
611
+ } : void 0, j = ie ? await import("@voltro/workflow") : void 0, M = j?.makeWorkflowRunRecorder({
612
+ store: e.store,
613
+ ...De === void 0 ? {} : { wakeups: De }
614
+ }), Ne = async (t, n) => {
615
+ await j.closeWorkflowChildrenForParent({
616
+ store: e.store,
617
+ parentExecutionId: t,
618
+ parentStatus: n,
619
+ recorder: M,
620
+ log: { warn: (e, t) => {
621
+ process.stderr.write(`[workflow] ${e} ${t ? JSON.stringify(t) : ""}\n`);
622
+ } },
623
+ interruptChild: async (t, n) => {
624
+ let r = (e.discovered.workflows ?? []).find((e) => e.definition.name === t);
625
+ if (!r) throw Error(`Unknown child workflow: ${t}`);
626
+ if (!c) throw Error("Workflow runtime is not ready");
627
+ await c.runPromise(r.definition.interrupt(n));
628
+ }
629
+ });
630
+ }, Pe = async (t, n, r) => {
631
+ let i = (await e.store.query({
632
+ table: "_voltro_workflow_runs",
633
+ order: [],
634
+ predicate: U("executionId", n),
635
+ projection: void 0,
636
+ skip: void 0,
637
+ take: 1
638
+ }))[0];
639
+ if (i === void 0) return;
640
+ let a = await e.store.update("_voltro_workflow_runs", i.id, {
641
+ status: "cancelled",
642
+ cancelled: !0,
643
+ completedAt: /* @__PURE__ */ new Date()
644
+ }), o = i.subject?.tenantId ?? void 0;
645
+ a && await M.recordEvent({
646
+ runId: i.id,
647
+ eventType: "run-cancelled",
648
+ payload: {
649
+ reason: r,
650
+ workflowName: t,
651
+ executionId: n,
652
+ ...o == null ? {} : { tenantId: o }
653
+ }
654
+ }), a && await Ne(n, "cancelled");
655
+ }, Fe = [...Xe(e.discovered.workflows ?? [], {
656
+ buildContext: (t, n) => {
657
+ let r = t?.subject ?? {
658
+ type: "anonymous",
659
+ id: null,
660
+ tenantId: null
661
+ };
662
+ return e.buildContextForWorkflow?.(t, n) ?? _({
663
+ subject: r,
664
+ traceId: t?.traceId ?? "workflow-bootstrap"
665
+ }, e.store, void 0, `workflow:${n.workflowName}`, { parentExecutionId: n.executionId });
666
+ },
667
+ resolveStartContext: re
668
+ }, (t, n, r) => {
669
+ let i = j.getWorkflowVersionMetadata(t.definition);
670
+ return j.wrapWorkflowExecuteWithRunRecording({
671
+ name: t.definition.name,
672
+ store: e.store,
673
+ subject: r?.subject ?? null,
674
+ source: r?.source ?? null,
675
+ traceId: r?.traceId ?? null,
676
+ workflowVersion: i.version,
677
+ workflowCompatibleVersions: i.compatibleWith,
678
+ workflowPatches: i.patches,
679
+ parentExecutionId: r?.parentExecutionId ?? null,
680
+ parentClosePolicy: r?.parentClosePolicy ?? null,
681
+ onParentClose: ({ executionId: e, status: t }) => Ne(e, t),
682
+ recorder: M
683
+ }, n);
684
+ }), ...e.discovered.workflowWorkers ?? []], Ie = Fe.length > 0 ? D.mergeAll(...Fe) : D.empty;
685
+ ((e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster") && e.workflowEngineLayer !== void 0 && (c = Ee.make(Ie.pipe(D.provideMerge(e.workflowEngineLayer))), await c.runPromise(E.void), a = (e.discovered.workflows?.length ?? 0) > 0 ? Je({
686
+ workflows: e.discovered.workflows ?? [],
687
+ runEffect: (e) => c.runPromise(e),
688
+ rememberStartContext: ne,
689
+ signal: async (t, n, r) => {
690
+ let i = await j.sendWorkflowSignal({
691
+ store: e.store,
692
+ recorder: M,
693
+ target: t,
694
+ signalName: n,
695
+ payload: r
696
+ });
697
+ return await c.runPromise(j.completeSuspendingSignal({
698
+ store: e.store,
699
+ target: t,
700
+ signalName: n,
701
+ payload: r
702
+ })).catch(() => {}), i;
703
+ },
704
+ update: (t, n, r, i) => j.sendWorkflowUpdate({
705
+ store: e.store,
706
+ recorder: M,
707
+ target: t,
708
+ updateName: n,
709
+ payload: r,
710
+ ...i === void 0 ? {} : { options: i }
711
+ }),
712
+ listRuns: (t) => x(e.store, t),
713
+ retry: (t, n) => v({
714
+ store: e.store,
715
+ workflows: e.discovered.workflows ?? [],
716
+ runPromise: (e) => c.runPromise(e)
717
+ }, t, n)
718
+ }) : void 0);
719
+ let Ve = D.mergeAll(Se.toLayer(w), Ce, we), He = s(w, e.discovered.queries.map((e) => e.descriptor.name), h), Ue = D.mergeAll(Se.toLayer(He), Ce, we), L = e.observability, et = await je({
720
+ ...L && L.spanProcessors.length > 0 ? { extraSpanProcessors: L.spanProcessors } : {},
721
+ ...L && L.metricReaders.length > 0 ? { extraMetricReaders: L.metricReaders } : {},
722
+ ...L && Object.keys(L.resourceAttributes).length > 0 ? { resourceAttributes: L.resourceAttributes } : {},
723
+ ...L && L.sampler !== void 0 ? { sampler: L.sampler } : {}
724
+ }), nt = !1, B = e.store.ping ? () => e.store.ping().then(() => !0).catch(() => !1) : void 0, V = R({
725
+ group: Se,
726
+ handlersLayer: Ve,
727
+ httpHandlersLayer: Ue,
728
+ port: e.port ?? 4e3,
729
+ path: e.path ?? "/ws",
730
+ tracerLayer: et.layer,
731
+ healthCheck: {
732
+ isReady: () => nt,
733
+ ...B ? { ping: B } : {}
734
+ },
735
+ ...be.length > 0 ? { httpRoutes: be } : {},
736
+ ...ce.size > 0 ? { webhookRoutes: ce } : {}
737
+ });
738
+ if (await N(V), (e.discovered.schedules?.length ?? 0) > 0) {
739
+ let t = (e.scheduleCoordination ?? "single") === "advisoryLock" ? Be(e.store, e.scheduleReplicaId ?? `pid-${process.pid}`) : it;
740
+ p = await at(e.discovered.schedules ?? [], {
741
+ store: e.store,
742
+ coordinator: t,
743
+ defaultTrigger: e.scheduleDefaultTrigger ?? "self",
744
+ replicaId: e.scheduleReplicaId ?? `pid-${process.pid}`,
745
+ armSelf: e.scheduleArmSelf ?? !0,
746
+ dormancy: e.dormancy ?? "always-on",
747
+ dormancyTenantId: e.dormancyTenantId ?? "default",
748
+ buildContext: ({ traceId: t, scheduleName: n }) => _({
749
+ subject: {
750
+ type: "anonymous",
751
+ id: null,
752
+ tenantId: null
753
+ },
754
+ traceId: t
755
+ }, e.store, void 0, `schedule:${n}`),
756
+ log: {
757
+ info: (e, t) => {
758
+ process.stdout.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
759
+ },
760
+ warn: (e, t) => {
761
+ process.stderr.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
762
+ },
763
+ debug: () => {}
764
+ },
765
+ ...e.scheduleFireInterceptor === void 0 ? {} : { interceptFire: e.scheduleFireInterceptor },
766
+ ...e.onScheduleRunEvent === void 0 ? {} : { onRunEvent: e.onScheduleRunEvent }
767
+ }), e.onSchedulerReady?.(p);
768
+ }
769
+ let st = e.log ?? O({ scope: "voltro:serve" }), ct, ut;
770
+ if ((e.discovered.subscribers?.length ?? 0) > 0 && (ct = d(e.discovered.subscribers ?? [], e.store, st.child("subscribe"))), (e.discovered.reactions?.length ?? 0) > 0) {
771
+ let t = st.child("reaction");
772
+ ut = f(e.discovered.reactions ?? [], e.store, {
773
+ runAct: async (n, r) => {
774
+ if (n.kind === "workflow") {
775
+ if (m === void 0) {
776
+ t.warn("reaction workflow act skipped — no workflow engine in this app", { workflow: n.workflow });
777
+ return;
778
+ }
779
+ let e = r.new ?? r.old ?? {};
780
+ await Ye(m, {
781
+ traceId: `reaction:${n.workflow}`,
782
+ source: `reaction:${n.workflow}`
783
+ }).start(n.workflow, e);
784
+ return;
785
+ }
786
+ await de(n.agent, r, {
787
+ findAgentSend: (t) => e.discovered.actions.find((e) => e.descriptor.name === `${t}.send`),
788
+ runAction: (e, t, n) => Promise.resolve(fe(e, t, n)),
789
+ makeSubject: (e) => _t(e),
790
+ now: () => Date.now(),
791
+ log: t
792
+ });
793
+ },
794
+ checkBudget: async (n, r) => {
795
+ try {
796
+ let { requireAiBudget: t } = await import("@voltro/ai");
797
+ return (await E.runPromise(E.either(t(e.store, {
798
+ tenantId: n,
799
+ limitUsd: r
800
+ }))))._tag === "Right";
801
+ } catch (e) {
802
+ return t.warn("reaction budget check failed — refusing the act", { tenantId: n }, e), !1;
803
+ }
804
+ }
805
+ }, t);
806
+ }
807
+ let Et;
808
+ return (e.discovered.aggregates?.length ?? 0) > 0 && (Et = await r({
809
+ discovered: e.discovered.aggregates ?? [],
810
+ store: e.store,
811
+ log: st.child("aggregate"),
812
+ ...e.analytics === void 0 ? {} : { analytics: e.analytics },
813
+ ...e.aggregateStorage === void 0 ? {} : { storage: e.aggregateStorage },
814
+ ...e.aggregateCoordinator === void 0 ? {} : { coordinator: e.aggregateCoordinator }
815
+ }), y = D.succeed(k, Et.registry)), nt = !0, e.bootTiming?.mark("ready"), {
816
+ dispatcher: t,
817
+ server: V,
818
+ scheduler: p,
819
+ close: async () => {
820
+ nt = !1, Et?.detach(), ut?.(), ct?.(), await p?.shutdown(), t.close(), await c?.dispose(), await new Promise((e) => V.close(() => e()));
821
+ }
822
+ };
823
+ }, $ = O({ scope: "voltro:serve" }), ln = (e, t, n) => (e === "production" || e === "staging") && t !== "memory" && n !== "0", un = (e, t) => {
824
+ let n = e.indexOf(t);
825
+ return n >= 0 ? e[n + 1] : void 0;
826
+ }, dn = async (e) => {
827
+ let t = xe(process.cwd());
828
+ if (De(t)) {
829
+ let n;
830
+ try {
831
+ let e = await import(we(t).href);
832
+ typeof e.runServe == "function" ? n = e.runServe : $.warn("serve bundle has no runServe export — using the standard serve path");
833
+ } catch (e) {
834
+ $.warn("serve bundle failed to load — using the standard serve path", {}, e);
835
+ }
836
+ if (n) return $.info("serve: booting from the precompiled serve bundle"), n(e);
837
+ }
838
+ return fn(e);
839
+ }, fn = async (r) => {
840
+ let o = Gt();
841
+ process.env.NODE_ENV || (process.env.NODE_ENV = "production"), st();
842
+ let s = process.cwd(), l = Number(process.env.PORT ?? un(r, "--port") ?? 4e3), u = await fe(s);
843
+ nt(et(u?.secrets)), await ae({
844
+ rawEnv: u?.env,
845
+ appType: "api",
846
+ root: s,
847
+ log: $,
848
+ generateTypes: !1
849
+ }), o.mark("config");
850
+ let d = (process.env.DB_DIALECT ?? u?.store ?? "memory").toLowerCase(), f = (d === "mariadb" || d === "postgres" || d === "mssql") && (process.env.CDC ?? "1") !== "0", v = d === "mariadb" ? "mariadb" : d === "mssql" ? "mssql" : void 0, de = Se(s);
851
+ if (!be() && De(de)) try {
852
+ let e = await import(we(de).href);
853
+ if (e.modules) {
854
+ let t = {};
855
+ for (let [n, r] of Object.entries(e.modules)) t[Ce(s, n)] = r;
856
+ ye(t), $.info("precompiled api bundle loaded", { modules: Object.keys(t).length });
857
+ }
858
+ } catch (e) {
859
+ $.warn("precompiled api bundle failed to load — falling back to source", {}, e);
860
+ }
861
+ let x = await g(s), T = await w(x, { cdc: f && v !== void 0 }), ge = x.filter((e) => _e.test(e)), ve = ge.length > 0 ? await te(ge, $.child("webhooks")) : void 0, xe = ie({
862
+ mix: T.featureMix,
863
+ plugins: u?.plugins ?? [],
864
+ cdc: f && v !== void 0,
865
+ ...v ? { cdcDialect: v } : {}
866
+ }), O = u?.analytics !== void 0 && u.analytics.kind !== "noop" && d !== "memory" ? (await b(d)).makeSqlLayer(y()) : void 0, k = await m({
867
+ spec: u?.analytics,
868
+ sqlLayer: O,
869
+ log: $
870
+ }), A = (() => {
871
+ let e = new Set(T.tables.map((e) => e.tableName)), t = [...T.tables];
872
+ for (let n of [...xe, ...k.tables]) e.has(n.tableName) || (e.add(n.tableName), t.push(n));
873
+ return t;
874
+ })();
875
+ for (let e of A) ut(e);
876
+ let Oe = (process.env.NODE_ENV ?? "").toLowerCase();
877
+ if (ln(Oe, d, process.env.VOLTRO_AUTO_MIGRATE)) {
878
+ let e = (await b(d)).makeSqlLayer(y()), t = await E.runPromise(ct.SqlClient.pipe(E.flatMap((e) => Ot(e, A, {
879
+ appliedBy: `serve:${Oe}`,
880
+ environment: "prod",
881
+ dialectId: d
882
+ })), E.provide(e)));
883
+ t.kind === "prod-mismatch" && ($.error(Dt(t, d)), $.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(Dt(t, d));
884
+ }
885
+ let ke = L(A);
886
+ o.mark("discover");
887
+ let N = await S(u, void 0);
888
+ u?.cache && !process.env.CACHE_BACKEND && (process.env.CACHE_BACKEND = u.cache), u?.cacheRedisUrl && !process.env.CACHE_REDIS_URL && (process.env.CACHE_REDIS_URL = u.cacheRedisUrl), u?.cacheRedisDriver && !process.env.CACHE_REDIS_DRIVER && (process.env.CACHE_REDIS_DRIVER = u.cacheRedisDriver), u?.cacheKeyPrefix && !process.env.CACHE_KEY_PREFIX && (process.env.CACHE_KEY_PREFIX = u.cacheKeyPrefix);
889
+ let { service: P, invalidationBus: Ae, snapshotCache: F, cache: je, backend: Me, dispose: Le } = await c({ env: process.env });
890
+ $.info(`cache backend resolved: ${Me}` + (Me === "redis" ? ` (driver ${process.env.CACHE_REDIS_DRIVER ?? "resp"})` : " — in-process, not cross-instance")), N.onChange((e) => {
891
+ E.runFork(Ae.publish(e.table));
892
+ }), u?.kv && !process.env.KV_BACKEND && (process.env.KV_BACKEND = u.kv), u?.kvRedisUrl && !process.env.KV_REDIS_URL && (process.env.KV_REDIS_URL = u.kvRedisUrl), u?.kvKeyPrefix && !process.env.KV_KEY_PREFIX && (process.env.KV_KEY_PREFIX = u.kvKeyPrefix);
893
+ let { kv: Re, service: ze } = await He({ store: N });
894
+ o.mark("store");
895
+ let We = M({
896
+ store: N,
897
+ sink: k.sink,
898
+ log: $
899
+ }), Ge = C({
900
+ store: N,
901
+ dialect: d
902
+ }), I = u?.plugins ?? [], Ke = process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, qe, Je;
903
+ d !== "memory" && (qe = Ee.make((await b(d)).makeSqlLayer(y())), Je = await qe.runPromise(ct.SqlClient));
904
+ let Ye = Ue({
905
+ coordinator: [
906
+ "postgres",
907
+ "mariadb",
908
+ "mysql",
909
+ "mssql"
910
+ ].includes(d) ? Be(N, Ke, $) : it,
911
+ replicaId: Ke,
912
+ log: $
913
+ }), Xe = [], Ze = {
914
+ ...Je ? { sql: Je } : {},
915
+ scheduleCoordinated: (e, t, n) => {
916
+ let r = Ye(e, t, n);
917
+ return Xe.push(r), r;
918
+ }
919
+ };
920
+ for (let e of I) e.bindDataStore?.(N, Ze);
921
+ let Qe = I.filter((e) => typeof e.onChangeEvent == "function");
922
+ if (Qe.length > 0) {
923
+ let e = N.changeScope ?? "local";
924
+ N.onChange((t) => {
925
+ let n = {
926
+ table: t.table,
927
+ op: t.op,
928
+ new: t.new ?? null,
929
+ old: t.old ?? null,
930
+ ...t.origin === void 0 ? {} : { origin: t.origin },
931
+ changeScope: e
932
+ };
933
+ for (let e of Qe) E.runFork(e.onChangeEvent(n).pipe(E.catchAllCause((t) => E.sync(() => $.warn(`plugin ${e.name} onChangeEvent failed`, { error: Te.pretty(t) })))));
934
+ });
935
+ }
936
+ let $e = oe({
937
+ plugins: I,
938
+ appName: u?.name ?? "voltro-api",
939
+ appType: "api",
940
+ voltroVersion: process.env.npm_package_version ?? "0.0.0",
941
+ log: $
942
+ });
943
+ I.length && await $e.activate(), o.mark("plugins");
944
+ let tt = await $e.gatherObservability(), rt = await le(N, u, d, {
945
+ info: (e, t) => process.stdout.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
946
+ warn: (e, t) => process.stderr.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
947
+ debug: () => {}
948
+ }), R = u?.apiKeys, at = (typeof R == "object" ? R.prefix : void 0) ?? "voltro_", z = R ? Ve(Pe(N), { prefix: at }) : void 0, ot = z ? [Ie(z, { prefix: at })] : [], B = me([...u?.auth?.strategies ?? [], ...ot], kt(u?.plugins ?? []), u?.auth?.anonymousTenantRequired ?? !1), V = [...u?.restRoutes ?? [], ...z ? j(z, (typeof R == "object" ? R.managementPath : void 0) ?? "/v1/api-keys") : []], H = u?.idempotency, lt = H ? {
949
+ store: Fe(N),
950
+ header: (typeof H == "object" ? H.header : void 0) ?? "Idempotency-Key",
951
+ ttlMs: (typeof H == "object" ? H.ttlMs : void 0) ?? 864e5
952
+ } : void 0, U = V.length > 0 ? jt(V, {
953
+ store: N,
954
+ resolveSubject: (e) => B({
955
+ headers: e,
956
+ clientId: -1
957
+ }),
958
+ ...lt ? { idempotency: lt } : {}
959
+ }) : [], dt = I.map((e) => e.services).filter((e) => e !== void 0), ft = D.mergeAll(h({
960
+ analyticsLayer: k.layer,
961
+ cacheService: P,
962
+ kvService: ze,
963
+ pluginServices: dt,
964
+ userLayers: u?.layers ?? []
965
+ }), re), pt = u?.scheduling ?? {}, mt = pt.trigger ?? "self", W = /* @__PURE__ */ new Set([
966
+ "postgres",
967
+ "mysql",
968
+ "mariadb",
969
+ "mssql"
970
+ ]), ht = pt.coordination ?? (W.has(d) ? "advisoryLock" : "single"), G = ht === "cluster" && W.has(d), gt = G ? "cluster" : ht === "advisoryLock" && W.has(d) ? "advisoryLock" : "single";
971
+ ht === "cluster" && !G && $.warn("scheduling.coordination=cluster needs a sql-backed store except sqlite — falling back to single"), ht === "advisoryLock" && !W.has(d) && $.warn("scheduling.coordination=advisoryLock needs a SQL store (the claim-row gate) — falling back to single");
972
+ let K, _t = T.workflows.length > 0 || T.workflowWorkers.length > 0 || T.eventTriggers.length > 0 || (ve?.outgoing.length ?? 0) > 0 || G, vt;
973
+ if (_t) {
974
+ if (d === "mssql") {
975
+ let e = await n(process.cwd());
976
+ e && $.warn(e);
977
+ }
978
+ let [{ WorkflowEngine: e }, { makeClusterCronLayer: t, workflowEngineLayer: r, resolveRunnerStorage: i }] = await Promise.all([import("@effect/workflow"), import("@voltro/workflow/cluster")]), a = G ? T.schedules.filter((e) => (e.trigger ?? mt) === "self").map((e) => t({
979
+ name: e.name,
980
+ cron: Ne(e),
981
+ execute: async () => {
982
+ await K?.fireFromCluster(e.name);
983
+ }
984
+ })) : [];
985
+ vt = d === "memory" ? e.layerMemory : await (async () => {
986
+ let e = await b(d), t = i({ sqliteFamily: e.id === "sqlite" || e.id === "turso" });
987
+ 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)" : "") : "")), r({
988
+ sqlClientLayer: e.makeSqlLayer(y()),
989
+ runnerStorage: t,
990
+ dialectId: e.id,
991
+ ...process.env.VOLTRO_WORKFLOW_RUNNER_PORT ? { runnerListenPort: Number(process.env.VOLTRO_WORKFLOW_RUNNER_PORT) } : {},
992
+ ...a.length > 0 ? { extraShardingLayers: a } : {}
993
+ });
994
+ })();
995
+ }
996
+ let q = _(I, pe()), yt = x.filter((e) => /\.subscribe\.tsx?$/.test(e)), bt = yt.length > 0 ? await p(yt, $) : [], J = x.filter((e) => /\.reaction\.tsx?$/.test(e)), xt = J.length > 0 ? await t(J, $) : [], St = x.filter((e) => /\.outbox\.tsx?$/.test(e)), Ct = St.length > 0 ? await ue(St, $) : [], Y = x.filter((e) => /\.aggregate\.tsx?$/.test(e)), X = Y.length > 0 ? await ne(Y, $) : [], Z = a();
997
+ if (X.length > 0 && d !== "memory") try {
998
+ Z = i((await b(d)).makeSqlLayer(y()));
999
+ } catch (e) {
1000
+ $.warn("aggregate: SQL storage init failed — falling back to in-process", { err: String(e) });
1001
+ }
1002
+ let wt = d === "memory" ? it : Be(N, `aggregate@${process.pid}`, $), Tt = [], At = [], Mt = x.filter((e) => ee.test(e));
1003
+ if (Mt.length > 0) {
1004
+ let t = $.child("agent"), n = x.filter((t) => e.test(t));
1005
+ n.length > 0 && await he(n, t);
1006
+ let r = await ce(Mt, t);
1007
+ for (let e of r.agents) for (let t of se(e)) (t.kind === "action" ? Tt : At).push({
1008
+ file: t.file,
1009
+ descriptor: t.descriptor,
1010
+ executor: t.executor
1011
+ });
1012
+ r.agents.length > 0 && t.info("synthesized agent routes", { agents: r.agents.map((e) => e.descriptor.name) });
1013
+ }
1014
+ o.mark("workflow");
1015
+ let Nt = await cn({
1016
+ bootTiming: o,
1017
+ discovered: {
1018
+ queries: [...T.queries, ...At],
1019
+ mutations: T.mutations,
1020
+ actions: [...T.actions, ...Tt],
1021
+ streams: T.streams,
1022
+ workflows: T.workflows,
1023
+ workflowWorkers: T.workflowWorkers,
1024
+ eventTriggers: T.eventTriggers,
1025
+ schedules: T.schedules,
1026
+ subscribers: bt,
1027
+ outboxHandlers: Ct,
1028
+ reactions: xt,
1029
+ aggregates: X,
1030
+ ...ve === void 0 ? {} : { webhooks: ve }
1031
+ },
1032
+ log: $,
1033
+ analytics: k.sink,
1034
+ aggregateStorage: Z,
1035
+ aggregateCoordinator: wt,
1036
+ store: N,
1037
+ kv: Re,
1038
+ cache: je,
1039
+ snapshotCache: F,
1040
+ schemaRegistry: ke,
1041
+ tenantScopedTables: T.tenantScopedTables,
1042
+ softDeleteScopedTables: T.softDeleteScopedTables,
1043
+ dataTransferSnapshot: Et(A),
1044
+ dataTransferDialect: d,
1045
+ tenantIsolation: (process.env.VOLTRO_TENANT_ISOLATION ?? u?.tenancy?.isolation) === "namespace" ? "namespace" : "shared-schema",
1046
+ resolveSubject: (e, t) => B({
1047
+ headers: e,
1048
+ clientId: t
1049
+ }),
1050
+ httpRoutes: [...I.flatMap((e) => e.httpRoutes ?? []), ...U],
1051
+ ...ft ? { baseLayer: ft } : {},
1052
+ ...vt === void 0 ? {} : { workflowEngineLayer: vt },
1053
+ scheduleDefaultTrigger: mt,
1054
+ scheduleCoordination: gt,
1055
+ scheduleArmSelf: !G,
1056
+ dormancy: process.env.VOLTRO_DORMANCY === "sleep" || process.env.VOLTRO_DORMANCY === "always-on" ? process.env.VOLTRO_DORMANCY : u?.dormancy ?? "always-on",
1057
+ scheduleReplicaId: process.env.HOSTNAME ?? `pid-${process.pid}`,
1058
+ ...q === void 0 ? {} : { scheduleFireInterceptor: q },
1059
+ onSchedulerReady: (e) => {
1060
+ K = e;
1061
+ },
1062
+ observability: tt,
1063
+ port: l,
1064
+ ...u?.transport?.wsPath ? { path: u.transport.wsPath } : {}
1065
+ });
1066
+ $.info(`API listening on :${l}`, {
1067
+ dialect: d,
1068
+ queries: T.queries.length,
1069
+ mutations: T.mutations.length,
1070
+ actions: T.actions.length,
1071
+ streams: T.streams.length,
1072
+ workflows: T.workflows.length,
1073
+ workflowWorkers: T.workflowWorkers.length,
1074
+ schedules: T.schedules.length,
1075
+ scheduleCoordination: gt
1076
+ }), o.finish($);
1077
+ let Pt = () => {
1078
+ for (let e of Xe) e.stop();
1079
+ We.detach(), Ge.stop(), Le(), qe?.dispose(), Promise.resolve($e.deactivate()).then(() => rt?.close()).then(() => k.dispose()).then(() => Nt.close()).then(() => N.close?.()).then(() => process.exit(0));
1080
+ };
1081
+ return process.on("SIGINT", Pt), process.on("SIGTERM", Pt), await new Promise(() => {}), 0;
1082
+ };
1083
+ //#endregion
1084
+ export { dn as n, on as r, fn as t };