@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,65 @@
|
|
|
1
|
+
import { Context as e, Metric as t } from "effect";
|
|
2
|
+
//#region src/dbMetrics.ts
|
|
3
|
+
var n = t.exponentialBoundaries({
|
|
4
|
+
start: 5e-4,
|
|
5
|
+
factor: 2,
|
|
6
|
+
count: 16
|
|
7
|
+
}), r = t.counter("voltro_db_queries_total", { description: "Database operations executed, by dialect and operation kind." }), i = t.histogram("voltro_db_query_duration_seconds", {
|
|
8
|
+
boundaries: n,
|
|
9
|
+
description: "Database operation duration in seconds, by dialect and operation kind."
|
|
10
|
+
}), a = t.counter("voltro_db_errors_total", { description: "Database operations that threw, by dialect and operation kind." }), o = t.gauge("voltro_db_operations_in_flight", { description: "Database operations currently executing, by dialect. An upper bound on connections the framework holds; NOT the driver pool's waiting count." }), s = t.counter("voltro_db_eager_fallback_total", { description: "Eager-load queries that degraded from the single-roundtrip JSON-agg path to the multi-query walker, by dialect and reason." }), c = e.empty(), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), f = (e, n) => {
|
|
11
|
+
let o = `${e}\u0000${n}`, s = l.get(o);
|
|
12
|
+
if (s !== void 0) return s;
|
|
13
|
+
let c = (r) => t.withAttributes(t.withAttributes(r, { dialect: e }), { op: n }), u = {
|
|
14
|
+
count: c(r),
|
|
15
|
+
duration: c(i),
|
|
16
|
+
errors: c(a)
|
|
17
|
+
};
|
|
18
|
+
return l.set(o, u), u;
|
|
19
|
+
}, p = () => {
|
|
20
|
+
l.clear(), u.clear(), d.clear();
|
|
21
|
+
}, m = () => l.size + u.size + d.size, h = /* @__PURE__ */ new Map(), g = (e, n) => {
|
|
22
|
+
let r = Math.max(0, (h.get(e) ?? 0) + n);
|
|
23
|
+
r === 0 ? h.delete(e) : h.set(e, r);
|
|
24
|
+
let i = u.get(e);
|
|
25
|
+
i === void 0 && (i = t.withAttributes(o, { dialect: e }), u.set(e, i)), i.updateUnsafe(r, c);
|
|
26
|
+
}, _ = (e) => h.get(e) ?? 0, v = (e) => {
|
|
27
|
+
let t = f(String(e.dialect), e.op);
|
|
28
|
+
t.count.updateUnsafe(1, c), t.duration.updateUnsafe(e.durationMs / 1e3, c), e.status === "error" && t.errors.updateUnsafe(1, c);
|
|
29
|
+
}, y = async (e, t, n) => {
|
|
30
|
+
let r = performance.now(), i = String(e);
|
|
31
|
+
g(i, 1);
|
|
32
|
+
let a = "ok";
|
|
33
|
+
try {
|
|
34
|
+
return await n();
|
|
35
|
+
} catch (e) {
|
|
36
|
+
throw a = "error", e;
|
|
37
|
+
} finally {
|
|
38
|
+
g(i, -1), v({
|
|
39
|
+
dialect: e,
|
|
40
|
+
op: t,
|
|
41
|
+
durationMs: performance.now() - r,
|
|
42
|
+
status: a
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}, b = 3e5, x = (e) => {
|
|
46
|
+
if (e == null || e === "") return;
|
|
47
|
+
let t = Number(e);
|
|
48
|
+
return Number.isFinite(t) && t >= 0 ? Math.floor(t) : void 0;
|
|
49
|
+
}, S = (e, t = process.env) => x(t.VOLTRO_DB_EAGER_FALLBACK_WARN_INTERVAL_MS) ?? x(e) ?? 3e5, C = (e, n = {}) => {
|
|
50
|
+
let r = S(n.warnIntervalMs), i = n.now ?? (() => Date.now()), a = /* @__PURE__ */ new Map();
|
|
51
|
+
return (n) => {
|
|
52
|
+
let o = `${n.dialect} ${n.reason}`, l = d.get(o);
|
|
53
|
+
l === void 0 && (l = t.withAttributes(t.withAttributes(s, { dialect: String(n.dialect) }), { reason: n.reason }), d.set(o, l)), l.updateUnsafe(1, c);
|
|
54
|
+
let u = `${n.table}\u0000${n.reason}`, f = a.get(u), p = f === void 0 || r > 0 && i() - f >= r, m = {
|
|
55
|
+
table: n.table,
|
|
56
|
+
dialect: String(n.dialect),
|
|
57
|
+
reason: n.reason,
|
|
58
|
+
metric: "voltro_db_eager_fallback_total",
|
|
59
|
+
...n.error === void 0 ? {} : { err: n.error }
|
|
60
|
+
};
|
|
61
|
+
p ? (a.set(u, i()), e.warn(n.reason === "execute-failed" ? "eager-load JSON-agg statement FAILED and was re-run on the multi-query walker — this query pays both paths on every call. Counted as voltro_db_eager_fallback_total{reason=\"execute-failed\"}." : "eager-load could not be compiled to a single JSON-agg roundtrip and is running on the multi-query walker — one round trip per relation level, on every call. Counted as voltro_db_eager_fallback_total{reason=\"not-compilable\"}.", m)) : e.debug("eager-load is still running on the walker (rate-limited; the counter is not)", m);
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
export { b as DEFAULT_EAGER_FALLBACK_WARN_INTERVAL_MS, m as dbMetricTagCacheSizeForTests, _ as dbOperationsInFlight, C as makeEagerFallbackReporter, y as observeDbOp, v as recordDbOp, p as resetDbMetricTagCacheForTests, S as resolveEagerFallbackWarnIntervalMs };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/decimalComparison.ts
|
|
2
|
+
var e = (e) => {
|
|
3
|
+
if (typeof e != "string" || !/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(e)) return null;
|
|
4
|
+
let [t = "", n = ""] = e.replace(/^[+-]/, "").split("."), r = t.replace(/^0+/, "") || "0";
|
|
5
|
+
return {
|
|
6
|
+
negative: e.startsWith("-") && /[1-9]/.test(r + n),
|
|
7
|
+
whole: r,
|
|
8
|
+
fraction: n
|
|
9
|
+
};
|
|
10
|
+
}, t = (t, n) => {
|
|
11
|
+
let r = e(t), i = e(n);
|
|
12
|
+
if (!r || !i) return null;
|
|
13
|
+
if (r.negative !== i.negative) return r.negative ? -1 : 1;
|
|
14
|
+
let a = r.whole.length - i.whole.length;
|
|
15
|
+
if (a === 0 && (a = r.whole === i.whole ? 0 : r.whole > i.whole ? 1 : -1), a === 0) {
|
|
16
|
+
let e = Math.max(r.fraction.length, i.fraction.length), t = r.fraction.padEnd(e, "0"), n = i.fraction.padEnd(e, "0");
|
|
17
|
+
a = t === n ? 0 : t > n ? 1 : -1;
|
|
18
|
+
}
|
|
19
|
+
return a === 0 ? 0 : (a > 0 ? 1 : -1) * (r.negative ? -1 : 1);
|
|
20
|
+
}, n = (t) => {
|
|
21
|
+
let n = e(t);
|
|
22
|
+
if (n === null) return null;
|
|
23
|
+
let r = n.fraction.replace(/0+$/, "");
|
|
24
|
+
return `${n.negative ? "-" : ""}${n.whole}${r ? "." + r : ""}`;
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { t as compareDecimal, n as decimalEqualityKey };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { createHash as e } from "node:crypto";
|
|
2
|
+
//#region src/derivedRowId.ts
|
|
3
|
+
var t = 64, n = "\0", r = 32, i = (t, ...i) => `${t}_${e("sha256").update(i.map(String).join(n)).digest("hex").slice(0, r)}`, a = (e) => e.length + 1 + r;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { t as ID_COLUMN_MAX_LENGTH, i as derivedRowId, a as derivedRowIdLength };
|
package/dist/dialect.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/dialect.ts
|
|
2
|
+
var e = (e) => e === "sqlite" || e === "turso", t = (e) => e === "mysql" || e === "mariadb", n = (e, t) => {
|
|
3
|
+
switch (t) {
|
|
4
|
+
case "mysql":
|
|
5
|
+
case "mariadb": return `\`${e.replace(/`/g, "``")}\``;
|
|
6
|
+
case "mssql": return `[${e.replace(/\]/g, "]]")}]`;
|
|
7
|
+
case "postgres":
|
|
8
|
+
case "sqlite":
|
|
9
|
+
case "turso": return `"${e.replace(/"/g, "\"\"")}"`;
|
|
10
|
+
}
|
|
11
|
+
}, r = 1e4;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { r as DEFAULT_ACQUIRE_TIMEOUT_MS, t as isMysqlFamily, e as isSqliteFamily, n as quoteIdent };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/enumRenames.ts
|
|
2
|
+
var e = /* @__PURE__ */ new Map(), t = (t, n) => {
|
|
3
|
+
if (n.from === n.to) throw Error(`declareEnumRename('${t}'): \`from\` and \`to\` are both '${n.from}' — a rename must change the value.`);
|
|
4
|
+
let r = e.get(t) ?? [];
|
|
5
|
+
for (let e of r) {
|
|
6
|
+
if (e.from === n.from && e.to === n.to) return;
|
|
7
|
+
if (e.from === n.from && e.to !== n.to) throw Error(`declareEnumRename('${t}'): value '${n.from}' is already declared as renamed to '${e.to}', cannot also rename it to '${n.to}'.`);
|
|
8
|
+
}
|
|
9
|
+
r.push(n), e.set(t, r);
|
|
10
|
+
}, n = (t) => e.get(t) ?? [], r = () => e, i = () => {
|
|
11
|
+
e.clear();
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { r as allEnumRenames, i as clearEnumRenames, t as declareEnumRename, n as getEnumRenames };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { timestamp as e } from "./columns.js";
|
|
2
|
+
import { defineMixin as t } from "./mixins.js";
|
|
3
|
+
//#region src/expiresMixin.ts
|
|
4
|
+
var n = "voltro/expires", r = () => t({
|
|
5
|
+
id: n,
|
|
6
|
+
fields: { expiresAt: e().nullable() },
|
|
7
|
+
behaviors: { defaultWhere: () => "expiresAt IS NULL OR expiresAt > now()" }
|
|
8
|
+
});
|
|
9
|
+
//#endregion
|
|
10
|
+
export { n as VOLTRO_EXPIRES_MIXIN_ID, r as expires };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
//#region src/fieldEncryption.ts
|
|
2
|
+
var e = "enc:v1:", t = "enc:v2:", n = (e, t, n) => {
|
|
3
|
+
let r = `${e}:${t}`, i = n == null || n === "" ? void 0 : String(n);
|
|
4
|
+
return i === void 0 ? { column: r } : {
|
|
5
|
+
column: r,
|
|
6
|
+
row: `${r}:${i}`
|
|
7
|
+
};
|
|
8
|
+
}, r = (e) => typeof e == "string" && e.startsWith("enc:v2:"), i = class extends Error {
|
|
9
|
+
_tag = "FieldDecryptionError";
|
|
10
|
+
table;
|
|
11
|
+
column;
|
|
12
|
+
reason;
|
|
13
|
+
constructor(e) {
|
|
14
|
+
super(`column "${e.table}.${e.column}" is .encrypted() but could not be decrypted (${e.reason}) — the stored value was most likely encrypted under a different key`), this.name = "FieldDecryptionError", this.table = e.table, this.column = e.column, this.reason = e.reason;
|
|
15
|
+
}
|
|
16
|
+
}, a = (e) => typeof e == "object" && !!e && e._tag === "FieldDecryptionError", o = (e) => typeof e == "string" && (e.startsWith("enc:v1:") || e.startsWith("enc:v2:")), s = (e, t, n) => e.encrypt(JSON.stringify(t), n), c = /* @__PURE__ */ new Set([
|
|
17
|
+
"text",
|
|
18
|
+
"id",
|
|
19
|
+
"reference",
|
|
20
|
+
"enum",
|
|
21
|
+
"uuid",
|
|
22
|
+
"email",
|
|
23
|
+
"url"
|
|
24
|
+
]), l = (e, t, n, r) => {
|
|
25
|
+
let i = e.decrypt(t, r), a;
|
|
26
|
+
try {
|
|
27
|
+
a = JSON.parse(i);
|
|
28
|
+
} catch {
|
|
29
|
+
return i;
|
|
30
|
+
}
|
|
31
|
+
return typeof a == "string" ? a : n === void 0 || c.has(n) ? i : a;
|
|
32
|
+
}, u = (e, t, n, r) => {
|
|
33
|
+
let i = e.decrypt(t, r);
|
|
34
|
+
try {
|
|
35
|
+
return typeof JSON.parse(i) == "string" ? !1 : n === void 0 || c.has(n) ? !0 : void 0;
|
|
36
|
+
} catch {
|
|
37
|
+
return !0;
|
|
38
|
+
}
|
|
39
|
+
}, d = (e, t) => e.fields[t]?.type, f = (e) => {
|
|
40
|
+
let t = [];
|
|
41
|
+
for (let [n, r] of Object.entries(e.fields)) r.encrypted === !0 && t.push(n);
|
|
42
|
+
return t;
|
|
43
|
+
}, p = "id", m = (e, t, n, r) => {
|
|
44
|
+
if (!t) return e;
|
|
45
|
+
let i = f(t);
|
|
46
|
+
return i.length === 0 ? e : g(e, i, t.tableName ?? "?", n, r);
|
|
47
|
+
}, h = (e, t, n) => {
|
|
48
|
+
if (t === void 0 || e.length === 0) return e;
|
|
49
|
+
let r = f(t);
|
|
50
|
+
if (r.length === 0) return e;
|
|
51
|
+
let i = t.tableName ?? "?";
|
|
52
|
+
return e.map((e) => g(e, r, i, n));
|
|
53
|
+
}, g = (e, t, r, i, a) => {
|
|
54
|
+
let c = a ?? e[p], l = { ...e };
|
|
55
|
+
for (let e of t) {
|
|
56
|
+
let t = l[e];
|
|
57
|
+
if (!(t == null || o(t))) {
|
|
58
|
+
if (!i) throw Error(`column "${r}.${e}" is .encrypted() but no field cipher is registered — set VOLTRO_FIELD_ENCRYPTION_KEY (\`voltro dev\` mints one; \`voltro serve\` refuses to boot without it); in a test, pass \`fieldEncryptionKey\` to makeTestContext`);
|
|
59
|
+
l[e] = s(i, t, n(r, e, c));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return l;
|
|
63
|
+
}, _ = (e, t, r, a) => {
|
|
64
|
+
if (!t) return e;
|
|
65
|
+
let s = f(t);
|
|
66
|
+
if (s.length === 0 || !r) return e;
|
|
67
|
+
let c = a?.onError ?? "throw", u = t.tableName ?? "?";
|
|
68
|
+
return e.map((e) => {
|
|
69
|
+
let f;
|
|
70
|
+
for (let m of s) {
|
|
71
|
+
let s = e[m];
|
|
72
|
+
if (o(s)) {
|
|
73
|
+
f ??= { ...e };
|
|
74
|
+
try {
|
|
75
|
+
f[m] = l(r, s, d(t, m), n(u, m, a?.rowId ?? e[p]));
|
|
76
|
+
} catch (e) {
|
|
77
|
+
let t = String(e?.message ?? e);
|
|
78
|
+
if (c === "null") {
|
|
79
|
+
f[m] = null, a?.warn?.({
|
|
80
|
+
table: u,
|
|
81
|
+
column: m,
|
|
82
|
+
reason: t
|
|
83
|
+
});
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
throw new i({
|
|
87
|
+
table: u,
|
|
88
|
+
column: m,
|
|
89
|
+
reason: t
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return f ?? e;
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
//#endregion
|
|
98
|
+
export { t as BOUND_ENCRYPTED_PREFIX, e as ENCRYPTED_PREFIX, i as FieldDecryptionError, l as decodeFieldValue, _ as decryptFieldsOnRead, s as encodeFieldValue, m as encryptFieldsForWrite, h as encryptFieldsForWriteBatch, f as encryptedColumnsOf, n as fieldBinding, r as isBoundCiphertext, o as isEncrypted, a as isFieldDecryptionError, u as isRawEncoding };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { id as e, integer as t, json as n, text as r, timestamp as i } from "./columns.js";
|
|
2
|
+
import { table as a } from "./table.js";
|
|
3
|
+
//#region src/frameworkTables.ts
|
|
4
|
+
var o = a("_voltro_migrations", {
|
|
5
|
+
id: e({ prefix: "mig" }),
|
|
6
|
+
name: r(),
|
|
7
|
+
hash: r(),
|
|
8
|
+
status: r(),
|
|
9
|
+
appliedAt: i().nullable(),
|
|
10
|
+
durationMs: t().nullable(),
|
|
11
|
+
errorMessage: r().nullable(),
|
|
12
|
+
errorStack: r().nullable(),
|
|
13
|
+
workflowRunId: r().nullable(),
|
|
14
|
+
createdAt: i().default("now"),
|
|
15
|
+
updatedAt: i().default("now").onUpdate("now")
|
|
16
|
+
}).index(["status"]), s = a("_voltro_seeds", {
|
|
17
|
+
id: e({ prefix: "seed" }),
|
|
18
|
+
name: r(),
|
|
19
|
+
lifecycle: r(),
|
|
20
|
+
fingerprint: r(),
|
|
21
|
+
cronSchedule: r().nullable(),
|
|
22
|
+
watchedTables: n().nullable(),
|
|
23
|
+
nextRunAt: i().nullable(),
|
|
24
|
+
lastRunStatus: r().nullable(),
|
|
25
|
+
lastRunAt: i().nullable(),
|
|
26
|
+
lastRunDurationMs: t().nullable(),
|
|
27
|
+
lastRunRowsTouched: t().nullable(),
|
|
28
|
+
lastError: r().nullable(),
|
|
29
|
+
workflowRunId: r().nullable(),
|
|
30
|
+
createdAt: i().default("now"),
|
|
31
|
+
updatedAt: i().default("now").onUpdate("now")
|
|
32
|
+
}).index(["lifecycle"]).index(["nextRunAt"]), c = a("_voltro_schema_owner", {
|
|
33
|
+
id: e({ prefix: "own" }),
|
|
34
|
+
appName: r(),
|
|
35
|
+
projectName: r().nullable(),
|
|
36
|
+
frameworkVersion: r().nullable(),
|
|
37
|
+
claimedAt: i().default("now")
|
|
38
|
+
}), l = a("_voltro_plugin_migrations", {
|
|
39
|
+
id: e({ prefix: "plm" }),
|
|
40
|
+
plugin_name: r(),
|
|
41
|
+
migration_id: r(),
|
|
42
|
+
description: r().nullable(),
|
|
43
|
+
applied_at: r()
|
|
44
|
+
}), u = a("_voltro_migration_plans", {
|
|
45
|
+
id: e({ prefix: "plan" }),
|
|
46
|
+
fingerprint: r(),
|
|
47
|
+
liveFingerprint: r().nullable(),
|
|
48
|
+
operations: n(),
|
|
49
|
+
rollbackPlan: n().nullable(),
|
|
50
|
+
appliedBy: r(),
|
|
51
|
+
environment: r(),
|
|
52
|
+
source: r(),
|
|
53
|
+
onlineStrategy: r().nullable(),
|
|
54
|
+
durationMs: t(),
|
|
55
|
+
notes: r().nullable(),
|
|
56
|
+
squashedAt: i().nullable(),
|
|
57
|
+
appliedAt: i().default("now"),
|
|
58
|
+
createdAt: i().default("now"),
|
|
59
|
+
updatedAt: i().default("now").onUpdate("now")
|
|
60
|
+
}).index(["fingerprint"]).index(["environment"]), d = a("_voltro_idempotency", {
|
|
61
|
+
id: e({ prefix: "idem" }),
|
|
62
|
+
scope: r(),
|
|
63
|
+
key: r(),
|
|
64
|
+
status: r(),
|
|
65
|
+
response: n().nullable(),
|
|
66
|
+
createdAt: i().default("now")
|
|
67
|
+
}).unique(["scope", "key"]).index(["createdAt"]), f = a("_voltro_devices", {
|
|
68
|
+
id: e({ prefix: "device" }),
|
|
69
|
+
tenantId: r(),
|
|
70
|
+
name: r(),
|
|
71
|
+
scopes: n().nullable(),
|
|
72
|
+
pairingHash: r().maxLength(64).nullable(),
|
|
73
|
+
pairingExpiresAt: i().nullable(),
|
|
74
|
+
accessHash: r().maxLength(64).nullable(),
|
|
75
|
+
accessExpiresAt: i().nullable(),
|
|
76
|
+
refreshHash: r().maxLength(64).nullable(),
|
|
77
|
+
refreshExpiresAt: i().nullable(),
|
|
78
|
+
previousRefreshHash: r().maxLength(64).nullable(),
|
|
79
|
+
generation: t().default(0),
|
|
80
|
+
pairedAt: i().nullable(),
|
|
81
|
+
lastSeenAt: i().nullable(),
|
|
82
|
+
revokedAt: i().nullable(),
|
|
83
|
+
revokedReason: r().nullable(),
|
|
84
|
+
createdBy: r().nullable(),
|
|
85
|
+
metadata: n().nullable(),
|
|
86
|
+
createdAt: i()
|
|
87
|
+
}).index(["tenantId"]).index(["pairingHash"]).index(["accessHash"]).index(["refreshHash"]).index(["previousRefreshHash"]), p = a("_voltro_tenant_selections", {
|
|
88
|
+
id: e({ prefix: "tsel" }),
|
|
89
|
+
subjectType: r().maxLength(32),
|
|
90
|
+
subjectId: r(),
|
|
91
|
+
tenantId: r(),
|
|
92
|
+
selectedAt: i()
|
|
93
|
+
}).primaryKey(["id"]).nonReactive(), m = a("_voltro_kv", {
|
|
94
|
+
id: e({ prefix: "kv" }),
|
|
95
|
+
key: r().unique(),
|
|
96
|
+
value: r().nullable(),
|
|
97
|
+
expiresAt: i().nullable(),
|
|
98
|
+
createdAt: i().default("now"),
|
|
99
|
+
updatedAt: i().default("now").onUpdate("now")
|
|
100
|
+
}).index(["expiresAt"]), h = a("_voltro_api_keys", {
|
|
101
|
+
id: e({ prefix: "apikey" }),
|
|
102
|
+
tenantId: r().nullable(),
|
|
103
|
+
name: r(),
|
|
104
|
+
hashedKey: r().maxLength(64).unique(),
|
|
105
|
+
keyPrefix: r(),
|
|
106
|
+
scopes: n().nullable(),
|
|
107
|
+
lastUsedAt: i().nullable(),
|
|
108
|
+
requestCount: t().default(0),
|
|
109
|
+
expiresAt: i().nullable(),
|
|
110
|
+
revokedAt: i().nullable(),
|
|
111
|
+
createdBy: r().nullable(),
|
|
112
|
+
onBehalfOf: r().nullable(),
|
|
113
|
+
metadata: n().nullable(),
|
|
114
|
+
createdAt: i().default("now")
|
|
115
|
+
}).index("byApiKeyTenant", ["tenantId"]), g = a("_voltro_replica_observations", {
|
|
116
|
+
id: e({ prefix: "robs" }),
|
|
117
|
+
replicaId: r().maxLength(191),
|
|
118
|
+
startedAt: i(),
|
|
119
|
+
version: r().maxLength(64).nullable(),
|
|
120
|
+
kind: r().maxLength(64),
|
|
121
|
+
payload: r().nullable(),
|
|
122
|
+
reachableAt: r().maxLength(255).nullable(),
|
|
123
|
+
writtenAt: i().default("now").onUpdate("now")
|
|
124
|
+
}).unique(["replicaId", "kind"]).index(["kind"]), _ = [
|
|
125
|
+
o,
|
|
126
|
+
s,
|
|
127
|
+
u
|
|
128
|
+
];
|
|
129
|
+
//#endregion
|
|
130
|
+
export { h as _voltroApiKeysTable, f as _voltroDevicesTable, d as _voltroIdempotencyTable, m as _voltroKvTable, u as _voltroMigrationPlansTable, o as _voltroMigrationsTable, l as _voltroPluginMigrationsTable, g as _voltroReplicaObservationsTable, c as _voltroSchemaOwnerTable, s as _voltroSeedsTable, p as _voltroTenantSelectionsTable, _ as frameworkTables };
|
package/dist/ginIndex.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/ginIndex.ts
|
|
2
|
+
var e = (e) => {
|
|
3
|
+
let t = e?.gin?.opclass;
|
|
4
|
+
if (t !== void 0) {
|
|
5
|
+
if (!/^[a-z_][a-z0-9_$]*(?:\.[a-z_][a-z0-9_$]*)?$/i.test(t)) throw Error("GIN opclass must be an unquoted, optionally schema-qualified identifier");
|
|
6
|
+
return t.toLowerCase().replace(/^public\./, "");
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { e as resolveGinOpclass };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { resolveFullTextIndex as e } from "./queryBuilder.js";
|
|
2
|
+
//#region src/hybridSearch.ts
|
|
3
|
+
var t = (t) => {
|
|
4
|
+
let n = t.alpha ?? .5;
|
|
5
|
+
if (n < 0 || n > 1) throw Error(`hybridSearch: alpha must be in [0, 1], got ${n}`);
|
|
6
|
+
return (r) => {
|
|
7
|
+
let i = Array.isArray(t.vector.query) ? {
|
|
8
|
+
column: t.vector.col,
|
|
9
|
+
queryVector: t.vector.query,
|
|
10
|
+
distance: t.vector.distance ?? "cosine",
|
|
11
|
+
alpha: n
|
|
12
|
+
} : {
|
|
13
|
+
column: t.vector.col,
|
|
14
|
+
queryText: t.vector.query,
|
|
15
|
+
distance: t.vector.distance ?? "cosine",
|
|
16
|
+
alpha: n
|
|
17
|
+
}, a = e(r.table, t.fts.indexName, r.fullTextIndexes);
|
|
18
|
+
return {
|
|
19
|
+
...r,
|
|
20
|
+
annClause: i,
|
|
21
|
+
fullTextSearch: {
|
|
22
|
+
indexName: t.fts.indexName,
|
|
23
|
+
query: t.fts.query,
|
|
24
|
+
columns: a.columns,
|
|
25
|
+
...a.config === void 0 ? {} : { config: a.config },
|
|
26
|
+
...a.weights === void 0 ? {} : { weights: a.weights }
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { t as hybridSearch };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { validateTypeIdPrefix as e } from "./identifierLimits.js";
|
|
2
|
+
import { generateSnowflake as t } from "./snowflake.js";
|
|
3
|
+
import { typeid as n } from "typeid-js";
|
|
4
|
+
import { ulid as r } from "ulid";
|
|
5
|
+
//#region src/idGenerator.ts
|
|
6
|
+
var i = (t) => {
|
|
7
|
+
let n = t.toLowerCase();
|
|
8
|
+
if (n.startsWith("_")) throw Error(`cannot derive a typeid prefix for table '${t}' (table names starting with '_' are not valid typeid prefixes). Pick an explicit prefix via id({ prefix: '...' }) or use a different scheme like id({ scheme: 'numeric' }) for internal tables.`);
|
|
9
|
+
if (!/^[a-z][a-z0-9_]*$/.test(n)) throw Error(`cannot derive a typeid prefix from table name '${t}' (must match [a-z][a-z0-9_]*). Pick an explicit prefix via id({ prefix: '...' }).`);
|
|
10
|
+
let r = n.endsWith("ies") && n.length > 3 ? n.slice(0, -3) + "y" : n.endsWith("ses") || n.endsWith("xes") || n.endsWith("zes") || n.endsWith("shes") || n.endsWith("ches") ? n.slice(0, -2) : n.endsWith("s") && n.length > 1 ? n.slice(0, -1) : n;
|
|
11
|
+
return e(r, {
|
|
12
|
+
kind: "derived",
|
|
13
|
+
tableName: t
|
|
14
|
+
}), r;
|
|
15
|
+
}, a = (t, n) => {
|
|
16
|
+
if (t === void 0) return {
|
|
17
|
+
kind: "typeid",
|
|
18
|
+
prefix: i(n)
|
|
19
|
+
};
|
|
20
|
+
if ("prefix" in t && !("scheme" in t)) return e(t.prefix, {
|
|
21
|
+
kind: "explicit",
|
|
22
|
+
tableName: n
|
|
23
|
+
}), {
|
|
24
|
+
kind: "typeid",
|
|
25
|
+
prefix: t.prefix
|
|
26
|
+
};
|
|
27
|
+
if (!("scheme" in t)) throw Error("invalid id() options: no scheme or prefix");
|
|
28
|
+
switch (t.scheme) {
|
|
29
|
+
case "typeid": {
|
|
30
|
+
let r = t.prefix ?? i(n);
|
|
31
|
+
return t.prefix !== void 0 && e(t.prefix, {
|
|
32
|
+
kind: "explicit",
|
|
33
|
+
tableName: n
|
|
34
|
+
}), {
|
|
35
|
+
kind: "typeid",
|
|
36
|
+
prefix: r
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
case "ulid": return { kind: "ulid" };
|
|
40
|
+
case "numeric": return { kind: "numeric" };
|
|
41
|
+
case "snowflake": return { kind: "snowflake" };
|
|
42
|
+
case "custom": return {
|
|
43
|
+
kind: "custom",
|
|
44
|
+
generate: t.generate
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}, o = (e, i) => {
|
|
48
|
+
switch (e.kind) {
|
|
49
|
+
case "typeid": return n(e.prefix).toString();
|
|
50
|
+
case "ulid": return r();
|
|
51
|
+
case "numeric": return null;
|
|
52
|
+
case "snowflake": return t();
|
|
53
|
+
case "custom": return e.generate(i);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
//#endregion
|
|
57
|
+
export { i as deriveTypeIdPrefix, o as generateId, a as resolveIdScheme };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/identifierLimits.ts
|
|
2
|
+
var e = 63, t = 60, n = /* @__PURE__ */ new Set(), r = (e) => {
|
|
3
|
+
n.add(e);
|
|
4
|
+
}, i = () => {
|
|
5
|
+
let e = [...n];
|
|
6
|
+
return n.clear(), e;
|
|
7
|
+
}, a = /^[a-zA-Z_][a-zA-Z0-9_]*$/, o = (e, t) => {
|
|
8
|
+
if (t.length === 0) throw Error(`${e} cannot be empty.`);
|
|
9
|
+
if (!a.test(t)) throw Error(`${e} '${t}' contains characters outside [A-Za-z0-9_] or starts with a digit. Dialect-portable identifiers must match /^[a-zA-Z_][a-zA-Z0-9_]*$/.`);
|
|
10
|
+
}, s = (e) => {
|
|
11
|
+
if (o("table name", e), e.length > 63) throw Error(`table name '${e}' is ${e.length} chars — exceeds the 63-byte cross-dialect limit (Postgres floor). Shorten the name; long table names also cascade into auto-named indexes and FK constraints that would themselves exceed the limit.`);
|
|
12
|
+
e.length > 60 && r(`table name '${e}' is ${e.length} chars — ${63 - e.length} from the Postgres 63-byte limit. Auto-named indexes on this table will run out of room fast.`);
|
|
13
|
+
}, c = (e, t) => {
|
|
14
|
+
if (o("column name", t), t.length > 63) throw Error(`column '${t}' on table '${e}' is ${t.length} chars — exceeds the 63-byte cross-dialect limit (Postgres floor). Rename it.`);
|
|
15
|
+
t.length > 60 && r(`column '${t}' on table '${e}' is ${t.length} chars — close to the 63-byte limit.`);
|
|
16
|
+
}, l = (e, t, n, i) => {
|
|
17
|
+
if (o("index name", t), t.length > 63) throw Error(n ? `auto-named index '${t}' on table '${e}' is ${t.length} chars — exceeds the 63-byte cross-dialect limit (Postgres floor). Supply an explicit short name: .index('<shortName>', ${JSON.stringify([...i])}).` : `index name '${t}' on table '${e}' is ${t.length} chars — exceeds the 63-byte cross-dialect limit (Postgres floor). Shorten it.`);
|
|
18
|
+
t.length > 60 && r(`index '${t}' on table '${e}' is ${t.length} chars — ${63 - t.length} from the 63-byte limit. ${n ? `Consider .index('<shortName>', ${JSON.stringify([...i])}) before it grows.` : ""}`);
|
|
19
|
+
}, u = (e, t) => {
|
|
20
|
+
if (e.length === 0) throw Error(`typeid prefix on table '${t.tableName}' cannot be empty.`);
|
|
21
|
+
if (!/^[a-z][a-z0-9_]*$/.test(e)) {
|
|
22
|
+
let n = t.kind === "derived" ? "the derived prefix doesn't match typeid's required shape — supply an explicit one via id({ prefix: '...' })." : "the prefix must match typeid's required shape /^[a-z][a-z0-9_]*$/.";
|
|
23
|
+
throw Error(`typeid prefix '${e}' on table '${t.tableName}' is invalid — ${n}`);
|
|
24
|
+
}
|
|
25
|
+
if (e.length > 63) {
|
|
26
|
+
let n = t.kind === "derived" ? "shorten the table name, or supply an explicit short prefix via id({ prefix: '...' })." : "pick a shorter prefix.";
|
|
27
|
+
throw Error(`typeid prefix '${e}' on table '${t.tableName}' is ${e.length} chars — exceeds the 63-byte limit; ${n}`);
|
|
28
|
+
}
|
|
29
|
+
e.length > 60 && r(`typeid prefix '${e}' on table '${t.tableName}' is ${e.length} chars — close to the 63-byte limit. Generated ids will be even longer (prefix + '_' + 26).`);
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { e as MAX_IDENTIFIER_LENGTH, t as WARN_IDENTIFIER_LENGTH, i as drainIdentifierWarnings, c as validateColumnName, l as validateIndexName, s as validateTableName, u as validateTypeIdPrefix };
|
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ import { YieldableError } from 'effect/Cause';
|
|
|
17
17
|
|
|
18
18
|
/** The store shape this needs — a read, nothing more. */
|
|
19
19
|
export declare interface ActorLookupStore {
|
|
20
|
-
query: (descriptor:
|
|
20
|
+
query: (descriptor: QueryDescriptor) => Promise<ReadonlyArray<Record<string, unknown>>>;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
/** The framework's built-in `actors` core table. */
|
|
@@ -4567,11 +4567,17 @@ export declare type IndexField = string | {
|
|
|
4567
4567
|
export declare type IndexKind = 'btree' | 'gist' | 'gin' | 'brin' | 'hnsw';
|
|
4568
4568
|
|
|
4569
4569
|
/**
|
|
4570
|
-
* Per-kind tuning options.
|
|
4571
|
-
* build-time
|
|
4570
|
+
* Per-kind tuning options. GIN supports a single-column operator class;
|
|
4571
|
+
* HNSW supports pgvector build-time parameters. `m` controls graph connectivity (default 16),
|
|
4572
4572
|
* `efConstruction` the build-time candidate-list size (default 64).
|
|
4573
4573
|
*/
|
|
4574
4574
|
export declare interface IndexKindOptions {
|
|
4575
|
+
/** PostgreSQL GIN operator class for a single plain column.
|
|
4576
|
+
* `gin_trgm_ops` installs pg_trgm and accelerates contains/ILIKE searches.
|
|
4577
|
+
*/
|
|
4578
|
+
readonly gin?: {
|
|
4579
|
+
readonly opclass: string;
|
|
4580
|
+
};
|
|
4575
4581
|
readonly hnsw?: {
|
|
4576
4582
|
readonly m?: number;
|
|
4577
4583
|
readonly efConstruction?: number;
|
|
@@ -6534,6 +6540,11 @@ Joins extends JoinsMap = {}> {
|
|
|
6534
6540
|
export declare interface QueryDescriptor<R = Row> {
|
|
6535
6541
|
readonly table: string;
|
|
6536
6542
|
readonly predicate: Predicate | undefined;
|
|
6543
|
+
/** Additional reactive invalidation sources, independent of SQL row selection.
|
|
6544
|
+
* The runtime merges a query handler's declared `source` tables here. Changes
|
|
6545
|
+
* to these tables recheck subscription authority even when SQL rows do not
|
|
6546
|
+
* change. They add no joins, predicates or cross-tenant access. */
|
|
6547
|
+
readonly dependentTables?: ReadonlyArray<string>;
|
|
6537
6548
|
/** Phantom — carries the row type through to `store.query()`. Never set at
|
|
6538
6549
|
* runtime; erased entirely by the compiler. */
|
|
6539
6550
|
readonly __row?: R;
|
|
@@ -7470,12 +7481,12 @@ declare type Row_2 = Readonly<Record<string, unknown>>;
|
|
|
7470
7481
|
declare type Row_3 = Readonly<Record<string, unknown>>;
|
|
7471
7482
|
|
|
7472
7483
|
/** Addresses one row: its `id`, or the columns of an explicit primary key. */
|
|
7473
|
-
export declare type RowKey = string | Readonly<Record<string, unknown>>;
|
|
7484
|
+
export declare type RowKey = string | number | Readonly<Record<string, unknown>>;
|
|
7474
7485
|
|
|
7475
7486
|
/**
|
|
7476
7487
|
* The `(column, value)` pairs a key addresses, in declaration order.
|
|
7477
7488
|
*
|
|
7478
|
-
* A
|
|
7489
|
+
* A scalar is the `id` column — that is the contract every existing caller
|
|
7479
7490
|
* relies on, and widening it must not change what a string means.
|
|
7480
7491
|
*/
|
|
7481
7492
|
export declare const rowKeyColumns: (key: RowKey) => ReadonlyArray<readonly [string, unknown]>;
|
|
@@ -8914,8 +8925,8 @@ export declare interface TableIndex {
|
|
|
8914
8925
|
*/
|
|
8915
8926
|
readonly kind?: IndexKind;
|
|
8916
8927
|
/**
|
|
8917
|
-
* Per-kind tuning
|
|
8918
|
-
*
|
|
8928
|
+
* Per-kind tuning: `gin.opclass` or `hnsw.{m, efConstruction, opclass}`.
|
|
8929
|
+
* Ignored for kinds that do not read the corresponding options.
|
|
8919
8930
|
*/
|
|
8920
8931
|
readonly kindOptions?: IndexKindOptions;
|
|
8921
8932
|
/**
|