@voltro/database 0.2.0 → 0.2.2
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 +24 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +139 -126
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -39,6 +39,30 @@ _Changes staged for the next release accumulate here (rolled up from
|
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
+
## [0.2.2] — 2026-07-17
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- **@voltro/cli** — `voltro build` now precompiles the whole serve path (framework + effect + `@voltro` inlined, app modules as lazy chunks) into a single **serve bundle** (`.framework/dist-api/serveBundle/serveEntry.js`), and `voltro serve` boots from it in-process — no child `node --import tsx`, no CLI command graph, no per-module resolution of the ~2700-module framework graph. This cuts `serve: ready` from ~1000 ms to ~180 ms (~5–6×) on both driverless (memory) and driver-backed (postgres) apps; the win is larger on a cold scale-to-zero container where module resolution dominates. The app's declared SQL driver is inlined into the bundle so it shares the framework's single effect instance (only the native leaf like `pg` stays external, resolved at runtime so it survives the deploy relocation). Fully fallback-safe: a missing, stale, or corrupt bundle degrades to the standard tsx serve path, so it can never stop `voltro serve` from booting. Nothing to configure — building an API app produces the bundle and serving prefers it automatically.
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- **@voltro/database** — The core-table registry (`registerCoreTables` / `requireActors` / `requireTenants`) now stores its state on a process-global `Symbol.for` singleton, the same mechanism the main table registry already uses — instead of module-local `let` bindings. Module-local state splits when the `@voltro/database` module is duplicated in a process (e.g. resolved through both the `.` and `./sql` entry points, or a bundled framework copy alongside an externally-resolved one): one instance's `registerCoreTables` becomes invisible to the instance that reads it, surfacing as a spurious `core 'actors' table not registered` at store construction. Pinning it to `globalThis` makes every copy share one store, matching the table registry's already-global behaviour.
|
|
51
|
+
|
|
52
|
+
### Internal (no consumer-facing effect)
|
|
53
|
+
|
|
54
|
+
- **@voltro/cli** — `appModuleLoader` now accepts lazy `() => import()` loaders alongside eager module namespaces (the eager path — today's `apiEntry.js` bundle — is unchanged). Groundwork for the serve bundle: app modules registered as lazy loaders evaluate on first `importAppModule` (during `runServe`, after `registerCoreTables`) rather than eagerly at bundle-import time. No consumer-facing effect on its own.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## [0.2.1] — 2026-07-17
|
|
59
|
+
|
|
60
|
+
### Fixed
|
|
61
|
+
|
|
62
|
+
- **@voltro/cli, @voltro/database** — `voltro codegen` / `dev` / `serve` / `build` no longer crash with `Cannot find package '@voltro/sql-mysql'` on an app that doesn't declare that driver (e.g. a memory-store app, or a postgres app for the mysql/mssql drivers). The CLI's framework-table assembly statically imported the CDC-offsets table schema from `@voltro/sql-mysql` / `@voltro/sql-mssql` (`import { _voltroCdcOffsetsTable } from '@voltro/sql-mysql'`), so merely LOADING the CLI resolved those driver packages — failing whenever one wasn't installed. This surfaced only in a production install where the drivers aren't present (0.2.0's app-declared-driver change), not in the workspace where all drivers are devDependencies. The two CDC-offsets table schemas (pure schema, no driver runtime) move to `@voltro/database` — the driver-agnostic package both the CLI and the drivers already depend on; the drivers re-export them so their public API + CDC readers are unchanged. The CLI now references a SQL driver only through the runtime `importDriver()` lookup (lazy, and only for the dialect actually in use). The lazily-imported driver modules are also typed with local structural interfaces instead of `typeof import('@voltro/sql-*')`, so no driver package is referenced in a type position either.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
42
66
|
## [0.2.0] — 2026-07-17
|
|
43
67
|
|
|
44
68
|
### ⚠ BREAKING
|
package/dist/index.d.ts
CHANGED
|
@@ -391,6 +391,8 @@ export declare const bytes: () => ColumnBuilder<Uint8Array<ArrayBufferLike>, "by
|
|
|
391
391
|
|
|
392
392
|
export declare type CaughtUpVerdict = 'caught-up' | 'behind';
|
|
393
393
|
|
|
394
|
+
export declare const CDC_OFFSETS_TABLE = "_voltro_cdc_offsets";
|
|
395
|
+
|
|
394
396
|
/**
|
|
395
397
|
* Dialect-neutral CDC wiring passed to `makeStore` when a push-based
|
|
396
398
|
* change source needs out-of-band connection + identity info that the
|
|
@@ -5009,6 +5011,8 @@ export declare const viewSql: (v: View<string, Record<string, ColumnDefinition<u
|
|
|
5009
5011
|
*/
|
|
5010
5012
|
export declare const _voltroApiKeysTable: TableLike;
|
|
5011
5013
|
|
|
5014
|
+
export declare const _voltroCdcOffsetsTable: TableLike;
|
|
5015
|
+
|
|
5012
5016
|
/**
|
|
5013
5017
|
* `_voltro_idempotency` — one row per (scope, key) for HTTP idempotency
|
|
5014
5018
|
* (the `Idempotency-Key` header on REST routes). `scope` namespaces the key
|
|
@@ -5056,6 +5060,8 @@ export declare const _voltroMigrationPlansTable: TableLike;
|
|
|
5056
5060
|
*/
|
|
5057
5061
|
export declare const _voltroMigrationsTable: TableLike;
|
|
5058
5062
|
|
|
5063
|
+
export declare const _voltroMssqlCdcOffsetsTable: TableLike;
|
|
5064
|
+
|
|
5059
5065
|
/**
|
|
5060
5066
|
* `_voltro_seeds` — one row per registered seed. Written to by the
|
|
5061
5067
|
* seed runner as each seed's lifecycle changes. Unlike migrations,
|
package/dist/index.js
CHANGED
|
@@ -859,13 +859,13 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
859
859
|
...t,
|
|
860
860
|
value: Hn(t.value)
|
|
861
861
|
};
|
|
862
|
-
}, Hn = (e) => e == null ? e : e instanceof Date ? e.toISOString() : typeof e == "boolean" ? +!!e : Array.isArray(e) ? e.map((e) => Hn(e)) : e, Un, Wn, Gn = (e) => {
|
|
863
|
-
e.actors !== void 0 && (
|
|
864
|
-
},
|
|
862
|
+
}, Hn = (e) => e == null ? e : e instanceof Date ? e.toISOString() : typeof e == "boolean" ? +!!e : Array.isArray(e) ? e.map((e) => Hn(e)) : e, Un = Symbol.for("@voltro/database/coreTablesRegistry"), Wn = globalThis, Gn = Wn[Un] ?? (Wn[Un] = {}), Kn = (e) => {
|
|
863
|
+
e.actors !== void 0 && (Gn.actors = e.actors), e.tenants !== void 0 && (Gn.tenants = e.tenants);
|
|
864
|
+
}, qn = (e, t) => () => {
|
|
865
865
|
let n = e();
|
|
866
866
|
if (n === void 0) throw Error(`core '${t}' table not registered; expected the framework CLI or your migrate step to call registerCoreTables({ ${t}: () => ${t}Table }) before the database handle is constructed`);
|
|
867
867
|
return n();
|
|
868
|
-
},
|
|
868
|
+
}, Jn = () => qn(() => Gn.actors, "actors"), Yn = () => qn(() => Gn.tenants, "tenants"), Xn = n("actors", {
|
|
869
869
|
id: T(),
|
|
870
870
|
kind: o().oneOf([
|
|
871
871
|
"user",
|
|
@@ -875,65 +875,65 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
875
875
|
]),
|
|
876
876
|
displayName: o().nullable(),
|
|
877
877
|
createdAt: v().default("now")
|
|
878
|
-
}),
|
|
878
|
+
}), Zn = (e, t) => ({
|
|
879
879
|
column: e,
|
|
880
880
|
op: "eq",
|
|
881
881
|
value: t
|
|
882
|
-
}),
|
|
882
|
+
}), Qn = (e, t) => ({
|
|
883
883
|
column: e,
|
|
884
884
|
op: "neq",
|
|
885
885
|
value: t
|
|
886
|
-
}),
|
|
886
|
+
}), $n = (e, t) => ({
|
|
887
887
|
column: e,
|
|
888
888
|
op: "gt",
|
|
889
889
|
value: t
|
|
890
|
-
}),
|
|
890
|
+
}), er = (e, t) => ({
|
|
891
891
|
column: e,
|
|
892
892
|
op: "gte",
|
|
893
893
|
value: t
|
|
894
|
-
}),
|
|
894
|
+
}), tr = (e, t) => ({
|
|
895
895
|
column: e,
|
|
896
896
|
op: "lt",
|
|
897
897
|
value: t
|
|
898
|
-
}),
|
|
898
|
+
}), nr = (e, t) => ({
|
|
899
899
|
column: e,
|
|
900
900
|
op: "lte",
|
|
901
901
|
value: t
|
|
902
|
-
}),
|
|
902
|
+
}), rr = (e, t) => ({
|
|
903
903
|
column: e,
|
|
904
904
|
op: "in",
|
|
905
905
|
value: t
|
|
906
|
-
}),
|
|
906
|
+
}), ir = (e, t) => ({
|
|
907
907
|
column: e,
|
|
908
908
|
op: "notIn",
|
|
909
909
|
value: t
|
|
910
|
-
}),
|
|
910
|
+
}), ar = (e, t) => ({
|
|
911
911
|
column: e,
|
|
912
912
|
op: "contains",
|
|
913
913
|
value: t
|
|
914
|
-
}),
|
|
914
|
+
}), or = (e, t) => ({
|
|
915
915
|
column: e,
|
|
916
916
|
op: "arrayContains",
|
|
917
917
|
value: t
|
|
918
|
-
}),
|
|
918
|
+
}), sr = (e, t) => ({
|
|
919
919
|
column: e,
|
|
920
920
|
op: "arrayOverlaps",
|
|
921
921
|
value: t
|
|
922
|
-
}),
|
|
922
|
+
}), cr = (e, t) => ({
|
|
923
923
|
column: e,
|
|
924
924
|
op: "arrayHas",
|
|
925
925
|
value: t
|
|
926
|
-
}),
|
|
926
|
+
}), lr = (e) => ({
|
|
927
927
|
column: e,
|
|
928
928
|
op: "isNull"
|
|
929
|
-
}),
|
|
929
|
+
}), ur = (e) => ({
|
|
930
930
|
column: e,
|
|
931
931
|
op: "isNotNull"
|
|
932
|
-
}),
|
|
932
|
+
}), dr = (e, t) => ({
|
|
933
933
|
column: e,
|
|
934
934
|
op: "spatial",
|
|
935
935
|
value: t
|
|
936
|
-
}),
|
|
936
|
+
}), fr = (...e) => ({ and: e }), pr = (...e) => ({ or: e }), mr = (e) => ({ not: e }), hr = (e, ...t) => {
|
|
937
937
|
if (t.length === 0) throw Error(`jsonField("${e}"): at least one path segment is required`);
|
|
938
938
|
let n = (n, r) => ({
|
|
939
939
|
column: e,
|
|
@@ -954,29 +954,29 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
954
954
|
isNull: () => n("isNull"),
|
|
955
955
|
isNotNull: () => n("isNotNull")
|
|
956
956
|
};
|
|
957
|
-
},
|
|
957
|
+
}, gr = (e) => "descriptor" in e ? e.descriptor : e, _r = (e, t) => ({
|
|
958
958
|
column: e,
|
|
959
959
|
op: "subquery-in",
|
|
960
|
-
subquery:
|
|
961
|
-
}),
|
|
960
|
+
subquery: gr(t)
|
|
961
|
+
}), vr = (e, t) => ({
|
|
962
962
|
column: e,
|
|
963
963
|
op: "subquery-not-in",
|
|
964
|
-
subquery:
|
|
965
|
-
}), vr = (e) => ({
|
|
966
|
-
op: "exists",
|
|
967
|
-
subquery: hr(e)
|
|
964
|
+
subquery: gr(t)
|
|
968
965
|
}), yr = (e) => ({
|
|
966
|
+
op: "exists",
|
|
967
|
+
subquery: gr(e)
|
|
968
|
+
}), br = (e) => ({
|
|
969
969
|
op: "not-exists",
|
|
970
|
-
subquery:
|
|
971
|
-
}),
|
|
970
|
+
subquery: gr(e)
|
|
971
|
+
}), xr = (e, t) => e == null || t == null ? null : typeof e == typeof t ? e === t ? 0 : e > t ? 1 : -1 : null, Sr = (e, t, n = null) => {
|
|
972
972
|
if (!t) return !1;
|
|
973
|
-
if ("not" in e) return !
|
|
973
|
+
if ("not" in e) return !Sr(e.not, t, n);
|
|
974
974
|
if ("and" in e) {
|
|
975
|
-
for (let r of e.and) if (!
|
|
975
|
+
for (let r of e.and) if (!Sr(r, t, n)) return !1;
|
|
976
976
|
return !0;
|
|
977
977
|
}
|
|
978
978
|
if ("or" in e) {
|
|
979
|
-
for (let r of e.or) if (
|
|
979
|
+
for (let r of e.or) if (Sr(r, t, n)) return !0;
|
|
980
980
|
return !1;
|
|
981
981
|
}
|
|
982
982
|
if (e.op === "subquery-in" || e.op === "subquery-not-in") {
|
|
@@ -995,10 +995,10 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
995
995
|
switch (r.op) {
|
|
996
996
|
case "eq": return i === r.value;
|
|
997
997
|
case "neq": return i !== r.value;
|
|
998
|
-
case "gt": return (
|
|
999
|
-
case "gte": return (
|
|
1000
|
-
case "lt": return (
|
|
1001
|
-
case "lte": return (
|
|
998
|
+
case "gt": return (xr(i, r.value) ?? -1) > 0;
|
|
999
|
+
case "gte": return (xr(i, r.value) ?? -1) >= 0;
|
|
1000
|
+
case "lt": return (xr(i, r.value) ?? 1) < 0;
|
|
1001
|
+
case "lte": return (xr(i, r.value) ?? 1) <= 0;
|
|
1002
1002
|
case "in": return Array.isArray(r.value) && r.value.includes(i);
|
|
1003
1003
|
case "notIn": return Array.isArray(r.value) && !r.value.includes(i);
|
|
1004
1004
|
case "contains": return typeof i == "string" && typeof r.value == "string" && i.toLowerCase().includes(r.value.toLowerCase());
|
|
@@ -1015,17 +1015,17 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1015
1015
|
case "isNotNull": return i != null;
|
|
1016
1016
|
case "spatial": throw Error("@voltro/plugin-postgis: spatial predicates (ST_DWithin / ST_Contains / ST_Within / ST_Intersects / bbox &&) are not evaluable in-memory — use them in one-shot ctx.store.query reads, not reactive subscriptions.");
|
|
1017
1017
|
}
|
|
1018
|
-
},
|
|
1018
|
+
}, Cr = function* (e) {
|
|
1019
1019
|
if ("not" in e) {
|
|
1020
|
-
yield*
|
|
1020
|
+
yield* Cr(e.not);
|
|
1021
1021
|
return;
|
|
1022
1022
|
}
|
|
1023
1023
|
if ("and" in e) {
|
|
1024
|
-
for (let t of e.and) yield*
|
|
1024
|
+
for (let t of e.and) yield* Cr(t);
|
|
1025
1025
|
return;
|
|
1026
1026
|
}
|
|
1027
1027
|
if ("or" in e) {
|
|
1028
|
-
for (let t of e.or) yield*
|
|
1028
|
+
for (let t of e.or) yield* Cr(t);
|
|
1029
1029
|
return;
|
|
1030
1030
|
}
|
|
1031
1031
|
e.op === "subquery-in" || e.op === "subquery-not-in" ? yield {
|
|
@@ -1035,27 +1035,27 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1035
1035
|
kind: "exists",
|
|
1036
1036
|
descriptor: e.subquery
|
|
1037
1037
|
});
|
|
1038
|
-
},
|
|
1038
|
+
}, wr = function* (e, t = !0) {
|
|
1039
1039
|
if ("not" in e) {
|
|
1040
|
-
yield*
|
|
1040
|
+
yield* wr(e.not, !1);
|
|
1041
1041
|
return;
|
|
1042
1042
|
}
|
|
1043
1043
|
if ("and" in e) {
|
|
1044
|
-
for (let n of e.and) yield*
|
|
1044
|
+
for (let n of e.and) yield* wr(n, t);
|
|
1045
1045
|
return;
|
|
1046
1046
|
}
|
|
1047
1047
|
if ("or" in e) {
|
|
1048
|
-
for (let t of e.or) yield*
|
|
1048
|
+
for (let t of e.or) yield* wr(t, !1);
|
|
1049
1049
|
return;
|
|
1050
1050
|
}
|
|
1051
1051
|
e.op === "subquery-in" || e.op === "subquery-not-in" || e.op === "exists" || e.op === "not-exists" || (yield {
|
|
1052
1052
|
...e,
|
|
1053
1053
|
conjunctive: t
|
|
1054
1054
|
});
|
|
1055
|
-
},
|
|
1055
|
+
}, Tr = class extends nt.TaggedError("TableStreamError") {}, Er = 1e3, Dr = (e, t, n, r) => {
|
|
1056
1056
|
let i = O.match(r, {
|
|
1057
1057
|
onNone: () => e.where,
|
|
1058
|
-
onSome: (n) => e.where ?
|
|
1058
|
+
onSome: (n) => e.where ? fr(e.where, $n(t, n)) : $n(t, n)
|
|
1059
1059
|
});
|
|
1060
1060
|
return {
|
|
1061
1061
|
table: e.table,
|
|
@@ -1070,19 +1070,19 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1070
1070
|
...e.includeDeleted === void 0 ? {} : { includeDeleted: e.includeDeleted },
|
|
1071
1071
|
...e.crossTenant === void 0 ? {} : { crossTenant: e.crossTenant }
|
|
1072
1072
|
};
|
|
1073
|
-
},
|
|
1074
|
-
let n = t.pk ?? "id", r = t.chunkSize ??
|
|
1073
|
+
}, Or = (e, t) => {
|
|
1074
|
+
let n = t.pk ?? "id", r = t.chunkSize ?? Er;
|
|
1075
1075
|
return it.paginateChunkEffect(O.none(), (i) => {
|
|
1076
1076
|
let a = rt.tryPromise({
|
|
1077
|
-
try: () => e.query(
|
|
1078
|
-
catch: (e) => new
|
|
1077
|
+
try: () => e.query(Dr(t, n, r, i)),
|
|
1078
|
+
catch: (e) => new Tr({
|
|
1079
1079
|
table: t.table,
|
|
1080
1080
|
cause: e
|
|
1081
1081
|
})
|
|
1082
1082
|
});
|
|
1083
1083
|
return (t.retry ? a.pipe(rt.retry(t.retry)) : a).pipe(rt.map((e) => [tt.fromIterable(e), e.length === r && e.length > 0 ? O.some(O.some(e[e.length - 1][n])) : O.none()]));
|
|
1084
1084
|
});
|
|
1085
|
-
},
|
|
1085
|
+
}, kr = (e) => {
|
|
1086
1086
|
let t = e.alpha ?? .5;
|
|
1087
1087
|
if (t < 0 || t > 1) throw Error(`hybridSearch: alpha must be in [0, 1], got ${t}`);
|
|
1088
1088
|
return (n) => {
|
|
@@ -1109,14 +1109,14 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1109
1109
|
}
|
|
1110
1110
|
};
|
|
1111
1111
|
};
|
|
1112
|
-
},
|
|
1112
|
+
}, Ar = async (e, t) => {
|
|
1113
1113
|
let n = e.as ?? "embedding", r = t.row[e.from];
|
|
1114
1114
|
if (typeof r != "string" || r.length === 0) return {};
|
|
1115
1115
|
let i = await t.embed(r);
|
|
1116
1116
|
return { [n]: i };
|
|
1117
|
-
},
|
|
1117
|
+
}, jr = (e) => {
|
|
1118
1118
|
if (!Number.isInteger(e.dimensions) || e.dimensions <= 0) throw Error(`vectorEmbedding: dimensions must be a positive integer, got ${String(e.dimensions)}.`);
|
|
1119
|
-
let t = e.as ?? "embedding", n = (t) =>
|
|
1119
|
+
let t = e.as ?? "embedding", n = (t) => Ar(e, t);
|
|
1120
1120
|
return d({
|
|
1121
1121
|
id: "voltro/vectorEmbedding",
|
|
1122
1122
|
fields: { [t]: ke(e.dimensions) },
|
|
@@ -1134,19 +1134,19 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1134
1134
|
beforeUpdate: n
|
|
1135
1135
|
}
|
|
1136
1136
|
});
|
|
1137
|
-
},
|
|
1137
|
+
}, Mr = 63, Nr = "br_pr", Y = class extends Error {
|
|
1138
1138
|
_tag = "BranchNameInvalid";
|
|
1139
1139
|
constructor(e) {
|
|
1140
1140
|
super(e), this.name = "BranchNameInvalid";
|
|
1141
1141
|
}
|
|
1142
|
-
},
|
|
1142
|
+
}, Pr = (e, t) => {
|
|
1143
1143
|
if (!Number.isInteger(t) || t < 0) throw new Y(`prNumber must be a non-negative integer, got ${String(t)}`);
|
|
1144
1144
|
let n = Zt(e);
|
|
1145
1145
|
if (n.replace(/_/g, "") === "") throw new Y(`app slug '${e}' has no usable identifier characters`);
|
|
1146
|
-
let r = `${
|
|
1147
|
-
if (r.length >
|
|
1146
|
+
let r = `${Nr}${t}_${n}`;
|
|
1147
|
+
if (r.length > Mr) throw new Y(`branch namespace '${r}' exceeds the ${Mr}-byte identifier limit — use a shorter app slug`);
|
|
1148
1148
|
return r;
|
|
1149
|
-
},
|
|
1149
|
+
}, Fr = (e) => e.startsWith(Nr), Ir = {
|
|
1150
1150
|
requested: {
|
|
1151
1151
|
provision: "provisioning",
|
|
1152
1152
|
destroy: "destroying"
|
|
@@ -1165,18 +1165,18 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1165
1165
|
fail: "failed"
|
|
1166
1166
|
},
|
|
1167
1167
|
destroyed: {}
|
|
1168
|
-
},
|
|
1168
|
+
}, Lr = class extends Error {
|
|
1169
1169
|
from;
|
|
1170
1170
|
event;
|
|
1171
1171
|
_tag = "BranchTransitionInvalid";
|
|
1172
1172
|
constructor(e, t) {
|
|
1173
1173
|
super(`invalid branch transition: ${e} --${t}-->`), this.from = e, this.event = t, this.name = "BranchTransitionInvalid";
|
|
1174
1174
|
}
|
|
1175
|
-
},
|
|
1176
|
-
let n =
|
|
1177
|
-
if (n === void 0) throw new
|
|
1175
|
+
}, Rr = (e, t) => {
|
|
1176
|
+
let n = Ir[e][t];
|
|
1177
|
+
if (n === void 0) throw new Lr(e, t);
|
|
1178
1178
|
return n;
|
|
1179
|
-
},
|
|
1179
|
+
}, zr = (e, t, n, r) => {
|
|
1180
1180
|
if (n === "copy" && (r === void 0 || r === "")) throw new Y("seed 'copy' requires a parentNamespace to snapshot from");
|
|
1181
1181
|
let i = [{
|
|
1182
1182
|
kind: "create-namespace",
|
|
@@ -1197,13 +1197,13 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1197
1197
|
detail: `run boot seeds into ${e}`
|
|
1198
1198
|
});
|
|
1199
1199
|
return i;
|
|
1200
|
-
},
|
|
1201
|
-
if (!
|
|
1200
|
+
}, Br = (e) => {
|
|
1201
|
+
if (!Fr(e)) throw new Y(`refusing to plan teardown of '${e}' — not a branch namespace`);
|
|
1202
1202
|
return [{
|
|
1203
1203
|
kind: "drop-namespace",
|
|
1204
1204
|
detail: e
|
|
1205
1205
|
}];
|
|
1206
|
-
},
|
|
1206
|
+
}, Vr = (e) => {
|
|
1207
1207
|
if (e === void 0 || e === "") return !1;
|
|
1208
1208
|
try {
|
|
1209
1209
|
let t = new URL(e).hostname.toLowerCase();
|
|
@@ -1211,27 +1211,27 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1211
1211
|
} catch {
|
|
1212
1212
|
return /\bneon\.(tech|build)\b/i.test(e);
|
|
1213
1213
|
}
|
|
1214
|
-
},
|
|
1214
|
+
}, Hr = (e) => e.prefer === void 0 ? e.seed === "copy" && Vr(e.dbUrl) ? "neon-cow" : "namespace" : e.prefer, Ur = (e, t = {}) => [{
|
|
1215
1215
|
kind: "neon-branch-create",
|
|
1216
1216
|
detail: `${t.parentBranch ?? "main"} → ${e} (copy-on-write)`
|
|
1217
|
-
}],
|
|
1218
|
-
if (!
|
|
1217
|
+
}], Wr = (e) => {
|
|
1218
|
+
if (!Fr(e)) throw new Y(`refusing to plan teardown of '${e}' — not a branch namespace`);
|
|
1219
1219
|
return [{
|
|
1220
1220
|
kind: "neon-branch-delete",
|
|
1221
1221
|
detail: e
|
|
1222
1222
|
}];
|
|
1223
|
-
},
|
|
1223
|
+
}, Gr = (e) => e.mechanism === "neon-cow" ? Ur(e.branchId, e.neonParentBranch === void 0 ? {} : { parentBranch: e.neonParentBranch }) : zr(e.branchId, e.tableNames, e.seed, e.parentNamespace), Kr = (e, t) => e === "neon-cow" ? Wr(t) : Br(t), qr = (e, t, n) => {
|
|
1224
1224
|
let r = e.filter((e) => e.state !== "destroyed" && e.state !== "destroying"), i = r.filter((e) => n - e.createdAtMs > t.ttlMs).map((e) => e.namespace), a = new Set(i);
|
|
1225
1225
|
return {
|
|
1226
1226
|
evict: i,
|
|
1227
1227
|
rejectNew: r.filter((e) => !a.has(e.namespace)).length >= t.maxBranches
|
|
1228
1228
|
};
|
|
1229
|
-
},
|
|
1230
|
-
let n =
|
|
1229
|
+
}, Jr = async (e, t) => {
|
|
1230
|
+
let n = Pr(e.appSlug, e.prNumber), r = Hr({
|
|
1231
1231
|
seed: e.seed,
|
|
1232
1232
|
...e.dbUrl === void 0 ? {} : { dbUrl: e.dbUrl },
|
|
1233
1233
|
...e.prefer === void 0 ? {} : { prefer: e.prefer }
|
|
1234
|
-
}), i =
|
|
1234
|
+
}), i = Gr({
|
|
1235
1235
|
mechanism: r,
|
|
1236
1236
|
branchId: n,
|
|
1237
1237
|
tableNames: e.tableNames,
|
|
@@ -1256,10 +1256,10 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1256
1256
|
mechanism: r,
|
|
1257
1257
|
steps: i
|
|
1258
1258
|
};
|
|
1259
|
-
},
|
|
1260
|
-
let r =
|
|
1259
|
+
}, Yr = async (e, t, n) => {
|
|
1260
|
+
let r = Kr(t, e);
|
|
1261
1261
|
return t === "neon-cow" ? await n.neonBranchDelete(e) : await n.dropNamespace(e), r;
|
|
1262
|
-
},
|
|
1262
|
+
}, Xr = (e, t, n) => qr(e, t, n), X = (e) => `"${e.replace(/"/g, "\"\"")}"`, Zr = (e) => {
|
|
1263
1263
|
let t = () => {
|
|
1264
1264
|
throw Error("namespace branch executor: Neon ops require a neon-cow executor (use a Neon connection for copy-on-write branches)");
|
|
1265
1265
|
};
|
|
@@ -1271,18 +1271,18 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1271
1271
|
neonBranchCreate: t,
|
|
1272
1272
|
neonBranchDelete: t
|
|
1273
1273
|
};
|
|
1274
|
-
},
|
|
1274
|
+
}, Qr = class extends Error {
|
|
1275
1275
|
_tag = "TenantResidencyUnresolved";
|
|
1276
1276
|
constructor(e) {
|
|
1277
1277
|
super(e), this.name = "TenantResidencyUnresolved";
|
|
1278
1278
|
}
|
|
1279
|
-
},
|
|
1279
|
+
}, $r = class extends Error {
|
|
1280
1280
|
region;
|
|
1281
1281
|
_tag = "TenantRegionUnavailable";
|
|
1282
1282
|
constructor(e, t) {
|
|
1283
1283
|
super(t), this.region = e, this.name = "TenantRegionUnavailable";
|
|
1284
1284
|
}
|
|
1285
|
-
},
|
|
1285
|
+
}, ei, ti = (e) => {
|
|
1286
1286
|
if (e.homes === void 0) throw Error("setResidencyConfig: `homes` is required");
|
|
1287
1287
|
if (e.servableRegions === void 0 || e.servableRegions.length === 0) throw Error("setResidencyConfig: `servableRegions` must be non-empty (which regions this deployment serves)");
|
|
1288
1288
|
let t = /* @__PURE__ */ new Map();
|
|
@@ -1291,32 +1291,32 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1291
1291
|
if (e !== void 0 && e !== n.region) throw Error(`residency: tenant '${n.tenantId}' is mapped to two regions ('${e}' and '${n.region}')`);
|
|
1292
1292
|
t.set(n.tenantId, n.region);
|
|
1293
1293
|
}
|
|
1294
|
-
return
|
|
1295
|
-
},
|
|
1296
|
-
|
|
1297
|
-
},
|
|
1298
|
-
if (e == null || e === "") throw new
|
|
1294
|
+
return ei = e, e;
|
|
1295
|
+
}, ni = () => ei, ri = () => {
|
|
1296
|
+
ei = void 0;
|
|
1297
|
+
}, ii = (e, t) => {
|
|
1298
|
+
if (e == null || e === "") throw new Qr("residency is on but the request has no resolvable tenant — refusing to bind a store");
|
|
1299
1299
|
let n = t.homes.find((t) => t.tenantId === e);
|
|
1300
|
-
if (n === void 0) throw new
|
|
1300
|
+
if (n === void 0) throw new Qr(`no residency home is mapped for tenant '${e}' — refusing to fall back to a default store (would be a residency violation)`);
|
|
1301
1301
|
return n;
|
|
1302
|
-
},
|
|
1303
|
-
let n =
|
|
1302
|
+
}, ai = (e, t) => t.servableRegions.includes(e), oi = (e, t) => {
|
|
1303
|
+
let n = ii(e.tenantId, t), r = Qt(n.tenantId);
|
|
1304
1304
|
return {
|
|
1305
1305
|
region: n.region,
|
|
1306
1306
|
namespace: r,
|
|
1307
1307
|
...n.connectionKey === void 0 ? {} : { connectionKey: n.connectionKey }
|
|
1308
1308
|
};
|
|
1309
|
-
},
|
|
1310
|
-
let r =
|
|
1311
|
-
if (!
|
|
1309
|
+
}, si = (e, t, n) => {
|
|
1310
|
+
let r = oi(e, t);
|
|
1311
|
+
if (!ai(r.region, t)) throw new $r(r.region, `tenant homed in region '${r.region}', which this deployment does not serve — route to the home region`);
|
|
1312
1312
|
let i = n.get(r.region);
|
|
1313
|
-
if (i === void 0) throw new
|
|
1313
|
+
if (i === void 0) throw new $r(r.region, `no store handle for home region '${r.region}' (declared servable but not wired) — failing closed`);
|
|
1314
1314
|
return {
|
|
1315
1315
|
store: i,
|
|
1316
1316
|
placement: r
|
|
1317
1317
|
};
|
|
1318
|
-
},
|
|
1319
|
-
let { store: i, placement: a } =
|
|
1318
|
+
}, ci = async (e, t, n, r) => {
|
|
1319
|
+
let { store: i, placement: a } = si(e, t, n);
|
|
1320
1320
|
return await r(i, a), a;
|
|
1321
1321
|
}, Z = (e) => {
|
|
1322
1322
|
if (typeof e == "string") return e;
|
|
@@ -1325,21 +1325,21 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1325
1325
|
return `(json:${t}->${n.join(".")}${r ? "::num" : ""})`;
|
|
1326
1326
|
}
|
|
1327
1327
|
return `(${e.expr})`;
|
|
1328
|
-
}, Q = (e) => e.map(Z),
|
|
1328
|
+
}, Q = (e) => e.map(Z), li = (e, t) => {
|
|
1329
1329
|
if (e.length !== t.length) return !1;
|
|
1330
1330
|
for (let n = 0; n < e.length; n++) if (Z(e[n]) !== Z(t[n])) return !1;
|
|
1331
1331
|
return !0;
|
|
1332
|
-
},
|
|
1332
|
+
}, ui = (e, t) => {
|
|
1333
1333
|
if (e.length >= t.length) return !1;
|
|
1334
1334
|
for (let n = 0; n < e.length; n++) if (Z(e[n]) !== Z(t[n])) return !1;
|
|
1335
1335
|
return !0;
|
|
1336
|
-
},
|
|
1336
|
+
}, di = (e) => {
|
|
1337
1337
|
let t = [], n = e.appliedIndexes, r = e.tableName;
|
|
1338
1338
|
for (let e = 0; e < n.length; e++) {
|
|
1339
1339
|
let i = n[e];
|
|
1340
1340
|
for (let a = e + 1; a < n.length; a++) {
|
|
1341
1341
|
let e = n[a];
|
|
1342
|
-
if (
|
|
1342
|
+
if (li(i.fields, e.fields)) {
|
|
1343
1343
|
let [n, a] = i.name < e.name ? [i, e] : [e, i];
|
|
1344
1344
|
t.push({
|
|
1345
1345
|
kind: "duplicate-fields",
|
|
@@ -1350,13 +1350,13 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1350
1350
|
});
|
|
1351
1351
|
continue;
|
|
1352
1352
|
}
|
|
1353
|
-
|
|
1353
|
+
ui(i.fields, e.fields) ? t.push({
|
|
1354
1354
|
kind: "redundant-prefix",
|
|
1355
1355
|
table: r,
|
|
1356
1356
|
redundant: i,
|
|
1357
1357
|
coveredBy: e,
|
|
1358
1358
|
message: `'${r}' index '${i.name}' on [${Q(i.fields).join(", ")}] is a leading prefix of '${e.name}' on [${Q(e.fields).join(", ")}]. Every B-tree dialect we support (Postgres / MySQL / MariaDB / MSSQL / SQLite) can serve a [${Q(i.fields).join(", ")}] query from '${e.name}' too via the leading-prefix rule, so '${i.name}' adds write cost without read benefit. Drop '${i.name}' — unless you specifically need a smaller index for cache locality on a write-heavy table (rare; profile first).`
|
|
1359
|
-
}) :
|
|
1359
|
+
}) : ui(e.fields, i.fields) && t.push({
|
|
1360
1360
|
kind: "redundant-prefix",
|
|
1361
1361
|
table: r,
|
|
1362
1362
|
redundant: e,
|
|
@@ -1366,23 +1366,23 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1366
1366
|
}
|
|
1367
1367
|
}
|
|
1368
1368
|
return t;
|
|
1369
|
-
},
|
|
1369
|
+
}, fi = (e) => {
|
|
1370
1370
|
let t = [];
|
|
1371
|
-
for (let n of e) t.push(...
|
|
1371
|
+
for (let n of e) t.push(...di(n));
|
|
1372
1372
|
return t;
|
|
1373
|
-
},
|
|
1374
|
-
let n = t.color ?? !0, r = t.indent ?? " ", i = (e) => $(n, k.dim, e.padEnd(11)), a = (e) => $(n, (e) => k.bold(k.brand(e)), e), o = (e) => $(n, k.brightRed24, e), s = (e) => $(n,
|
|
1373
|
+
}, pi = "\x1B[", mi = `${pi}38;2;245;158;11m`, hi = `${pi}38;2;16;185;129m`, gi = (e, t) => `${e}${t}${k.reset}`, $ = (e, t, n) => e ? typeof t == "function" ? t(n) : gi(t, n) : n, _i = (e, t = {}) => {
|
|
1374
|
+
let n = t.color ?? !0, r = t.indent ?? " ", i = (e) => $(n, k.dim, e.padEnd(11)), a = (e) => $(n, (e) => k.bold(k.brand(e)), e), o = (e) => $(n, k.brightRed24, e), s = (e) => $(n, hi, e), c = (e) => $(n, mi, e), l = (e) => $(n, k.dim, e), u = `${c("index audit")} ${l("·")} ${$(n, k.bold, e.kind)}`, d = e.redundant.fields.length, f = Q(e.coveredBy.fields.slice(d)), p = (e, t) => {
|
|
1375
1375
|
let n = e.slice(0, t), r = e.slice(t), i = [];
|
|
1376
1376
|
return n.length > 0 && i.push(s(`[${n.join(", ")}]`)), r.length > 0 && i.push(c(`+ [${r.join(", ")}]`)), i.join(" ");
|
|
1377
1377
|
}, m = [];
|
|
1378
1378
|
return m.push(u), m.push(""), m.push(`${i("table")}${a(e.table)}`), m.push(""), m.push(`${i("redundant")}${o(e.redundant.name)}`), m.push(`${i("")}${p(Q(e.redundant.fields), d)}`), m.push(""), m.push(`${i("covered by")}${s(e.coveredBy.name)}`), m.push(`${i("")}${p(Q(e.coveredBy.fields), d)}`), f.length > 0 && m.push(`${i("")}${l(`└ extra columns: ${f.join(", ")}`)}`), m.push(""), e.kind === "redundant-prefix" ? (m.push(`${i("why")}B-tree indexes serve queries that filter on a LEADING PREFIX of`), m.push(`${i("")}their column list. The wider index already covers every`), m.push(`${i("")}query the narrower one can serve.`), m.push(`${i("")}${l("Same rule on Postgres / MySQL / MariaDB / MSSQL / SQLite.")}`)) : (m.push(`${i("why")}Two indexes on the same columns under different names.`), m.push(`${i("")}The B-tree engine builds both — same coverage, double cost.`), m.push(`${i("")}${l("Same rule on Postgres / MySQL / MariaDB / MSSQL / SQLite.")}`)), m.push(""), m.push(`${i("cost")}Every ${a("INSERT")} / ${a("UPDATE")} / ${a("DELETE")} on this table writes`), m.push(`${i("")}to ${$(n, k.bold, "both")} B-trees. Pure write overhead, zero read benefit.`), m.push(""), m.push(`${i("fix")}Drop ${o(e.redundant.name)}`), m.push(`${i("")}${l("Keep only if profiling shows the smaller index gives a")}`), m.push(`${i("")}${l("measurable cache-locality boost on a write-heavy hot path.")}`), m.push(`${i("")}${l("Silence with VOLTRO_INDEX_AUDIT=off if intentional.")}`), m.map((e) => `${r}${e}`).join("\n");
|
|
1379
|
-
},
|
|
1379
|
+
}, vi = (e, t) => ({
|
|
1380
1380
|
name: e,
|
|
1381
1381
|
body: t
|
|
1382
|
-
}),
|
|
1382
|
+
}), yi = (e) => {
|
|
1383
1383
|
if (e.lifecycle === "cron" && !e.cron) throw Error(`seed "${e.id}": lifecycle 'cron' requires a 'cron' field`);
|
|
1384
1384
|
if (e.lifecycle === "onSchemaChange" && (!e.watchedTables || e.watchedTables.length === 0)) throw Error(`seed "${e.id}": lifecycle 'onSchemaChange' requires at least one entry in 'watchedTables'`);
|
|
1385
|
-
let t = e.steps({ step:
|
|
1385
|
+
let t = e.steps({ step: vi });
|
|
1386
1386
|
if (t.length === 0) throw Error(`seed "${e.id}": at least one step is required`);
|
|
1387
1387
|
return {
|
|
1388
1388
|
__seed: !0,
|
|
@@ -1394,13 +1394,13 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1394
1394
|
...e.fingerprint === void 0 ? {} : { fingerprint: e.fingerprint },
|
|
1395
1395
|
steps: t
|
|
1396
1396
|
};
|
|
1397
|
-
},
|
|
1397
|
+
}, bi = (e) => typeof e == "object" && !!e && "__seed" in e && e.__seed === !0, xi = (e, { apply: t, undo: n }) => ({
|
|
1398
1398
|
name: e,
|
|
1399
1399
|
apply: t,
|
|
1400
1400
|
undo: n
|
|
1401
|
-
}),
|
|
1401
|
+
}), Si = (e) => {
|
|
1402
1402
|
if (!/^\d{14}_/.test(e.id)) throw Error(`migration "${e.id}": id must start with a 14-digit timestamp followed by "_" (convention: <YYYYMMDDHHMMSS>_<slug>)`);
|
|
1403
|
-
let t = e.steps({ step:
|
|
1403
|
+
let t = e.steps({ step: xi });
|
|
1404
1404
|
if (t.length === 0) throw Error(`migration "${e.id}": at least one step is required`);
|
|
1405
1405
|
return {
|
|
1406
1406
|
__migration: !0,
|
|
@@ -1408,7 +1408,7 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1408
1408
|
name: e.name,
|
|
1409
1409
|
steps: t
|
|
1410
1410
|
};
|
|
1411
|
-
},
|
|
1411
|
+
}, Ci = (e) => typeof e == "object" && !!e && "__migration" in e && e.__migration === !0, wi = n("_voltro_migrations", {
|
|
1412
1412
|
id: T({ prefix: "mig" }),
|
|
1413
1413
|
name: o(),
|
|
1414
1414
|
hash: o(),
|
|
@@ -1420,7 +1420,7 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1420
1420
|
workflowRunId: o().nullable(),
|
|
1421
1421
|
createdAt: v().default("now"),
|
|
1422
1422
|
updatedAt: v().default("now").onUpdate("now")
|
|
1423
|
-
}).index(["status"]).reactive(),
|
|
1423
|
+
}).index(["status"]).reactive(), Ti = n("_voltro_seeds", {
|
|
1424
1424
|
id: T({ prefix: "seed" }),
|
|
1425
1425
|
name: o(),
|
|
1426
1426
|
lifecycle: o(),
|
|
@@ -1436,7 +1436,7 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1436
1436
|
workflowRunId: o().nullable(),
|
|
1437
1437
|
createdAt: v().default("now"),
|
|
1438
1438
|
updatedAt: v().default("now").onUpdate("now")
|
|
1439
|
-
}).index(["lifecycle"]).index(["nextRunAt"]).reactive(),
|
|
1439
|
+
}).index(["lifecycle"]).index(["nextRunAt"]).reactive(), Ei = n("_voltro_migration_plans", {
|
|
1440
1440
|
id: T({ prefix: "plan" }),
|
|
1441
1441
|
fingerprint: o(),
|
|
1442
1442
|
operations: E(),
|
|
@@ -1451,21 +1451,21 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1451
1451
|
appliedAt: v().default("now"),
|
|
1452
1452
|
createdAt: v().default("now"),
|
|
1453
1453
|
updatedAt: v().default("now").onUpdate("now")
|
|
1454
|
-
}).index(["fingerprint"]).index(["environment"]).reactive(),
|
|
1454
|
+
}).index(["fingerprint"]).index(["environment"]).reactive(), Di = n("_voltro_idempotency", {
|
|
1455
1455
|
id: T({ prefix: "idem" }),
|
|
1456
1456
|
scope: o(),
|
|
1457
1457
|
key: o(),
|
|
1458
1458
|
status: o(),
|
|
1459
1459
|
response: E().nullable(),
|
|
1460
1460
|
createdAt: v().default("now")
|
|
1461
|
-
}).unique(["scope", "key"]).index(["createdAt"]).reactive(),
|
|
1461
|
+
}).unique(["scope", "key"]).index(["createdAt"]).reactive(), Oi = n("_voltro_kv", {
|
|
1462
1462
|
id: T({ prefix: "kv" }),
|
|
1463
1463
|
key: o().unique(),
|
|
1464
1464
|
value: o().nullable(),
|
|
1465
1465
|
expiresAt: v().nullable(),
|
|
1466
1466
|
createdAt: v().default("now"),
|
|
1467
1467
|
updatedAt: v().default("now").onUpdate("now")
|
|
1468
|
-
}).index(["expiresAt"]).reactive(),
|
|
1468
|
+
}).index(["expiresAt"]).reactive(), ki = n("_voltro_api_keys", {
|
|
1469
1469
|
id: T({ prefix: "apikey" }),
|
|
1470
1470
|
tenantId: o().nullable(),
|
|
1471
1471
|
name: o(),
|
|
@@ -1477,29 +1477,42 @@ var at = (e) => e === "mysql" || e === "mariadb" || e === "mssql" || e === "sqli
|
|
|
1477
1477
|
revokedAt: v().nullable(),
|
|
1478
1478
|
createdBy: o().nullable(),
|
|
1479
1479
|
createdAt: v().default("now")
|
|
1480
|
-
}).index("byTenant", ["tenantId"]).reactive(),
|
|
1481
|
-
Ci,
|
|
1480
|
+
}).index("byTenant", ["tenantId"]).reactive(), Ai = [
|
|
1482
1481
|
wi,
|
|
1483
|
-
Ti
|
|
1484
|
-
|
|
1482
|
+
Ti,
|
|
1483
|
+
Ei
|
|
1484
|
+
], ji = (e, t, n) => ({
|
|
1485
1485
|
_tag: "PrimaryKeyConflictError",
|
|
1486
1486
|
table: e,
|
|
1487
1487
|
key: t,
|
|
1488
1488
|
cause: n
|
|
1489
|
-
}),
|
|
1489
|
+
}), Mi = (e) => typeof e == "object" && !!e && e._tag === "PrimaryKeyConflictError", Ni = /* @__PURE__ */ new Map(), Pi = (e) => {
|
|
1490
1490
|
if (!e.table || !e.timeColumn) throw Error("registerRetention: table + timeColumn are required");
|
|
1491
1491
|
if (!Number.isFinite(e.ttlMs) || e.ttlMs <= 0) throw Error(`registerRetention(${e.table}): ttlMs must be a positive number`);
|
|
1492
|
-
|
|
1493
|
-
},
|
|
1492
|
+
Ni.set(e.table, e);
|
|
1493
|
+
}, Fi = () => [...Ni.values()], Ii = () => Ni.clear(), Li = async (e, t, n, r = 2e4) => {
|
|
1494
1494
|
let i = new Date(t - e.ttlMs), a = 0;
|
|
1495
1495
|
for (;;) {
|
|
1496
1496
|
let t = await n(e.table, e.timeColumn, i, r, e.where);
|
|
1497
1497
|
if (a += t, t < r) break;
|
|
1498
1498
|
}
|
|
1499
1499
|
return a;
|
|
1500
|
-
},
|
|
1500
|
+
}, Ri = (e, t) => {
|
|
1501
1501
|
let n = Number(e ?? String(t));
|
|
1502
1502
|
return (Number.isFinite(n) && n > 0 ? n : t) * 36e5;
|
|
1503
|
-
},
|
|
1503
|
+
}, zi = "_voltro_cdc_offsets", Bi = n(zi, {
|
|
1504
|
+
id: T({ prefix: "cdcoff" }),
|
|
1505
|
+
replicaId: o(),
|
|
1506
|
+
streamName: o(),
|
|
1507
|
+
binlogFile: o(),
|
|
1508
|
+
binlogPosition: o(),
|
|
1509
|
+
updatedAt: v()
|
|
1510
|
+
}).index(["replicaId"]), Vi = n(zi, {
|
|
1511
|
+
id: T({ prefix: "cdcoff" }),
|
|
1512
|
+
replicaId: o(),
|
|
1513
|
+
streamName: o(),
|
|
1514
|
+
ctVersion: o(),
|
|
1515
|
+
updatedAt: v()
|
|
1516
|
+
}).index(["replicaId"]), Hi = "postgres";
|
|
1504
1517
|
//#endregion
|
|
1505
|
-
export { Y as BranchNameInvalid,
|
|
1518
|
+
export { Y as BranchNameInvalid, Lr as BranchTransitionInvalid, zi as CDC_OFFSETS_TABLE, We as ColumnBuilder, lt as ENCRYPTED_PREFIX, Hi as ENGINE, Ge as FILE_MIGRATION_PATTERN, oe as MAX_IDENTIFIER_LENGTH, Tr as TableStreamError, Jt as TenantNamespaceInvalid, qt as TenantNamespaceUnresolved, $r as TenantRegionUnavailable, Qr as TenantResidencyUnresolved, ce as WARN_IDENTIFIER_LENGTH, ki as _voltroApiKeysTable, Bi as _voltroCdcOffsetsTable, Di as _voltroIdempotencyTable, Oi as _voltroKvTable, Ei as _voltroMigrationPlansTable, wi as _voltroMigrationsTable, Vi as _voltroMssqlCdcOffsetsTable, Ti as _voltroSeedsTable, Xn as actorsTable, Xr as admitBranch, He as allEnumRenames, kt as allRegisteredRelations, De as allRegisteredTables, fr as and, ge as array, or as arrayContains, cr as arrayHas, sr as arrayOverlaps, zt as attachEagerLoads, fi as auditAllTableIndexes, di as auditTableIndexes, Ae as avg, qe as avgOver, je as bigint, si as bindResidentStore, Je as boolean, Pr as branchNamespaceName, ve as bytes, Ee as clearEnumRenames, At as clearRelationsRegistry, ri as clearResidencyConfig, Ii as clearRetentions, g as clearTableRegistry, Cr as collectSubqueries, _e as column, dn as compileEagerJson, R as compilePredicate, $t as compileRawFragment, z as compileSelect, Ar as computeEmbedding, ar as contains, be as count, Re as countDistinct, Me as databaseHandle, xe as date, ze as dbEnum, Ne as decimal, fe as declareEnumRename, It as decodeRowsFromSchema, pt as decryptFieldsOnRead, Si as defineMigration, d as defineMixin, yi as defineSeed, we as denseRank, u as deriveTypeIdPrefix, ct as deserializeArraysOnRead, b as drainIdentifierWarnings, Te as dropped, Rt as encodeRowForSchema, ft as encryptFieldsForWrite, dt as encryptedColumnsOf, qr as enforceBranchLimits, _ as ensureTableRegistered, Zn as eq, L as escapeLike, Sr as evaluatePredicate, Se as except, yr as exists, _i as formatIndexAuditIssue, Ai as frameworkTables, m as generateId, p as generateSnowflake, Ce as geography, ue as geometry, Le as getEnumRenames, Ot as getRelation, M as getRelations, ni as getResidencyConfig, y as getTable, $n as gt, er as gte, Kt as hasEagerLoads, kr as hybridSearch, T as id, rr as inSet, _r as inSubquery, A as inferForeignKey, D as integer, le as intersect, me as interval, Fr as isBranchNamespace, ut as isEncrypted, Pe as isFileMigration, Ci as isMigrationDefinition, Vr as isNeonConnection, ur as isNotNull, lr as isNull, Mi as isPrimaryKeyConflictError, ai as isRegionServable, bt as isRelationsSpec, bi as isSeedDefinition, h as isSqliteFamily, de as isView, E as json, hr as jsonField, et as jsonIndex, Ye as lag, $e as lead, Fi as listRetentions, tr as lt, nr as lte, Zr as makeNamespaceBranchExecutor, St as many, Ct as manyToMany, S as materializeFields, pe as max, Ve as migration, Qe as min, re as mixin, Qn as neq, Rr as nextBranchState, mr as not, br as notExists, ir as notInSet, vr as notInSubquery, i as numeric, xt as one, pr as or, te as paginateById, Gr as planBranch, zr as planBranchProvision, Br as planBranchTeardown, Kr as planBranchTeardownFor, Ur as planNeonBranchProvision, Wr as planNeonBranchTeardown, ji as primaryKeyConflictError, Jr as provisionBranch, ci as provisionResidentTenant, I as qualifyTable, r as queryFor, Ie as queryForView, x as quoteIdent, Xe as rank, Ze as raw, ne as real, c as reference, Kn as registerCoreTables, Dt as registerDiscoveredRelations, Et as registerRelations, Pi as registerRetention, l as registerTable, yt as relations, Jn as requireActors, f as requireTable, Yn as requireTenants, se as resetSnowflake, oi as residentPlacement, Hr as resolveBranchMechanism, C as resolveFullTextIndex, Be as resolveIdScheme, ae as resolveMixinGraph, ii as resolveTenantHome, Qt as resolveTenantNamespace, Ri as retentionTtlMsFromEnv, s as rowNumber, Zt as sanitizeIdentifierFragment, st as serializeArraysForWrite, ti as setResidencyConfig, dr as spatialPredicate, Or as streamTable, a as sum, ee as sumOver, Li as sweepRetention, n as table, Yr as teardownBranch, o as text, v as timestamp, Oe as union, t as unionAll, e as validateColumnName, ye as validateIndexName, Ke as validateTableName, Fe as validateTypeIdPrefix, ke as vector, ie as vectorDistanceToOpclass, jr as vectorEmbedding, Ue as view, he as viewSql, wr as walkLeaves };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/database",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Browser-safe schema DSL, query builder, and cross-dialect migration planner for Voltro — one schema, every SQL backend.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@effect/sql": "^0.51.1",
|
|
41
|
-
"@voltro/logger": "0.2.
|
|
41
|
+
"@voltro/logger": "0.2.2",
|
|
42
42
|
"typeid-js": "^1.2.0",
|
|
43
43
|
"ulidx": "^2.4.1"
|
|
44
44
|
},
|