@voltro/runtime 0.85.0 → 0.86.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 +666 -0
- package/THIRD-PARTY-NOTICES.md +5 -33
- package/dist/aggregate.js +42 -0
- package/dist/aggregateExtrema.js +80 -0
- package/dist/aggregateIvm.js +115 -0
- package/dist/analyticsMirror.js +228 -0
- package/dist/analyticsSink.js +38 -0
- package/dist/apiKeyUsage.js +33 -0
- package/dist/apiKeys.js +223 -0
- package/dist/apiKeysWiring.js +114 -0
- package/dist/approvalBuiltins.js +10 -0
- package/dist/approvals.js +269 -0
- package/dist/authMiddlewareLayer.js +47 -0
- package/dist/bindEvent.js +72 -0
- package/dist/bootListener.js +76 -0
- package/dist/bootRefusal.js +7 -0
- package/dist/bootStoreCodec.js +70 -0
- package/dist/businessRules.js +67 -0
- package/dist/changeClaimsTable.js +12 -0
- package/dist/circuitBreaker.js +72 -0
- package/dist/columnOnUpdate.js +23 -0
- package/dist/composeAnalytics.js +108 -0
- package/dist/computedQuery.js +4 -0
- package/dist/connectionBuiltins.js +81 -0
- package/dist/connectionCredentials.js +66 -0
- package/dist/connectionState.js +34 -0
- package/dist/connectionVault.js +410 -0
- package/dist/connectionsFacade.js +54 -0
- package/dist/coordinatedSchedule.js +139 -0
- package/dist/crdtHistory.js +138 -0
- package/dist/crdtMerge.js +179 -0
- package/dist/crdtVersionsTable.js +25 -0
- package/dist/credentialBound.js +12 -0
- package/dist/crud.js +72 -0
- package/dist/dataStore.js +679 -0
- package/dist/dataloader.js +61 -0
- package/dist/declaredTablesGuard.js +48 -0
- package/dist/defineExecutor.js +4 -0
- package/dist/dependencyGraph.js +32 -0
- package/dist/devices.js +228 -0
- package/dist/devicesWiring.js +168 -0
- package/dist/dialectReplicationAdapter.js +29 -0
- package/dist/dispatcher.js +447 -0
- package/dist/effectStore.js +71 -0
- package/dist/eventBus.js +260 -0
- package/dist/eventPublish.js +49 -0
- package/dist/events.js +193 -0
- package/dist/expectation.js +52 -0
- package/dist/expectationEvaluator.js +308 -0
- package/dist/experiment.js +96 -0
- package/dist/experimentEvaluator.js +245 -0
- package/dist/externalizedTasks.js +25 -0
- package/dist/fieldCipher.js +61 -0
- package/dist/fingerprint.js +21 -0
- package/dist/finops.js +42 -0
- package/dist/finopsAccountant.js +216 -0
- package/dist/handlerBody.js +8 -0
- package/dist/healthProbes.js +55 -0
- package/dist/httpClientSsrf.js +49 -0
- package/dist/httpClientTracing.js +11 -0
- package/dist/httpCompression.js +76 -0
- package/dist/httpKeepAlive.js +12 -0
- package/dist/httpRouteMounts.js +47 -0
- package/dist/idempotencyStore.js +70 -0
- package/dist/idleDetector.js +21 -0
- package/dist/index.d.ts +88 -69
- package/dist/index.js +144 -15292
- package/dist/insertRequiredColumns.js +19 -0
- package/dist/inspectWorkflow.js +1 -0
- package/dist/instanceMembership.js +98 -0
- package/dist/ivm.js +125 -0
- package/dist/kvDataStore.js +86 -0
- package/dist/kvFacade.js +32 -0
- package/dist/matcher.js +304 -0
- package/dist/memoryColumnDefaults.js +11 -0
- package/dist/memoryQueryJoins.js +114 -0
- package/dist/metrics.js +161 -0
- package/dist/observability.js +123 -0
- package/dist/observedGraph.js +52 -0
- package/dist/originGuard.js +116 -0
- package/dist/outbox.js +352 -0
- package/dist/pluginRefRules.js +65 -0
- package/dist/policyGuardResolver.js +55 -0
- package/dist/preview.js +62 -0
- package/dist/projectedRows.js +12 -0
- package/dist/provenance.js +63 -0
- package/dist/rangeIndex.js +89 -0
- package/dist/rawReadScope.js +17 -0
- package/dist/reaction.js +85 -0
- package/dist/reactiveConfig.js +11 -0
- package/dist/readClassification.js +57 -0
- package/dist/readRecorder.js +66 -0
- package/dist/rebac.js +104 -0
- package/dist/rebacInterceptor.js +81 -0
- package/dist/registry.js +29 -0
- package/dist/relevantFields.js +65 -0
- package/dist/replicaHealth.js +42 -0
- package/dist/replicaLocality.js +44 -0
- package/dist/replicaObservations.js +121 -0
- package/dist/replicaSelection.js +32 -0
- package/dist/replicatedDataStore.js +239 -0
- package/dist/requestLoader.js +7 -0
- package/dist/resumeCensus.js +28 -0
- package/dist/revalidation.js +22 -0
- package/dist/rowFilter.js +65 -0
- package/dist/rowStateBytes.js +45 -0
- package/dist/rpcBodyCap.js +63 -0
- package/dist/rpcConnections.js +83 -0
- package/dist/rpcDefectDiagnostics.js +15 -0
- package/dist/rpcServer.js +992 -0
- package/dist/runAsSystem.js +23 -0
- package/dist/rywPositionStore.js +84 -0
- package/dist/schedule.js +23 -0
- package/dist/scheduleBackfillRequests.js +151 -0
- package/dist/scheduleClaimsTable.js +11 -0
- package/dist/scheduleRunsTable.js +37 -0
- package/dist/scheduler.js +835 -0
- package/dist/schemaRegistry.js +65 -0
- package/dist/secretsResolver.js +35 -0
- package/dist/securityHeaders.js +33 -0
- package/dist/servePipeline.js +305 -0
- package/dist/serverOnlyAudit.js +66 -0
- package/dist/serverTracer.js +15 -0
- package/dist/serviceCredentials.js +40 -0
- package/dist/singleNodeOrchestrator.js +91 -0
- package/dist/sourceResolution.js +42 -0
- package/dist/storeMiddleware.js +880 -0
- package/dist/storeQuery.js +204 -0
- package/dist/storeRead.js +10 -0
- package/dist/subscriber.js +7 -0
- package/dist/subscriptionOutbox.js +139 -0
- package/dist/subscriptionRegistry.js +82 -0
- package/dist/subscriptionResume.js +132 -0
- package/dist/subscriptionSocketMetrics.js +65 -0
- package/dist/systemSubject.js +5 -0
- package/dist/tenantScope.js +23 -0
- package/dist/tenantSelection.js +27 -0
- package/dist/timeline.js +105 -0
- package/dist/traceContext.js +5 -0
- package/dist/traceSink.js +63 -0
- package/dist/traceSpansTable.js +29 -0
- package/dist/traceparent.js +34 -0
- package/dist/transactionSubject.js +12 -0
- package/dist/trustedProxy.js +155 -0
- package/dist/undo.js +129 -0
- package/dist/undoBuiltins.js +69 -0
- package/dist/undoCapture.js +74 -0
- package/dist/undoLogTable.js +16 -0
- package/dist/upsertBinding.js +20 -0
- package/dist/wakeOrchestrator.js +34 -0
- package/dist/wakeRegistry.js +71 -0
- package/dist/wakeRouter.js +63 -0
- package/dist/wakeSupervisor.js +62 -0
- package/dist/wakeupsTable.js +12 -0
- package/dist/webSocketGatewayRuntime.js +114 -0
- package/dist/webhookVerification.js +18 -0
- package/dist/wireColumnStrip.js +84 -0
- package/dist/workflowReadBuiltins.js +87 -0
- package/dist/workflowRuntime.js +708 -0
- package/package.json +7 -7
|
@@ -0,0 +1,880 @@
|
|
|
1
|
+
import { isolateRawReadScope as e, rawSqlPreview as t, recordRawRead as n } from "./rawReadScope.js";
|
|
2
|
+
import { applySealedWrite as r, assertCrdtUpdateAdmissible as i, mergeCrdtColumnsIntoPatch as a, patchTouchesCrdt as o } from "./crdtMerge.js";
|
|
3
|
+
import { NO_ROW_FILTER as s, applyRowFilter as c, rowFilterRegistered as l } from "./rowFilter.js";
|
|
4
|
+
import { readMaybeOne as u } from "./storeRead.js";
|
|
5
|
+
import { CRDT_VERSIONS_TABLE as d } from "./crdtVersionsTable.js";
|
|
6
|
+
import { getFieldCipher as f } from "./fieldCipher.js";
|
|
7
|
+
import { observeStore as p } from "./observedGraph.js";
|
|
8
|
+
import { upsertConflictId as m } from "./upsertBinding.js";
|
|
9
|
+
import { applyColumnOnUpdate as h } from "./columnOnUpdate.js";
|
|
10
|
+
import { prepareInsertRequiredColumns as g } from "./insertRequiredColumns.js";
|
|
11
|
+
import { makeFluentStore as _, missingRowError as v } from "./storeQuery.js";
|
|
12
|
+
import { Schema as ee, SchemaIssue as te } from "effect";
|
|
13
|
+
import { INITIAL_VERSION as ne, VersionConflict as re, and as y, classifyConstraintViolation as ie, decryptFieldsOnRead as ae, deserializeArraysOnRead as oe, encryptFieldsForWrite as se, encryptFieldsForWriteBatch as ce, encryptedColumnsOf as le, eq as b, extractDbCause as ue, generateId as de, getRelations as fe, getTable as x, gt as pe, inSet as me, isCompositeRowKey as he, isNull as S, jsonPatchAssignments as ge, missingConflictColumns as _e, missingRequiredColumns as ve, or as ye, planVersionedUpdate as be, rowKeyColumns as xe, rowKeyIdentity as C, serializeArraysForWrite as Se, settleVersionedUpdate as Ce, storeRefusalOf as we, upsertUpdateValues as Te } from "@voltro/database";
|
|
14
|
+
import { ConstraintViolation as Ee, TableValidationFailed as w, TenantRowNotFound as De, TenantScopeViolation as Oe, ValidationError as ke, isMachineSubject as Ae, subjectAuditActorId as T } from "@voltro/protocol";
|
|
15
|
+
import { createLogger as je } from "@voltro/logger";
|
|
16
|
+
import { defaultCrdtBackend as E } from "@voltro/local-first";
|
|
17
|
+
//#region src/storeMiddleware.ts
|
|
18
|
+
var Me = (e, t, n) => {
|
|
19
|
+
let r = fe(e);
|
|
20
|
+
if (r === void 0) return t;
|
|
21
|
+
let i = {};
|
|
22
|
+
for (let [a, o] of Object.entries(t)) {
|
|
23
|
+
if (o === !1 || o === void 0) {
|
|
24
|
+
i[a] = o;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
let t = r[a];
|
|
28
|
+
if (t === void 0) {
|
|
29
|
+
i[a] = o;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
let s = t.through;
|
|
33
|
+
if (s !== void 0) {
|
|
34
|
+
let t;
|
|
35
|
+
try {
|
|
36
|
+
t = s().tableName;
|
|
37
|
+
} catch {
|
|
38
|
+
t = void 0;
|
|
39
|
+
}
|
|
40
|
+
if (t !== void 0 && n(t) !== void 0) throw Error(`row filter: the junction table '${t}' behind relation '${a}' on '${e}' is row-filtered, and a many-to-many junction is read below the seam that could narrow it — its rows would be joined unfiltered. Refusing the read rather than serving it.\n → read '${t}' as its own query (it is filtered there), or\n → drop '${a}' from this .with(...).`);
|
|
41
|
+
}
|
|
42
|
+
let c;
|
|
43
|
+
try {
|
|
44
|
+
c = t.target().tableName;
|
|
45
|
+
} catch {
|
|
46
|
+
c = void 0;
|
|
47
|
+
}
|
|
48
|
+
let l = o === !0 ? {} : { ...o };
|
|
49
|
+
if (c !== void 0) {
|
|
50
|
+
let e = n(c);
|
|
51
|
+
if (e !== void 0) {
|
|
52
|
+
let t = l.where;
|
|
53
|
+
l.where = t === void 0 ? e : y(t, e);
|
|
54
|
+
}
|
|
55
|
+
let t = l.with;
|
|
56
|
+
t !== void 0 && (l.with = Me(c, t, n));
|
|
57
|
+
}
|
|
58
|
+
i[a] = l;
|
|
59
|
+
}
|
|
60
|
+
return i;
|
|
61
|
+
}, D = "id", Ne = 3, O = 8, Pe = (e) => "descriptor" in e ? e.descriptor : e, Fe = (e, t) => {
|
|
62
|
+
let n = {};
|
|
63
|
+
for (let r of t) e[r] !== void 0 && (n[r] = e[r]);
|
|
64
|
+
return n;
|
|
65
|
+
}, k = "cannot insert into tenant-scoped table without an authenticated tenant — subject.tenantId is null. Either authenticate first or pass tenantId explicitly in the row (admin tooling).", Ie = (e) => {
|
|
66
|
+
throw new Oe({
|
|
67
|
+
table: e,
|
|
68
|
+
reason: k
|
|
69
|
+
});
|
|
70
|
+
}, Le = (e) => T(e), Re = (fe, T) => {
|
|
71
|
+
let k = p(fe);
|
|
72
|
+
e();
|
|
73
|
+
let A = Le(T.subject), M = T.subject.tenantId;
|
|
74
|
+
if (T.rowFilter === void 0 && !Ae(T.subject) && l()) throw Error("row filter registered, but this store was scoped without one — refusing to serve an unfiltered read.\n\nThis app called `setRowFilter`, so every scoped store must receive a resolved `rowFilter` (the serve pipeline's `withRowFilter` does this per request). Reaching here with none means a read path was built outside that spine, and continuing would serve rows the filter exists to hide — silently, which is how this was found in the first place.\n\nIf this path is deliberately unfiltered (a system sweep, a migration), pass `rowFilter: NO_ROW_FILTER` explicitly.");
|
|
75
|
+
let N = T.rowFilter ?? s, P = (e, t) => {
|
|
76
|
+
let n = { ...t }, r = T.schemaRegistry, i = r.idScheme(e);
|
|
77
|
+
if (i !== void 0 && n[D] == null) {
|
|
78
|
+
if (i.kind === "numeric") delete n[D];
|
|
79
|
+
else {
|
|
80
|
+
let t = de(i, e);
|
|
81
|
+
t !== null && (n[D] = t);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
let a = r.versionColumn(e);
|
|
85
|
+
if (a !== void 0) {
|
|
86
|
+
let e = n[a];
|
|
87
|
+
(typeof e != "number" || !Number.isFinite(e)) && (n[a] = ne);
|
|
88
|
+
}
|
|
89
|
+
if (r.hasAudit(e)) {
|
|
90
|
+
let e = /* @__PURE__ */ new Date();
|
|
91
|
+
"createdAt" in n || (n.createdAt = e), "updatedAt" in n || (n.updatedAt = e), A !== null && ("createdBy" in n || (n.createdBy = A), "updatedBy" in n || (n.updatedBy = A));
|
|
92
|
+
}
|
|
93
|
+
r.hasTenant(e) && ("tenantId" in n || (M === null && Ie(e), n.tenantId = M));
|
|
94
|
+
let o = r.defaultFactories(e);
|
|
95
|
+
if (o.size > 0) for (let [e, t] of o) (!(e in n) || n[e] === void 0) && (n[e] = t());
|
|
96
|
+
let s = r.computedFields(e);
|
|
97
|
+
if (s.size > 0) for (let [e, t] of s) n[e] = t(n);
|
|
98
|
+
let c = r.generatedColumns(e);
|
|
99
|
+
if (c.size > 0) for (let e of c) delete n[e];
|
|
100
|
+
return n;
|
|
101
|
+
}, F = (e, t, n = []) => {
|
|
102
|
+
let r = h(T.schemaRegistry, e, t, n);
|
|
103
|
+
if (!T.schemaRegistry.hasAudit(e)) return r;
|
|
104
|
+
let i = { ...r };
|
|
105
|
+
return "updatedAt" in i || (i.updatedAt = /* @__PURE__ */ new Date()), A !== null && !("updatedBy" in i) && (i.updatedBy = A), i;
|
|
106
|
+
}, I = async (e, t, n, r) => {
|
|
107
|
+
try {
|
|
108
|
+
return await r();
|
|
109
|
+
} catch (r) {
|
|
110
|
+
let i = we(r);
|
|
111
|
+
if (i !== void 0) throw new Ee({
|
|
112
|
+
kind: i.kind,
|
|
113
|
+
table: e,
|
|
114
|
+
operation: t,
|
|
115
|
+
...i.constraint === void 0 ? {} : { constraint: i.constraint },
|
|
116
|
+
...i.column === void 0 ? {} : { column: i.column },
|
|
117
|
+
detail: i.detail
|
|
118
|
+
});
|
|
119
|
+
let a = ue(r), o = ie(a, t);
|
|
120
|
+
if (o === void 0) throw r;
|
|
121
|
+
if (T.schemaRegistry.hasTenant(e) && (o.kind === "foreignKey" || o.kind === "foreignKeyInUse")) {
|
|
122
|
+
let t = n?.tenantId, r = `${a.dbConstraint ?? ""} ${a.dbColumn ?? ""} ${a.dbMessage ?? ""} ${a.dbCauseChain ?? ""}`.toLowerCase();
|
|
123
|
+
if (r.includes("tenantid") || /\btenants\b/.test(r) || t != null && r.includes(String(t).toLowerCase())) throw new Oe({
|
|
124
|
+
table: e,
|
|
125
|
+
reason: t == null ? "write references a tenant that does not exist" : `tenant '${String(t)}' does not exist — seed the row in \`tenants\`, or fix how the request resolved this tenant (subject.tenantId / the x-tenant header / the dev TENANT fallback)`
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
throw new Ee({
|
|
129
|
+
kind: o.kind,
|
|
130
|
+
table: e,
|
|
131
|
+
operation: t,
|
|
132
|
+
...o.constraint === void 0 ? {} : { constraint: o.constraint },
|
|
133
|
+
...o.column === void 0 ? {} : { column: o.column }
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}, ze = (e, t, n) => {
|
|
137
|
+
let r = T.schemaRegistry.computedFields(e);
|
|
138
|
+
if (r.size === 0) return n;
|
|
139
|
+
let i = {
|
|
140
|
+
...t,
|
|
141
|
+
...n
|
|
142
|
+
}, a = { ...n };
|
|
143
|
+
for (let [e, t] of r) a[e] = t(i);
|
|
144
|
+
return a;
|
|
145
|
+
}, L = (e, t) => {
|
|
146
|
+
let n = T.schemaRegistry.validatePatchSchema(e);
|
|
147
|
+
if (n === void 0) return t;
|
|
148
|
+
let r = ee.decodeUnknownResult(n)(t);
|
|
149
|
+
if (r._tag === "Success") return t;
|
|
150
|
+
let i = te.makeFormatterStandardSchemaV1()(r.failure.issue).issues.map((e) => ({
|
|
151
|
+
path: (e.path ?? []).length === 0 ? "<root>" : (e.path ?? []).join("."),
|
|
152
|
+
message: e.message
|
|
153
|
+
})), a = i[0];
|
|
154
|
+
throw new w({
|
|
155
|
+
table: e,
|
|
156
|
+
summary: a === void 0 ? "patch validation failed" : `${a.path}: ${a.message}`,
|
|
157
|
+
issues: i
|
|
158
|
+
});
|
|
159
|
+
}, Be = () => {
|
|
160
|
+
let e = { deletedAt: /* @__PURE__ */ new Date() };
|
|
161
|
+
return A !== null && (e.deletedBy = A), e;
|
|
162
|
+
}, Ve = (e, t, n) => {
|
|
163
|
+
let r = _e(x(e), n, t);
|
|
164
|
+
if (r.length !== 0) throw new w({
|
|
165
|
+
table: e,
|
|
166
|
+
summary: `upsert conflictColumns [${n.map((e) => `'${e}'`).join(", ")}] cannot match: ` + r.map((e) => e.reason === "null" ? `'${e.column}' is NULL` : `'${e.column}' is absent`).join(", "),
|
|
167
|
+
issues: r.map((e) => ({
|
|
168
|
+
path: e.column,
|
|
169
|
+
message: e.reason === "null" ? "named in conflictColumns but NULL — NULL never matches a unique conflict target, so this write would always INSERT. Use a plain insert for NULL-keyed rows, or make the column NOT NULL." : "named in conflictColumns but absent from the payload"
|
|
170
|
+
}))
|
|
171
|
+
});
|
|
172
|
+
}, R = (e, t, n) => {
|
|
173
|
+
let i = T.schemaRegistry.crdtColumns(e);
|
|
174
|
+
o(i, t) && (t = a(i, void 0, t, e));
|
|
175
|
+
for (let n of T.schemaRegistry.sealedColumns(e)) {
|
|
176
|
+
let i = t[n];
|
|
177
|
+
i instanceof Uint8Array && (t = {
|
|
178
|
+
...t,
|
|
179
|
+
[n]: r(e, n, void 0, i).log
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
let s = x(e);
|
|
183
|
+
if (s !== void 0) {
|
|
184
|
+
let r = n === void 0 ? ve(s, t) : n.filter((e) => t[e] === void 0 || t[e] === null);
|
|
185
|
+
if (r.length > 0) throw new w({
|
|
186
|
+
table: e,
|
|
187
|
+
summary: `missing required column${r.length > 1 ? "s" : ""} ${r.map((e) => `'${e}'`).join(", ")} — NOT NULL with no default and not auto-stamped`,
|
|
188
|
+
issues: r.map((e) => ({
|
|
189
|
+
path: e,
|
|
190
|
+
message: "required (NOT NULL, no default) but absent from the payload"
|
|
191
|
+
}))
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
let c = T.schemaRegistry.insertSchema(e);
|
|
195
|
+
if (c === void 0) return t;
|
|
196
|
+
let l = ee.decodeUnknownResult(c)(t);
|
|
197
|
+
if (l._tag === "Success") return t;
|
|
198
|
+
let u = te.makeFormatterStandardSchemaV1()(l.failure.issue).issues.map((e) => ({
|
|
199
|
+
path: (e.path ?? []).length === 0 ? "<root>" : (e.path ?? []).join("."),
|
|
200
|
+
message: e.message
|
|
201
|
+
})), d = u[0];
|
|
202
|
+
throw new w({
|
|
203
|
+
table: e,
|
|
204
|
+
summary: d === void 0 ? "row validation failed" : `${d.path}: ${d.message}`,
|
|
205
|
+
issues: u
|
|
206
|
+
});
|
|
207
|
+
}, z = T.dialect, B = (e, t, n) => {
|
|
208
|
+
let r = x(e), i = z ? Se(t, r, z) : t;
|
|
209
|
+
return se(i, r, f(), n);
|
|
210
|
+
}, V = (e, t) => {
|
|
211
|
+
let n = x(e);
|
|
212
|
+
return n !== void 0 && le(n).some((e) => t[e] !== void 0 && t[e] !== null);
|
|
213
|
+
}, He = (e) => {
|
|
214
|
+
let t = e.projection;
|
|
215
|
+
if (t === void 0 || t.includes(D)) return {
|
|
216
|
+
descriptor: e,
|
|
217
|
+
stripId: !1
|
|
218
|
+
};
|
|
219
|
+
let n = x(e.table);
|
|
220
|
+
return n === void 0 || le(n).length === 0 ? {
|
|
221
|
+
descriptor: e,
|
|
222
|
+
stripId: !1
|
|
223
|
+
} : {
|
|
224
|
+
descriptor: {
|
|
225
|
+
...e,
|
|
226
|
+
projection: [...t, D]
|
|
227
|
+
},
|
|
228
|
+
stripId: !0
|
|
229
|
+
};
|
|
230
|
+
}, Ue = process.env.VOLTRO_FIELD_DECRYPT_ON_ERROR === "null" ? "null" : "throw", We = je({ scope: "store.fieldEncryption" }), Ge = /* @__PURE__ */ new Set(), Ke = (e) => {
|
|
231
|
+
let t = `${e.table}.${e.column}`;
|
|
232
|
+
Ge.has(t) || (Ge.add(t), We.warn("encrypted column degraded to null — could not decrypt with the active key", {
|
|
233
|
+
table: e.table,
|
|
234
|
+
column: e.column,
|
|
235
|
+
reason: e.reason,
|
|
236
|
+
hint: "VOLTRO_FIELD_DECRYPT_ON_ERROR=null is set — this row was likely encrypted under a different key"
|
|
237
|
+
}));
|
|
238
|
+
}, H = (e, t, n) => {
|
|
239
|
+
let r = x(e), i = ae(t, r, f(), {
|
|
240
|
+
onError: Ue,
|
|
241
|
+
...Ue === "null" ? { warn: Ke } : {},
|
|
242
|
+
...n === void 0 ? {} : { rowId: n }
|
|
243
|
+
});
|
|
244
|
+
return z ? oe(i, r, z) : i;
|
|
245
|
+
}, qe = (e) => {
|
|
246
|
+
let t = e.table, n = e.predicate;
|
|
247
|
+
if (!e.crossTenant && M != null && T.schemaRegistry.hasTenant(t)) {
|
|
248
|
+
let e = b("tenantId", M);
|
|
249
|
+
n = n ? y(n, e) : e;
|
|
250
|
+
}
|
|
251
|
+
if (!e.includeDeleted && T.schemaRegistry.hasSoftDelete(t)) {
|
|
252
|
+
let e = S("deletedAt");
|
|
253
|
+
n = n ? y(n, e) : e;
|
|
254
|
+
}
|
|
255
|
+
if (!e.includeExpired && T.schemaRegistry.hasExpires(t)) {
|
|
256
|
+
let e = ye(S("expiresAt"), pe("expiresAt", /* @__PURE__ */ new Date()));
|
|
257
|
+
n = n ? y(n, e) : e;
|
|
258
|
+
}
|
|
259
|
+
n = c(N, t, n);
|
|
260
|
+
let r = e.eager === void 0 ? void 0 : Me(t, e.eager, N);
|
|
261
|
+
return r === void 0 ? n === e.predicate ? e : {
|
|
262
|
+
...e,
|
|
263
|
+
predicate: n
|
|
264
|
+
} : {
|
|
265
|
+
...e,
|
|
266
|
+
predicate: n,
|
|
267
|
+
eager: r
|
|
268
|
+
};
|
|
269
|
+
}, Je = async (e) => {
|
|
270
|
+
let t = He(e), n = await k.query(t.descriptor), r = H(e.table, n);
|
|
271
|
+
return Ye(e.table, r), t.stripId ? r.map((e) => {
|
|
272
|
+
let { [D]: t, ...n } = e;
|
|
273
|
+
return n;
|
|
274
|
+
}) : r;
|
|
275
|
+
}, U = async (e) => Je(qe(e)), W = (e, t, n) => {
|
|
276
|
+
if (he(n)) return;
|
|
277
|
+
let r = T.schemaRegistry.declaredPrimaryKey(e);
|
|
278
|
+
if (r.length === 0 || r.length === 1 && r[0] === "id") return;
|
|
279
|
+
let i = r.map((e) => `${e}: …`).join(", ");
|
|
280
|
+
throw Error(`${t}('${e}', <${typeof n}>, …) cannot address a row: '${e}' has no \`id\` column — its primary key is (${r.join(", ")}). Pass those columns instead:\n store.${t}('${e}', { ${i} }${t === "delete" ? "" : ", patch"})\nThis used to return ${t === "delete" ? "`false`" : "`null`"}, which is also what a missing row returns.`);
|
|
281
|
+
}, G = async (e, t) => {
|
|
282
|
+
if (M === null || !T.schemaRegistry.hasTenant(e)) return;
|
|
283
|
+
let n = xe(t).map(([e, t]) => b(e, t)).reduce((e, t) => e === void 0 ? t : y(e, t), void 0);
|
|
284
|
+
if (!((await k.query({
|
|
285
|
+
table: e,
|
|
286
|
+
predicate: y(n, b("tenantId", M)),
|
|
287
|
+
order: [],
|
|
288
|
+
take: 1,
|
|
289
|
+
skip: void 0,
|
|
290
|
+
projection: xe(t).map(([e]) => e)
|
|
291
|
+
})).length > 0)) throw new De({
|
|
292
|
+
table: e,
|
|
293
|
+
id: C(t),
|
|
294
|
+
reason: "no row with this id in your tenant — it does not exist, or it belongs to another tenant. These are deliberately indistinguishable: reporting them differently would let a caller probe for row ids in other tenants."
|
|
295
|
+
});
|
|
296
|
+
}, K = Symbol.for("@voltro/runtime:tx-fold-releases"), q = Symbol.for("@voltro/runtime:tx-read-versions"), J = (e) => e[q], Y = (e, t) => `${e}\u0000${String(t)}`, Ye = (e, t) => {
|
|
297
|
+
let n = J(k);
|
|
298
|
+
if (n === void 0 || t.length === 0) return;
|
|
299
|
+
let r = T.schemaRegistry.versionColumn(e);
|
|
300
|
+
if (r !== void 0) for (let i of t) {
|
|
301
|
+
let t = i[D], a = i[r];
|
|
302
|
+
typeof t == "string" && typeof a == "number" && Number.isFinite(a) && n.set(Y(e, t), a);
|
|
303
|
+
}
|
|
304
|
+
}, X = (() => {
|
|
305
|
+
let e = globalThis, t = Symbol.for("@voltro/runtime:crdt-fold-locks");
|
|
306
|
+
return e[t] ??= /* @__PURE__ */ new Map();
|
|
307
|
+
})(), Xe = async (e, t, n) => {
|
|
308
|
+
let r = `${e}\u0000${C(t)}`, i = X.get(r) ?? Promise.resolve(), a, o = new Promise((e) => {
|
|
309
|
+
a = e;
|
|
310
|
+
});
|
|
311
|
+
X.set(r, i.then(() => o)), await i;
|
|
312
|
+
try {
|
|
313
|
+
return await n();
|
|
314
|
+
} finally {
|
|
315
|
+
a(), X.get(r) === o && X.delete(r);
|
|
316
|
+
}
|
|
317
|
+
}, Z = async (e, t, n) => {
|
|
318
|
+
let r = T.schemaRegistry.sealedColumns(e);
|
|
319
|
+
if (o(r, n)) {
|
|
320
|
+
let i = {}, a = {};
|
|
321
|
+
for (let [e, t] of Object.entries(n)) (r.has(e) ? i : a)[e] = t;
|
|
322
|
+
let o = await et(e, t, i);
|
|
323
|
+
return o === null || Object.keys(a).length === 0 ? o : Z(e, t, a);
|
|
324
|
+
}
|
|
325
|
+
let a = T.schemaRegistry.crdtColumns(e);
|
|
326
|
+
if (o(a, n)) {
|
|
327
|
+
for (let t of a) t in n && i(e, t, n[t]);
|
|
328
|
+
let r = k[K];
|
|
329
|
+
if (r !== void 0) {
|
|
330
|
+
let i = {}, o = {};
|
|
331
|
+
for (let [e, t] of Object.entries(n)) a.has(e) ? i[e] = t : o[e] = t;
|
|
332
|
+
if (r.push({
|
|
333
|
+
table: e,
|
|
334
|
+
pk: t,
|
|
335
|
+
patch: i
|
|
336
|
+
}), Object.keys(o).length > 0) return Q(e, t, o);
|
|
337
|
+
await G(e, t);
|
|
338
|
+
let s = await k.query({
|
|
339
|
+
table: e,
|
|
340
|
+
predicate: {
|
|
341
|
+
column: D,
|
|
342
|
+
op: "eq",
|
|
343
|
+
value: t
|
|
344
|
+
},
|
|
345
|
+
order: [],
|
|
346
|
+
take: 1,
|
|
347
|
+
skip: void 0,
|
|
348
|
+
projection: void 0
|
|
349
|
+
});
|
|
350
|
+
return s[0] === void 0 ? null : H(e, [s[0]])[0];
|
|
351
|
+
}
|
|
352
|
+
return Xe(e, t, () => Q(e, t, n));
|
|
353
|
+
}
|
|
354
|
+
return Q(e, t, n);
|
|
355
|
+
}, Q = async (e, t, n) => {
|
|
356
|
+
W(e, "update", t), await G(e, t);
|
|
357
|
+
let r = F(e, n), i = T.schemaRegistry.crdtColumns(e);
|
|
358
|
+
if (o(i, r)) return tt(e, t, r, i);
|
|
359
|
+
if (T.schemaRegistry.computedFields(e).size > 0) {
|
|
360
|
+
let n = (await k.query({
|
|
361
|
+
table: e,
|
|
362
|
+
predicate: {
|
|
363
|
+
column: D,
|
|
364
|
+
op: "eq",
|
|
365
|
+
value: t
|
|
366
|
+
},
|
|
367
|
+
order: [],
|
|
368
|
+
take: 1,
|
|
369
|
+
skip: void 0,
|
|
370
|
+
projection: void 0
|
|
371
|
+
}))[0];
|
|
372
|
+
if (n === void 0) return null;
|
|
373
|
+
let i = H(e, [n])[0];
|
|
374
|
+
r = ze(e, i, r);
|
|
375
|
+
}
|
|
376
|
+
r = L(e, r);
|
|
377
|
+
let a = T.schemaRegistry.versionColumn(e), s;
|
|
378
|
+
if (a !== void 0) {
|
|
379
|
+
let n = be({
|
|
380
|
+
versionColumn: a,
|
|
381
|
+
patch: r
|
|
382
|
+
}), i = J(k)?.get(Y(e, C(t))), o = n.expected === void 0 && i !== void 0, c = n.expected ?? i, l = (e) => {
|
|
383
|
+
throw o ? new j(e) : e;
|
|
384
|
+
}, u = async () => {
|
|
385
|
+
let n = await k.query({
|
|
386
|
+
table: e,
|
|
387
|
+
predicate: {
|
|
388
|
+
column: D,
|
|
389
|
+
op: "eq",
|
|
390
|
+
value: t
|
|
391
|
+
},
|
|
392
|
+
order: [],
|
|
393
|
+
take: 1,
|
|
394
|
+
skip: void 0,
|
|
395
|
+
projection: void 0
|
|
396
|
+
}), r = n[0] === void 0 ? void 0 : n[0][a];
|
|
397
|
+
return typeof r == "number" && Number.isFinite(r) ? r : null;
|
|
398
|
+
}, d = await u(), f = Ce({
|
|
399
|
+
table: e,
|
|
400
|
+
id: C(t),
|
|
401
|
+
expected: c,
|
|
402
|
+
current: d
|
|
403
|
+
});
|
|
404
|
+
if (f !== void 0 && l(f), d === null) return null;
|
|
405
|
+
s = null;
|
|
406
|
+
for (let i = 0;; i += 1) {
|
|
407
|
+
let o = d;
|
|
408
|
+
if (r = {
|
|
409
|
+
...n.patch,
|
|
410
|
+
[a]: o + 1
|
|
411
|
+
}, await I(e, "update", r, () => k.updateMany(e, B(e, r, t), { where: y(b(D, t), b(a, o)) })) > 0) {
|
|
412
|
+
s = (await k.query({
|
|
413
|
+
table: e,
|
|
414
|
+
predicate: {
|
|
415
|
+
column: D,
|
|
416
|
+
op: "eq",
|
|
417
|
+
value: t
|
|
418
|
+
},
|
|
419
|
+
order: [],
|
|
420
|
+
take: 1,
|
|
421
|
+
skip: void 0,
|
|
422
|
+
projection: void 0
|
|
423
|
+
}))[0] ?? null, J(k)?.set(Y(e, C(t)), o + 1);
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
let f = await u();
|
|
427
|
+
(c !== void 0 || f === null || i >= Ne) && l(new re({
|
|
428
|
+
table: e,
|
|
429
|
+
id: C(t),
|
|
430
|
+
expected: c ?? o,
|
|
431
|
+
actual: f
|
|
432
|
+
})), d = f;
|
|
433
|
+
}
|
|
434
|
+
} else s = await I(e, "update", r, () => k.update(e, t, B(e, r, t)));
|
|
435
|
+
return s === null ? null : H(e, [s], t)[0];
|
|
436
|
+
}, Ze = async (e, t, n) => {
|
|
437
|
+
let r = await k.query({
|
|
438
|
+
table: d,
|
|
439
|
+
predicate: y(b("tableName", e), b("rowId", C(t)), b("columnName", n), b("reason", "rebase")),
|
|
440
|
+
order: [{
|
|
441
|
+
column: "createdAt",
|
|
442
|
+
direction: "desc"
|
|
443
|
+
}],
|
|
444
|
+
take: void 0,
|
|
445
|
+
skip: void 0,
|
|
446
|
+
projection: void 0
|
|
447
|
+
});
|
|
448
|
+
return H(d, r).map((e) => e.state).filter((e) => e instanceof Uint8Array);
|
|
449
|
+
}, Qe = async (e, t, n, r, i) => {
|
|
450
|
+
let a = P(d, {
|
|
451
|
+
tableName: e,
|
|
452
|
+
rowId: C(t),
|
|
453
|
+
columnName: n,
|
|
454
|
+
state: r,
|
|
455
|
+
reason: "rebase",
|
|
456
|
+
label: null,
|
|
457
|
+
epoch: i === void 0 ? E.epochOf(r) ?? null : i,
|
|
458
|
+
createdBy: null
|
|
459
|
+
});
|
|
460
|
+
await I(d, "insert", a, () => k.insert(d, B(d, R(d, a))));
|
|
461
|
+
}, $e = async (e, t, n, r, i) => {
|
|
462
|
+
if (!(r instanceof Uint8Array) || !(i instanceof Uint8Array) || r.length === 0) return i;
|
|
463
|
+
let a = E.authorsOf(r), o = [...E.authorsOf(i)].filter((e) => !a.has(e));
|
|
464
|
+
if (o.length === 0 || E.epochOf(r) === void 0) return i;
|
|
465
|
+
for (let a of await Ze(e, t, n)) {
|
|
466
|
+
let t = E.authorsOf(a);
|
|
467
|
+
if (!o.some((e) => t.has(e))) continue;
|
|
468
|
+
let s = E.translate(a, i, r);
|
|
469
|
+
if (s === void 0) throw new ke({
|
|
470
|
+
field: n,
|
|
471
|
+
message: "crdt.staleLineage",
|
|
472
|
+
params: { table: e }
|
|
473
|
+
});
|
|
474
|
+
return s;
|
|
475
|
+
}
|
|
476
|
+
return i;
|
|
477
|
+
}, et = async (e, t, n) => {
|
|
478
|
+
await G(e, t);
|
|
479
|
+
for (let i = 0;; i += 1) {
|
|
480
|
+
let a = (await k.query({
|
|
481
|
+
table: e,
|
|
482
|
+
predicate: {
|
|
483
|
+
column: D,
|
|
484
|
+
op: "eq",
|
|
485
|
+
value: t
|
|
486
|
+
},
|
|
487
|
+
order: [],
|
|
488
|
+
take: 1,
|
|
489
|
+
skip: void 0,
|
|
490
|
+
projection: void 0
|
|
491
|
+
}))[0];
|
|
492
|
+
if (a === void 0) return null;
|
|
493
|
+
let o = H(e, [a])[0], s = {}, c = [b(D, t)], l = [];
|
|
494
|
+
for (let [t, i] of Object.entries(n)) {
|
|
495
|
+
if (i === null) s[t] = null;
|
|
496
|
+
else {
|
|
497
|
+
let n = r(e, t, o[t], i);
|
|
498
|
+
s[t] = n.log, n.replaced !== void 0 && l.push({
|
|
499
|
+
column: t,
|
|
500
|
+
...n.replaced
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
let n = a[t];
|
|
504
|
+
c.push(n == null ? S(t) : b(t, n));
|
|
505
|
+
}
|
|
506
|
+
let u = F(e, s);
|
|
507
|
+
if (await I(e, "update", u, () => k.updateMany(e, B(e, u, t), { where: y(...c) })) > 0) {
|
|
508
|
+
for (let n of l) await Qe(e, t, n.column, n.log, n.epoch === "" ? null : n.epoch);
|
|
509
|
+
let n = await k.query({
|
|
510
|
+
table: e,
|
|
511
|
+
predicate: {
|
|
512
|
+
column: D,
|
|
513
|
+
op: "eq",
|
|
514
|
+
value: t
|
|
515
|
+
},
|
|
516
|
+
order: [],
|
|
517
|
+
take: 1,
|
|
518
|
+
skip: void 0,
|
|
519
|
+
projection: void 0
|
|
520
|
+
});
|
|
521
|
+
return n[0] === void 0 ? null : H(e, [n[0]], t)[0];
|
|
522
|
+
}
|
|
523
|
+
if (i + 1 >= O) throw Error(`sealed crdt append on ${e} lost ${O} compare-and-swap rounds to concurrent writers; the frame was not written and can be retried`);
|
|
524
|
+
await new Promise((e) => setTimeout(e, Math.random() * 5 * (i + 1)));
|
|
525
|
+
}
|
|
526
|
+
}, tt = async (e, t, n, r) => {
|
|
527
|
+
let i = async () => (await k.query({
|
|
528
|
+
table: e,
|
|
529
|
+
predicate: {
|
|
530
|
+
column: D,
|
|
531
|
+
op: "eq",
|
|
532
|
+
value: t
|
|
533
|
+
},
|
|
534
|
+
order: [],
|
|
535
|
+
take: 1,
|
|
536
|
+
skip: void 0,
|
|
537
|
+
projection: void 0
|
|
538
|
+
}))[0], o = [...r].filter((e) => e in n), s = T.schemaRegistry.versionColumn(e), c = s === void 0 ? void 0 : be({
|
|
539
|
+
versionColumn: s,
|
|
540
|
+
patch: n
|
|
541
|
+
}), l = s === void 0 ? void 0 : J(k)?.get(Y(e, C(t))), u = c !== void 0 && c.expected === void 0 && l !== void 0, d = c?.expected ?? l, f = c?.patch ?? n, p = await i();
|
|
542
|
+
for (let n = 0;; n += 1) {
|
|
543
|
+
if (p === void 0) return null;
|
|
544
|
+
let c = H(e, [p])[0], l = f;
|
|
545
|
+
for (let n of o) {
|
|
546
|
+
let r = await $e(e, t, n, c[n], f[n]);
|
|
547
|
+
r !== f[n] && (l = {
|
|
548
|
+
...l,
|
|
549
|
+
[n]: r
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
let m = [], h = a(r, c, l, e, (e, t) => {
|
|
553
|
+
m.push({
|
|
554
|
+
column: e,
|
|
555
|
+
archived: t
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
T.schemaRegistry.computedFields(e).size > 0 && (h = ze(e, c, h));
|
|
559
|
+
let g = [b(D, t)];
|
|
560
|
+
for (let e of o) {
|
|
561
|
+
let t = p[e];
|
|
562
|
+
g.push(t == null ? S(e) : b(e, t));
|
|
563
|
+
}
|
|
564
|
+
let _;
|
|
565
|
+
if (s !== void 0) {
|
|
566
|
+
let n = p[s];
|
|
567
|
+
_ = typeof n == "number" && Number.isFinite(n) ? n : void 0;
|
|
568
|
+
let r = Ce({
|
|
569
|
+
table: e,
|
|
570
|
+
id: C(t),
|
|
571
|
+
expected: d,
|
|
572
|
+
current: _ ?? null
|
|
573
|
+
});
|
|
574
|
+
if (r !== void 0) throw u ? new j(r) : r;
|
|
575
|
+
_ !== void 0 && (h = {
|
|
576
|
+
...h,
|
|
577
|
+
[s]: _ + 1
|
|
578
|
+
}, g.push(b(s, _)));
|
|
579
|
+
}
|
|
580
|
+
h = L(e, h);
|
|
581
|
+
let v = h;
|
|
582
|
+
if (await I(e, "update", v, () => k.updateMany(e, B(e, v, t), { where: y(...g) })) > 0) {
|
|
583
|
+
for (let { column: n, archived: r } of m) await Qe(e, t, n, r);
|
|
584
|
+
let n = await i();
|
|
585
|
+
return n === void 0 ? null : (s !== void 0 && _ !== void 0 && J(k)?.set(Y(e, C(t)), _ + 1), H(e, [n], t)[0]);
|
|
586
|
+
}
|
|
587
|
+
if (n + 1 >= O) throw Error(`crdt fold on ${e} lost ${O} compare-and-swap rounds to concurrent writers; the update was not written and can be retried`);
|
|
588
|
+
await new Promise((e) => setTimeout(e, Math.random() * 5 * (n + 1))), p = await i();
|
|
589
|
+
}
|
|
590
|
+
}, nt = async (e, t) => (W(e, "delete", t), await G(e, t), T.schemaRegistry.hasSoftDelete(e) ? await Z(e, t, Be()) !== null : I(e, "delete", void 0, () => k.delete(e, t))), rt = async (e, t, n) => {
|
|
591
|
+
let r = F(e, t), i = T.schemaRegistry.versionColumn(e);
|
|
592
|
+
if (i === void 0) {
|
|
593
|
+
if (!V(e, r)) return I(e, "updateMany", r, () => k.updateMany(e, B(e, r), n));
|
|
594
|
+
let t = await k.query({
|
|
595
|
+
table: e,
|
|
596
|
+
predicate: n.where,
|
|
597
|
+
order: [],
|
|
598
|
+
take: void 0,
|
|
599
|
+
skip: void 0,
|
|
600
|
+
projection: [D]
|
|
601
|
+
}), i = 0;
|
|
602
|
+
for (let a of t) {
|
|
603
|
+
let t = a[D];
|
|
604
|
+
t != null && (i += await I(e, "updateMany", r, () => k.updateMany(e, B(e, r, t), { where: y(n.where, b(D, t)) })));
|
|
605
|
+
}
|
|
606
|
+
return i;
|
|
607
|
+
}
|
|
608
|
+
let a = await k.query({
|
|
609
|
+
table: e,
|
|
610
|
+
predicate: n.where,
|
|
611
|
+
order: [],
|
|
612
|
+
take: void 0,
|
|
613
|
+
skip: void 0,
|
|
614
|
+
projection: [D, i]
|
|
615
|
+
}), { [i]: o, ...s } = r, c = 0;
|
|
616
|
+
for (let t of a) {
|
|
617
|
+
let r = t[D];
|
|
618
|
+
if (typeof r != "string") continue;
|
|
619
|
+
let a = t[i];
|
|
620
|
+
for (let t = 0; typeof a == "number" && Number.isFinite(a); t += 1) {
|
|
621
|
+
let o = a, l = {
|
|
622
|
+
...s,
|
|
623
|
+
[i]: o + 1
|
|
624
|
+
}, u = await I(e, "updateMany", l, () => k.updateMany(e, B(e, l, r), { where: y(n.where, b(D, r), b(i, o)) }));
|
|
625
|
+
if (u > 0) {
|
|
626
|
+
c += u;
|
|
627
|
+
break;
|
|
628
|
+
}
|
|
629
|
+
if (t >= Ne) throw new re({
|
|
630
|
+
table: e,
|
|
631
|
+
id: r,
|
|
632
|
+
expected: o,
|
|
633
|
+
actual: null
|
|
634
|
+
});
|
|
635
|
+
a = (await k.query({
|
|
636
|
+
table: e,
|
|
637
|
+
predicate: y(n.where, b(D, r)),
|
|
638
|
+
order: [],
|
|
639
|
+
take: 1,
|
|
640
|
+
skip: void 0,
|
|
641
|
+
projection: [i]
|
|
642
|
+
}))[0]?.[i];
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
return c;
|
|
646
|
+
}, it = async (e, t) => I(e, "deleteMany", void 0, () => k.deleteMany(e, t)), at = (e, t) => M != null && T.schemaRegistry.hasTenant(e) ? y(t, b("tenantId", M)) : t, ot = async (e, t, n) => rt(e, t, {
|
|
647
|
+
...n,
|
|
648
|
+
where: at(e, n.where)
|
|
649
|
+
}), st = async (e, t) => it(e, {
|
|
650
|
+
...t,
|
|
651
|
+
where: at(e, t.where)
|
|
652
|
+
}), $ = _({
|
|
653
|
+
query: Je,
|
|
654
|
+
updateMany: rt,
|
|
655
|
+
deleteMany: it,
|
|
656
|
+
delete: (e, t) => k.delete(e, t)
|
|
657
|
+
}, {
|
|
658
|
+
subject: T.subject,
|
|
659
|
+
schemaRegistry: T.schemaRegistry,
|
|
660
|
+
rowFilter: N
|
|
661
|
+
}), ct = ((e, t, n) => t === void 0 ? $.updateWhere(e) : Z(e, t, n)), lt = ((e, t) => t === void 0 ? $.deleteWhere(e) : nt(e, t)), ut = async (e, t) => {
|
|
662
|
+
let n = t.map((t) => P(e, t)), r = x(e), i = t.length >= 32 && r !== void 0 && T.schemaRegistry.insertSchema(e) === void 0 && T.schemaRegistry.crdtColumns(e).size === 0 && T.schemaRegistry.sealedColumns(e).size === 0 ? g(r) : void 0, a = n.map((t) => R(e, t, i)), o = z ? a.map((e) => Se(e, r, z)) : a, s = ce(o, r, f()), c = await I(e, "insertMany", n[0], () => k.insertMany(e, s));
|
|
663
|
+
return H(e, c);
|
|
664
|
+
}, dt = (e, t) => {
|
|
665
|
+
let n = Object.keys(t);
|
|
666
|
+
if (n.length !== 1) throw Error(`store.links('${e}'): anchor must name exactly one source column, got [${n.join(", ")}]`);
|
|
667
|
+
let r = n[0], i = t[r], a = x(e);
|
|
668
|
+
if (a === void 0) throw Error(`store.links('${e}'): unknown table (not registered) — declare it and its relation first`);
|
|
669
|
+
let o = Object.entries(a.fields).filter(([, e]) => e.type === "reference").map(([e]) => e);
|
|
670
|
+
if (o.length !== 2) throw Error(`store.links('${e}'): expected a junction with exactly two reference() columns, found ${o.length} [${o.join(", ")}]. Use plain insert/deleteMany for a non-standard junction.`);
|
|
671
|
+
if (!o.includes(r)) throw Error(`store.links('${e}'): '${r}' is not a reference column of the junction [${o.join(", ")}]`);
|
|
672
|
+
return {
|
|
673
|
+
sourceCol: r,
|
|
674
|
+
sourceId: i,
|
|
675
|
+
targetCol: o.find((e) => e !== r)
|
|
676
|
+
};
|
|
677
|
+
}, ft = (e, t) => {
|
|
678
|
+
let n = x(e);
|
|
679
|
+
if (n === void 0) throw Error(`store.relationLinks('${e}'): unknown table (not registered) — declare it and its relation first`);
|
|
680
|
+
let r = Object.entries(n.fields).filter(([, e]) => e.type === "reference").filter(([, e]) => {
|
|
681
|
+
let n = e.references;
|
|
682
|
+
try {
|
|
683
|
+
return n !== void 0 && n().tableName === t;
|
|
684
|
+
} catch {
|
|
685
|
+
return !1;
|
|
686
|
+
}
|
|
687
|
+
}).map(([e]) => e);
|
|
688
|
+
if (r.length === 1) return r[0];
|
|
689
|
+
throw r.length === 0 ? Error(`store.relationLinks('${e}'): no reference column points at '${t}' — the junction's reference() targets decide the anchor, and none matches.`) : Error(`store.relationLinks('${e}'): ${r.length} reference columns point at '${t}' [${r.join(", ")}] — a self-junction is ambiguous; use store.links('${e}', { <column>: id }) and name the side.`);
|
|
690
|
+
}, pt = (e, t) => {
|
|
691
|
+
let { sourceCol: n, sourceId: r, targetCol: i } = dt(e, t), a = async () => (await U({
|
|
692
|
+
table: e,
|
|
693
|
+
predicate: b(n, r),
|
|
694
|
+
order: [],
|
|
695
|
+
projection: void 0,
|
|
696
|
+
skip: void 0,
|
|
697
|
+
take: void 0
|
|
698
|
+
})).map((e) => String(e[i])), o = async (t) => {
|
|
699
|
+
t.length !== 0 && await ut(e, t.map((e) => ({
|
|
700
|
+
[n]: r,
|
|
701
|
+
[i]: e
|
|
702
|
+
})));
|
|
703
|
+
}, s = async (t) => {
|
|
704
|
+
t.length !== 0 && await st(e, { where: y(b(n, r), me(i, t)) });
|
|
705
|
+
};
|
|
706
|
+
return {
|
|
707
|
+
columns: {
|
|
708
|
+
anchorColumn: n,
|
|
709
|
+
targetColumn: i
|
|
710
|
+
},
|
|
711
|
+
list: a,
|
|
712
|
+
set: async (e) => {
|
|
713
|
+
let t = new Set(e), n = new Set(await a()), r = [...t].filter((e) => !n.has(e)), i = [...n].filter((e) => !t.has(e));
|
|
714
|
+
return await s(i), await o(r), {
|
|
715
|
+
added: r,
|
|
716
|
+
removed: i
|
|
717
|
+
};
|
|
718
|
+
},
|
|
719
|
+
add: async (e) => {
|
|
720
|
+
let t = new Set(await a()), n = [...new Set(e)].filter((e) => !t.has(e));
|
|
721
|
+
return await o(n), n;
|
|
722
|
+
},
|
|
723
|
+
remove: async (e) => {
|
|
724
|
+
let t = new Set(await a()), n = [...new Set(e)].filter((e) => t.has(e));
|
|
725
|
+
return await s(n), n;
|
|
726
|
+
},
|
|
727
|
+
setRows: async (t) => {
|
|
728
|
+
let a = /* @__PURE__ */ new Map(), o = await U({
|
|
729
|
+
table: e,
|
|
730
|
+
predicate: b(n, r),
|
|
731
|
+
order: [],
|
|
732
|
+
projection: void 0,
|
|
733
|
+
skip: void 0,
|
|
734
|
+
take: void 0
|
|
735
|
+
});
|
|
736
|
+
for (let e of o) a.set(String(e[i]), e);
|
|
737
|
+
let c = /* @__PURE__ */ new Map();
|
|
738
|
+
for (let e of t) c.set(String(e[i]), e);
|
|
739
|
+
let l = [...a.keys()].filter((e) => !c.has(e));
|
|
740
|
+
await s(l);
|
|
741
|
+
let u = [], d = [], f = [];
|
|
742
|
+
for (let [t, o] of c) if (!a.has(t)) u.push(t), f.push({
|
|
743
|
+
...o,
|
|
744
|
+
[n]: r,
|
|
745
|
+
[i]: t
|
|
746
|
+
});
|
|
747
|
+
else {
|
|
748
|
+
let s = a.get(t), c = {}, l = !1;
|
|
749
|
+
for (let [e, t] of Object.entries(o)) e !== n && e !== i && s[e] !== t && (c[e] = t, l = !0);
|
|
750
|
+
l && (d.push(t), await ot(e, c, { where: y(b(n, r), b(i, t)) }));
|
|
751
|
+
}
|
|
752
|
+
return f.length > 0 && await ut(e, f), {
|
|
753
|
+
added: u,
|
|
754
|
+
removed: l,
|
|
755
|
+
updated: d
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
};
|
|
759
|
+
}, mt = async (e, t, n, r) => {
|
|
760
|
+
let i = t[D] !== void 0 && t[D] !== null, a = P(e, t), o = Te(n), s = n;
|
|
761
|
+
if (Ve(e, a, n.conflictColumns), typeof n.update == "function") {
|
|
762
|
+
let t = n.update;
|
|
763
|
+
s = {
|
|
764
|
+
conflictColumns: n.conflictColumns,
|
|
765
|
+
update: (n) => {
|
|
766
|
+
let r = n.id, i = H(e, [n], r)[0], a = F(e, {
|
|
767
|
+
...t(i),
|
|
768
|
+
...o
|
|
769
|
+
});
|
|
770
|
+
return B(e, L(e, a), r);
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
} else {
|
|
774
|
+
let r = n.update ?? Object.keys(t).filter((t) => t !== "id" && !n.conflictColumns.includes(t) && (!T.schemaRegistry.hasAudit(e) || t !== "createdAt" && t !== "createdBy"));
|
|
775
|
+
s = {
|
|
776
|
+
...n,
|
|
777
|
+
update: r
|
|
778
|
+
};
|
|
779
|
+
let i = {
|
|
780
|
+
...Object.fromEntries(r.filter((e) => e in t).map((e) => [e, t[e]])),
|
|
781
|
+
...o
|
|
782
|
+
}, a = F(e, i);
|
|
783
|
+
o = Te({
|
|
784
|
+
conflictColumns: n.conflictColumns,
|
|
785
|
+
updateValues: {
|
|
786
|
+
...o,
|
|
787
|
+
...Object.fromEntries(Object.entries(a).filter(([e]) => i[e] === void 0))
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
let c = !i && typeof a[D] == "string" ? a[D] : void 0, l = V(e, a) || V(e, o) || r && c === void 0, u = l ? await m(k, e, a, n.conflictColumns) : void 0, d = l ? u === void 0 ? a[D] : u : void 0, f = l ? u === void 0 ? "inserted" : "updated" : void 0, p = await I(e, "upsert", a, () => k.upsert(e, B(e, R(e, a), d), {
|
|
792
|
+
...s,
|
|
793
|
+
...typeof n.update != "function" && (n.updateValues !== void 0 || Object.keys(o).length > 0) ? { updateValues: B(e, L(e, o), d) } : {}
|
|
794
|
+
}));
|
|
795
|
+
return {
|
|
796
|
+
row: H(e, [p], d)[0],
|
|
797
|
+
outcome: f ?? (c !== void 0 && p[D] !== c ? "updated" : "inserted")
|
|
798
|
+
};
|
|
799
|
+
}, ht = async (e, t, n) => {
|
|
800
|
+
let r = P(e, t);
|
|
801
|
+
Ve(e, r, n.conflictColumns);
|
|
802
|
+
let i = await I(e, "insertIgnore", r, () => k.insertIgnoreWithOutcome(e, B(e, R(e, r)), n));
|
|
803
|
+
return {
|
|
804
|
+
row: H(e, [i.row])[0],
|
|
805
|
+
outcome: i.outcome
|
|
806
|
+
};
|
|
807
|
+
};
|
|
808
|
+
return {
|
|
809
|
+
query: U,
|
|
810
|
+
one: (async (e, t) => {
|
|
811
|
+
let n = Pe(e), r = await U({
|
|
812
|
+
...n,
|
|
813
|
+
take: 2
|
|
814
|
+
}), i = r[0];
|
|
815
|
+
if (i === void 0) throw v({
|
|
816
|
+
table: n.table,
|
|
817
|
+
found: 0
|
|
818
|
+
}, t);
|
|
819
|
+
if (r.length > 1) throw v({
|
|
820
|
+
table: n.table,
|
|
821
|
+
found: r.length
|
|
822
|
+
}, t);
|
|
823
|
+
return i;
|
|
824
|
+
}),
|
|
825
|
+
first: ((e) => u({ query: U }, e)),
|
|
826
|
+
maybeOne: ((e) => u({ query: U }, e)),
|
|
827
|
+
insert: async (e, t) => {
|
|
828
|
+
let n = P(e, t), r = await I(e, "insert", n, () => k.insert(e, B(e, R(e, n))));
|
|
829
|
+
return H(e, [r])[0];
|
|
830
|
+
},
|
|
831
|
+
insertMany: (async (e, t) => ut(e, t)),
|
|
832
|
+
links: pt,
|
|
833
|
+
relationLinks: (e, t, n) => pt(e, { [ft(e, t)]: n }),
|
|
834
|
+
patchJson: async (e, t, n, r, i) => {
|
|
835
|
+
W(e, "patchJson", t), await G(e, t);
|
|
836
|
+
let a = ge(t, n, F(e, ge(t, n, i), [n.split(".")[0]])), o = await I(e, "patchJson", a, () => k.patchJson(e, t, n, r, B(e, L(e, a), t)));
|
|
837
|
+
return o === null ? null : H(e, [o], t)[0];
|
|
838
|
+
},
|
|
839
|
+
select: $.select,
|
|
840
|
+
update: ct,
|
|
841
|
+
delete: lt,
|
|
842
|
+
applyDefined: Fe,
|
|
843
|
+
hardDelete: async (e, t) => (W(e, "hardDelete", t), await G(e, t), I(e, "hardDelete", void 0, () => k.delete(e, t))),
|
|
844
|
+
updateMany: ot,
|
|
845
|
+
deleteMany: st,
|
|
846
|
+
upsert: async (e, t, n) => (await mt(e, t, n, !1)).row,
|
|
847
|
+
upsertWithOutcome: (e, t, n) => mt(e, t, n, !0),
|
|
848
|
+
insertIgnore: async (e, t, n) => (await ht(e, t, n)).row,
|
|
849
|
+
insertIgnoreWithOutcome: (e, t, n) => ht(e, t, n),
|
|
850
|
+
transactional: async (e) => {
|
|
851
|
+
let t = await k.transactional(async (t) => {
|
|
852
|
+
let n = [];
|
|
853
|
+
return t[K] = n, t[q] = /* @__PURE__ */ new Map(), {
|
|
854
|
+
result: await e(Re(t, T)),
|
|
855
|
+
jobs: n
|
|
856
|
+
};
|
|
857
|
+
});
|
|
858
|
+
for (let e of t.jobs) await Z(e.table, e.pk, e.patch);
|
|
859
|
+
return t.result;
|
|
860
|
+
},
|
|
861
|
+
...k.raw ? { raw: ((e, r) => (n(Object.freeze({
|
|
862
|
+
sql: t(e.strings),
|
|
863
|
+
dependsOn: r?.dependsOn ?? e.dependsOn ?? []
|
|
864
|
+
})), k.raw(e, r))) } : {},
|
|
865
|
+
...k.savepoint ? { savepoint: (e) => k.savepoint(e) } : {},
|
|
866
|
+
onChange: (e) => k.onChange(e),
|
|
867
|
+
injectExternalChange: (e) => k.injectExternalChange(e),
|
|
868
|
+
...k.changeScope === void 0 ? {} : { changeScope: k.changeScope },
|
|
869
|
+
...k[K] === void 0 ? {} : { [K]: k[K] },
|
|
870
|
+
...J(k) === void 0 ? {} : { [q]: J(k) }
|
|
871
|
+
};
|
|
872
|
+
}, A = "VoltroTransactionReadConflict", j = class extends Error {
|
|
873
|
+
conflict;
|
|
874
|
+
name = A;
|
|
875
|
+
constructor(e) {
|
|
876
|
+
super(e.message), this.conflict = e;
|
|
877
|
+
}
|
|
878
|
+
}, M = (e) => typeof e == "object" && !!e && e.name === "VoltroTransactionReadConflict" && "conflict" in e, N = Symbol.for("@voltro/runtime:tx-read-versions");
|
|
879
|
+
//#endregion
|
|
880
|
+
export { A as TRANSACTION_READ_CONFLICT_NAME, N as TX_READ_VERSIONS_KEY, j as TransactionReadConflict, Le as actingUserId, Fe as applyDefined, M as isTransactionReadConflict, Re as wrapStoreWithMixinBehaviour };
|