@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
package/dist/servePipeline.js
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
1
|
+
import { cachedComputedCall as e, computedCacheKey as t, currentQueryDependencies as n, enterQueryDependencies as r } from "./computedQueryCache.js";
|
|
2
|
+
import { enterReadRecording as i } from "./readRecorder.js";
|
|
3
|
+
import { getRowFilter as a, makeDefaultRefilter as o, resolveRowFilterScope as s } from "./rowFilter.js";
|
|
4
|
+
import { isComputedQuery as c } from "./computedQuery.js";
|
|
5
|
+
import { TX_READ_VERSIONS_KEY as l, isTransactionReadConflict as u } from "./storeMiddleware.js";
|
|
6
|
+
import { evaluateTouchedRules as d, makeRuleCapture as f } from "./businessRules.js";
|
|
7
|
+
import { enforceApproval as p } from "./approvals.js";
|
|
8
|
+
import { observeApiRoleEffect as m } from "./apiRoleWorkloadMetrics.js";
|
|
9
|
+
import { Cause as h, Effect as g, Exit as _, Option as v } from "effect";
|
|
10
|
+
import { isTransientContention as y } from "@voltro/database";
|
|
11
|
+
import { SubjectService as b, checkGuardsEffect as x, currentSubjectAuthority as S, recheckGuardsEffect as C } from "@voltro/protocol";
|
|
12
|
+
import { createLogger as w } from "@voltro/logger";
|
|
11
13
|
//#region src/servePipeline.ts
|
|
12
|
-
var
|
|
13
|
-
if (
|
|
14
|
-
let t =
|
|
15
|
-
throw
|
|
16
|
-
}),
|
|
17
|
-
let i = await
|
|
14
|
+
var T = (e, t) => g.runPromiseExit(e, t).then((e) => {
|
|
15
|
+
if (_.isSuccess(e)) return e.value;
|
|
16
|
+
let t = h.findErrorOption(e.cause);
|
|
17
|
+
throw v.isSome(t) ? t.value : h.squash(e.cause);
|
|
18
|
+
}), E = (e) => T(e), D = (e, t) => e.pipe(g.provideService(b, t)), O = async (e, t, n, r) => {
|
|
19
|
+
let i = await g.runPromise(x(t, e.guards, n, {
|
|
18
20
|
defaultDeny: r === !0,
|
|
19
21
|
procedure: e.name
|
|
20
22
|
}));
|
|
21
23
|
if (i) throw i;
|
|
22
|
-
},
|
|
23
|
-
e.requiresApproval !== void 0 && await
|
|
24
|
+
}, k = async (e, t, n, r) => {
|
|
25
|
+
e.requiresApproval !== void 0 && await p({
|
|
24
26
|
procedure: e.name,
|
|
25
27
|
kind: t,
|
|
26
28
|
policy: e.requiresApproval,
|
|
@@ -28,20 +30,20 @@ var b = (e, t) => d.runPromiseExit(e, t).then((e) => {
|
|
|
28
30
|
input: r,
|
|
29
31
|
traceId: n.traceId
|
|
30
32
|
});
|
|
31
|
-
},
|
|
32
|
-
if (
|
|
33
|
-
let
|
|
34
|
-
|
|
33
|
+
}, A = w({ scope: "voltro:rpc" }), j = async (e) => {
|
|
34
|
+
if (a() === void 0) return e;
|
|
35
|
+
let t = await E(s(e.subject, (e) => {
|
|
36
|
+
A.error("row filter failed to load", {}, e instanceof Error ? e : Error(String(e)));
|
|
35
37
|
}));
|
|
36
38
|
return {
|
|
37
39
|
...e,
|
|
38
|
-
rowFilter:
|
|
40
|
+
rowFilter: t
|
|
39
41
|
};
|
|
40
|
-
},
|
|
42
|
+
}, M = (e) => ({
|
|
41
43
|
...e.surface === void 0 ? {} : { surface: e.surface },
|
|
42
44
|
...e.publicApi === void 0 ? {} : { publicApi: e.publicApi },
|
|
43
45
|
...e.remoteAddr === void 0 ? {} : { remoteAddr: e.remoteAddr }
|
|
44
|
-
}),
|
|
46
|
+
}), N = (e) => {
|
|
45
47
|
let t = e.descriptor.target;
|
|
46
48
|
if (t == null) return [];
|
|
47
49
|
let n = Array.isArray(t) ? t : [t], r = /* @__PURE__ */ new Set();
|
|
@@ -50,7 +52,7 @@ var b = (e, t) => d.runPromiseExit(e, t).then((e) => {
|
|
|
50
52
|
typeof t == "string" && t.length > 0 && r.add(t);
|
|
51
53
|
}
|
|
52
54
|
return [...r];
|
|
53
|
-
},
|
|
55
|
+
}, P = async (e) => {
|
|
54
56
|
let { store: t, target: n, procedure: r, input: i, output: a } = e;
|
|
55
57
|
if (n == null) return;
|
|
56
58
|
let o = Array.isArray(n) ? n : [n];
|
|
@@ -67,15 +69,15 @@ var b = (e, t) => d.runPromiseExit(e, t).then((e) => {
|
|
|
67
69
|
await u.set(c.map((e) => String(e)));
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
|
-
},
|
|
72
|
+
}, F = (e, t) => e === void 0 ? {} : { enqueueOutcome: async (n, r, i) => {
|
|
71
73
|
let a = e(t);
|
|
72
74
|
if (a === void 0) throw TypeError("Invocation outcome outbox is unavailable");
|
|
73
75
|
return a.enqueue(n, r, i);
|
|
74
|
-
} },
|
|
76
|
+
} }, I = async (e) => {
|
|
75
77
|
let t = `${e.kind}.${e.name}`, n = Date.now(), r = "ok";
|
|
76
78
|
try {
|
|
77
79
|
if (e.interceptor) {
|
|
78
|
-
let t =
|
|
80
|
+
let t = g.tryPromise({
|
|
79
81
|
try: () => e.runExecutor(),
|
|
80
82
|
catch: (e) => e
|
|
81
83
|
}), n = e.interceptor(t, {
|
|
@@ -87,10 +89,10 @@ var b = (e, t) => d.runPromiseExit(e, t).then((e) => {
|
|
|
87
89
|
...e.enqueueOutcome === void 0 ? {} : { enqueueOutcome: e.enqueueOutcome },
|
|
88
90
|
...e.requestContext.spanId === void 0 ? {} : { spanId: e.requestContext.spanId },
|
|
89
91
|
...e.target !== void 0 && e.target.length > 0 ? { target: e.target } : {},
|
|
90
|
-
...
|
|
91
|
-
}), r = await
|
|
92
|
-
if (
|
|
93
|
-
throw
|
|
92
|
+
...M(e.requestContext)
|
|
93
|
+
}), r = await g.runPromiseExit(n, e.requestContext.signal === void 0 ? void 0 : { signal: e.requestContext.signal });
|
|
94
|
+
if (_.isSuccess(r)) return r.value;
|
|
95
|
+
throw h.squash(r.cause);
|
|
94
96
|
}
|
|
95
97
|
return await e.runExecutor();
|
|
96
98
|
} catch (e) {
|
|
@@ -103,50 +105,55 @@ var b = (e, t) => d.runPromiseExit(e, t).then((e) => {
|
|
|
103
105
|
status: r
|
|
104
106
|
});
|
|
105
107
|
}
|
|
106
|
-
},
|
|
107
|
-
let n = t?.delay ?? ((e) =>
|
|
108
|
+
}, L = (e) => y(e) || u(e), R = 3, z = (e) => new Promise((t) => setTimeout(t, e)), B = async (e, t) => {
|
|
109
|
+
let n = t?.delay ?? ((e) => z(e * 20 + Math.floor(Math.random() * 30))), r = t?.attempts ?? 3;
|
|
108
110
|
for (let t = 1;; t++) try {
|
|
109
111
|
return await e();
|
|
110
112
|
} catch (e) {
|
|
111
|
-
if (t >= r || !
|
|
113
|
+
if (t >= r || !L(e)) throw u(e) ? e.conflict : e;
|
|
112
114
|
await n(t);
|
|
113
115
|
}
|
|
114
|
-
},
|
|
116
|
+
}, V = (e) => (t, n, r) => I({
|
|
115
117
|
name: t.descriptor.name,
|
|
116
118
|
kind: "mutation",
|
|
117
119
|
input: n,
|
|
118
120
|
requestContext: r,
|
|
119
|
-
...
|
|
120
|
-
target:
|
|
121
|
+
...F(e.outcomeOutbox, r),
|
|
122
|
+
target: N(t),
|
|
121
123
|
...e.interceptor ? { interceptor: e.interceptor } : {},
|
|
122
124
|
...e.recordMetric ? { recordMetric: e.recordMetric } : {},
|
|
123
125
|
runExecutor: async () => {
|
|
124
126
|
let i = Date.now();
|
|
125
|
-
await
|
|
126
|
-
let
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
await q(t, "mutation", { defaultDeny: e.defaultDeny === !0 })(n, r);
|
|
128
|
+
let a = {
|
|
129
|
+
...r,
|
|
130
|
+
subject: S(r.subject)
|
|
131
|
+
};
|
|
132
|
+
await k(t.descriptor, "mutation", a, n);
|
|
133
|
+
let o = await j(a), s = e.resolveStore === void 0 ? e.store : await e.resolveStore(o), c = [], u = [], p = await B(async () => s.transactional(async (a) => {
|
|
134
|
+
c.length = 0, u.length = 0, a[Symbol.for("@voltro/runtime:tx-fold-releases")] = u, a[l] = /* @__PURE__ */ new Map();
|
|
135
|
+
let p = t.descriptor.undo?.capture === !1 ? void 0 : e.undoCapture?.(a), m = p ? p.tx : a, h = f(m), _ = e.buildContext(o, h.tx, {
|
|
136
|
+
committedStore: s,
|
|
130
137
|
afterCommit: (e) => {
|
|
131
|
-
|
|
138
|
+
c.push(e);
|
|
132
139
|
}
|
|
133
|
-
}), v = t.executor(n, _), y =
|
|
134
|
-
if (await
|
|
140
|
+
}), v = e.measureSync ? e.measureSync(() => t.executor(n, _)) : t.executor(n, _), y = g.isEffect(v) ? await e.runEffect(D(v, o.subject), _.store) : await v;
|
|
141
|
+
if (await P({
|
|
135
142
|
store: _.store,
|
|
136
143
|
target: t.descriptor.target,
|
|
137
144
|
procedure: t.descriptor.name,
|
|
138
145
|
input: n,
|
|
139
146
|
output: y
|
|
140
|
-
}),
|
|
147
|
+
}), p && await p.persist(_.store, {
|
|
141
148
|
tag: t.descriptor.name,
|
|
142
|
-
subject:
|
|
149
|
+
subject: o.subject,
|
|
143
150
|
traceId: r.traceId
|
|
144
|
-
}), await
|
|
145
|
-
touched:
|
|
151
|
+
}), await d({
|
|
152
|
+
touched: h.drain(),
|
|
146
153
|
store: _.store,
|
|
147
|
-
subject:
|
|
154
|
+
subject: o.subject
|
|
148
155
|
}), e.beforeMutationCommit !== void 0) {
|
|
149
|
-
let
|
|
156
|
+
let r = N(t), a = e.beforeMutationCommit({
|
|
150
157
|
tag: t.descriptor.name,
|
|
151
158
|
kind: "mutation",
|
|
152
159
|
input: n,
|
|
@@ -158,122 +165,179 @@ var b = (e, t) => d.runPromiseExit(e, t).then((e) => {
|
|
|
158
165
|
startedAt: i,
|
|
159
166
|
durationMs: Math.max(0, Date.now() - i),
|
|
160
167
|
...o.spanId === void 0 ? {} : { spanId: o.spanId },
|
|
161
|
-
...
|
|
162
|
-
...
|
|
168
|
+
...r.length > 0 ? { target: r } : {},
|
|
169
|
+
...M(o)
|
|
163
170
|
});
|
|
164
|
-
await e.runEffect(
|
|
171
|
+
await e.runEffect(D(a, o.subject), _.store);
|
|
165
172
|
}
|
|
166
173
|
return y;
|
|
167
174
|
}), { ...e.replayAttempts === void 0 ? {} : { attempts: e.replayAttempts } });
|
|
168
|
-
if (
|
|
169
|
-
let t = e.buildContext(o,
|
|
170
|
-
committedStore:
|
|
175
|
+
if (u.length > 0) {
|
|
176
|
+
let t = e.buildContext(o, s, {
|
|
177
|
+
committedStore: s,
|
|
171
178
|
afterCommit: () => {}
|
|
172
179
|
}).store;
|
|
173
|
-
for (let e of
|
|
180
|
+
for (let e of u.splice(0)) await t.update(e.table, e.pk, e.patch);
|
|
174
181
|
}
|
|
175
|
-
for (let e of
|
|
176
|
-
return p;
|
|
182
|
+
for (let e of c) await e();
|
|
183
|
+
return e.settleCacheInvalidations !== void 0 && await e.settleCacheInvalidations(), p;
|
|
177
184
|
}
|
|
178
|
-
}),
|
|
185
|
+
}), H = (e) => (t, n, r, i) => I({
|
|
179
186
|
name: t.name,
|
|
180
187
|
kind: "workflow",
|
|
181
188
|
input: n,
|
|
182
189
|
requestContext: r,
|
|
183
|
-
...
|
|
190
|
+
...F(e.outcomeOutbox, r),
|
|
184
191
|
...e.interceptor ? { interceptor: e.interceptor } : {},
|
|
185
192
|
...e.recordMetric ? { recordMetric: e.recordMetric } : {},
|
|
186
|
-
runExecutor: async () => (await
|
|
187
|
-
}),
|
|
193
|
+
runExecutor: async () => (await O(t, r.subject, n, e.defaultDeny), i())
|
|
194
|
+
}), U = (e) => e && typeof e == "object" && "descriptor" in e ? e.descriptor : e, W = (e) => typeof e == "object" && !!e && !Array.isArray(e) && "table" in e && "order" in e, G = (e) => {
|
|
188
195
|
let t = e.descriptor.source;
|
|
189
196
|
return t == null ? [] : typeof t == "string" ? [t] : [...t];
|
|
190
|
-
},
|
|
197
|
+
}, K = (e, t, n) => (r) => () => g.runPromise(C(r, e.descriptor.guards, t, {
|
|
191
198
|
defaultDeny: n === !0,
|
|
192
199
|
procedure: e.descriptor.name
|
|
193
|
-
})),
|
|
194
|
-
let
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
+
})), q = (e, t, n = {}) => async (r, i) => {
|
|
201
|
+
let a = i.subject;
|
|
202
|
+
n.bindReplayAuthority?.({
|
|
203
|
+
tag: e.descriptor.name,
|
|
204
|
+
kind: t,
|
|
205
|
+
input: r,
|
|
206
|
+
subject: a,
|
|
207
|
+
traceId: i.traceId,
|
|
208
|
+
...i.surface === void 0 ? {} : { surface: i.surface },
|
|
209
|
+
...i.publicApi === void 0 ? {} : { publicApi: i.publicApi },
|
|
210
|
+
...i.remoteAddr === void 0 ? {} : { remoteAddr: i.remoteAddr }
|
|
211
|
+
});
|
|
212
|
+
let o = await K(e, r, n.defaultDeny)(a)();
|
|
213
|
+
if (o) throw o;
|
|
214
|
+
}, J = (e, t) => e.rowFilter !== void 0 || a() === void 0 ? t(e) : g.promise(() => j(e)).pipe(g.flatMap((e) => {
|
|
215
|
+
let n = t(e);
|
|
216
|
+
return g.isEffect(n) ? n : g.succeed(n);
|
|
217
|
+
})), Y = (e, t) => X(e, t, /* @__PURE__ */ new Set()), X = (o, s, l) => (u, d) => (f) => {
|
|
218
|
+
if (f.rowFilter === void 0 && a() !== void 0) return J(f, (e) => X(o, s, l)(u, d)(e));
|
|
219
|
+
let p = s ?? (f.connection?.transport === "http" ? "rpc" : "subscriptions"), h = (e) => o.workloadMetrics ? o.workloadMetrics.measureSync(p, e) : e(), _ = (e, t) => {
|
|
220
|
+
let n = o.provideEffect(e, t);
|
|
221
|
+
return o.workloadMetrics ? m(n, o.workloadMetrics, p) : n;
|
|
222
|
+
}, v = o.buildContext(f), y = K(u, d, o.defaultDeny)(f.subject), b = async () => {
|
|
223
|
+
let e = await y();
|
|
200
224
|
if (e) throw e;
|
|
201
225
|
let t = {
|
|
202
|
-
...
|
|
203
|
-
subject:
|
|
204
|
-
},
|
|
205
|
-
if (
|
|
206
|
-
return
|
|
207
|
-
},
|
|
208
|
-
let
|
|
209
|
-
if (
|
|
210
|
-
let e =
|
|
211
|
-
if (
|
|
212
|
-
let
|
|
226
|
+
...f,
|
|
227
|
+
subject: S(f.subject)
|
|
228
|
+
}, n = o.buildContext(await j(t)), r = h(() => u.executor(d, n)), i = g.isEffect(r) ? await T(_(D(r, t.subject), n.store), f.signal === void 0 ? void 0 : { signal: f.signal }) : U(await Promise.resolve(r)), a = await y();
|
|
229
|
+
if (a) throw a;
|
|
230
|
+
return i;
|
|
231
|
+
}, C = (e, t = n()) => {
|
|
232
|
+
let r = U(e);
|
|
233
|
+
if (W(r)) {
|
|
234
|
+
let e = o.finalize(r, f), t = G(u);
|
|
235
|
+
if (t.length === 0) return e;
|
|
236
|
+
let n = e.dependentTables ?? [];
|
|
213
237
|
return {
|
|
214
238
|
...e,
|
|
215
|
-
dependentTables: [.../* @__PURE__ */ new Set([...
|
|
239
|
+
dependentTables: [.../* @__PURE__ */ new Set([...n, ...t])]
|
|
216
240
|
};
|
|
217
241
|
}
|
|
218
242
|
return {
|
|
219
243
|
__voltroComputed: !0,
|
|
220
|
-
value:
|
|
221
|
-
dependentTables:
|
|
222
|
-
tenantId:
|
|
223
|
-
recompute:
|
|
244
|
+
value: r,
|
|
245
|
+
dependentTables: [.../* @__PURE__ */ new Set([...G(u), ...t])],
|
|
246
|
+
tenantId: f.subject?.tenantId ?? null,
|
|
247
|
+
recompute: b
|
|
224
248
|
};
|
|
225
|
-
},
|
|
226
|
-
let
|
|
227
|
-
return
|
|
228
|
-
try:
|
|
249
|
+
}, w = (e, t) => {
|
|
250
|
+
let n = C(e, t);
|
|
251
|
+
return c(n) ? g.tryPromise({
|
|
252
|
+
try: y,
|
|
229
253
|
catch: (e) => e
|
|
230
|
-
}).pipe(
|
|
231
|
-
},
|
|
232
|
-
let
|
|
233
|
-
return
|
|
234
|
-
},
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
let
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
254
|
+
}).pipe(g.flatMap((e) => e ? g.fail(e) : g.succeed(n))) : n;
|
|
255
|
+
}, E = (e, t) => {
|
|
256
|
+
let n = w(e, t);
|
|
257
|
+
return g.isEffect(n) ? n : g.succeed(n);
|
|
258
|
+
}, O = () => {
|
|
259
|
+
let n = o.computedCache, r = u.descriptor.cache;
|
|
260
|
+
if (n === void 0 || r === void 0 || l.has(u.descriptor.name)) return;
|
|
261
|
+
let i = n.policyFor(r);
|
|
262
|
+
if (i === void 0) return;
|
|
263
|
+
let a = f.subject, s = G(u), c = t({
|
|
264
|
+
name: u.descriptor.name,
|
|
265
|
+
codeIdentity: n.codeIdentity,
|
|
266
|
+
output: u.descriptor.output,
|
|
267
|
+
input: u.descriptor.input,
|
|
268
|
+
decodedInput: d,
|
|
269
|
+
scope: i.scope,
|
|
270
|
+
subject: a,
|
|
271
|
+
rowFilter: f.rowFilter,
|
|
272
|
+
declaredSources: s
|
|
273
|
+
});
|
|
274
|
+
if ("bypass" in c) c.bypass === "input-not-encodable" && n.notice(u.descriptor.name, c.bypass, `${u.descriptor.name}: \`cache:\` NOT applied — the input does not encode through its \`input\` schema, so it has no key.`);
|
|
275
|
+
else return e({
|
|
276
|
+
cache: n,
|
|
277
|
+
policy: i,
|
|
278
|
+
key: c.key,
|
|
279
|
+
name: u.descriptor.name,
|
|
280
|
+
sources: s,
|
|
281
|
+
output: u.descriptor.output,
|
|
282
|
+
subject: f.subject,
|
|
283
|
+
rowFilter: f.rowFilter,
|
|
284
|
+
ctx: v,
|
|
285
|
+
...f.signal === void 0 ? {} : { signal: f.signal },
|
|
286
|
+
execute: (e, t) => {
|
|
287
|
+
let n = h(() => u.executor(d, e));
|
|
288
|
+
return g.isEffect(n) ? T(_(D(n, t), v.store), f.signal === void 0 ? void 0 : { signal: f.signal }) : Promise.resolve(n);
|
|
289
|
+
},
|
|
290
|
+
onDescriptor: () => {
|
|
291
|
+
l.add(u.descriptor.name);
|
|
292
|
+
},
|
|
293
|
+
isDescriptor: (e) => W(U(e)),
|
|
294
|
+
unwrap: (e) => U(e)
|
|
295
|
+
}).pipe(g.flatMap(({ value: e, dependencies: t }) => E(e, t)));
|
|
296
|
+
}, k = () => {
|
|
297
|
+
i(u.descriptor.name, G(u)), r();
|
|
298
|
+
let e = O();
|
|
299
|
+
if (e !== void 0) return e;
|
|
300
|
+
let t = h(() => u.executor(d, v));
|
|
301
|
+
return g.isEffect(t) ? _(D(t, f.subject), v.store).pipe(g.flatMap(E)) : t instanceof Promise ? g.promise(() => t).pipe(g.flatMap(E)) : w(t);
|
|
302
|
+
}, A = () => {
|
|
303
|
+
let e = u.descriptor.guards;
|
|
304
|
+
return (!e || e.length === 0) && o.defaultDeny !== !0 && f.subject.type !== "service" ? k() : x(f.subject, e, d, {
|
|
305
|
+
defaultDeny: o.defaultDeny === !0,
|
|
306
|
+
procedure: u.descriptor.name
|
|
307
|
+
}).pipe(g.flatMap((e) => {
|
|
308
|
+
if (e) return g.fail(e);
|
|
309
|
+
let t = k();
|
|
310
|
+
return g.isEffect(t) ? t : g.succeed(t);
|
|
247
311
|
}));
|
|
248
312
|
};
|
|
249
|
-
if (!
|
|
250
|
-
let
|
|
251
|
-
let e =
|
|
252
|
-
return
|
|
313
|
+
if (!o.interceptor) return A();
|
|
314
|
+
let N = g.suspend(() => {
|
|
315
|
+
let e = A();
|
|
316
|
+
return g.isEffect(e) ? e : g.succeed(e);
|
|
253
317
|
});
|
|
254
|
-
return
|
|
255
|
-
tag:
|
|
318
|
+
return o.interceptor(N, {
|
|
319
|
+
tag: u.descriptor.name,
|
|
256
320
|
kind: "query",
|
|
257
|
-
input:
|
|
258
|
-
subject:
|
|
259
|
-
traceId:
|
|
260
|
-
...
|
|
261
|
-
...
|
|
321
|
+
input: d,
|
|
322
|
+
subject: f.subject,
|
|
323
|
+
traceId: f.traceId,
|
|
324
|
+
...f.spanId === void 0 ? {} : { spanId: f.spanId },
|
|
325
|
+
...M(f)
|
|
262
326
|
});
|
|
263
|
-
},
|
|
264
|
-
let
|
|
265
|
-
if (
|
|
266
|
-
let
|
|
327
|
+
}, Z = (e) => async (t, n, r) => {
|
|
328
|
+
let i = await j(r), a = Y(e, "rpc")(t, n)(i), o = g.isEffect(a) ? await E(a) : a;
|
|
329
|
+
if (c(o)) return o.value;
|
|
330
|
+
let s = e.buildContext(i), l = await e.queryRows(o, i, s.store), u = await K(t, n, e.defaultDeny)(i.subject)();
|
|
267
331
|
if (u) throw u;
|
|
268
332
|
return l;
|
|
269
|
-
},
|
|
270
|
-
let
|
|
333
|
+
}, Q = (e) => (t, n, r, i) => {
|
|
334
|
+
let a = !1, s;
|
|
271
335
|
return (async () => {
|
|
272
336
|
try {
|
|
273
|
-
let l = await
|
|
274
|
-
|
|
337
|
+
let l = await j(r), u = Y(e, "subscriptions")(t, n)(l), d = g.isEffect(u) ? await E(u) : u, f = (e) => i(e), p = c(d) ? await e.subscribeComputed(d, f, l) : await e.subscribeDescriptor(d, f, l, K(t, n, e.defaultDeny)(l.subject), o(l.subject));
|
|
338
|
+
a ? p() : s = p;
|
|
275
339
|
} catch (e) {
|
|
276
|
-
|
|
340
|
+
i({
|
|
277
341
|
_tag: "error",
|
|
278
342
|
error: e instanceof Error ? {
|
|
279
343
|
message: e.message,
|
|
@@ -282,24 +346,29 @@ var b = (e, t) => d.runPromiseExit(e, t).then((e) => {
|
|
|
282
346
|
});
|
|
283
347
|
}
|
|
284
348
|
})(), () => {
|
|
285
|
-
|
|
349
|
+
a = !0, s?.();
|
|
286
350
|
};
|
|
287
|
-
},
|
|
288
|
-
name:
|
|
351
|
+
}, $ = (e) => (t, n, r) => I({
|
|
352
|
+
name: t.descriptor.name,
|
|
289
353
|
kind: "action",
|
|
290
|
-
input:
|
|
291
|
-
requestContext:
|
|
292
|
-
...
|
|
293
|
-
target:
|
|
294
|
-
...
|
|
295
|
-
...
|
|
354
|
+
input: n,
|
|
355
|
+
requestContext: r,
|
|
356
|
+
...F(e.outcomeOutbox, r),
|
|
357
|
+
target: N(t),
|
|
358
|
+
...e.interceptor ? { interceptor: e.interceptor } : {},
|
|
359
|
+
...e.recordMetric ? { recordMetric: e.recordMetric } : {},
|
|
296
360
|
runExecutor: async () => {
|
|
297
|
-
await
|
|
298
|
-
let a =
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
361
|
+
await q(t, "action", { defaultDeny: e.defaultDeny === !0 })(n, r);
|
|
362
|
+
let a = {
|
|
363
|
+
...r,
|
|
364
|
+
subject: S(r.subject)
|
|
365
|
+
};
|
|
366
|
+
await k(t.descriptor, "action", a, n);
|
|
367
|
+
let o = e.buildContext(await j(a));
|
|
368
|
+
i(t.descriptor.name, G(t));
|
|
369
|
+
let s = e.measureSync ? e.measureSync(() => t.executor(n, o)) : t.executor(n, o), c = g.isEffect(s) ? await e.runEffect(D(s, a.subject), o.store) : await s;
|
|
370
|
+
return e.settleCacheInvalidations !== void 0 && await e.settleCacheInvalidations(), c;
|
|
302
371
|
}
|
|
303
372
|
});
|
|
304
373
|
//#endregion
|
|
305
|
-
export {
|
|
374
|
+
export { R as DEFAULT_MUTATION_REPLAY_ATTEMPTS, P as applyDeclaredRelations, $ as makeActionRunner, q as makeMutationReplayAdmission, V as makeMutationRunner, Z as makeOneShotQueryRunner, Y as makeQueryDescriptorProducer, K as makeQueryReauthorizer, Q as makeQuerySubscriber, H as makeWorkflowStartRunner, E as runProvidedEffect, B as runWithDeadlockRetry, j as withRowFilter, J as withScopedRequest };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/setReadScopes.ts
|
|
2
|
+
var e = [
|
|
3
|
+
"crossTenant",
|
|
4
|
+
"includeDeleted",
|
|
5
|
+
"includeExpired"
|
|
6
|
+
], t = (t, n) => {
|
|
7
|
+
let r = (t, i) => {
|
|
8
|
+
let a = t;
|
|
9
|
+
for (let t of e) i?.[t] === !0 && a[t] !== !0 && (a = {
|
|
10
|
+
...a,
|
|
11
|
+
[t]: !0
|
|
12
|
+
});
|
|
13
|
+
let o = a.setOp;
|
|
14
|
+
if (o === void 0) return n(a);
|
|
15
|
+
if (o.queries.length < 2) throw Error("A set operation requires at least two inputs");
|
|
16
|
+
let s = o.queries.map((e) => r(e, a));
|
|
17
|
+
return s.every((e, t) => e === o.queries[t]) ? a : {
|
|
18
|
+
...a,
|
|
19
|
+
setOp: {
|
|
20
|
+
...o,
|
|
21
|
+
queries: s
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
return r(t);
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { t as mapSetReadScopes };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//#region src/snapshotValueCodec.ts
|
|
2
|
+
var e = "\0", t = `${e}d`, n = `${e}n`, r = `${e}b`, i = `${e}o`, a = 1, o = (e) => {
|
|
3
|
+
if (typeof e != "object" || !e) return !1;
|
|
4
|
+
let t = Object.getPrototypeOf(e);
|
|
5
|
+
return t === Object.prototype || t === null;
|
|
6
|
+
}, s = (a) => {
|
|
7
|
+
if (typeof a != "object" || !a) return typeof a == "bigint" ? { [n]: a.toString() } : a;
|
|
8
|
+
if (a instanceof Date) return { [t]: Number.isNaN(a.getTime()) ? null : a.toISOString() };
|
|
9
|
+
if (a instanceof Uint8Array) return { [r]: Buffer.from(a.buffer, a.byteOffset, a.byteLength).toString("base64") };
|
|
10
|
+
if (Array.isArray(a)) return a.map(s);
|
|
11
|
+
if (o(a)) {
|
|
12
|
+
let t = {}, n = !1;
|
|
13
|
+
for (let [r, i] of Object.entries(a)) r.startsWith(e) && (n = !0), t[r] = s(i);
|
|
14
|
+
return n ? { [i]: t } : t;
|
|
15
|
+
}
|
|
16
|
+
throw TypeError("A snapshot value carries a non-plain object; it cannot be cached faithfully.");
|
|
17
|
+
}, c = (e) => {
|
|
18
|
+
if (typeof e != "object" || !e) return e;
|
|
19
|
+
if (Array.isArray(e)) return e.map(c);
|
|
20
|
+
let a = e, o = Object.keys(a);
|
|
21
|
+
if (o.length === 1) {
|
|
22
|
+
let e = o[0], s = a[e];
|
|
23
|
+
if (e === t) return s === null ? /* @__PURE__ */ new Date(NaN) : new Date(s);
|
|
24
|
+
if (e === n) return BigInt(s);
|
|
25
|
+
if (e === r) return new Uint8Array(Buffer.from(s, "base64"));
|
|
26
|
+
if (e === i) {
|
|
27
|
+
let e = {};
|
|
28
|
+
for (let [t, n] of Object.entries(s)) e[t] = c(n);
|
|
29
|
+
return e;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
let s = {};
|
|
33
|
+
for (let [e, t] of Object.entries(a)) s[e] = c(t);
|
|
34
|
+
return s;
|
|
35
|
+
}, l = (e) => ({
|
|
36
|
+
v: a,
|
|
37
|
+
value: s(e)
|
|
38
|
+
}), u = (e) => {
|
|
39
|
+
if (o(e) && e.v === a && "value" in e) try {
|
|
40
|
+
return { value: c(e.value) };
|
|
41
|
+
} catch {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
46
|
+
export { u as decodeSnapshotValue, l as encodeSnapshotValue };
|
package/dist/sourceResolution.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { captureOptionalQuerySources as e, declaredReactivityChannelKeys as t, isReactivityChannelKey as n, sourceKeys as r } from "@voltro/protocol";
|
|
2
2
|
//#region src/sourceResolution.ts
|
|
3
|
-
var
|
|
3
|
+
var i = (e, t) => {
|
|
4
4
|
let n, r = 0;
|
|
5
5
|
for (let i of t) {
|
|
6
6
|
let t = 0;
|
|
@@ -11,32 +11,42 @@ var r = (e, t) => {
|
|
|
11
11
|
o > r && o >= .6 && (r = o, n = i);
|
|
12
12
|
}
|
|
13
13
|
return n;
|
|
14
|
-
},
|
|
15
|
-
let
|
|
16
|
-
for (let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
14
|
+
}, a = (a, o) => {
|
|
15
|
+
let s = t(), c = [], l = /* @__PURE__ */ new Map();
|
|
16
|
+
for (let t of a) {
|
|
17
|
+
let a = new Set(e(t.name, t.source, t.optionalSource));
|
|
18
|
+
for (let e of r(t.source)) if (n(e)) {
|
|
19
|
+
if (s.has(e)) continue;
|
|
20
|
+
c.push({
|
|
21
|
+
procedure: t.name,
|
|
22
|
+
source: e,
|
|
23
|
+
didYouMean: void 0,
|
|
24
|
+
channel: !0,
|
|
25
|
+
...a.has(e) ? { optional: !0 } : {}
|
|
26
|
+
});
|
|
27
|
+
} else o.size === 0 || o.has(e) || (l.has(e) || l.set(e, i(e, o)), c.push({
|
|
28
|
+
procedure: t.name,
|
|
29
|
+
source: e,
|
|
30
|
+
didYouMean: a.has(e) ? void 0 : l.get(e),
|
|
31
|
+
channel: !1,
|
|
32
|
+
...a.has(e) ? { optional: !0 } : {}
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
return c;
|
|
36
|
+
}, o = (e) => {
|
|
32
37
|
if (e.length === 0) return;
|
|
33
|
-
let t = e.
|
|
34
|
-
|
|
38
|
+
let t = e.filter((e) => e.optional === !0);
|
|
39
|
+
if (t.length > 0) {
|
|
40
|
+
let n = o(e.filter((e) => e.optional !== !0)), r = t.map((e) => ` ${e.procedure}: optional integration source '${e.source}' is unavailable`);
|
|
41
|
+
return [n, `${t.length} optional integration source(s) are unavailable:\n${r.join("\n")}\nTheir observers remain declared. Installed sources still trigger recomputation; executor authorization still applies.`].filter((e) => e !== void 0).join("\n\n");
|
|
42
|
+
}
|
|
43
|
+
let n = e.map((e) => e.channel ? ` ${e.procedure}: source '${e.source}' names a reactivity channel nobody declared` : ` ${e.procedure}: source '${e.source}' matches no declared table` + (e.didYouMean === void 0 ? "" : ` — did you mean '${e.didYouMean}'?`)), r = e.some((e) => e.channel) ? "\nFor the `channel:` entries: declare it with `reactivityChannel(<name>)` and pass the\nCHANNEL as `source:`, not its key as a string. Authoring against the object is what\nmakes a channel source impossible to leave stale — you cannot import a declaration\nthat does not exist." : "";
|
|
44
|
+
return `${e.length} reactive source(s) name a table that does not exist:\n${n.join("\n")}\n
|
|
35
45
|
These queries are NOT broken. They serve their first snapshot and then never
|
|
36
46
|
update again, which is indistinguishable from "nothing has changed" — so the
|
|
37
47
|
symptom is silence, and silence is what this surface exists to eliminate.
|
|
38
48
|
A \`source:\` is a STRING, so \`tsc\` cannot see a stale one and a rename leaves it
|
|
39
|
-
behind quietly.` +
|
|
49
|
+
behind quietly.` + r;
|
|
40
50
|
};
|
|
41
51
|
//#endregion
|
|
42
|
-
export {
|
|
52
|
+
export { o as formatUnresolvedSources, a as unresolvedSources };
|