@voltro/runtime 0.86.0 → 0.87.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.
- package/CHANGELOG.md +5321 -0
- package/README.md +43 -0
- package/THIRD-PARTY-NOTICES.md +860 -221
- package/dist/analyticsSink.js +8 -14
- package/dist/apiKeys.js +82 -78
- package/dist/apiRoleBucketSampler.js +64 -0
- package/dist/apiRoleWorkloadHistory.js +56 -0
- package/dist/apiRoleWorkloadMetrics.js +78 -0
- package/dist/apiRoleWorkloadStorage.js +95 -0
- package/dist/approvals.js +67 -74
- package/dist/authMiddlewareLayer.js +7 -6
- package/dist/bindEvent.js +48 -28
- package/dist/bootListener.js +106 -39
- package/dist/bootStoreCodec.js +38 -37
- package/dist/circuitBreaker.js +1 -72
- package/dist/composeAnalytics.js +31 -10
- package/dist/computedQueryCache.js +231 -0
- package/dist/connectionsFacade.js +32 -30
- package/dist/coordinatedSchedule.js +84 -78
- package/dist/dataStore.js +154 -121
- package/dist/declaredTablesGuard.js +2 -1
- package/dist/dispatcher.js +403 -328
- package/dist/effectStore.js +2 -2
- package/dist/engineClients.js +24 -0
- package/dist/externalizedTasks.js +19 -6
- package/dist/fieldCipher.js +109 -40
- package/dist/fieldKeyRegistry.js +295 -0
- package/dist/fieldKeyRekey.js +286 -0
- package/dist/fieldKeyScan.js +136 -0
- package/dist/fieldKeyring.js +77 -0
- package/dist/hot.d.ts +56 -0
- package/dist/hot.js +3 -0
- package/dist/hotDataStore.js +148 -0
- package/dist/hotDataStoreSnapshot.js +98 -0
- package/dist/hotDataStoreTables.js +18 -0
- package/dist/http-range.d.ts +53 -0
- package/dist/http-range.js +52 -0
- package/dist/httpClientSsrf.js +12 -37
- package/dist/httpClientTracing.js +12 -9
- package/dist/httpCompression.js +17 -17
- package/dist/httpInputStream.js +82 -0
- package/dist/httpRouteMounts.js +1 -0
- package/dist/idempotencyStore.js +92 -52
- package/dist/index.d.ts +1164 -451
- package/dist/index.js +143 -132
- package/dist/kvFacade.js +23 -17
- package/dist/memoryQueryJoins.js +16 -16
- package/dist/memorySetOperations.js +43 -0
- package/dist/metrics.js +38 -24
- package/dist/outbox.js +1 -1
- package/dist/readRecorder.js +35 -34
- package/dist/readScopePredicate.js +12 -0
- package/dist/replicatedDataStore.js +22 -4
- package/dist/rowFilter.js +56 -39
- package/dist/rpcConnections.js +8 -8
- package/dist/rpcServer.js +522 -449
- package/dist/rpcWorkloadAdmission.js +50 -0
- package/dist/rywPositionStore.js +82 -47
- package/dist/scheduler.js +6 -1
- package/dist/servePipeline.js +215 -146
- package/dist/setReadScopes.js +28 -0
- package/dist/snapshotValueCodec.js +46 -0
- package/dist/sourceResolution.js +34 -24
- package/dist/storeMiddleware.js +211 -209
- package/dist/subscriber.js +1 -0
- package/dist/tenantScope.js +8 -20
- package/dist/traceparent.js +8 -19
- package/dist/webSocketGatewayRuntime.js +111 -71
- package/dist/workflowRuntime.js +9 -9
- package/package.json +19 -7
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { decimalEqualityKey as e, getTable as t } from "@voltro/database";
|
|
2
|
+
//#region src/memorySetOperations.ts
|
|
3
|
+
var n = (e, t = !1) => e == null ? ["null"] : e instanceof Date ? t ? ["string", e.toISOString()] : ["date", e.getTime()] : typeof e == "bigint" ? ["bigint", e.toString()] : typeof e == "number" ? t && !Number.isFinite(e) ? ["null"] : ["number", Number.isFinite(e) ? e : String(e)] : typeof e == "object" ? e instanceof ArrayBuffer ? ["bytes", [...new Uint8Array(e)]] : ArrayBuffer.isView(e) ? ["bytes", [...new Uint8Array(e.buffer, e.byteOffset, e.byteLength)]] : Array.isArray(e) ? ["array", e.map((e) => n(e, t))] : ["object", Object.entries(e).filter(([, e]) => e !== void 0).sort(([e], [t]) => e < t ? -1 : +(e > t)).map(([e, r]) => [e, n(r, t)])] : [typeof e, e], r = (t, r, i) => JSON.stringify(r.map((r) => {
|
|
4
|
+
let a = t[r], o = a == null || i[r]?.type !== "decimal" ? null : e(a);
|
|
5
|
+
return o === null ? n(a, i[r]?.type === "json") : ["decimal", o];
|
|
6
|
+
})), i = (e, n) => {
|
|
7
|
+
if (e.setOp) return i(e.setOp.queries[0], n);
|
|
8
|
+
let r = (e.sourceTable ?? t(e.table))?.fields ?? {}, a = { ...r }, o = e.alias ?? e.table;
|
|
9
|
+
for (let [e, t] of Object.entries(r)) a[`${o}.${e}`] = t;
|
|
10
|
+
for (let n of e.joins ?? []) {
|
|
11
|
+
let e = (n.sourceTable ?? t(n.table))?.fields ?? {};
|
|
12
|
+
for (let [t, r] of Object.entries(e)) a[`${n.alias}.${t}`] = r;
|
|
13
|
+
}
|
|
14
|
+
if (e.aggregations?.length) return Object.fromEntries(e.aggregations.map((e) => {
|
|
15
|
+
let t = e.column === void 0 ? { type: "unknown" } : a[e.column] ?? { type: "unknown" }, n = e.op === "count" || e.op === "count-distinct" || e.op === "window-row-number" || e.op === "window-rank" || e.op === "window-dense-rank", r = e.op === "avg" || e.op === "window-avg-over";
|
|
16
|
+
return [e.alias, n ? { type: "integer" } : r && t.type !== "decimal" ? { type: "real" } : t];
|
|
17
|
+
}));
|
|
18
|
+
if (e.joinedProjection) return Object.fromEntries(e.joinedProjection.map((e) => [e.outputKey, a[e.source] ?? { type: "unknown" }]));
|
|
19
|
+
let s = e.projection ?? (Object.keys(r).length > 0 ? Object.keys(r) : [...new Set(n.flatMap((e) => Object.keys(e)))]);
|
|
20
|
+
return Object.fromEntries(s.map((e) => [e, a[e] ?? { type: "unknown" }]));
|
|
21
|
+
}, a = (e, t) => {
|
|
22
|
+
let n = e.setOp;
|
|
23
|
+
if (!n || n.queries.length < 2) throw Error("A set operation requires at least two inputs");
|
|
24
|
+
let a = n.queries.map((e) => ({
|
|
25
|
+
rows: t(e),
|
|
26
|
+
query: e
|
|
27
|
+
})), o = a.map((e) => i(e.query, e.rows)), s = o[0], c = Object.keys(s), l = a.map((e, t) => {
|
|
28
|
+
let n = Object.keys(o[t]);
|
|
29
|
+
if (n.length !== c.length) throw Error("Set operation inputs must have the same column count");
|
|
30
|
+
return e.rows.map((e) => Object.fromEntries(c.map((t, r) => [t, e[n[r]] ?? null])));
|
|
31
|
+
});
|
|
32
|
+
if (n.kind === "union-all") return l.flat();
|
|
33
|
+
let u = (e) => new Map(e.map((e) => [r(e, c, s), e]));
|
|
34
|
+
if (n.kind === "union") return [...u(l.flat()).values()];
|
|
35
|
+
let d = u(l[0]);
|
|
36
|
+
for (let e of l.slice(1)) {
|
|
37
|
+
let t = u(e);
|
|
38
|
+
for (let e of d.keys()) (n.kind === "intersect" ? !t.has(e) : t.has(e)) && d.delete(e);
|
|
39
|
+
}
|
|
40
|
+
return [...d.values()];
|
|
41
|
+
};
|
|
42
|
+
//#endregion
|
|
43
|
+
export { i as memoryOutputColumns, r as memoryRowKey, a as memorySetRows };
|
package/dist/metrics.js
CHANGED
|
@@ -17,7 +17,7 @@ var r = n.exponentialBoundaries({
|
|
|
17
17
|
}), u = n.counter("voltro_plugin_hook_errors_total", { description: "Plugin interceptor invocations that errored." }), d = n.counter("voltro_subscription_deliveries_total", { description: "Total subscription deliveries (snapshot + delta)." }), f = n.histogram("voltro_subscription_delivery_seconds", {
|
|
18
18
|
boundaries: r,
|
|
19
19
|
description: "Subscription delivery produce→push latency in seconds."
|
|
20
|
-
}),
|
|
20
|
+
}), p = n.gauge("voltro_subscriptions_active", { description: "Currently-open subscriptions." }), m = n.counter("voltro_schedule_runs_total", { description: "Schedule firings by name + outcome." }), ee = n.histogram("voltro_schedule_duration_seconds", {
|
|
21
21
|
boundaries: r,
|
|
22
22
|
description: "Schedule handler duration in seconds."
|
|
23
23
|
}), h = n.gauge("voltro_schedule_last_success_timestamp_seconds", { description: "UNIX time of the last successful firing, per schedule." }), g = n.gauge("voltro_schedule_queued", { description: "Firings waiting for their turn under onOverlap: 'queue', per schedule, on THIS replica." }), _ = n.histogram("voltro_schedule_queue_wait_seconds", {
|
|
@@ -36,11 +36,11 @@ var r = n.exponentialBoundaries({
|
|
|
36
36
|
O.clear();
|
|
37
37
|
}, j = () => O.size, M = (e) => {
|
|
38
38
|
t.runSync(n.update(k(w, `p:${e}`, [["event", e]]), 1));
|
|
39
|
-
},
|
|
39
|
+
}, N = (e, r = 1) => {
|
|
40
40
|
r <= 0 || t.runSync(n.update(k(T, `d:${e}`, [["event", e]]), r));
|
|
41
|
-
},
|
|
41
|
+
}, P = (e, r, i = 1) => {
|
|
42
42
|
i <= 0 || t.runSync(n.update(k(E, `x:${r}:${e}`, [["event", e], ["reason", r]]), i));
|
|
43
|
-
},
|
|
43
|
+
}, te = (e, r) => {
|
|
44
44
|
r !== 0 && t.runSync(n.update(k(D, `s:${e}`, [["event", e]]), r));
|
|
45
45
|
}, F = (e) => {
|
|
46
46
|
let r = e.durationMs / 1e3, d = e.kind === "rpc" ? t.andThen(n.update(i, 1).pipe(t.provideService(n.CurrentMetricAttributes, {
|
|
@@ -51,8 +51,22 @@ var r = n.exponentialBoundaries({
|
|
|
51
51
|
status: e.status
|
|
52
52
|
})), n.update(c, r).pipe(t.provideService(n.CurrentMetricAttributes, { route: e.tag }))) : t.andThen(n.update(l, r).pipe(t.provideService(n.CurrentMetricAttributes, { hook: e.tag })), e.status === "error" ? n.update(u, 1).pipe(t.provideService(n.CurrentMetricAttributes, { hook: e.tag })) : t.void);
|
|
53
53
|
t.runSync(d);
|
|
54
|
-
}, I =
|
|
55
|
-
let r =
|
|
54
|
+
}, I = n.counter("voltro_field_decrypts_total", { description: "Opens of sealed field values, by key id, location (table:column) and outcome." }), L = /* @__PURE__ */ new Map(), R = (e, r, i) => {
|
|
55
|
+
let a = `${e}|${r}`, o = L.get(a) ?? L.set(a, {
|
|
56
|
+
key: e,
|
|
57
|
+
location: r,
|
|
58
|
+
ok: 0,
|
|
59
|
+
failed: 0
|
|
60
|
+
}).get(a);
|
|
61
|
+
o[i] += 1, t.runSync(n.update(k(I, `field|${a}|${i}`, [
|
|
62
|
+
["key", e],
|
|
63
|
+
["location", r],
|
|
64
|
+
["outcome", i]
|
|
65
|
+
]), 1));
|
|
66
|
+
}, z = () => [...L.values()].map((e) => ({ ...e })).sort((e, t) => e.location.localeCompare(t.location) || e.key.localeCompare(t.key)), B = () => {
|
|
67
|
+
L.clear();
|
|
68
|
+
}, V = (e) => e.startsWith("subscription.") ? e.slice(13) : e, H = (e) => {
|
|
69
|
+
let r = V(e.label);
|
|
56
70
|
t.runSync(t.andThen(n.update(d, 1).pipe(t.provideService(n.CurrentMetricAttributes, {
|
|
57
71
|
tag: r,
|
|
58
72
|
kind: e.kind
|
|
@@ -60,42 +74,42 @@ var r = n.exponentialBoundaries({
|
|
|
60
74
|
tag: r,
|
|
61
75
|
kind: e.kind
|
|
62
76
|
}))));
|
|
63
|
-
},
|
|
64
|
-
let i =
|
|
65
|
-
a === 0 ?
|
|
66
|
-
},
|
|
67
|
-
let r = n.update(
|
|
77
|
+
}, U = /* @__PURE__ */ new Map(), W = (e, r) => {
|
|
78
|
+
let i = V(e), a = Math.max(0, (U.get(i) ?? 0) + r);
|
|
79
|
+
a === 0 ? U.delete(i) : U.set(i, a), t.runSync(n.update(p, a).pipe(t.provideService(n.CurrentMetricAttributes, { tag: i })));
|
|
80
|
+
}, G = (e) => {
|
|
81
|
+
let r = n.update(m, 1).pipe(t.provideService(n.CurrentMetricAttributes, {
|
|
68
82
|
schedule: e.name,
|
|
69
83
|
status: e.status
|
|
70
|
-
})), i = n.update(
|
|
84
|
+
})), i = n.update(ee, e.durationMs / 1e3).pipe(t.provideService(n.CurrentMetricAttributes, { schedule: e.name })), a = e.status === "succeeded" && e.completedAtSec !== void 0 ? n.update(h, e.completedAtSec).pipe(t.provideService(n.CurrentMetricAttributes, { schedule: e.name })) : t.void;
|
|
71
85
|
t.runSync(t.andThen(r, t.andThen(i, a)));
|
|
72
|
-
},
|
|
73
|
-
let i = Math.max(0, (
|
|
74
|
-
i === 0 ?
|
|
75
|
-
},
|
|
86
|
+
}, K = /* @__PURE__ */ new Map(), q = (e, r) => {
|
|
87
|
+
let i = Math.max(0, (K.get(e) ?? 0) + r);
|
|
88
|
+
i === 0 ? K.delete(e) : K.set(e, i), t.runSync(n.update(g, i).pipe(t.provideService(n.CurrentMetricAttributes, { schedule: e })));
|
|
89
|
+
}, J = (e, r) => {
|
|
76
90
|
t.runSync(n.update(_, r / 1e3).pipe(t.provideService(n.CurrentMetricAttributes, { schedule: e })));
|
|
77
|
-
},
|
|
91
|
+
}, Y = (e, r) => {
|
|
78
92
|
t.runSync(n.update(v, 1).pipe(t.provideService(n.CurrentMetricAttributes, {
|
|
79
93
|
schedule: e,
|
|
80
94
|
outcome: r
|
|
81
95
|
})));
|
|
82
|
-
},
|
|
96
|
+
}, X = (e, r) => {
|
|
83
97
|
t.runSync(n.update(y, 1).pipe(t.provideService(n.CurrentMetricAttributes, {
|
|
84
98
|
schedule: e,
|
|
85
99
|
outcome: r
|
|
86
100
|
})));
|
|
87
|
-
},
|
|
101
|
+
}, Z = (e, r = 1) => {
|
|
88
102
|
r <= 0 || t.runSync(n.update(b, r).pipe(t.provideService(n.CurrentMetricAttributes, { schedule: e })));
|
|
89
|
-
},
|
|
103
|
+
}, Q = (e) => {
|
|
90
104
|
let r = n.update(x, 1).pipe(t.provideService(n.CurrentMetricAttributes, {
|
|
91
105
|
workflow: e.name,
|
|
92
106
|
status: e.status
|
|
93
107
|
})), i = n.update(S, e.durationMs / 1e3).pipe(t.provideService(n.CurrentMetricAttributes, { workflow: e.name })), a = e.status === "succeeded" && e.completedAtSec !== void 0 ? n.update(C, e.completedAtSec).pipe(t.provideService(n.CurrentMetricAttributes, { workflow: e.name })) : t.void;
|
|
94
108
|
t.runSync(t.andThen(r, t.andThen(i, a)));
|
|
95
|
-
},
|
|
109
|
+
}, ne = (e, t) => n.counter(e, t === void 0 ? {} : { description: t }), re = (e, t) => n.gauge(e, t === void 0 ? {} : { description: t }), ie = (e, t = r, i) => n.histogram(e, {
|
|
96
110
|
boundaries: t,
|
|
97
111
|
...i === void 0 ? {} : { description: i }
|
|
98
|
-
}), { exponentialBoundaries:
|
|
112
|
+
}), { exponentialBoundaries: ae, linearBoundaries: oe } = n, $ = n.snapshot.pipe(t.map((e) => e.map((e) => {
|
|
99
113
|
let t = e.id, n = { ...e.attributes ?? {} }, r = e.description === void 0 ? {} : { description: e.description };
|
|
100
114
|
switch (e.type) {
|
|
101
115
|
case "Histogram": return {
|
|
@@ -156,6 +170,6 @@ var r = n.exponentialBoundaries({
|
|
|
156
170
|
let n = e();
|
|
157
171
|
for (let e of n) t.push(e);
|
|
158
172
|
return t;
|
|
159
|
-
})),
|
|
173
|
+
})), se = () => t.runSync($);
|
|
160
174
|
//#endregion
|
|
161
|
-
export {
|
|
175
|
+
export { ne as counter, j as eventMetricTagCacheSizeForTests, ae as exponentialBoundaries, z as fieldDecryptSnapshot, re as gauge, ie as histogramMetric, oe as linearBoundaries, N as recordEventDelivered, P as recordEventDropped, M as recordEventPublished, te as recordEventSubscribers, Z as recordExternalMissed, X as recordExternalTrigger, R as recordFieldDecrypt, F as recordSample, Y as recordScheduleQueueRecovery, J as recordScheduleQueueWait, q as recordScheduleQueued, G as recordScheduleRun, W as recordSubscriptionActive, H as recordSubscriptionDelivery, Q as recordWorkflowRun, A as resetEventMetricTagCacheForTests, B as resetFieldDecryptCountsForTests, $ as snapshotMetrics, se as snapshotMetricsSync };
|
package/dist/outbox.js
CHANGED
|
@@ -285,7 +285,7 @@ var m = p({ scope: "voltro:outbox" }), h = "_voltro_outbox", g = {
|
|
|
285
285
|
subjectId: t.subjectId ?? null,
|
|
286
286
|
tenantId: t.tenantId ?? null,
|
|
287
287
|
traceId: t.traceId ?? null
|
|
288
|
-
}, a = o.handler(i), c = e.isEffect(a) ? a : await a, d = e.isEffect(c) ? await (r.runEffect ? r.runEffect(c, i) : e.runPromise(c)) : c;
|
|
288
|
+
}, a = r.measureSync ? r.measureSync(() => o.handler(i)) : o.handler(i), c = e.isEffect(a) ? a : await a, d = e.isEffect(c) ? await (r.runEffect ? r.runEffect(c, i) : e.runPromise(c)) : c;
|
|
289
289
|
await k(r.store, {
|
|
290
290
|
outboxRow: t,
|
|
291
291
|
attempt: s,
|
package/dist/readRecorder.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { classifyRead as e } from "./readClassification.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { noteCacheRead as t } from "./computedQueryCache.js";
|
|
3
|
+
import { Effect as n } from "effect";
|
|
4
|
+
import { AsyncLocalStorage as r } from "node:async_hooks";
|
|
4
5
|
//#region src/readRecorder.ts
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
},
|
|
8
|
-
if (
|
|
9
|
-
let n = new Set(t),
|
|
10
|
-
|
|
6
|
+
var i = new r(), a, o = /* @__PURE__ */ new Set(), s = (e) => {
|
|
7
|
+
a = e, o.clear();
|
|
8
|
+
}, c = () => a !== void 0, l = (e, t) => {
|
|
9
|
+
if (a === void 0) return;
|
|
10
|
+
let n = new Set(t), r = o.has(e) || n.size === 0;
|
|
11
|
+
i.enterWith({
|
|
11
12
|
procedure: e,
|
|
12
13
|
declared: n,
|
|
13
14
|
composed: /* @__PURE__ */ new Set(),
|
|
14
15
|
restricting: /* @__PURE__ */ new Set(),
|
|
15
16
|
depth: { n: 0 },
|
|
16
|
-
...
|
|
17
|
+
...r ? { muted: !0 } : {}
|
|
17
18
|
});
|
|
18
|
-
},
|
|
19
|
-
let
|
|
19
|
+
}, u = async (e, t, n = []) => {
|
|
20
|
+
let r = {
|
|
20
21
|
procedure: e,
|
|
21
22
|
declared: new Set(n),
|
|
22
23
|
composed: /* @__PURE__ */ new Set(),
|
|
@@ -24,12 +25,12 @@ var r = new n(), i, a = /* @__PURE__ */ new Set(), o = (e) => {
|
|
|
24
25
|
depth: { n: 0 }
|
|
25
26
|
};
|
|
26
27
|
return {
|
|
27
|
-
result: await
|
|
28
|
-
composed:
|
|
29
|
-
restricting:
|
|
28
|
+
result: await i.run(r, t),
|
|
29
|
+
composed: r.composed,
|
|
30
|
+
restricting: r.restricting
|
|
30
31
|
};
|
|
31
|
-
},
|
|
32
|
-
let t =
|
|
32
|
+
}, d = async (e) => {
|
|
33
|
+
let t = i.getStore();
|
|
33
34
|
if (t === void 0) return e();
|
|
34
35
|
t.depth.n += 1;
|
|
35
36
|
try {
|
|
@@ -37,30 +38,30 @@ var r = new n(), i, a = /* @__PURE__ */ new Set(), o = (e) => {
|
|
|
37
38
|
} finally {
|
|
38
39
|
--t.depth.n;
|
|
39
40
|
}
|
|
40
|
-
},
|
|
41
|
-
let
|
|
42
|
-
return
|
|
43
|
-
|
|
44
|
-
}), () => e, () =>
|
|
45
|
-
--
|
|
41
|
+
}, f = (e) => n.suspend(() => {
|
|
42
|
+
let t = i.getStore();
|
|
43
|
+
return t === void 0 ? e : n.acquireUseRelease(n.sync(() => {
|
|
44
|
+
t.depth.n += 1;
|
|
45
|
+
}), () => e, () => n.sync(() => {
|
|
46
|
+
--t.depth.n;
|
|
46
47
|
}));
|
|
47
|
-
}),
|
|
48
|
-
let n =
|
|
48
|
+
}), p = (t) => {
|
|
49
|
+
let n = i.getStore();
|
|
49
50
|
if (n === void 0 || n.muted === !0) return;
|
|
50
|
-
let { composed:
|
|
51
|
-
for (let e of
|
|
51
|
+
let { composed: r, restricting: s } = e(t, n.depth.n > 0);
|
|
52
|
+
for (let e of r) n.composed.add(e);
|
|
52
53
|
for (let e of s) n.composed.has(e) || n.restricting.add(e);
|
|
53
|
-
if (
|
|
54
|
-
let c =
|
|
55
|
-
c !== void 0 && (
|
|
56
|
-
},
|
|
57
|
-
let
|
|
58
|
-
return typeof
|
|
59
|
-
} }),
|
|
54
|
+
if (a === void 0 || o.has(n.procedure)) return;
|
|
55
|
+
let c = h(n.procedure, n.composed, n.declared, n.restricting);
|
|
56
|
+
c !== void 0 && (o.add(n.procedure), a(c));
|
|
57
|
+
}, m = (e) => new Proxy(e, { get(e, n) {
|
|
58
|
+
let r = Reflect.get(e, n, e);
|
|
59
|
+
return typeof r == "function" && n !== "query" ? r.bind(e) : n !== "query" || typeof r != "function" ? r : (n) => (p(n), t(n), r.call(e, n));
|
|
60
|
+
} }), h = (e, t, n, r) => {
|
|
60
61
|
let i = [...t], a = 0;
|
|
61
62
|
for (let e of i) n.has(e) || (i[a++] = e);
|
|
62
63
|
if (i.length = a, i.sort(), i.length !== 0) return `${e}: read ${i.map((e) => `\`${e}\``).join(", ")} without declaring ${i.length === 1 ? "it" : "them"} in \`source:\`.\n A write to ${i.length === 1 ? "that table" : "those tables"} will not re-run this query, so an open view keeps\n showing what it showed before. The write itself is fine, which is why nothing else reports this.
|
|
63
64
|
Observed on this boot — a branch that did not run contributes nothing, so this names what WAS\n read and never claims the declaration is otherwise complete.` + (r.size > 0 ? `\n Not counted (read only to narrow the result): ${[...r].sort().map((e) => `\`${e}\``).join(", ")}.` : "");
|
|
64
65
|
};
|
|
65
66
|
//#endregion
|
|
66
|
-
export {
|
|
67
|
+
export { l as enterReadRecording, p as noteRead, c as readRecordingActive, u as recordReads, m as recordingStore, d as restrictingReads, f as restrictingReadsEffect, s as setSourceGapSink, h as sourceGapReport };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { and as e } from "@voltro/database";
|
|
2
|
+
//#region src/readScopePredicate.ts
|
|
3
|
+
var t = (t, n) => {
|
|
4
|
+
let r = t.setOp === void 0 ? t.alias ?? ((t.joins?.length ?? 0) > 0 ? t.table : void 0) : void 0, i = n((e) => r === void 0 ? e : `${r}.${e}`);
|
|
5
|
+
return {
|
|
6
|
+
...t,
|
|
7
|
+
...r === void 0 ? {} : { alias: r },
|
|
8
|
+
predicate: t.predicate ? e(t.predicate, i) : i
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { t as addReadScopePredicate };
|
|
@@ -11,6 +11,7 @@ var s = a({ scope: "voltro:replication" }), c = new o(), l = (e, t) => c.run(e,
|
|
|
11
11
|
a(e);
|
|
12
12
|
}), r.asVoid(i.interrupt(o));
|
|
13
13
|
})), d = () => c.getStore(), f = class {
|
|
14
|
+
integrityQuery;
|
|
14
15
|
primary;
|
|
15
16
|
replicas;
|
|
16
17
|
adapter;
|
|
@@ -22,8 +23,9 @@ var s = a({ scope: "voltro:replication" }), c = new o(), l = (e, t) => c.run(e,
|
|
|
22
23
|
health;
|
|
23
24
|
recordRouting;
|
|
24
25
|
now;
|
|
26
|
+
closing;
|
|
25
27
|
constructor(r) {
|
|
26
|
-
this.primary = r.primary, this.replicas = r.replicas, this.adapter = r.replicationAdapter, this.policy = r.rywPolicy ?? "fallback", this.rywTtlMs = r.rywTtlMs ?? 3e4, this.rywMaxWaitMs = r.rywMaxWaitMs ?? 500, this.now = r.now ?? Date.now, this.rywStore = r.rywStore ?? n({ now: this.now }), this.selector = r.replicaSelector ?? e(), this.health = r.replicaHealth ?? t({ now: this.now }), r.recordRouting !== void 0 && (this.recordRouting = r.recordRouting);
|
|
28
|
+
this.primary = r.primary, r.primary.integrityQuery !== void 0 && (this.integrityQuery = r.primary.integrityQuery.bind(r.primary)), this.replicas = r.replicas, this.adapter = r.replicationAdapter, this.policy = r.rywPolicy ?? "fallback", this.rywTtlMs = r.rywTtlMs ?? 3e4, this.rywMaxWaitMs = r.rywMaxWaitMs ?? 500, this.now = r.now ?? Date.now, this.rywStore = r.rywStore ?? n({ now: this.now }), this.selector = r.replicaSelector ?? e(), this.health = r.replicaHealth ?? t({ now: this.now }), r.recordRouting !== void 0 && (this.recordRouting = r.recordRouting);
|
|
27
29
|
}
|
|
28
30
|
async query(e) {
|
|
29
31
|
let t = c.getStore(), n = t?.subjectKey ?? "anon:bg";
|
|
@@ -166,9 +168,9 @@ var s = a({ scope: "voltro:replication" }), c = new o(), l = (e, t) => c.run(e,
|
|
|
166
168
|
let n = await this.primary.insert(e, t);
|
|
167
169
|
return await this.stampPostWrite(), n;
|
|
168
170
|
}
|
|
169
|
-
async insertMany(e, t) {
|
|
170
|
-
let
|
|
171
|
-
return await this.stampPostWrite(),
|
|
171
|
+
async insertMany(e, t, n) {
|
|
172
|
+
let r = await this.primary.insertMany(e, t, n);
|
|
173
|
+
return await this.stampPostWrite(), r;
|
|
172
174
|
}
|
|
173
175
|
async patchJson(e, t, n, r, i) {
|
|
174
176
|
let a = await this.primary.patchJson(e, t, n, r, i);
|
|
@@ -218,6 +220,22 @@ var s = a({ scope: "voltro:replication" }), c = new o(), l = (e, t) => c.run(e,
|
|
|
218
220
|
get changeScope() {
|
|
219
221
|
return this.primary.changeScope ?? "local";
|
|
220
222
|
}
|
|
223
|
+
close(e) {
|
|
224
|
+
return this.closing ??= (async () => {
|
|
225
|
+
let t = [];
|
|
226
|
+
try {
|
|
227
|
+
await this.rywStore.close?.();
|
|
228
|
+
} catch (e) {
|
|
229
|
+
t.push(e);
|
|
230
|
+
}
|
|
231
|
+
for (let n of /* @__PURE__ */ new Set([this.primary, ...this.replicas])) try {
|
|
232
|
+
await n.close?.(e);
|
|
233
|
+
} catch (e) {
|
|
234
|
+
t.push(e);
|
|
235
|
+
}
|
|
236
|
+
if (t.length > 0) throw AggregateError(t, "Read replica shutdown failed");
|
|
237
|
+
})();
|
|
238
|
+
}
|
|
221
239
|
async stampPostWrite() {
|
|
222
240
|
if (this.replicas.length === 0) return;
|
|
223
241
|
let e = c.getStore()?.subjectKey ?? "anon:bg";
|
package/dist/rowFilter.js
CHANGED
|
@@ -1,65 +1,82 @@
|
|
|
1
1
|
import { restrictingReadsEffect as e } from "./readRecorder.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { mapSetReadScopes as t } from "./setReadScopes.js";
|
|
3
|
+
import { Effect as n, Schedule as r, Schema as i } from "effect";
|
|
4
|
+
import { and as a } from "@voltro/database";
|
|
5
|
+
import { currentSubjectAuthority as o, isMachineSubject as s } from "@voltro/protocol";
|
|
6
|
+
import { createLogger as c } from "@voltro/logger";
|
|
6
7
|
//#region src/rowFilter.ts
|
|
7
|
-
var
|
|
8
|
-
table:
|
|
9
|
-
declared:
|
|
8
|
+
var l = class extends i.TaggedError()("RowFilterUnavailable", { cause: i.String }) {}, u = class extends i.TaggedError()("RowFilterDeclarationViolated", {
|
|
9
|
+
table: i.String,
|
|
10
|
+
declared: i.Array(i.String)
|
|
10
11
|
}) {
|
|
11
12
|
get message() {
|
|
12
13
|
return `row filter narrowed '${this.table}', which its declaration does not name (declared: ${this.declared.join(", ") || "none"})`;
|
|
13
14
|
}
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
},
|
|
17
|
-
|
|
15
|
+
}, d = r.max([r.exponential("20 millis"), r.recurs(2)]), f = Symbol.for("@voltro/runtime/rowFilter"), p = globalThis, m = p[f] ?? (p[f] = {}), h = (e) => {
|
|
16
|
+
m.filter = e;
|
|
17
|
+
}, g = () => m.filter, _ = () => m.filter !== void 0, v = () => void 0, y = c({ scope: "voltro:row-filter" }), b = /* @__PURE__ */ new Set(), x = (e, t) => {
|
|
18
|
+
b.has(e) || (b.add(e), y.info("row filter: RESOLVED on a live read path", {
|
|
18
19
|
arm: e,
|
|
19
20
|
...t === void 0 ? {} : { constrains: t },
|
|
20
|
-
armsSeen: [...
|
|
21
|
+
armsSeen: [...b].sort().join(",")
|
|
21
22
|
}));
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
},
|
|
25
|
-
let e =
|
|
26
|
-
e !== void 0 &&
|
|
27
|
-
})),
|
|
28
|
-
if (
|
|
29
|
-
let a =
|
|
30
|
-
return
|
|
31
|
-
let r =
|
|
32
|
-
if (r !== void 0 && !p.has(
|
|
33
|
-
table:
|
|
23
|
+
}, S = () => [...b].sort(), C = () => {
|
|
24
|
+
b.clear();
|
|
25
|
+
}, w = (e, t) => n.tap(T(g(), e, t), () => n.sync(() => {
|
|
26
|
+
let e = g();
|
|
27
|
+
e !== void 0 && x("request", e.tables?.length);
|
|
28
|
+
})), T = (t, r, i) => {
|
|
29
|
+
if (t === void 0 || s(r)) return n.succeed(v);
|
|
30
|
+
let a = t.retry ?? d, o = e(t.load(r)), c = a === !1 ? o : n.retry(o, a), f = t.tables, p = f === void 0 ? void 0 : new Set(f);
|
|
31
|
+
return c.pipe(n.map((e) => p === void 0 ? (n) => t.predicate(e, n) : (n) => {
|
|
32
|
+
let r = t.predicate(e, n);
|
|
33
|
+
if (r !== void 0 && !p.has(n)) throw new u({
|
|
34
|
+
table: n,
|
|
34
35
|
declared: f ?? []
|
|
35
36
|
});
|
|
36
37
|
return r;
|
|
37
|
-
}),
|
|
38
|
-
},
|
|
38
|
+
}), n.catch((e) => n.suspend(() => (i?.(e), t.onLoadError === "deny" ? n.succeed(E) : n.fail(new l({ cause: String(e) }))))));
|
|
39
|
+
}, E = () => ({
|
|
39
40
|
column: "id",
|
|
40
41
|
op: "isNull"
|
|
41
|
-
}),
|
|
42
|
-
let t =
|
|
42
|
+
}), D = (e) => {
|
|
43
|
+
let t = g();
|
|
43
44
|
if (t === void 0) return !1;
|
|
44
45
|
let n = t.tables;
|
|
45
46
|
if (n === void 0) return !0;
|
|
46
47
|
let r = new Set(n);
|
|
47
48
|
return e.some((e) => r.has(e));
|
|
48
|
-
},
|
|
49
|
+
}, O = (e, t, n) => {
|
|
49
50
|
let r = e(t);
|
|
50
|
-
return r === void 0 ? n : n ?
|
|
51
|
-
}, O = (e, t) => {
|
|
52
|
-
let n = D(e, t.table, t.predicate);
|
|
53
|
-
return n === t.predicate ? t : {
|
|
54
|
-
...t,
|
|
55
|
-
predicate: n
|
|
56
|
-
};
|
|
51
|
+
return r === void 0 ? n : n ? a(n, r) : r;
|
|
57
52
|
}, k = (e, n) => {
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
let r = n;
|
|
54
|
+
if (r.setOp !== void 0) {
|
|
55
|
+
let i = {
|
|
56
|
+
...r,
|
|
57
|
+
table: n.table,
|
|
58
|
+
predicate: n.predicate,
|
|
59
|
+
order: r.order ?? [],
|
|
60
|
+
projection: r.projection,
|
|
61
|
+
take: r.take,
|
|
62
|
+
skip: r.skip
|
|
63
|
+
}, a = t(i, (t) => k(e, t));
|
|
64
|
+
return {
|
|
65
|
+
...n,
|
|
66
|
+
setOp: a.setOp
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
let i = O(e, n.table, n.predicate);
|
|
70
|
+
return i === n.predicate ? n : {
|
|
71
|
+
...n,
|
|
72
|
+
predicate: i
|
|
73
|
+
};
|
|
74
|
+
}, A = (e, t) => {
|
|
75
|
+
if (g() !== void 0) return async () => {
|
|
76
|
+
let r = await n.runPromise(n.result(w(o(e), t)));
|
|
60
77
|
if (r._tag === "Failure") throw r.failure;
|
|
61
78
|
return r.success;
|
|
62
79
|
};
|
|
63
80
|
};
|
|
64
81
|
//#endregion
|
|
65
|
-
export {
|
|
82
|
+
export { d as DEFAULT_ROW_FILTER_RETRY, v as NO_ROW_FILTER, u as RowFilterDeclarationViolated, l as RowFilterUnavailable, O as applyRowFilter, k as applyRowFilterToDescriptor, g as getRowFilter, A as makeDefaultRefilter, x as noteRowFilterResolved, C as resetRowFilterResolvedArms, w as resolveRowFilterScope, T as resolveRowFilterScopeFor, D as rowFilterMayNarrow, _ as rowFilterRegistered, S as rowFilterResolvedArms, h as setRowFilter };
|
package/dist/rpcConnections.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { interruptConnectionStreams as e, unbindConnection as t } from "./connectionCredentials.js";
|
|
2
2
|
import { Effect as n, Layer as r, Queue as i } from "effect";
|
|
3
3
|
import { randomUUID as a } from "node:crypto";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { RpcServer as o } from "effect/rpc";
|
|
5
|
+
import { Headers as s } from "effect/http";
|
|
6
6
|
//#region src/rpcConnections.ts
|
|
7
7
|
var c = Symbol.for("@voltro/runtime/rpcConnections"), l = globalThis, u = l[c] ??= {
|
|
8
8
|
nextId: 1,
|
|
9
9
|
entries: /* @__PURE__ */ new Map(),
|
|
10
10
|
addressMark: a()
|
|
11
11
|
}, d = "x-voltro-client-address", f = (e) => `${u.addressMark} ${e}`, p = (e, t) => {
|
|
12
|
-
let n =
|
|
12
|
+
let n = s.remove(e.headers, d), r = t === void 0 ? n : s.set(n, d, f(t)), i = Object.create(e);
|
|
13
13
|
return Object.defineProperty(i, "headers", {
|
|
14
14
|
value: r,
|
|
15
15
|
configurable: !0
|
|
@@ -21,8 +21,8 @@ var c = Symbol.for("@voltro/runtime/rpcConnections"), l = globalThis, u = l[c] ?
|
|
|
21
21
|
remoteAddr: n,
|
|
22
22
|
headers: r.length === e.length ? e : r
|
|
23
23
|
};
|
|
24
|
-
}, h = (e) => u.entries.get(e)?.connection, g = (
|
|
25
|
-
let r = yield*
|
|
24
|
+
}, h = (e) => u.entries.get(e)?.connection, g = (s, c) => r.effect(o.Protocol, n.gen(function* () {
|
|
25
|
+
let r = yield* o.Protocol, s = yield* i.make(), l = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), f = (e, t) => {
|
|
26
26
|
let n = l.get(e);
|
|
27
27
|
if (n !== void 0) return t !== void 0 && n.connection.remoteAddr === void 0 && (n.connection = Object.freeze({
|
|
28
28
|
...n.connection,
|
|
@@ -48,10 +48,10 @@ var c = Symbol.for("@voltro/runtime/rpcConnections"), l = globalThis, u = l[c] ?
|
|
|
48
48
|
for (let e of l.keys()) p(e);
|
|
49
49
|
})), yield* n.forkScoped(n.gen(function* () {
|
|
50
50
|
let e = yield* i.take(r.disconnects), t = p(e);
|
|
51
|
-
t !== void 0 && (yield* i.offer(
|
|
51
|
+
t !== void 0 && (yield* i.offer(s, t));
|
|
52
52
|
}).pipe(n.forever)), {
|
|
53
53
|
...r,
|
|
54
|
-
disconnects:
|
|
54
|
+
disconnects: s,
|
|
55
55
|
run: (e) => r.run((t, i) => n.gen(function* () {
|
|
56
56
|
if (!(yield* r.clientIds).has(t)) return;
|
|
57
57
|
if (i._tag !== "Request") {
|
|
@@ -78,6 +78,6 @@ var c = Symbol.for("@voltro/runtime/rpcConnections"), l = globalThis, u = l[c] ?
|
|
|
78
78
|
return n;
|
|
79
79
|
})
|
|
80
80
|
};
|
|
81
|
-
})).pipe(r.provide(
|
|
81
|
+
})).pipe(r.provide(s));
|
|
82
82
|
//#endregion
|
|
83
83
|
export { d as RPC_CLIENT_ADDRESS_HEADER, h as getRpcConnection, f as stampRpcClientAddress, m as takeRpcClientAddress, p as withRpcClientAddress, g as withRpcConnectionIdentity };
|