@voltro/database 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/actorSnapshot.js +24 -0
- package/dist/arrayCodec.js +32 -0
- package/dist/branchExecute.js +92 -0
- package/dist/branching.js +106 -0
- package/dist/bulkInsertLimits.js +25 -0
- package/dist/cdcOffsetsTables.js +19 -0
- package/dist/changeEvent.js +41 -0
- package/dist/changeIdentity.js +65 -0
- package/dist/changeListenerCeiling.js +6 -0
- package/dist/columnReference.js +17 -0
- package/dist/columns.js +326 -0
- package/dist/committedChanges.js +12 -0
- package/dist/connectionIdentity.js +36 -0
- package/dist/coreTables.js +16 -0
- package/dist/coreTablesRegistry.js +10 -0
- package/dist/dataTransfers.js +22 -0
- package/dist/dbCause.js +222 -0
- package/dist/dbMetrics.js +65 -0
- package/dist/decimalComparison.js +27 -0
- package/dist/derivedRowId.js +5 -0
- package/dist/dialect.js +13 -0
- package/dist/enumRenames.js +14 -0
- package/dist/expiresMixin.js +10 -0
- package/dist/fieldEncryption.js +98 -0
- package/dist/frameworkTables.js +130 -0
- package/dist/ginIndex.js +10 -0
- package/dist/hybridSearch.js +32 -0
- package/dist/idGenerator.js +57 -0
- package/dist/identifierLimits.js +32 -0
- package/dist/index.d.ts +18 -7
- package/dist/index.js +81 -2183
- package/dist/indexAudit.js +61 -0
- package/dist/indexStorage.js +58 -0
- package/dist/joinCompiler.js +160 -0
- package/dist/jsonEagerCompiler.js +436 -0
- package/dist/jsonPatch.js +78 -0
- package/dist/jsonPatchAssignments.js +13 -0
- package/dist/jsonPath.js +31 -0
- package/dist/localFirstMixin.js +12 -0
- package/dist/migrate.js +624 -0
- package/dist/migration.js +18 -0
- package/dist/migrations/appliedAtValue.js +8 -0
- package/dist/migrations/applier.js +1085 -0
- package/dist/migrations/boot.js +196 -0
- package/dist/migrations/branchRehearsal.js +122 -0
- package/dist/migrations/columnEquivalence.js +85 -0
- package/dist/migrations/ddlError.js +63 -0
- package/dist/migrations/declaredSchema.js +162 -0
- package/dist/migrations/deployLedger.js +19 -0
- package/dist/migrations/fileBased.js +57 -0
- package/dist/migrations/fileContext.js +482 -0
- package/dist/migrations/fileDiscovery.js +318 -0
- package/dist/migrations/fileSkipProbes.js +117 -0
- package/dist/migrations/fingerprint.js +46 -0
- package/dist/migrations/fkCycles.js +13 -0
- package/dist/migrations/frameworkLiveTables.js +25 -0
- package/dist/migrations/idempotentDdl.js +37 -0
- package/dist/migrations/indexPredicate.js +50 -0
- package/dist/migrations/introspect.js +799 -0
- package/dist/migrations/ledgerRows.js +4 -0
- package/dist/migrations/lock.js +91 -0
- package/dist/migrations/migrationTableExists.js +9 -0
- package/dist/migrations/mssqlColumnDependencies.js +76 -0
- package/dist/migrations/mysqlEngine.js +11 -0
- package/dist/migrations/namespaceCharset.js +51 -0
- package/dist/migrations/planner.js +775 -0
- package/dist/migrations/postgresEnumCheck.js +19 -0
- package/dist/migrations/reactiveTriggerDrift.js +58 -0
- package/dist/migrations/reactiveTriggerName.js +7 -0
- package/dist/migrations/renameMssqlCheck.js +21 -0
- package/dist/migrations/restoreSnapshots.js +206 -0
- package/dist/migrations/resumeLedger.js +86 -0
- package/dist/migrations/rollingDeploy.js +106 -0
- package/dist/migrations/schemaOwner.js +46 -0
- package/dist/migrations/schemaOwnerTable.js +4 -0
- package/dist/migrations/softDropSnapshot.js +20 -0
- package/dist/migrations/sqlLimit.js +8 -0
- package/dist/migrations/sqliteConstraintIdentity.js +97 -0
- package/dist/migrations/sqliteDecimalBoot.js +22 -0
- package/dist/migrations/sqliteDecimalPublication.js +257 -0
- package/dist/migrations/sqliteDecimalReview.js +30 -0
- package/dist/migrations/sqliteDecimalReviewStore.js +188 -0
- package/dist/migrations/sqliteDecimalReviewWitness.js +38 -0
- package/dist/migrations/sqliteDecimalSource.js +69 -0
- package/dist/migrations/sqliteDecimalStage.js +135 -0
- package/dist/migrations/sqliteForeignKeys.js +38 -0
- package/dist/migrations/sqliteMigrationBatch.js +37 -0
- package/dist/migrations/sqliteRetainedSource.js +106 -0
- package/dist/migrations/sqliteRowIdentity.js +63 -0
- package/dist/migrations/sqliteSchemaEpoch.js +12 -0
- package/dist/migrations/sqliteSnapshotGuard.js +10 -0
- package/dist/migrations/sqliteTableContents.js +34 -0
- package/dist/migrations/sqliteTableCopy.js +25 -0
- package/dist/migrations/sqliteTableSchema.js +19 -0
- package/dist/migrations/sqliteWitnessProtection.js +8 -0
- package/dist/migrations/squash.js +81 -0
- package/dist/migrations/storeCharset.js +66 -0
- package/dist/migrations/transactionCause.js +10 -0
- package/dist/migrations/undeclaredCharset.js +40 -0
- package/dist/migrations/uniqueActiveLowering.js +39 -0
- package/dist/mixins.js +22 -0
- package/dist/mssqlDecimalDistinct.js +51 -0
- package/dist/mssqlJsonValueCheck.js +42 -0
- package/dist/mssqlTextStorage.js +9 -0
- package/dist/namespace.js +21 -0
- package/dist/{wire-CG2j7J3f.js → optimisticVersion.js} +2 -2
- package/dist/pendingAttribution.js +79 -0
- package/dist/pluginRef.js +17 -0
- package/dist/predicate.js +266 -0
- package/dist/predicateCoercion.js +13 -0
- package/dist/projectedColumn.js +37 -0
- package/dist/queryBuilder.js +382 -0
- package/dist/rawSql.js +8 -0
- package/dist/relations.js +69 -0
- package/dist/relationsRegistry.js +38 -0
- package/dist/replaceInProgress.js +53 -0
- package/dist/requiredColumns.js +26 -0
- package/dist/residency.js +52 -0
- package/dist/retention.js +62 -0
- package/dist/rowDecoder.js +123 -0
- package/dist/rowKey.js +8 -0
- package/dist/rowSchema.js +31 -0
- package/dist/scopeKey.js +8 -0
- package/dist/seed.js +33 -0
- package/dist/snowflake.js +26 -0
- package/dist/sql.d.ts +27 -6
- package/dist/sql.js +41 -6905
- package/dist/sqlCompiler.js +343 -0
- package/dist/sqlError.js +8 -0
- package/dist/sqlPoolCapacity.js +12 -0
- package/dist/sqliteDecimal.js +22 -0
- package/dist/sqliteDecimalAggregateSql.js +61 -0
- package/dist/sqliteDecimalColumnSql.js +108 -0
- package/dist/sqliteDecimalConversion.js +15 -0
- package/dist/sqliteDecimalCte.js +154 -0
- package/dist/sqliteDecimalEncodeSql.js +32 -0
- package/dist/sqliteDecimalOutputs.js +74 -0
- package/dist/sqliteDecimalPredicate.js +66 -0
- package/dist/sqliteDecimalQuery.js +183 -0
- package/dist/sqliteDecimalQueryPlan.js +37 -0
- package/dist/sqliteDecimalResultSql.js +44 -0
- package/dist/sqliteDecimalRowQuery.js +63 -0
- package/dist/sqliteDecimalSetQuery.js +50 -0
- package/dist/sqliteDecimalSource.js +63 -0
- package/dist/sqliteDecimalStorage.js +29 -0
- package/dist/sqliteDecimalSubquery.js +19 -0
- package/dist/sqliteDecimalWindowQuery.js +196 -0
- package/dist/sqliteValueCoercion.js +4 -0
- package/dist/stampId.js +21 -0
- package/dist/storeErrors.js +9 -0
- package/dist/storeRefusal.js +20 -0
- package/dist/stream.js +36 -0
- package/dist/subjectGraph.js +175 -0
- package/dist/table.js +394 -0
- package/dist/tableRegistry.js +16 -0
- package/dist/tenantSelection.js +27 -0
- package/dist/transactionOutcome.js +97 -0
- package/dist/transientContention.js +36 -0
- package/dist/typedStore.js +16 -0
- package/dist/upsertUpdate.js +20 -0
- package/dist/vectorEmbedding.js +31 -0
- package/dist/view.js +39 -0
- package/dist/wire.js +6 -2
- package/dist/writeAttribution.js +16 -0
- package/dist/writeRecorder.js +37 -0
- package/package.json +3 -3
- package/dist/replaceInProgress-DC88Pdiy.js +0 -3735
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { authoredError as e } from "./dbCause.js";
|
|
2
|
+
//#region src/relations.ts
|
|
3
|
+
var t = (e) => typeof e == "function" ? e : () => e, n = (e, n) => ({
|
|
4
|
+
kind: "one",
|
|
5
|
+
target: t(e),
|
|
6
|
+
...n?.foreignKey === void 0 ? {} : { foreignKey: n.foreignKey },
|
|
7
|
+
...n?.sourceKey === void 0 ? {} : { sourceKey: n.sourceKey }
|
|
8
|
+
}), r = (e, n) => ({
|
|
9
|
+
kind: "many",
|
|
10
|
+
target: t(e),
|
|
11
|
+
...n?.foreignKey === void 0 ? {} : { foreignKey: n.foreignKey },
|
|
12
|
+
...n?.sourceKey === void 0 ? {} : { sourceKey: n.sourceKey }
|
|
13
|
+
}), i = (e, n) => ({
|
|
14
|
+
kind: "manyToMany",
|
|
15
|
+
target: t(e),
|
|
16
|
+
through: t(n.through),
|
|
17
|
+
sourceKey: n.sourceKey,
|
|
18
|
+
targetKey: n.targetKey
|
|
19
|
+
}), a = {
|
|
20
|
+
one: n,
|
|
21
|
+
many: r,
|
|
22
|
+
manyToMany: i
|
|
23
|
+
}, o = (e, t) => {
|
|
24
|
+
let n = typeof e == "function" ? e : () => e;
|
|
25
|
+
return {
|
|
26
|
+
source: n,
|
|
27
|
+
relations: t(a, n())
|
|
28
|
+
};
|
|
29
|
+
}, s = (e) => {
|
|
30
|
+
if (typeof e != "object" || !e) return !1;
|
|
31
|
+
let t = e;
|
|
32
|
+
return typeof t.source != "function" || typeof t.relations != "object" || t.relations === null ? !1 : Object.keys(t.relations).length === 0;
|
|
33
|
+
}, c = (e) => {
|
|
34
|
+
if (typeof e != "object" || !e) return !1;
|
|
35
|
+
let t = e;
|
|
36
|
+
if (typeof t.source != "function" || typeof t.relations != "object" || t.relations === null) return !1;
|
|
37
|
+
let n = Object.values(t.relations);
|
|
38
|
+
return n.length !== 0 && n.every((e) => {
|
|
39
|
+
let t = e?.kind;
|
|
40
|
+
return t === "one" || t === "many" || t === "manyToMany";
|
|
41
|
+
});
|
|
42
|
+
}, l = n, u = r, d = i, f = (t, n, r) => {
|
|
43
|
+
let i = [];
|
|
44
|
+
for (let [e, r] of Object.entries(t.fields)) r.type === "reference" && r.references?.()?.tableName === n && i.push(e);
|
|
45
|
+
if (i.length === 0) throw e(`relation '${r}': no reference() column on '${t.tableName}' points at '${n}'. Either add one or pass an explicit { foreignKey: '<column>' }.`);
|
|
46
|
+
if (i.length > 1) throw e(`relation '${r}': multiple reference() columns on '${t.tableName}' point at '${n}' (${i.join(", ")}). Pass an explicit { foreignKey: '<column>' } to disambiguate.`);
|
|
47
|
+
return i[0];
|
|
48
|
+
}, p = (e) => Object.keys(e.fields), m = (e, t) => Object.prototype.hasOwnProperty.call(e.fields, t), h = (e) => {
|
|
49
|
+
let t = p(e);
|
|
50
|
+
return t.length === 0 ? "<none>" : t.join(", ");
|
|
51
|
+
}, g = (t, n, r) => {
|
|
52
|
+
let i = `relation '${n}' on '${t.tableName}'`, a = r.target();
|
|
53
|
+
if (r.kind === "manyToMany") {
|
|
54
|
+
let n = r.through();
|
|
55
|
+
for (let [o, s] of [["sourceKey", r.sourceKey], ["targetKey", r.targetKey]]) if (!m(n, s)) throw e(`${i}: manyToMany ${o} '${s}' is not a column on the junction table '${n.tableName}'. Both keys name columns on the JUNCTION — ${o === "sourceKey" ? `sourceKey points at '${t.tableName}'` : `targetKey points at '${a.tableName}'`}. Columns on '${n.tableName}': ${h(n)}.`);
|
|
56
|
+
} else {
|
|
57
|
+
if (r.sourceKey !== void 0 && r.foreignKey !== void 0) throw e(`${i}: pass EITHER sourceKey OR foreignKey, not both. sourceKey '${r.sourceKey}' names a column on the source ('${t.tableName}') holding the target's id; foreignKey '${r.foreignKey}' names a column on the target ('${a.tableName}') holding the source's id. With both, foreignKey is ignored.`);
|
|
58
|
+
if (r.sourceKey !== void 0 && !m(t, r.sourceKey)) {
|
|
59
|
+
let n = m(a, r.sourceKey);
|
|
60
|
+
throw e(`${i}: sourceKey '${r.sourceKey}' is not a column on the source table '${t.tableName}'.` + (n ? ` It IS a column on the target '${a.tableName}' — you probably want { foreignKey: '${r.sourceKey}' }, which names the column on the TARGET that holds this table's id.` : ` Columns on '${t.tableName}': ${h(t)}.`));
|
|
61
|
+
}
|
|
62
|
+
if (r.foreignKey !== void 0 && !m(a, r.foreignKey)) {
|
|
63
|
+
let n = m(t, r.foreignKey);
|
|
64
|
+
throw e(`${i}: foreignKey '${r.foreignKey}' is not a column on the target table '${a.tableName}'.` + (n ? ` It IS a column on the source '${t.tableName}' — you want { sourceKey: '${r.foreignKey}' }. foreignKey names the column on the TARGET that points back at this table; sourceKey names the column on THIS table that holds the target's id.` : ` Columns on '${a.tableName}': ${h(a)}.`));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
//#endregion
|
|
69
|
+
export { f as inferForeignKey, s as isEmptyRelationsSpec, c as isRelationsSpec, u as many, d as manyToMany, l as one, o as relations, g as validateRelationConfig };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { getTable as e } from "./tableRegistry.js";
|
|
2
|
+
import { isRelationsSpec as t, validateRelationConfig as n } from "./relations.js";
|
|
3
|
+
//#region src/relationsRegistry.ts
|
|
4
|
+
var r = Symbol.for("@voltro/database/relationsRegistry"), i = globalThis, a = i[r] ?? (i[r] = /* @__PURE__ */ new Map()), o = (e) => {
|
|
5
|
+
let t = e.source(), n = a.get(t.tableName);
|
|
6
|
+
if (n === void 0) a.set(t.tableName, new Map(Object.entries(e.relations)));
|
|
7
|
+
else for (let [r, i] of Object.entries(e.relations)) {
|
|
8
|
+
let e = n.get(r);
|
|
9
|
+
if (e !== i) {
|
|
10
|
+
if (e !== void 0) throw Error(`duplicate relation '${r}' on '${t.tableName}': two relations() blocks both declare it. Pick distinct names or merge them into one block.`);
|
|
11
|
+
n.set(r, i);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}, s = (e) => {
|
|
15
|
+
let n = 0;
|
|
16
|
+
for (let r of Object.values(e)) t(r) && (o(r), n += 1);
|
|
17
|
+
return n;
|
|
18
|
+
}, c = (e) => {
|
|
19
|
+
let t = a.get(e);
|
|
20
|
+
if (t !== void 0) return Object.fromEntries(t);
|
|
21
|
+
}, l = (e, t) => a.get(e)?.get(t), u = () => {
|
|
22
|
+
let e = [];
|
|
23
|
+
for (let [t, n] of a) for (let [r, i] of n) e.push({
|
|
24
|
+
source: t,
|
|
25
|
+
name: r,
|
|
26
|
+
relation: i
|
|
27
|
+
});
|
|
28
|
+
return e;
|
|
29
|
+
}, d = () => {
|
|
30
|
+
for (let [t, r] of a) {
|
|
31
|
+
let i = e(t);
|
|
32
|
+
if (i !== void 0) for (let [e, t] of r) n(i, e, t);
|
|
33
|
+
}
|
|
34
|
+
}, f = () => {
|
|
35
|
+
a.clear();
|
|
36
|
+
};
|
|
37
|
+
//#endregion
|
|
38
|
+
export { u as allRegisteredRelations, f as clearRelationsRegistry, l as getRelation, c as getRelations, s as registerDiscoveredRelations, o as registerRelations, d as validateRegisteredRelations };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { boolean as e, id as t, text as n, timestamp as r } from "./columns.js";
|
|
2
|
+
import { table as i } from "./table.js";
|
|
3
|
+
//#region src/replaceInProgress.ts
|
|
4
|
+
var a = "_voltro_replace_in_progress", o = i(a, {
|
|
5
|
+
id: t({ prefix: "repl" }),
|
|
6
|
+
startedAt: r().default("now"),
|
|
7
|
+
kind: n().default("replace"),
|
|
8
|
+
tables: n().nullable(),
|
|
9
|
+
capture: n().nullable(),
|
|
10
|
+
via: n(),
|
|
11
|
+
staging: n().nullable(),
|
|
12
|
+
heartbeatAt: r().nullable(),
|
|
13
|
+
resumable: e().nullable()
|
|
14
|
+
}).nonReactive(), s = 30, c = (e, t) => {
|
|
15
|
+
let n = typeof t == "number" && Number.isFinite(t) && t > 0 ? t : 30, r = Number(e.VOLTRO_STAGING_STALE_MINUTES);
|
|
16
|
+
return (Number.isFinite(r) && r > 0 ? r : n) * 6e4;
|
|
17
|
+
}, l = (e) => e == null || String(e).length === 0 ? [] : String(e).split(",").map((e) => e.trim()).filter((e) => e.length > 0), u = (e) => {
|
|
18
|
+
let t = e.filter((e) => e.kind !== "staging");
|
|
19
|
+
if (t.length !== 0) return `refusing to start: a destructive data operation did not finish.
|
|
20
|
+
${t.map((e) => {
|
|
21
|
+
let t = Number.isFinite(e.startedAt.getTime()) ? `${Math.max(0, Math.round((Date.now() - e.startedAt.getTime()) / 6e4))} minute(s) ago` : "at an unknown time";
|
|
22
|
+
if (e.kind === "restore") return ` - a native \`restore\` over ${e.via} began loading an artefact over this database ${t}\n and never reported finishing.\n` + (e.capture === null ? " The artefact it was loading was not recorded. Re-run the restore from your backup\n directory, or restore from another backup." : ` The artefact it was loading:\n ${e.capture}\n Re-run it to completion with: voltro data restore ${e.capture} --allow-live`);
|
|
23
|
+
let n = e.tables === null ? "this database" : `${e.tables} table(s)`;
|
|
24
|
+
return ` - a \`replace\` over ${e.via} began emptying ${n} ${t} and never reported finishing.\n` + (e.capture === null ? " NO capture was taken for that run, so the previous rows are not recoverable from here.\n Restore from your own backup." : ` The target's previous rows were captured first:\n ${e.capture}\n Restore them with: voltro data import ${e.capture} --mode replace`);
|
|
25
|
+
}).join("\n")}\n
|
|
26
|
+
A half-replaced database is indistinguishable from an empty one from the inside — every table
|
|
27
|
+
exists, every constraint holds, and every query returns nothing without erroring. That is why
|
|
28
|
+
this is a refusal and not a warning.
|
|
29
|
+
|
|
30
|
+
When the data is back, or you have decided the current state is correct, clear the marker:
|
|
31
|
+
voltro data clear-replace-marker --yes`;
|
|
32
|
+
}, d = (e, t, n) => {
|
|
33
|
+
let r = e.filter((e) => e.kind === "staging");
|
|
34
|
+
return {
|
|
35
|
+
all: r,
|
|
36
|
+
droppable: r.filter((e) => {
|
|
37
|
+
if (e.resumable) return !1;
|
|
38
|
+
let r = (e.heartbeatAt ?? e.startedAt).getTime();
|
|
39
|
+
return Number.isFinite(r) ? t - r >= n : !1;
|
|
40
|
+
})
|
|
41
|
+
};
|
|
42
|
+
}, f = (e, t) => {
|
|
43
|
+
if (e.all.length === 0) return;
|
|
44
|
+
let n = new Set(e.droppable.map((e) => e.id));
|
|
45
|
+
return `staged data-import leftovers:
|
|
46
|
+
${e.all.map((e) => {
|
|
47
|
+
let r = e.heartbeatAt ?? e.startedAt, i = Number.isFinite(r.getTime()) ? `${Math.max(0, Math.round((t - r.getTime()) / 6e4))} minute(s) ago` : "at an unknown time", a = `${e.staging.length} staging table(s) from a \`replace\` over ${e.via}, last active ${i}`;
|
|
48
|
+
return n.has(e.id) ? ` - ${a} — DROPPED: the run is not resumable and has been silent long enough that nothing is loading into them.` : e.resumable ? ` - ${a} — KEPT: the run was started \`--no-atomic\`, so these ARE its resume point. Re-run the same\n bundle to continue from them, or drop them with: voltro data clear-staging --yes` : ` - ${a} — KEPT: still beating, so an import is loading into them right now.`;
|
|
49
|
+
}).join("\n")}\n The target of a staged \`replace\` is untouched until one short swap at the end, so none of this is
|
|
50
|
+
a reason to refuse the boot — it is a reason to know the disk is holding a copy of a bundle.`;
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
export { a as REPLACE_IN_PROGRESS_TABLE, s as STAGING_STALE_MINUTES, o as _voltroReplaceInProgressTable, u as interruptedReplaceRefusal, f as stagingLeftoverReport, d as stagingLeftovers, l as stagingNamesOf, c as stagingStaleAfterMs };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/requiredColumns.ts
|
|
2
|
+
var e = (e, t) => {
|
|
3
|
+
let n = [], r = t;
|
|
4
|
+
for (let [t, i] of Object.entries(e.fields)) {
|
|
5
|
+
let e = i;
|
|
6
|
+
e.nullable || e.hasDefault || e.idScheme !== void 0 || e.generatedAs !== void 0 || (r[t] === void 0 || r[t] === null) && n.push(t);
|
|
7
|
+
}
|
|
8
|
+
return n;
|
|
9
|
+
}, t = (e, t, n) => {
|
|
10
|
+
let r = n, i = /* @__PURE__ */ new Set();
|
|
11
|
+
if (e !== void 0) {
|
|
12
|
+
let n = e.fields;
|
|
13
|
+
for (let e of new Set(t)) Object.getOwnPropertyDescriptor(n, e)?.enumerable && n[e]?.generatedAs !== void 0 && i.add(e);
|
|
14
|
+
}
|
|
15
|
+
let a = [];
|
|
16
|
+
for (let e of t) i.has(e) || (r[e] === void 0 ? a.push({
|
|
17
|
+
column: e,
|
|
18
|
+
reason: "absent"
|
|
19
|
+
}) : r[e] === null && a.push({
|
|
20
|
+
column: e,
|
|
21
|
+
reason: "null"
|
|
22
|
+
}));
|
|
23
|
+
return a;
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
export { t as missingConflictColumns, e as missingRequiredColumns };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { resolveTenantNamespace as e } from "./namespace.js";
|
|
2
|
+
//#region src/residency.ts
|
|
3
|
+
var t = class extends Error {
|
|
4
|
+
_tag = "TenantResidencyUnresolved";
|
|
5
|
+
constructor(e) {
|
|
6
|
+
super(e), this.name = "TenantResidencyUnresolved";
|
|
7
|
+
}
|
|
8
|
+
}, n = class extends Error {
|
|
9
|
+
region;
|
|
10
|
+
_tag = "TenantRegionUnavailable";
|
|
11
|
+
constructor(e, t) {
|
|
12
|
+
super(t), this.region = e, this.name = "TenantRegionUnavailable";
|
|
13
|
+
}
|
|
14
|
+
}, r, i = (e) => {
|
|
15
|
+
if (e.homes === void 0) throw Error("setResidencyConfig: `homes` is required");
|
|
16
|
+
if (e.servableRegions === void 0 || e.servableRegions.length === 0) throw Error("setResidencyConfig: `servableRegions` must be non-empty (which regions this deployment serves)");
|
|
17
|
+
let t = /* @__PURE__ */ new Map();
|
|
18
|
+
for (let n of e.homes) {
|
|
19
|
+
let e = t.get(n.tenantId);
|
|
20
|
+
if (e !== void 0 && e !== n.region) throw Error(`residency: tenant '${n.tenantId}' is mapped to two regions ('${e}' and '${n.region}')`);
|
|
21
|
+
t.set(n.tenantId, n.region);
|
|
22
|
+
}
|
|
23
|
+
return r = e, e;
|
|
24
|
+
}, a = () => r, o = () => {
|
|
25
|
+
r = void 0;
|
|
26
|
+
}, s = (e, n) => {
|
|
27
|
+
if (e == null || e === "") throw new t("residency is on but the request has no resolvable tenant — refusing to bind a store");
|
|
28
|
+
let r = n.homes.find((t) => t.tenantId === e);
|
|
29
|
+
if (r === void 0) throw new t(`no residency home is mapped for tenant '${e}' — refusing to fall back to a default store (would be a residency violation)`);
|
|
30
|
+
return r;
|
|
31
|
+
}, c = (e, t) => t.servableRegions.includes(e), l = (t, n) => {
|
|
32
|
+
let r = s(t.tenantId, n), i = e(r.tenantId);
|
|
33
|
+
return {
|
|
34
|
+
region: r.region,
|
|
35
|
+
namespace: i,
|
|
36
|
+
...r.connectionKey === void 0 ? {} : { connectionKey: r.connectionKey }
|
|
37
|
+
};
|
|
38
|
+
}, u = (e, t, r) => {
|
|
39
|
+
let i = l(e, t);
|
|
40
|
+
if (!c(i.region, t)) throw new n(i.region, `tenant homed in region '${i.region}', which this deployment does not serve — route to the home region`);
|
|
41
|
+
let a = r.get(i.region);
|
|
42
|
+
if (a === void 0) throw new n(i.region, `no store handle for home region '${i.region}' (declared servable but not wired) — failing closed`);
|
|
43
|
+
return {
|
|
44
|
+
store: a,
|
|
45
|
+
placement: i
|
|
46
|
+
};
|
|
47
|
+
}, d = async (e, t, n, r) => {
|
|
48
|
+
let { store: i, placement: a } = u(e, t, n);
|
|
49
|
+
return await r(i, a), a;
|
|
50
|
+
};
|
|
51
|
+
//#endregion
|
|
52
|
+
export { n as TenantRegionUnavailable, t as TenantResidencyUnresolved, u as bindResidentStore, o as clearResidencyConfig, a as getResidencyConfig, c as isRegionServable, d as provisionResidentTenant, l as residentPlacement, s as resolveTenantHome, i as setResidencyConfig };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { and as e, isNull as t, lt as n, or as r } from "./predicate.js";
|
|
2
|
+
import { Effect as i, Metric as a } from "effect";
|
|
3
|
+
//#region src/retention.ts
|
|
4
|
+
var o = {
|
|
5
|
+
app: 3,
|
|
6
|
+
plugin: 2,
|
|
7
|
+
framework: 1
|
|
8
|
+
}, s = /* @__PURE__ */ new Map(), c = [], l = () => [...c], u = (e) => {
|
|
9
|
+
if (!e.table || !e.timeColumn) throw Error("registerRetention: table + timeColumn are required");
|
|
10
|
+
if (!Number.isFinite(e.ttlMs) || e.ttlMs <= 0) throw Error(`registerRetention(${e.table}): ttlMs must be a positive number`);
|
|
11
|
+
let t = e.source ?? "app", n = s.get(e.table);
|
|
12
|
+
if (n !== void 0) {
|
|
13
|
+
let r = n.source ?? "app", i = n.ttlMs !== e.ttlMs || n.timeColumn !== e.timeColumn || JSON.stringify(n.activityColumns ?? []) !== JSON.stringify(e.activityColumns ?? []) || JSON.stringify(n.where) !== JSON.stringify(e.where);
|
|
14
|
+
if (o[t] < o[r]) {
|
|
15
|
+
i && c.push({
|
|
16
|
+
table: e.table,
|
|
17
|
+
kept: {
|
|
18
|
+
source: r,
|
|
19
|
+
ttlMs: n.ttlMs
|
|
20
|
+
},
|
|
21
|
+
dropped: {
|
|
22
|
+
source: t,
|
|
23
|
+
ttlMs: e.ttlMs
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
i && r !== t && c.push({
|
|
29
|
+
table: e.table,
|
|
30
|
+
kept: {
|
|
31
|
+
source: t,
|
|
32
|
+
ttlMs: e.ttlMs
|
|
33
|
+
},
|
|
34
|
+
dropped: {
|
|
35
|
+
source: r,
|
|
36
|
+
ttlMs: n.ttlMs
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
s.set(e.table, {
|
|
41
|
+
...e,
|
|
42
|
+
source: t
|
|
43
|
+
});
|
|
44
|
+
}, d = () => [...s.values()], f = () => {
|
|
45
|
+
s.clear(), c.length = 0;
|
|
46
|
+
}, p = async (o, s, c, l = 2e4) => {
|
|
47
|
+
let u = new Date(s - o.ttlMs), d = (o.activityColumns ?? []).map((e) => r(t(e), n(e, u))), f = d.length === 0 ? o.where : e(...o.where === void 0 ? [] : [o.where], ...d), p = 0;
|
|
48
|
+
try {
|
|
49
|
+
for (;;) {
|
|
50
|
+
let e = await c(o.table, o.timeColumn, u, l, f);
|
|
51
|
+
if (p += e, e < l) break;
|
|
52
|
+
}
|
|
53
|
+
} catch (e) {
|
|
54
|
+
throw i.runSync(a.update(a.withAttributes(h, { table: o.table }), 1)), e;
|
|
55
|
+
}
|
|
56
|
+
return p > 0 && i.runSync(a.update(a.withAttributes(m, { table: o.table }), p)), p;
|
|
57
|
+
}, m = a.counter("voltro_retention_swept_rows_total"), h = a.counter("voltro_retention_sweep_errors_total"), g = (e, t) => {
|
|
58
|
+
let n = Number(e ?? String(t));
|
|
59
|
+
return (Number.isFinite(n) && n > 0 ? n : t) * 36e5;
|
|
60
|
+
};
|
|
61
|
+
//#endregion
|
|
62
|
+
export { f as clearRetentions, l as listRetentionConflicts, d as listRetentions, u as registerRetention, g as retentionTtlMsFromEnv, p as sweepRetention };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { getTable as e } from "./tableRegistry.js";
|
|
2
|
+
import { decodeSqliteDecimal as t, encodeSqliteDecimal as n } from "./sqliteDecimal.js";
|
|
3
|
+
import { sqliteDecimalStorageShape as r } from "./sqliteDecimalStorage.js";
|
|
4
|
+
import { projectedColumn as i } from "./projectedColumn.js";
|
|
5
|
+
import { hasEncodedSqliteDecimalSource as a } from "./sqliteDecimalQueryPlan.js";
|
|
6
|
+
import { sqliteDecimalOutputs as o } from "./sqliteDecimalOutputs.js";
|
|
7
|
+
import { resolveSqliteDecimalSources as s } from "./sqliteDecimalCte.js";
|
|
8
|
+
//#region src/rowDecoder.ts
|
|
9
|
+
var c = (e) => e == null || typeof e == "boolean" ? e : typeof e == "number" ? e !== 0 : typeof e == "bigint" ? e !== 0n : typeof e == "string" ? e === "1" || e.toLowerCase() === "true" : e, l = (e) => {
|
|
10
|
+
if (e == null || typeof e != "string") return e;
|
|
11
|
+
let t = e.trim();
|
|
12
|
+
if (t.length === 0) return e;
|
|
13
|
+
let n = t.charAt(0);
|
|
14
|
+
if (n !== "{" && n !== "[" && n !== "\"" && n !== "t" && n !== "f" && n !== "n" && (n < "0" || n > "9") && n !== "-") return e;
|
|
15
|
+
try {
|
|
16
|
+
return JSON.parse(t);
|
|
17
|
+
} catch {
|
|
18
|
+
return e;
|
|
19
|
+
}
|
|
20
|
+
}, u = (e) => e == null || typeof e == "string" ? e : typeof e == "number" || typeof e == "bigint" ? String(e) : e, d = (e) => {
|
|
21
|
+
if (e == null) return e;
|
|
22
|
+
let t = typeof e == "number" ? e : Number(e);
|
|
23
|
+
if (!Number.isSafeInteger(t)) throw RangeError("Numeric id must be a safe integer; use a string id scheme for larger identities");
|
|
24
|
+
return t;
|
|
25
|
+
}, f = (e) => e.type === "id" && e.idScheme?.kind === "numeric" || e.type === "reference" && e.referenceStorage === "numeric", p = (e) => {
|
|
26
|
+
if (e == null || e instanceof Date) return e;
|
|
27
|
+
if (typeof e == "string" || typeof e == "number") {
|
|
28
|
+
let t = new Date(e);
|
|
29
|
+
return isNaN(t.getTime()) ? e : t;
|
|
30
|
+
}
|
|
31
|
+
return e;
|
|
32
|
+
}, m = (e, t, n) => {
|
|
33
|
+
if (e == null) return e;
|
|
34
|
+
switch (t) {
|
|
35
|
+
case "boolean": return n === "postgres" ? e : c(e);
|
|
36
|
+
case "vector": return n === "postgres" ? l(e) : e;
|
|
37
|
+
case "json": return n === "postgres" || n === "mysql" || n === "mariadb" ? e : l(e);
|
|
38
|
+
case "array": return n === "postgres" ? e : l(e);
|
|
39
|
+
case "timestamp":
|
|
40
|
+
case "date": return n === "sqlite" || n === "turso" ? p(e) : e;
|
|
41
|
+
case "decimal":
|
|
42
|
+
if ((n === "sqlite" || n === "turso") && typeof e == "string" && /^D\d+$/.test(e)) throw TypeError("Decimal storage representation does not match the application schema; stop access and complete the verified storage migration before reading this column");
|
|
43
|
+
return u(e);
|
|
44
|
+
case "bigint": return u(e);
|
|
45
|
+
default: return e;
|
|
46
|
+
}
|
|
47
|
+
}, h = (e, t) => {
|
|
48
|
+
switch (e) {
|
|
49
|
+
case "boolean": return t !== "postgres";
|
|
50
|
+
case "vector": return t === "postgres";
|
|
51
|
+
case "json": return t !== "postgres" && t !== "mysql" && t !== "mariadb";
|
|
52
|
+
case "array": return t !== "postgres";
|
|
53
|
+
case "timestamp":
|
|
54
|
+
case "date": return t === "sqlite" || t === "turso";
|
|
55
|
+
case "decimal":
|
|
56
|
+
case "bigint": return !0;
|
|
57
|
+
default: return !1;
|
|
58
|
+
}
|
|
59
|
+
}, g = (t, n, r, c) => {
|
|
60
|
+
if (t.length === 0) return t;
|
|
61
|
+
if (c && (r === "sqlite" || r === "turso") && a(c)) {
|
|
62
|
+
let e = o(s(c, void 0), void 0);
|
|
63
|
+
return t.map((t) => {
|
|
64
|
+
let n = { ...t };
|
|
65
|
+
for (let t of e) {
|
|
66
|
+
let e = t.decimal ? "decimal" : t.definition?.type;
|
|
67
|
+
e && t.name in n && (n[t.name] = m(n[t.name], e, r));
|
|
68
|
+
}
|
|
69
|
+
return n;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (c?.joinedProjection?.length) {
|
|
73
|
+
let e = c.joinedProjection.map((e) => ({
|
|
74
|
+
outputKey: e.outputKey,
|
|
75
|
+
definition: i(e.source, c)
|
|
76
|
+
}));
|
|
77
|
+
return t.map((t) => {
|
|
78
|
+
let n = { ...t };
|
|
79
|
+
for (let { outputKey: t, definition: i } of e) i && t in n && (n[t] = f(i) ? d(n[t]) : m(n[t], i.type, r));
|
|
80
|
+
return n;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
let l = c?.sourceTable?.tableName === n ? c.sourceTable : e(n);
|
|
84
|
+
return l === void 0 ? t : _(t, l, r);
|
|
85
|
+
}, _ = (e, n, i) => {
|
|
86
|
+
if (e.length === 0) return e;
|
|
87
|
+
let a = n.fields, o = [];
|
|
88
|
+
for (let [e, t] of Object.entries(a)) {
|
|
89
|
+
let n = i === "sqlite" || i === "turso" ? r(t) : void 0, a = t.type, s = f(t);
|
|
90
|
+
(s || n || h(a, i) || e in Object.prototype) && o.push({
|
|
91
|
+
key: e,
|
|
92
|
+
type: a,
|
|
93
|
+
...s ? { numericId: !0 } : {},
|
|
94
|
+
...n ? { decimalShape: n } : {}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return e.map((e) => {
|
|
98
|
+
let n = { ...e };
|
|
99
|
+
for (let { key: e, type: r, decimalShape: a, numericId: s } of o) e in n && (n[e] = s ? d(n[e]) : a && n[e] !== null && n[e] !== void 0 ? t(n[e], a) : m(n[e], r, i));
|
|
100
|
+
return n;
|
|
101
|
+
});
|
|
102
|
+
}, v = (e, t) => {
|
|
103
|
+
if (e == null) return e;
|
|
104
|
+
switch (t) {
|
|
105
|
+
case "json": return JSON.stringify(e);
|
|
106
|
+
case "array":
|
|
107
|
+
case "vector": return typeof e == "string" ? e : JSON.stringify(e);
|
|
108
|
+
default: return e;
|
|
109
|
+
}
|
|
110
|
+
}, y = (t, i, a = ["json", "array"]) => {
|
|
111
|
+
let o = e(i);
|
|
112
|
+
if (o === void 0) return t;
|
|
113
|
+
let s = o.fields, c = null;
|
|
114
|
+
for (let [e, i] of Object.entries(s)) if (a.includes(i.type) && e in t) {
|
|
115
|
+
let a = i.type === "decimal" ? r(i) : void 0, o = t[e];
|
|
116
|
+
if (a && o != null && typeof o != "string") throw TypeError("Encoded decimal writes require exact decimal strings");
|
|
117
|
+
let s = a && typeof o == "string" ? n(o, a) : v(o, i.type);
|
|
118
|
+
s !== t[e] && (c === null && (c = { ...t }), c[e] = s);
|
|
119
|
+
}
|
|
120
|
+
return c ?? t;
|
|
121
|
+
};
|
|
122
|
+
//#endregion
|
|
123
|
+
export { m as decodeCell, _ as decodeRowsForTable, g as decodeRowsFromSchema, y as encodeRowForSchema };
|
package/dist/rowKey.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/rowKey.ts
|
|
2
|
+
var e = (e) => typeof e == "string" || typeof e == "number" ? [["id", e]] : Object.entries(e).map(([e, t]) => [e, t]), t = (e) => {
|
|
3
|
+
if (typeof e == "string" || typeof e == "number") return String(e);
|
|
4
|
+
let t = Object.entries(e);
|
|
5
|
+
return t.length === 1 ? String(t[0][1]) : t.slice().sort(([e], [t]) => e < t ? -1 : +(e > t)).map(([e, t]) => `${e}=${String(t)}`).join("\0");
|
|
6
|
+
}, n = (e) => typeof e == "object";
|
|
7
|
+
//#endregion
|
|
8
|
+
export { n as isCompositeRowKey, e as rowKeyColumns, t as rowKeyIdentity };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { timestampMs as e } from "./wire.js";
|
|
2
|
+
import { Schema as t } from "effect";
|
|
3
|
+
//#region src/rowSchema.ts
|
|
4
|
+
var n = (n) => {
|
|
5
|
+
let r = (() => {
|
|
6
|
+
switch (n.type) {
|
|
7
|
+
case "id": return n.idScheme?.kind === "numeric" ? t.Number : t.String;
|
|
8
|
+
case "text":
|
|
9
|
+
case "enum": return t.String;
|
|
10
|
+
case "reference": return n.referenceStorage === "numeric" ? t.Number : t.String;
|
|
11
|
+
case "integer":
|
|
12
|
+
case "real":
|
|
13
|
+
case "decimal": return t.Number;
|
|
14
|
+
case "boolean": return t.Boolean;
|
|
15
|
+
case "timestamp":
|
|
16
|
+
case "date": return e;
|
|
17
|
+
case "bigint": return t.BigIntFromString;
|
|
18
|
+
case "bytes": return t.Uint8ArrayFromBase64;
|
|
19
|
+
case "array": return t.Array(t.Unknown);
|
|
20
|
+
case "interval": return t.String;
|
|
21
|
+
default: return t.Unknown;
|
|
22
|
+
}
|
|
23
|
+
})();
|
|
24
|
+
return n.nullable === !0 ? t.NullOr(r) : r;
|
|
25
|
+
}, r = (e, r) => {
|
|
26
|
+
let i = new Set(r?.omit ?? []), a = {};
|
|
27
|
+
for (let [t, r] of Object.entries(e.fields)) i.has(t) || (a[t] = n(r));
|
|
28
|
+
return t.Struct(a);
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
export { n as columnSchema, r as rowSchema };
|
package/dist/scopeKey.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/scopeKey.ts
|
|
2
|
+
var e = 255, t = (e) => e == null ? "null" : typeof e == "string" || typeof e == "number" || typeof e == "boolean" ? JSON.stringify(e) : Array.isArray(e) ? `[${e.map(t).join(",")}]` : typeof e == "object" ? `{${Object.entries(e).filter(([, e]) => e !== void 0).sort(([e], [t]) => e < t ? -1 : +(e > t)).map(([e, n]) => `${JSON.stringify(e)}:${t(n)}`).join(",")}}` : JSON.stringify(String(e)), n = (e) => {
|
|
3
|
+
if (e == null) return null;
|
|
4
|
+
let n = typeof e == "string" ? e : t(e);
|
|
5
|
+
return n.length > 255 ? n.slice(0, 255) : n;
|
|
6
|
+
};
|
|
7
|
+
//#endregion
|
|
8
|
+
export { e as SCOPE_KEY_MAX_LENGTH, n as scopeKeyOf };
|
package/dist/seed.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region src/seed.ts
|
|
2
|
+
var e = (e, t) => ({
|
|
3
|
+
name: e,
|
|
4
|
+
body: t
|
|
5
|
+
}), t = (t) => {
|
|
6
|
+
if (t.lifecycle === "cron" && !t.cron) throw Error(`seed "${t.id}": lifecycle 'cron' requires a 'cron' field`);
|
|
7
|
+
if (t.lifecycle === "onSchemaChange" && (!t.watchedTables || t.watchedTables.length === 0)) throw Error(`seed "${t.id}": lifecycle 'onSchemaChange' requires at least one entry in 'watchedTables'`);
|
|
8
|
+
let n = t.steps({ step: e });
|
|
9
|
+
if (n.length === 0) throw Error(`seed "${t.id}": at least one step is required`);
|
|
10
|
+
return {
|
|
11
|
+
__seed: !0,
|
|
12
|
+
id: t.id,
|
|
13
|
+
name: t.name,
|
|
14
|
+
lifecycle: t.lifecycle,
|
|
15
|
+
...t.cron === void 0 ? {} : { cron: t.cron },
|
|
16
|
+
...t.timezone === void 0 ? {} : { timezone: t.timezone },
|
|
17
|
+
...t.watchedTables === void 0 ? {} : { watchedTables: t.watchedTables },
|
|
18
|
+
...t.fingerprint === void 0 ? {} : { fingerprint: t.fingerprint },
|
|
19
|
+
steps: n
|
|
20
|
+
};
|
|
21
|
+
}, n = (e) => typeof e == "object" && !!e && "__seed" in e && e.__seed === !0, r = null, i = null, a = (e) => {
|
|
22
|
+
r = e;
|
|
23
|
+
}, o = (e) => {
|
|
24
|
+
i = e;
|
|
25
|
+
}, s = async (e) => {
|
|
26
|
+
let t = r;
|
|
27
|
+
t !== null && await t(e);
|
|
28
|
+
}, c = async (e) => {
|
|
29
|
+
let t = i;
|
|
30
|
+
t !== null && e.changedTables.length !== 0 && await t(e);
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
export { t as defineSeed, c as fireSchemaChangeSeeds, s as fireTenantCreateSeeds, n as isSeedDefinition, o as setSchemaChangeSeedHook, a as setTenantCreateSeedHook };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/snowflake.ts
|
|
2
|
+
var e = 10n, t = 12n, n = (1n << e) - 1n, r = (1n << t) - 1n, i = t, a = 22n, o = () => {
|
|
3
|
+
let e = process.env.SNOWFLAKE_MACHINE_ID;
|
|
4
|
+
if (e === void 0 || e === "") return 0n;
|
|
5
|
+
let t = BigInt(e);
|
|
6
|
+
if (t < 0n || t > n) throw Error(`SNOWFLAKE_MACHINE_ID out of range: ${e}. Must be 0..${n}.`);
|
|
7
|
+
return t;
|
|
8
|
+
}, s = () => ({
|
|
9
|
+
lastMs: 0n,
|
|
10
|
+
sequence: 0n,
|
|
11
|
+
machineId: o()
|
|
12
|
+
}), c, l = () => (c === void 0 && (c = s()), c), u = () => {
|
|
13
|
+
c = s();
|
|
14
|
+
}, d = () => BigInt(Date.now()), f = (e) => {
|
|
15
|
+
let t = d();
|
|
16
|
+
for (; t <= e;) t = d();
|
|
17
|
+
return t;
|
|
18
|
+
}, p = () => {
|
|
19
|
+
let e = l(), t = d();
|
|
20
|
+
t === e.lastMs ? (e.sequence = e.sequence + 1n & r, e.sequence === 0n && (t = f(e.lastMs), e.lastMs = t)) : (e.sequence = 0n, e.lastMs = t);
|
|
21
|
+
let n = t - 1704067200000n;
|
|
22
|
+
if (n < 0n) throw Error("Snowflake timestamp before configured epoch (2024-01-01). System clock is wrong.");
|
|
23
|
+
return (n << a | e.machineId << i | e.sequence).toString();
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
export { p as generateSnowflake, u as resetSnowflake };
|
package/dist/sql.d.ts
CHANGED
|
@@ -359,7 +359,12 @@ export declare interface ApplyPlanCtx {
|
|
|
359
359
|
* migration was a framework bug. `voltro db apply` did exactly that for two
|
|
360
360
|
* releases while `voltro dev`'s boot diff, which uses this parameter, did not.
|
|
361
361
|
*/
|
|
362
|
-
|
|
362
|
+
/** The applier supplies `execution` for every pre-execution replan (including
|
|
363
|
+
* interrupted-run reconciliation), and `convergence` only after planned work.
|
|
364
|
+
* Review-bound callers must validate full content in the execution phase before
|
|
365
|
+
* projecting their transactional/online subsets. Ordinary auto-diff callers
|
|
366
|
+
* can ignore the phase and adapt to the current schema as before. */
|
|
367
|
+
readonly replan: (sql: SqlClient.SqlClient, phase?: 'execution' | 'convergence') => Effect.Effect<MigrationPlan, SqlError, SqlClient.SqlClient>;
|
|
363
368
|
/**
|
|
364
369
|
* The declared store charset — the one `replan` plans with. Here only for
|
|
365
370
|
* the resume ledger this creates before the first statement: nothing declares
|
|
@@ -3581,11 +3586,17 @@ declare type IndexField = string | {
|
|
|
3581
3586
|
declare type IndexKind = 'btree' | 'gist' | 'gin' | 'brin' | 'hnsw';
|
|
3582
3587
|
|
|
3583
3588
|
/**
|
|
3584
|
-
* Per-kind tuning options.
|
|
3585
|
-
* build-time
|
|
3589
|
+
* Per-kind tuning options. GIN supports a single-column operator class;
|
|
3590
|
+
* HNSW supports pgvector build-time parameters. `m` controls graph connectivity (default 16),
|
|
3586
3591
|
* `efConstruction` the build-time candidate-list size (default 64).
|
|
3587
3592
|
*/
|
|
3588
3593
|
declare interface IndexKindOptions {
|
|
3594
|
+
/** PostgreSQL GIN operator class for a single plain column.
|
|
3595
|
+
* `gin_trgm_ops` installs pg_trgm and accelerates contains/ILIKE searches.
|
|
3596
|
+
*/
|
|
3597
|
+
readonly gin?: {
|
|
3598
|
+
readonly opclass: string;
|
|
3599
|
+
};
|
|
3589
3600
|
readonly hnsw?: {
|
|
3590
3601
|
readonly m?: number;
|
|
3591
3602
|
readonly efConstruction?: number;
|
|
@@ -4780,6 +4791,11 @@ export declare const publishSqliteDecimalStage: (sql: SqlClient.SqlClient, reque
|
|
|
4780
4791
|
declare interface QueryDescriptor<R = Row> {
|
|
4781
4792
|
readonly table: string;
|
|
4782
4793
|
readonly predicate: Predicate | undefined;
|
|
4794
|
+
/** Additional reactive invalidation sources, independent of SQL row selection.
|
|
4795
|
+
* The runtime merges a query handler's declared `source` tables here. Changes
|
|
4796
|
+
* to these tables recheck subscription authority even when SQL rows do not
|
|
4797
|
+
* change. They add no joins, predicates or cross-tenant access. */
|
|
4798
|
+
readonly dependentTables?: ReadonlyArray<string>;
|
|
4783
4799
|
/** Phantom — carries the row type through to `store.query()`. Never set at
|
|
4784
4800
|
* runtime; erased entirely by the compiler. */
|
|
4785
4801
|
readonly __row?: R;
|
|
@@ -5070,6 +5086,11 @@ declare interface QueryDescriptor<R = Row> {
|
|
|
5070
5086
|
declare interface QueryDescriptor_2<R = Row_2> {
|
|
5071
5087
|
readonly table: string;
|
|
5072
5088
|
readonly predicate: Predicate_2 | undefined;
|
|
5089
|
+
/** Additional reactive invalidation sources, independent of SQL row selection.
|
|
5090
|
+
* The runtime merges a query handler's declared `source` tables here. Changes
|
|
5091
|
+
* to these tables recheck subscription authority even when SQL rows do not
|
|
5092
|
+
* change. They add no joins, predicates or cross-tenant access. */
|
|
5093
|
+
readonly dependentTables?: ReadonlyArray<string>;
|
|
5073
5094
|
/** Phantom — carries the row type through to `store.query()`. Never set at
|
|
5074
5095
|
* runtime; erased entirely by the compiler. */
|
|
5075
5096
|
readonly __row?: R;
|
|
@@ -5688,7 +5709,7 @@ declare type Row = Readonly<Record<string, unknown>>;
|
|
|
5688
5709
|
declare type Row_2 = Readonly<Record<string, unknown>>;
|
|
5689
5710
|
|
|
5690
5711
|
/** Addresses one row: its `id`, or the columns of an explicit primary key. */
|
|
5691
|
-
declare type RowKey = string | Readonly<Record<string, unknown>>;
|
|
5712
|
+
declare type RowKey = string | number | Readonly<Record<string, unknown>>;
|
|
5692
5713
|
|
|
5693
5714
|
/** The context a rule predicate is evaluated with. */
|
|
5694
5715
|
declare interface RuleContext {
|
|
@@ -6868,8 +6889,8 @@ declare interface TableIndex {
|
|
|
6868
6889
|
*/
|
|
6869
6890
|
readonly kind?: IndexKind;
|
|
6870
6891
|
/**
|
|
6871
|
-
* Per-kind tuning
|
|
6872
|
-
*
|
|
6892
|
+
* Per-kind tuning: `gin.opclass` or `hnsw.{m, efConstruction, opclass}`.
|
|
6893
|
+
* Ignored for kinds that do not read the corresponding options.
|
|
6873
6894
|
*/
|
|
6874
6895
|
readonly kindOptions?: IndexKindOptions;
|
|
6875
6896
|
/**
|