@voltro/runtime 0.86.0 → 0.88.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 (184) hide show
  1. package/CHANGELOG.md +5484 -0
  2. package/README.md +43 -0
  3. package/THIRD-PARTY-NOTICES.md +1511 -276
  4. package/dist/aggregate.js +1 -2
  5. package/dist/aggregateExtrema.js +1 -2
  6. package/dist/aggregateIvm.js +1 -2
  7. package/dist/analyticsMirror.js +1 -2
  8. package/dist/analyticsSink.js +9 -16
  9. package/dist/apiKeyUsage.js +1 -2
  10. package/dist/apiKeys.js +83 -80
  11. package/dist/apiKeysWiring.js +1 -2
  12. package/dist/apiRoleBucketSampler.js +63 -0
  13. package/dist/apiRoleWorkloadHistory.js +55 -0
  14. package/dist/apiRoleWorkloadMetrics.js +77 -0
  15. package/dist/apiRoleWorkloadStorage.js +94 -0
  16. package/dist/approvalBuiltins.js +1 -2
  17. package/dist/approvals.js +68 -76
  18. package/dist/authMiddlewareLayer.js +8 -8
  19. package/dist/bindEvent.js +49 -30
  20. package/dist/boot-refusal.d.ts +10 -0
  21. package/dist/{bootRefusal.js → boot-refusal.js} +1 -2
  22. package/dist/bootListener.js +203 -47
  23. package/dist/bootStoreCodec.js +39 -39
  24. package/dist/businessRules.js +1 -2
  25. package/dist/changeClaimsTable.js +1 -2
  26. package/dist/circuitBreaker.js +1 -72
  27. package/dist/columnOnUpdate.js +1 -2
  28. package/dist/composeAnalytics.js +32 -12
  29. package/dist/computedQuery.js +1 -2
  30. package/dist/computedQueryCache.js +289 -0
  31. package/dist/connectionBuiltins.js +1 -2
  32. package/dist/connectionCredentials.js +1 -2
  33. package/dist/connectionState.js +1 -2
  34. package/dist/connectionVault.js +1 -2
  35. package/dist/connectionsFacade.js +33 -32
  36. package/dist/coordinatedSchedule.js +85 -80
  37. package/dist/crdtHistory.js +1 -2
  38. package/dist/crdtMerge.js +1 -2
  39. package/dist/crdtVersionsTable.js +1 -2
  40. package/dist/credentialBound.js +1 -2
  41. package/dist/crud.js +1 -2
  42. package/dist/dataStore.js +155 -123
  43. package/dist/dataloader.js +1 -2
  44. package/dist/declaredTablesGuard.js +3 -3
  45. package/dist/defineExecutor.js +1 -2
  46. package/dist/dependencyGraph.js +1 -2
  47. package/dist/devices.js +1 -2
  48. package/dist/devicesWiring.js +1 -2
  49. package/dist/dialectReplicationAdapter.js +1 -2
  50. package/dist/dispatcher.js +404 -330
  51. package/dist/effectStore.js +3 -4
  52. package/dist/engineClients.js +23 -0
  53. package/dist/eventBus.js +1 -2
  54. package/dist/eventPublish.js +1 -2
  55. package/dist/events.js +1 -2
  56. package/dist/expectation.js +1 -2
  57. package/dist/expectationEvaluator.js +2 -3
  58. package/dist/experiment.js +1 -2
  59. package/dist/experimentEvaluator.js +1 -2
  60. package/dist/externalizedTasks.js +20 -8
  61. package/dist/fieldCipher.js +110 -42
  62. package/dist/fieldKeyRegistry.js +294 -0
  63. package/dist/fieldKeyRekey.js +285 -0
  64. package/dist/fieldKeyScan.js +135 -0
  65. package/dist/fieldKeyring.js +76 -0
  66. package/dist/fingerprint.js +1 -2
  67. package/dist/finops.js +1 -2
  68. package/dist/finopsAccountant.js +1 -2
  69. package/dist/handlerBody.js +1 -2
  70. package/dist/healthProbes.js +1 -2
  71. package/dist/hot.d.ts +56 -0
  72. package/dist/hot.js +3 -0
  73. package/dist/hotDataStore.js +147 -0
  74. package/dist/hotDataStoreSnapshot.js +97 -0
  75. package/dist/hotDataStoreTables.js +17 -0
  76. package/dist/http-range.d.ts +53 -0
  77. package/dist/http-range.js +51 -0
  78. package/dist/httpClientSsrf.js +13 -39
  79. package/dist/httpClientTracing.js +13 -11
  80. package/dist/httpCompression.js +18 -19
  81. package/dist/httpInputStream.js +81 -0
  82. package/dist/httpKeepAlive.js +1 -2
  83. package/dist/httpRouteMounts.js +2 -2
  84. package/dist/idempotencyStore.js +93 -54
  85. package/dist/idleDetector.js +1 -2
  86. package/dist/index.d.ts +1185 -452
  87. package/dist/index.js +144 -134
  88. package/dist/insertRequiredColumns.js +1 -2
  89. package/dist/instanceMembership.js +1 -2
  90. package/dist/ivm.js +1 -2
  91. package/dist/kvDataStore.js +1 -2
  92. package/dist/kvFacade.js +24 -19
  93. package/dist/matcher.js +1 -2
  94. package/dist/memoryColumnDefaults.js +1 -2
  95. package/dist/memoryQueryJoins.js +17 -18
  96. package/dist/memorySetOperations.js +42 -0
  97. package/dist/metrics.js +39 -26
  98. package/dist/observability.js +2 -3
  99. package/dist/observedGraph.js +1 -2
  100. package/dist/originGuard.js +1 -2
  101. package/dist/outbox.js +2 -3
  102. package/dist/pluginRefRules.js +1 -2
  103. package/dist/policyGuardResolver.js +1 -2
  104. package/dist/preview.js +1 -2
  105. package/dist/projectedRows.js +1 -2
  106. package/dist/provenance.js +1 -2
  107. package/dist/rangeIndex.js +1 -2
  108. package/dist/rawReadScope.js +2 -3
  109. package/dist/reaction.js +1 -2
  110. package/dist/reactiveConfig.js +1 -2
  111. package/dist/readClassification.js +1 -2
  112. package/dist/readRecorder.js +36 -36
  113. package/dist/readScopePredicate.js +11 -0
  114. package/dist/rebac.js +1 -2
  115. package/dist/rebacInterceptor.js +1 -2
  116. package/dist/registry.js +1 -2
  117. package/dist/relevantFields.js +1 -2
  118. package/dist/replicaHealth.js +1 -2
  119. package/dist/replicaLocality.js +1 -2
  120. package/dist/replicaObservations.js +1 -2
  121. package/dist/replicaSelection.js +1 -2
  122. package/dist/replicatedDataStore.js +23 -6
  123. package/dist/requestLoader.js +1 -2
  124. package/dist/resumeCensus.js +1 -2
  125. package/dist/revalidation.js +1 -2
  126. package/dist/rowFilter.js +57 -41
  127. package/dist/rowStateBytes.js +1 -2
  128. package/dist/rpcBodyCap.js +1 -2
  129. package/dist/rpcConnections.js +9 -10
  130. package/dist/rpcDefectDiagnostics.js +1 -2
  131. package/dist/rpcServer.js +523 -451
  132. package/dist/rpcWorkloadAdmission.js +49 -0
  133. package/dist/runAsSystem.js +1 -2
  134. package/dist/rywPositionStore.js +83 -49
  135. package/dist/schedule.js +1 -2
  136. package/dist/scheduleBackfillRequests.js +1 -2
  137. package/dist/scheduleClaimsTable.js +1 -2
  138. package/dist/scheduleRunsTable.js +1 -2
  139. package/dist/scheduler.js +7 -3
  140. package/dist/schemaRegistry.js +1 -2
  141. package/dist/secretsResolver.js +1 -2
  142. package/dist/securityHeaders.js +1 -2
  143. package/dist/servePipeline.js +238 -154
  144. package/dist/serverOnlyAudit.js +1 -2
  145. package/dist/serverTracer.js +1 -2
  146. package/dist/serviceCredentials.js +1 -2
  147. package/dist/setReadScopes.js +27 -0
  148. package/dist/singleNodeOrchestrator.js +1 -2
  149. package/dist/snapshotValueCodec.js +45 -0
  150. package/dist/sourceResolution.js +35 -26
  151. package/dist/storeMiddleware.js +213 -212
  152. package/dist/storeQuery.js +1 -2
  153. package/dist/storeRead.js +1 -2
  154. package/dist/subscriber.js +2 -2
  155. package/dist/subscriptionOutbox.js +1 -2
  156. package/dist/subscriptionRegistry.js +1 -2
  157. package/dist/subscriptionResume.js +1 -2
  158. package/dist/subscriptionSocketMetrics.js +1 -2
  159. package/dist/systemSubject.js +1 -2
  160. package/dist/tenantScope.js +9 -22
  161. package/dist/tenantSelection.js +1 -2
  162. package/dist/timeline.js +1 -2
  163. package/dist/traceContext.js +1 -2
  164. package/dist/traceSink.js +1 -2
  165. package/dist/traceSpansTable.js +1 -2
  166. package/dist/traceparent.js +9 -21
  167. package/dist/transactionSubject.js +1 -2
  168. package/dist/trustedProxy.js +2 -3
  169. package/dist/undo.js +1 -2
  170. package/dist/undoBuiltins.js +1 -2
  171. package/dist/undoCapture.js +1 -2
  172. package/dist/undoLogTable.js +1 -2
  173. package/dist/upsertBinding.js +1 -2
  174. package/dist/wakeOrchestrator.js +1 -2
  175. package/dist/wakeRegistry.js +1 -2
  176. package/dist/wakeRouter.js +1 -2
  177. package/dist/wakeSupervisor.js +1 -2
  178. package/dist/wakeupsTable.js +1 -2
  179. package/dist/webSocketGatewayRuntime.js +112 -73
  180. package/dist/webhookVerification.js +1 -2
  181. package/dist/wireColumnStrip.js +1 -2
  182. package/dist/workflowReadBuiltins.js +1 -2
  183. package/dist/workflowRuntime.js +10 -11
  184. package/package.json +36 -17
@@ -1,76 +1,232 @@
1
1
  import { answerProbe as e, probeFor as t, resolveHealth as n } from "./healthProbes.js";
2
- import { createServer as r } from "node:http";
3
- //#region src/bootListener.ts
4
- var i = "no-store", a = "1", o = /* @__PURE__ */ new Set(["ready", "draining"]), s = async (s) => {
5
- let c = s.now ?? Date.now, l = {
2
+ import { trackEngineClient as r } from "./engineClients.js";
3
+ import { createServer as i } from "node:http";
4
+ // src/bootListener.ts
5
+ var a = "no-store", o = "1", s = 3e4, c = 3e5, l = 512, u = () => {
6
+ let e = process.env.VOLTRO_BOOT_HOLD_MS;
7
+ if (e === void 0 || e.trim() === "") return s;
8
+ let t = Number(e);
9
+ return !Number.isFinite(t) || t < 0 ? s : Math.min(c, Math.trunc(t));
10
+ }, d = `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="color-scheme" content="light dark"><meta http-equiv="refresh" content="${o}"><title>Starting…</title><style>body{margin:0;min-height:100vh;display:grid;place-items:center;font:16px/1.5 system-ui,sans-serif}</style></head><body><p role="status">Starting… this page reloads by itself.</p></body></html>`, f = (e) => (e.method === "GET" || e.method === "HEAD") && /\btext\/html\b/i.test(e.headers.accept ?? ""), p = (e, t) => {
11
+ if (t.headersSent || t.destroyed) return;
12
+ let n = f(e);
13
+ t.writeHead(503, {
14
+ "content-type": n ? "text/html; charset=utf-8" : "text/plain",
15
+ "cache-control": a,
16
+ "retry-after": o
17
+ }), t.end(e.method === "HEAD" ? void 0 : n ? d : "starting");
18
+ }, m = (e) => {
19
+ e.destroyed || e.end(`HTTP/1.1 503 Service Unavailable\r
20
+ Retry-After: ${o}\r\nCache-Control: no-store\r
21
+ Connection: close\r
22
+ Content-Length: 0\r
23
+ \r
24
+ `);
25
+ }, h = (e, t, n, i) => {
26
+ e !== void 0 && (r(t, n), e.upgrade(t, n, i));
27
+ }, g = /* @__PURE__ */ new Set(["ready", "draining"]), _ = /* @__PURE__ */ new Set([
28
+ "booting",
29
+ "migrating",
30
+ "ready"
31
+ ]), v = async (r) => {
32
+ let o = r.now ?? Date.now, s = {
6
33
  phase: "booting",
7
- startedAt: c()
8
- }, u, d, f = () => l.phase === "ready", p = () => o.has(l.phase), m = n(s.health, () => f()), h = s.health?.readiness === void 0 ? async () => f() && (d === void 0 || await d()) : m.readiness, g = {
9
- ...m,
10
- readiness: h
11
- }, _ = () => ({
12
- phase: l.phase,
13
- ready: f(),
14
- elapsedMs: c() - l.startedAt,
15
- ...l.tablesTotal === void 0 ? {} : { tablesTotal: l.tablesTotal },
16
- ...l.error === void 0 ? {} : { error: l.error }
17
- }), v = r((n, r) => {
18
- let o = n.url ?? "/", s = o.indexOf("?"), c = s === -1 ? o : o.slice(0, s), l = t(g, c);
19
- l === void 0 ? u !== void 0 && p() ? u.request(n, r) : (r.writeHead(503, {
20
- "content-type": "text/plain",
21
- "cache-control": i,
22
- "retry-after": a
23
- }), r.end("starting")) : e(g, l, _).then((e) => {
34
+ startedAt: o()
35
+ }, c, d, f = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y, b = Math.max(0, r.holdMs ?? u()), x = Math.max(0, r.maxHeld ?? l), S = /* @__PURE__ */ new Set(), C = !1, w = !1, T = () => s.phase === "ready", E = () => g.has(s.phase), D = () => c !== void 0 && E(), O = () => _.has(s.phase) || D(), k = n(r.health, () => T()), A = r.health?.readiness === void 0 ? async () => T() && (d === void 0 || await d()) : k.readiness, j = () => {
36
+ if ((f.size > 0 || y !== void 0) && !T()) return !1;
37
+ for (let e of f.values()) try {
38
+ if (e() !== !0) return !1;
39
+ } catch {
40
+ return !1;
41
+ }
42
+ return !0;
43
+ }, M = () => {
44
+ for (let e of v.values()) try {
45
+ if (e() !== !0) return !1;
46
+ } catch {
47
+ return !1;
48
+ }
49
+ return !0;
50
+ }, N = {
51
+ ...k,
52
+ readiness: async () => j() && await A() && j(),
53
+ liveness: async () => M() && await k.liveness() && M()
54
+ }, P = () => ({
55
+ phase: s.phase,
56
+ ready: T(),
57
+ elapsedMs: o() - s.startedAt,
58
+ ...s.tablesTotal === void 0 ? {} : { tablesTotal: s.tablesTotal },
59
+ ...s.error === void 0 ? {} : { error: s.error },
60
+ ...S.size > 0 ? { held: S.size } : {}
61
+ }), F = i((n, r) => {
62
+ let i = n.url ?? "/", o = i.indexOf("?"), l = o === -1 ? i : i.slice(0, o);
63
+ if (l === "/_voltro/health" && (y !== void 0 || f.size > 0)) {
64
+ if (n.method !== "GET" && n.method !== "HEAD") {
65
+ r.writeHead(405, {
66
+ allow: "GET, HEAD",
67
+ "cache-control": a
68
+ }), r.end();
69
+ return;
70
+ }
71
+ e(N, "readiness", P).then((e) => {
72
+ let t = e.status === 200 && T() && j();
73
+ r.writeHead(t ? 200 : 503, {
74
+ "content-type": "application/json",
75
+ "cache-control": a
76
+ }), r.end(n.method === "HEAD" ? void 0 : JSON.stringify({
77
+ ...y,
78
+ phase: s.phase,
79
+ ready: t
80
+ }));
81
+ });
82
+ return;
83
+ }
84
+ let u = t(N, l);
85
+ u === void 0 ? D() && S.size === 0 ? c?.request(n, r) : I({
86
+ attach: (e) => {
87
+ r.once("close", e);
88
+ },
89
+ detach: (e) => {
90
+ r.removeListener("close", e);
91
+ },
92
+ forward: (e) => {
93
+ e.request(n, r);
94
+ },
95
+ refuse: () => {
96
+ p(n, r);
97
+ }
98
+ }) : e(N, u, P).then((e) => {
24
99
  r.writeHead(e.status, {
25
100
  "content-type": e.contentType,
26
- "cache-control": i
101
+ "cache-control": a
27
102
  }), r.end(e.body);
28
103
  });
29
104
  });
30
- v.on("upgrade", (e, t, n) => {
31
- u !== void 0 && p() ? u.upgrade(e, t, n) : t.end(`HTTP/1.1 503 Service Unavailable\r
32
- Retry-After: ${a}\r\nCache-Control: no-store\r
33
- Connection: close\r
34
- Content-Length: 0\r
35
- \r
36
- `);
37
- }), await new Promise((e, t) => {
105
+ F.on("upgrade", (e, t, n) => {
106
+ if (D() && S.size === 0) {
107
+ h(c, e, t, n);
108
+ return;
109
+ }
110
+ let r = () => {};
111
+ I({
112
+ attach: (e) => {
113
+ t.on("error", r), t.once("close", e);
114
+ },
115
+ detach: (e) => {
116
+ t.removeListener("error", r), t.removeListener("close", e);
117
+ },
118
+ forward: (r) => {
119
+ h(r, e, t, n);
120
+ },
121
+ refuse: () => {
122
+ m(t);
123
+ }
124
+ });
125
+ });
126
+ function I(e) {
127
+ let t = D();
128
+ if (!t && (!O() || b === 0 || S.size >= x)) {
129
+ e.refuse();
130
+ return;
131
+ }
132
+ let n, i = () => {
133
+ a();
134
+ }, a = () => {
135
+ n !== void 0 && clearTimeout(n), e.detach(i), S.delete(o);
136
+ }, o = {
137
+ forward: e.forward,
138
+ refuse: e.refuse,
139
+ release: a
140
+ };
141
+ t || (n = setTimeout(() => {
142
+ a(), C || (C = !0, r.log?.info("boot still running after the hold window — answering 503 to waiting requests", {
143
+ holdMs: b,
144
+ phase: s.phase
145
+ })), e.refuse();
146
+ }, b), n.unref()), e.attach(i), S.add(o), t && L();
147
+ }
148
+ function L() {
149
+ w || S.size === 0 || (w = !0, setImmediate(() => {
150
+ w = !1, R();
151
+ }));
152
+ }
153
+ function R() {
154
+ if (D()) {
155
+ let e = c;
156
+ if (e === void 0) return;
157
+ let t = S.size;
158
+ for (let t of [...S]) t.release(), t.forward(e);
159
+ t > 0 && r.log?.info("handed requests held during boot to the app", { count: t });
160
+ } else if (!O()) for (let e of [...S]) e.release(), e.refuse();
161
+ }
162
+ await new Promise((e, t) => {
38
163
  let n = (e) => {
39
164
  t(e);
40
165
  };
41
- v.once("error", n), v.listen(s.host === void 0 ? { port: s.port } : {
42
- port: s.port,
43
- host: s.host
166
+ F.once("error", n), F.listen(r.host === void 0 ? { port: r.port } : {
167
+ port: r.port,
168
+ host: r.host
44
169
  }, () => {
45
- v.removeListener("error", n), e();
170
+ F.removeListener("error", n), e();
46
171
  });
47
172
  });
48
- let y = v.address()?.port ?? s.port;
49
- return s.log?.info("listening early — probes answer on the app port from here on", { port: y }), {
50
- server: v,
51
- port: y,
173
+ let z = F.address()?.port ?? r.port;
174
+ return r.log?.info("listening early — probes answer on the app port from here on", { port: z }), {
175
+ server: F,
176
+ port: z,
52
177
  get state() {
53
- return l;
178
+ return s;
179
+ },
180
+ get held() {
181
+ return S.size;
54
182
  },
55
183
  set: (e) => {
56
- l = {
57
- ...l,
184
+ s = {
185
+ ...s,
58
186
  ...e
59
- };
187
+ }, L();
60
188
  },
61
- isReady: f,
189
+ isReady: T,
62
190
  delegate: (e) => {
63
- u = e;
191
+ c = e, L();
64
192
  },
65
193
  setDependencyPing: (e) => {
66
194
  d = e;
67
195
  },
196
+ setRoleHealth: (e) => {
197
+ let t = (e) => {
198
+ if (!Array.isArray(e) || e.length === 0 || e.length > 64 || e.some((e) => typeof e != "string" || !/^[a-z][a-z0-9._-]{0,63}$/.test(e)) || new Set(e).size !== e.length) throw Error("Invalid role health identity");
199
+ return Object.freeze([...e]);
200
+ };
201
+ y = Object.freeze({
202
+ roles: t(e.roles),
203
+ workloads: t(e.workloads)
204
+ });
205
+ },
206
+ addReadinessGate: (e, t) => {
207
+ if (!/^[a-z][a-z0-9._-]{0,63}$/.test(e) || typeof t != "function") throw Error("Invalid readiness gate");
208
+ if (f.has(e)) throw Error("Readiness gate is already registered");
209
+ f.set(e, t);
210
+ let n = !1;
211
+ return () => {
212
+ n || (n = !0, f.get(e) === t && f.delete(e));
213
+ };
214
+ },
215
+ addLivenessGate: (e, t) => {
216
+ if (!/^[a-z][a-z0-9._-]{0,63}$/.test(e) || typeof t != "function") throw Error("Invalid liveness gate");
217
+ if (v.has(e)) throw Error("Liveness gate is already registered");
218
+ v.set(e, t);
219
+ let n = !1;
220
+ return () => {
221
+ n || (n = !0, v.get(e) === t && v.delete(e));
222
+ };
223
+ },
68
224
  close: () => new Promise((e) => {
69
- v.listening ? (v.closeAllConnections(), v.close(() => {
225
+ for (let e of [...S]) e.release(), e.refuse();
226
+ F.listening ? (F.closeAllConnections(), F.close(() => {
70
227
  e();
71
228
  })) : e();
72
229
  })
73
230
  };
74
231
  };
75
- //#endregion
76
- export { s as bindBootListener };
232
+ export { v as bindBootListener, u as bootHoldMsFromEnv };
@@ -1,70 +1,70 @@
1
1
  import { getFieldCipher as e } from "./fieldCipher.js";
2
2
  import { upsertDestinationId as t } from "./upsertBinding.js";
3
- import { decryptFieldsOnRead as n, deserializeArraysOnRead as r, encryptFieldsForWrite as i, encryptFieldsForWriteBatch as a, encryptedColumnsOf as o, getTable as s, jsonPatchAssignments as c, serializeArraysForWrite as l, upsertUpdateValues as u } from "@voltro/database";
4
- import { createLogger as d } from "@voltro/logger";
5
- //#region src/bootStoreCodec.ts
6
- var f = d({ scope: "store.fieldEncryption" }), p = (d, m) => {
7
- let h = m, g = process.env.VOLTRO_FIELD_DECRYPT_ON_ERROR === "null" ? "null" : "throw", _ = /* @__PURE__ */ new Set(), v = (e) => {
3
+ import { decryptFieldsOnRead as n, deserializeArraysOnRead as r, encryptFieldsForWrite as i, encryptFieldsForWriteBatch as a, encryptedColumnsOf as o, getTable as s, jsonPatchAssignments as c, refuseIdChangeOfSealedRow as l, serializeArraysForWrite as u, upsertUpdateValues as d } from "@voltro/database";
4
+ import { createLogger as f } from "@voltro/logger";
5
+ // src/bootStoreCodec.ts
6
+ var p = f({ scope: "store.fieldEncryption" }), m = (f, h) => {
7
+ let g = h, _ = process.env.VOLTRO_FIELD_DECRYPT_ON_ERROR === "null" ? "null" : "throw", v = /* @__PURE__ */ new Set(), y = (e) => {
8
8
  let t = `${e.table}.${e.column}`;
9
- _.has(t) || (_.add(t), f.warn("encrypted column degraded to null — could not decrypt with the active key", {
9
+ v.has(t) || (v.add(t), p.warn("encrypted column degraded to null — could not decrypt with the active key", {
10
10
  table: e.table,
11
11
  column: e.column,
12
12
  reason: e.reason,
13
13
  hint: "VOLTRO_FIELD_DECRYPT_ON_ERROR=null is set — this row was likely encrypted under a different key"
14
14
  }));
15
- }, y = (t, n, r) => {
16
- let a = s(t), o = h ? l(n, a, h) : n;
15
+ }, b = (t, n, r) => {
16
+ let a = s(t), o = g ? u(n, a, g) : n;
17
17
  return i(o, a, e(), r);
18
- }, b = (t, i, a) => {
18
+ }, x = (t, i, a) => {
19
19
  let o = s(t), c = n(i, o, e(), {
20
- onError: g,
21
- ...g === "null" ? { warn: v } : {},
20
+ onError: _,
21
+ ..._ === "null" ? { warn: y } : {},
22
22
  ...a === void 0 ? {} : { rowId: a }
23
23
  });
24
- return h ? r(c, o, h) : c;
25
- }, x = (e, t, n) => t === null ? null : b(e, [t], n)[0];
24
+ return g ? r(c, o, g) : c;
25
+ }, S = (e, t, n) => t === null ? null : x(e, [t], n)[0];
26
26
  return {
27
- delete: (e, t) => d.delete(e, t),
28
- deleteMany: (e, t) => d.deleteMany(e, t),
29
- onChange: (e) => d.onChange(e),
27
+ delete: (e, t) => f.delete(e, t),
28
+ deleteMany: (e, t) => f.deleteMany(e, t),
29
+ onChange: (e) => f.onChange(e),
30
30
  injectExternalChange: (e) => {
31
- d.injectExternalChange(e);
31
+ f.injectExternalChange(e);
32
32
  },
33
- ...d.changeScope === void 0 ? {} : { changeScope: d.changeScope },
34
- ...d.withNamespace === void 0 ? {} : { withNamespace: (e) => p(d.withNamespace(e), m) },
35
- ...d.raw === void 0 ? {} : { raw: ((...e) => d.raw(...e)) },
36
- ...d.close === void 0 ? {} : { close: (e) => d.close(e) },
37
- ...d.ping === void 0 ? {} : { ping: () => d.ping() },
38
- query: async (e) => b(e.table, await d.query(e)),
39
- insert: async (e, t) => x(e, await d.insert(e, y(e, t))),
40
- insertMany: async (t, n) => {
41
- let r = s(t), i = h ? n.map((e) => l(e, r, h)) : n, o = a(i, r, e());
42
- return b(t, await d.insertMany(t, o));
33
+ ...f.changeScope === void 0 ? {} : { changeScope: f.changeScope },
34
+ ...f.withNamespace === void 0 ? {} : { withNamespace: (e) => m(f.withNamespace(e), h) },
35
+ ...f.raw === void 0 ? {} : { raw: ((...e) => f.raw(...e)) },
36
+ ...f.close === void 0 ? {} : { close: (e) => f.close(e) },
37
+ ...f.ping === void 0 ? {} : { ping: () => f.ping() },
38
+ query: async (e) => x(e.table, await f.query(e)),
39
+ ...f.integrityQuery === void 0 ? {} : { integrityQuery: async (e) => x(e.table, await f.integrityQuery(e)) },
40
+ insert: async (e, t) => S(e, await f.insert(e, b(e, t))),
41
+ insertMany: async (t, n, r) => {
42
+ let i = s(t), o = g ? n.map((e) => u(e, i, g)) : n, c = a(o, i, e());
43
+ return x(t, await f.insertMany(t, c, r));
43
44
  },
44
- update: async (e, t, n) => x(e, await d.update(e, t, y(e, n, t)), t),
45
+ update: async (e, t, n) => S(e, await f.update(e, t, (l(n, s(e), t), b(e, n, t))), t),
45
46
  updateMany: async (e, t, n) => {
46
47
  let r = s(e), i = (r === void 0 ? [] : o(r)).filter((e) => t[e] !== void 0 && t[e] !== null);
47
48
  if (i.length > 0) throw Error(`updateMany on the boot store cannot write the .encrypted() column(s) ${i.join(", ")} on "${e}": an encrypted value is bound to its row and a set-based write has no row. Write them through the request-scoped store, or key the write with update(table, id, patch).`);
48
- return d.updateMany(e, y(e, t), n);
49
+ return f.updateMany(e, b(e, t), n);
49
50
  },
50
51
  upsert: async (e, n, r) => {
51
- let i = u(r), a = await t(d, e, n, r.conflictColumns);
52
- return x(e, await d.upsert(e, y(e, n, a), {
52
+ let i = d(r), a = await t(f, e, n, r.conflictColumns);
53
+ return S(e, await f.upsert(e, b(e, n, a), {
53
54
  ...r,
54
- ...r.updateValues === void 0 ? {} : { updateValues: y(e, i, a) }
55
+ ...r.updateValues === void 0 ? {} : { updateValues: b(e, i, a) }
55
56
  }), a);
56
57
  },
57
- insertIgnore: async (e, t, n) => x(e, await d.insertIgnore(e, y(e, t), n)),
58
+ insertIgnore: async (e, t, n) => S(e, await f.insertIgnore(e, b(e, t), n)),
58
59
  insertIgnoreWithOutcome: async (e, t, n) => {
59
- let r = await d.insertIgnoreWithOutcome(e, y(e, t), n);
60
+ let r = await f.insertIgnoreWithOutcome(e, b(e, t), n);
60
61
  return {
61
- row: x(e, r.row),
62
+ row: S(e, r.row),
62
63
  outcome: r.outcome
63
64
  };
64
65
  },
65
- patchJson: async (e, t, n, r, i) => x(e, await d.patchJson(e, t, n, r, y(e, c(t, n, i), t)), t),
66
- transactional: (e) => d.transactional((t) => e(p(t, m)))
66
+ patchJson: async (e, t, n, r, i) => S(e, await f.patchJson(e, t, n, r, b(e, c(t, n, i), t)), t),
67
+ transactional: (e) => f.transactional((t) => e(m(t, h)))
67
68
  };
68
69
  };
69
- //#endregion
70
- export { p as wrapStoreWithBootCodec };
70
+ export { m as wrapStoreWithBootCodec };
@@ -1,7 +1,7 @@
1
1
  import { getTable as e } from "@voltro/database";
2
2
  import { BusinessRuleViolation as t } from "@voltro/protocol";
3
3
  import { log as n } from "@voltro/logger";
4
- //#region src/businessRules.ts
4
+ // src/businessRules.ts
5
5
  var r = (e) => e.startsWith("_voltro"), i = (e) => {
6
6
  let t = e?.id;
7
7
  return typeof t == "string" ? t : void 0;
@@ -63,5 +63,4 @@ var r = (e) => e.startsWith("_voltro"), i = (e) => {
63
63
  }
64
64
  }
65
65
  };
66
- //#endregion
67
66
  export { s as evaluateTouchedRules, a as makeRuleCapture };
@@ -1,5 +1,5 @@
1
1
  import { id as e, integer as t, table as n, text as r, timestamp as i } from "@voltro/database";
2
- //#region src/changeClaimsTable.ts
2
+ // src/changeClaimsTable.ts
3
3
  var a = n("_voltro_change_claims", {
4
4
  id: e({ prefix: "chclaim" }),
5
5
  scope: r(),
@@ -8,5 +8,4 @@ var a = n("_voltro_change_claims", {
8
8
  claimedAt: i(),
9
9
  nextSlot: t().default(0)
10
10
  }).unique(["scope", "key"]).index(["claimedAt"]);
11
- //#endregion
12
11
  export { a as _voltroChangeClaimsTable };
@@ -1,72 +1 @@
1
- import { Cause as e, Clock as t, Duration as n, Effect as r, Ref as i, Schema as a } from "effect";
2
- //#region src/circuitBreaker.ts
3
- var o = class extends a.TaggedError()("CircuitOpen", {
4
- name: a.String,
5
- retryAfterMs: a.Number
6
- }) {}, s = {
7
- tag: "closed",
8
- failureCount: 0,
9
- halfOpenSuccesses: 0,
10
- openedAt: 0
11
- }, c = { make: (a) => r.gen(function* () {
12
- let c = a.name ?? "circuit", l = n.toMillis(n.fromInputUnsafe(a.resetTimeout)), u = a.halfOpenSuccessThreshold ?? 1, d = a.isFailure ?? (() => !0), f = yield* i.make(s), p = r.gen(function* () {
13
- let e = yield* i.get(f);
14
- if (e.tag === "half-open") {
15
- let t = e.halfOpenSuccesses + 1;
16
- yield* i.set(f, t >= u ? s : {
17
- ...e,
18
- halfOpenSuccesses: t
19
- });
20
- } else e.failureCount !== 0 && (yield* i.set(f, s));
21
- }), m = r.gen(function* () {
22
- let e = yield* t.currentTimeMillis, n = yield* i.get(f);
23
- if (n.tag === "half-open" || n.tag === "open") {
24
- yield* i.set(f, {
25
- tag: "open",
26
- failureCount: a.failureThreshold,
27
- halfOpenSuccesses: 0,
28
- openedAt: e
29
- });
30
- return;
31
- }
32
- let r = n.failureCount + 1;
33
- yield* i.set(f, r >= a.failureThreshold ? {
34
- tag: "open",
35
- failureCount: r,
36
- halfOpenSuccesses: 0,
37
- openedAt: e
38
- } : {
39
- ...n,
40
- failureCount: r
41
- });
42
- }), h = r.gen(function* () {
43
- let e = yield* i.get(f);
44
- if (e.tag !== "open") return null;
45
- let n = (yield* t.currentTimeMillis) - e.openedAt;
46
- return n >= l ? (yield* i.set(f, {
47
- tag: "half-open",
48
- failureCount: 0,
49
- halfOpenSuccesses: 0,
50
- openedAt: e.openedAt
51
- }), null) : l - n;
52
- }), g = (t) => r.gen(function* () {
53
- let n = yield* h;
54
- return n === null ? yield* t.pipe(r.tap(() => p), r.tapCause((t) => {
55
- if (e.hasInterruptsOnly(t)) return r.void;
56
- let n = e.findErrorOption(t), i = n._tag === "Some" ? n.value : void 0;
57
- return d(i) ? m : r.void;
58
- })) : yield* r.fail(new o({
59
- name: c,
60
- retryAfterMs: n
61
- }));
62
- }), _ = ((e) => g(e));
63
- return Object.defineProperty(_, "state", {
64
- value: i.get(f).pipe(r.map((e) => e.tag)),
65
- enumerable: !0
66
- }), Object.defineProperty(_, "reset", {
67
- value: i.set(f, s),
68
- enumerable: !0
69
- }), _;
70
- }) };
71
- //#endregion
72
- export { c as CircuitBreaker, o as CircuitOpen };
1
+ export { CircuitBreaker, CircuitOpen } from "@voltro/shared";
@@ -1,4 +1,4 @@
1
- //#region src/columnOnUpdate.ts
1
+ // src/columnOnUpdate.ts
2
2
  var e = (e) => {
3
3
  if (!(e.length < 32 || Object.getPrototypeOf(e) !== Array.prototype || Object.getOwnPropertySymbols(e).length > 0 || Object.hasOwn(e, "includes"))) {
4
4
  for (let t = 0; t < e.length; t++) {
@@ -19,5 +19,4 @@ var e = (e) => {
19
19
  }
20
20
  return o;
21
21
  };
22
- //#endregion
23
22
  export { t as applyColumnOnUpdate };
@@ -1,6 +1,6 @@
1
1
  import { AnalyticsCapabilityNotSupported as e } from "./analyticsSink.js";
2
2
  import { Effect as t } from "effect";
3
- //#region src/composeAnalytics.ts
3
+ // src/composeAnalytics.ts
4
4
  var n = "noop", r = () => {
5
5
  let r = (r) => t.fail(new e({
6
6
  provider: n,
@@ -86,23 +86,43 @@ var n = "noop", r = () => {
86
86
  ...d === void 0 ? {} : { mirror: d }
87
87
  };
88
88
  }, a = (e) => {
89
- let n = e.filter((e) => e.dispose !== void 0);
90
- return {
89
+ let n = [...e], r, a, o = () => t.suspend(() => t.forEach([...r ?? []].reverse(), (e) => e.released ? t.void : (e.released = !0, e.spec.dispose === void 0 ? t.void : t.suspend(() => e.spec.dispose(e.sink)).pipe(t.catchCause(() => t.logWarning("analytics member teardown failed")))), {
90
+ concurrency: 1,
91
+ discard: !0
92
+ })), s = () => t.promise(() => a ??= t.runPromise(o())), c = (e) => {
93
+ if (r !== void 0) throw Error("An analytics composite belongs to one app owner");
94
+ r = [];
95
+ for (let t of n) {
96
+ if (t.sql === "required" && e === void 0) throw Error("Analytics member requires SQL");
97
+ let n = t.sql === "required" ? t.build(e) : t.build();
98
+ r.push({
99
+ spec: t,
100
+ sink: n,
101
+ released: !1
102
+ });
103
+ }
104
+ return i(r.map((e) => e.sink));
105
+ }, l = {
91
106
  kind: "compose",
92
- build: (t) => i(e.map((e) => e.build(t))),
93
- tables: e.flatMap((e) => e.tables ?? []),
94
- initialize: (n) => t.forEach(e, (e) => e.initialize ? e.initialize(n) : t.void, {
107
+ tables: n.flatMap((e) => e.tables ?? []),
108
+ initialize: () => t.suspend(() => r === void 0 ? t.die(/* @__PURE__ */ Error("Build analytics members before initialization")) : t.forEach(r, (e) => e.spec.initialize === void 0 ? t.void : t.suspend(() => e.spec.initialize(e.sink)), {
95
109
  concurrency: 1,
96
110
  discard: !0
97
- }),
98
- ...n.length > 0 ? { dispose: (e) => t.forEach(n, (t) => t.dispose(e), {
99
- concurrency: 1,
100
- discard: !0
101
- }) } : {}
111
+ }).pipe(t.onError(s))),
112
+ ...n.some((e) => e.dispose !== void 0) ? { dispose: s } : {}
113
+ };
114
+ return n.some((e) => e.sql === "required") ? {
115
+ ...l,
116
+ sql: "required",
117
+ build: (e) => c(e)
118
+ } : {
119
+ ...l,
120
+ sql: "none",
121
+ build: () => c()
102
122
  };
103
123
  }, o = {
104
124
  kind: "noop",
125
+ sql: "none",
105
126
  build: () => r()
106
127
  };
107
- //#endregion
108
128
  export { n as NOOP_ANALYTICS_PROVIDER, a as composeAnalytics, i as composeAnalyticsSinks, r as noopAnalytics, o as noopAnalyticsSpec };
@@ -1,4 +1,3 @@
1
- //#region src/computedQuery.ts
1
+ // src/computedQuery.ts
2
2
  var e = (e) => typeof e == "object" && !!e && e.__voltroComputed === !0;
3
- //#endregion
4
3
  export { e as isComputedQuery };