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