@voltro/database 0.84.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.
Files changed (170) hide show
  1. package/CHANGELOG.md +1215 -0
  2. package/THIRD-PARTY-NOTICES.md +5 -89
  3. package/dist/actorSnapshot.js +24 -0
  4. package/dist/arrayCodec.js +32 -0
  5. package/dist/branchExecute.js +92 -0
  6. package/dist/branching.js +106 -0
  7. package/dist/bulkInsertLimits.js +25 -0
  8. package/dist/cdcOffsetsTables.js +19 -0
  9. package/dist/changeEvent.js +41 -0
  10. package/dist/changeIdentity.js +65 -0
  11. package/dist/changeListenerCeiling.js +6 -0
  12. package/dist/columnReference.js +17 -0
  13. package/dist/columns.js +326 -0
  14. package/dist/committedChanges.js +12 -0
  15. package/dist/connectionIdentity.js +36 -0
  16. package/dist/coreTables.js +16 -0
  17. package/dist/coreTablesRegistry.js +10 -0
  18. package/dist/dataTransfers.js +22 -0
  19. package/dist/dbCause.js +222 -0
  20. package/dist/dbMetrics.js +65 -0
  21. package/dist/decimalComparison.js +27 -0
  22. package/dist/derivedRowId.js +5 -0
  23. package/dist/dialect.js +13 -0
  24. package/dist/enumRenames.js +14 -0
  25. package/dist/expiresMixin.js +10 -0
  26. package/dist/fieldEncryption.js +98 -0
  27. package/dist/frameworkTables.js +130 -0
  28. package/dist/ginIndex.js +10 -0
  29. package/dist/hybridSearch.js +32 -0
  30. package/dist/idGenerator.js +57 -0
  31. package/dist/identifierLimits.js +32 -0
  32. package/dist/index.d.ts +122 -64
  33. package/dist/index.js +81 -2080
  34. package/dist/indexAudit.js +61 -0
  35. package/dist/indexStorage.js +58 -0
  36. package/dist/joinCompiler.js +160 -0
  37. package/dist/jsonEagerCompiler.js +436 -0
  38. package/dist/jsonPatch.js +78 -0
  39. package/dist/jsonPatchAssignments.js +13 -0
  40. package/dist/jsonPath.js +31 -0
  41. package/dist/localFirstMixin.js +12 -0
  42. package/dist/migrate.js +624 -0
  43. package/dist/migration.js +18 -0
  44. package/dist/migrations/appliedAtValue.js +8 -0
  45. package/dist/migrations/applier.js +1085 -0
  46. package/dist/migrations/boot.js +196 -0
  47. package/dist/migrations/branchRehearsal.js +122 -0
  48. package/dist/migrations/columnEquivalence.js +85 -0
  49. package/dist/migrations/ddlError.js +63 -0
  50. package/dist/migrations/declaredSchema.js +162 -0
  51. package/dist/migrations/deployLedger.js +19 -0
  52. package/dist/migrations/fileBased.js +57 -0
  53. package/dist/migrations/fileContext.js +482 -0
  54. package/dist/migrations/fileDiscovery.js +318 -0
  55. package/dist/migrations/fileSkipProbes.js +117 -0
  56. package/dist/migrations/fingerprint.js +46 -0
  57. package/dist/migrations/fkCycles.js +13 -0
  58. package/dist/migrations/frameworkLiveTables.js +25 -0
  59. package/dist/migrations/idempotentDdl.js +37 -0
  60. package/dist/migrations/indexPredicate.js +50 -0
  61. package/dist/migrations/introspect.js +799 -0
  62. package/dist/migrations/ledgerRows.js +4 -0
  63. package/dist/migrations/lock.js +91 -0
  64. package/dist/migrations/migrationTableExists.js +9 -0
  65. package/dist/migrations/mssqlColumnDependencies.js +76 -0
  66. package/dist/migrations/mysqlEngine.js +11 -0
  67. package/dist/migrations/namespaceCharset.js +51 -0
  68. package/dist/migrations/planner.js +775 -0
  69. package/dist/migrations/postgresEnumCheck.js +19 -0
  70. package/dist/migrations/reactiveTriggerDrift.js +58 -0
  71. package/dist/migrations/reactiveTriggerName.js +7 -0
  72. package/dist/migrations/renameMssqlCheck.js +21 -0
  73. package/dist/migrations/restoreSnapshots.js +206 -0
  74. package/dist/migrations/resumeLedger.js +86 -0
  75. package/dist/migrations/rollingDeploy.js +106 -0
  76. package/dist/migrations/schemaOwner.js +46 -0
  77. package/dist/migrations/schemaOwnerTable.js +4 -0
  78. package/dist/migrations/softDropSnapshot.js +20 -0
  79. package/dist/migrations/sqlLimit.js +8 -0
  80. package/dist/migrations/sqliteConstraintIdentity.js +97 -0
  81. package/dist/migrations/sqliteDecimalBoot.js +22 -0
  82. package/dist/migrations/sqliteDecimalPublication.js +257 -0
  83. package/dist/migrations/sqliteDecimalReview.js +30 -0
  84. package/dist/migrations/sqliteDecimalReviewStore.js +188 -0
  85. package/dist/migrations/sqliteDecimalReviewWitness.js +38 -0
  86. package/dist/migrations/sqliteDecimalSource.js +69 -0
  87. package/dist/migrations/sqliteDecimalStage.js +135 -0
  88. package/dist/migrations/sqliteForeignKeys.js +38 -0
  89. package/dist/migrations/sqliteMigrationBatch.js +37 -0
  90. package/dist/migrations/sqliteRetainedSource.js +106 -0
  91. package/dist/migrations/sqliteRowIdentity.js +63 -0
  92. package/dist/migrations/sqliteSchemaEpoch.js +12 -0
  93. package/dist/migrations/sqliteSnapshotGuard.js +10 -0
  94. package/dist/migrations/sqliteTableContents.js +34 -0
  95. package/dist/migrations/sqliteTableCopy.js +25 -0
  96. package/dist/migrations/sqliteTableSchema.js +19 -0
  97. package/dist/migrations/sqliteWitnessProtection.js +8 -0
  98. package/dist/migrations/squash.js +81 -0
  99. package/dist/migrations/storeCharset.js +66 -0
  100. package/dist/migrations/transactionCause.js +10 -0
  101. package/dist/migrations/undeclaredCharset.js +40 -0
  102. package/dist/migrations/uniqueActiveLowering.js +39 -0
  103. package/dist/mixins.js +22 -0
  104. package/dist/mssqlDecimalDistinct.js +51 -0
  105. package/dist/mssqlJsonValueCheck.js +42 -0
  106. package/dist/mssqlTextStorage.js +9 -0
  107. package/dist/namespace.js +21 -0
  108. package/dist/{wire-B28cPjEp.js → optimisticVersion.js} +2 -2
  109. package/dist/pendingAttribution.js +79 -0
  110. package/dist/pluginRef.js +17 -0
  111. package/dist/predicate.js +266 -0
  112. package/dist/predicateCoercion.js +13 -0
  113. package/dist/projectedColumn.js +37 -0
  114. package/dist/queryBuilder.js +382 -0
  115. package/dist/rawSql.js +8 -0
  116. package/dist/relations.js +69 -0
  117. package/dist/relationsRegistry.js +38 -0
  118. package/dist/replaceInProgress.js +53 -0
  119. package/dist/requiredColumns.js +26 -0
  120. package/dist/residency.js +52 -0
  121. package/dist/retention.js +62 -0
  122. package/dist/rowDecoder.js +123 -0
  123. package/dist/rowKey.js +8 -0
  124. package/dist/rowSchema.js +31 -0
  125. package/dist/scopeKey.js +8 -0
  126. package/dist/seed.js +33 -0
  127. package/dist/snowflake.js +26 -0
  128. package/dist/sql.d.ts +58 -29
  129. package/dist/sql.js +41 -6661
  130. package/dist/sqlCompiler.js +343 -0
  131. package/dist/sqlError.js +8 -0
  132. package/dist/sqlPoolCapacity.js +12 -0
  133. package/dist/sqliteDecimal.js +22 -0
  134. package/dist/sqliteDecimalAggregateSql.js +61 -0
  135. package/dist/sqliteDecimalColumnSql.js +108 -0
  136. package/dist/sqliteDecimalConversion.js +15 -0
  137. package/dist/sqliteDecimalCte.js +154 -0
  138. package/dist/sqliteDecimalEncodeSql.js +32 -0
  139. package/dist/sqliteDecimalOutputs.js +74 -0
  140. package/dist/sqliteDecimalPredicate.js +66 -0
  141. package/dist/sqliteDecimalQuery.js +183 -0
  142. package/dist/sqliteDecimalQueryPlan.js +37 -0
  143. package/dist/sqliteDecimalResultSql.js +44 -0
  144. package/dist/sqliteDecimalRowQuery.js +63 -0
  145. package/dist/sqliteDecimalSetQuery.js +50 -0
  146. package/dist/sqliteDecimalSource.js +63 -0
  147. package/dist/sqliteDecimalStorage.js +29 -0
  148. package/dist/sqliteDecimalSubquery.js +19 -0
  149. package/dist/sqliteDecimalWindowQuery.js +196 -0
  150. package/dist/sqliteValueCoercion.js +4 -0
  151. package/dist/stampId.js +21 -0
  152. package/dist/storeErrors.js +9 -0
  153. package/dist/storeRefusal.js +20 -0
  154. package/dist/stream.js +36 -0
  155. package/dist/subjectGraph.js +175 -0
  156. package/dist/table.js +394 -0
  157. package/dist/tableRegistry.js +16 -0
  158. package/dist/tenantSelection.js +27 -0
  159. package/dist/transactionOutcome.js +97 -0
  160. package/dist/transientContention.js +36 -0
  161. package/dist/typedStore.js +16 -0
  162. package/dist/upsertUpdate.js +20 -0
  163. package/dist/vectorEmbedding.js +31 -0
  164. package/dist/view.js +39 -0
  165. package/dist/wire.d.ts +9 -10
  166. package/dist/wire.js +6 -2
  167. package/dist/writeAttribution.js +16 -0
  168. package/dist/writeRecorder.js +37 -0
  169. package/package.json +4 -6
  170. package/dist/replaceInProgress-DUHl5JEz.js +0 -3557
@@ -0,0 +1,81 @@
1
+ import { withMigrationLock as e } from "./lock.js";
2
+ import { withMigrationTransaction as t } from "./transactionCause.js";
3
+ import { Effect as n } from "effect";
4
+ import { createHash as r, randomUUID as i } from "node:crypto";
5
+ import { SqlClient as a } from "effect/sql";
6
+ //#region src/migrations/squash.ts
7
+ var o = (e) => n.gen(function* () {
8
+ let t = yield* a.SqlClient;
9
+ if (!Number.isFinite(Date.parse(e.before))) return yield* n.fail(/* @__PURE__ */ Error("squash: cut-off must be a valid date"));
10
+ let i = yield* t`
11
+ SELECT id, fingerprint, ${t("appliedAt")} FROM _voltro_migration_plans
12
+ WHERE source = 'auto-diff'
13
+ AND ${t("squashedAt")} IS NULL
14
+ AND ${t("appliedAt")} < ${e.before}
15
+ ORDER BY ${t("appliedAt")} DESC, id DESC
16
+ `;
17
+ if (i.length === 0) return yield* n.fail(/* @__PURE__ */ Error(`squash: no rows applied before ${e.before}`));
18
+ let o = i[0];
19
+ if (o.fingerprint !== e.fingerprint) return yield* n.fail(/* @__PURE__ */ Error(`squash: latest pre-squash fingerprint (${o.fingerprint.slice(0, 12)}…) differs from current declared-schema fingerprint (${e.fingerprint.slice(0, 12)}…). The cut-off may select an older schema state, or declared changes may not have been applied.\n\nCheck the cut-off and selected history against the current declarations. Apply genuinely pending changes with \`voltro db apply\`; otherwise choose a cut-off whose newest eligible fingerprint matches the current schema.`));
20
+ let s = r("sha256").update(JSON.stringify({
21
+ before: e.before,
22
+ fingerprint: e.fingerprint,
23
+ rows: i.map((e) => [
24
+ e.id,
25
+ e.fingerprint,
26
+ e.appliedAt
27
+ ])
28
+ })).digest("hex");
29
+ return {
30
+ eligible: i,
31
+ preview: {
32
+ before: e.before,
33
+ fingerprint: e.fingerprint,
34
+ planIds: i.map((e) => e.id),
35
+ count: i.length,
36
+ token: s
37
+ }
38
+ };
39
+ }), s = (e) => o(e).pipe(n.map((e) => e.preview)), c = (r) => n.gen(function* () {
40
+ let s = yield* a.SqlClient;
41
+ return yield* e(s, t(s, n.gen(function* () {
42
+ let { eligible: e, preview: t } = yield* o(r);
43
+ if (r.expectedPreview !== void 0 && r.expectedPreview !== t.token) return yield* n.fail(/* @__PURE__ */ Error("squash: selected history changed after preview; review a new preview before confirming"));
44
+ yield* s`
45
+ UPDATE _voltro_migration_plans
46
+ SET ${s("squashedAt")} = CURRENT_TIMESTAMP
47
+ WHERE id IN ${s.in(e.map((e) => e.id))}
48
+ `;
49
+ let a = `plan_squash_${i()}`;
50
+ return yield* s`
51
+ INSERT INTO _voltro_migration_plans
52
+ (id, fingerprint, operations, ${s("rollbackPlan")}, ${s("appliedBy")}, environment, source,
53
+ ${s("onlineStrategy")}, ${s("durationMs")}, notes, ${s("squashedAt")}, ${s("appliedAt")}, ${s("createdAt")}, ${s("updatedAt")})
54
+ VALUES (
55
+ ${a},
56
+ ${r.fingerprint},
57
+ ${JSON.stringify({
58
+ kind: "squash-snapshot",
59
+ rowsSquashed: e.length
60
+ })},
61
+ ${null},
62
+ ${r.appliedBy},
63
+ ${r.environment},
64
+ ${"squash-snapshot"},
65
+ ${null},
66
+ ${0},
67
+ ${r.note ?? null},
68
+ ${null},
69
+ CURRENT_TIMESTAMP,
70
+ CURRENT_TIMESTAMP,
71
+ CURRENT_TIMESTAMP
72
+ )
73
+ `, {
74
+ squashedCount: e.length,
75
+ snapshotFingerprint: r.fingerprint,
76
+ snapshotId: a
77
+ };
78
+ })));
79
+ });
80
+ //#endregion
81
+ export { s as previewMigrationSquash, c as squashMigrationPlans };
@@ -0,0 +1,66 @@
1
+ import { isMysqlFamily as e } from "../dialect.js";
2
+ import { isSoftDropSnapshotName as t } from "./frameworkLiveTables.js";
3
+ //#region src/migrations/storeCharset.ts
4
+ var n = ["utf8mb3", "utf8mb4"], r = (e) => e === "utf8mb3" || e === "utf8mb4", i = (e) => {
5
+ switch (e.type) {
6
+ case "text":
7
+ case "enum": return !0;
8
+ case "id": return e.idScheme?.kind !== "numeric" && e.idStorage !== "numeric";
9
+ case "reference": return e.referenceStorage !== "numeric";
10
+ default: return !1;
11
+ }
12
+ }, a = (e, t) => e.map((e) => ({
13
+ ...e,
14
+ columns: e.columns.map((e) => i(e) && e.charset === void 0 ? {
15
+ ...e,
16
+ charset: t
17
+ } : e)
18
+ })), o = (e) => e.columns.flatMap((e) => e.charset === void 0 ? [] : [{
19
+ column: e.name,
20
+ charset: e.charset
21
+ }]), s = "utf8mb4", c = (e) => e.columns.some((e) => e.type === "json" || e.type === "array" || e.storageType === "json"), l = (n) => {
22
+ if (!e(n.dialect)) return [];
23
+ let r = [];
24
+ for (let e of [...n.live.tables].sort((e, t) => e.name.localeCompare(t.name))) {
25
+ if (t(e.name)) continue;
26
+ let i = o(e);
27
+ if (i.length === 0) continue;
28
+ if (n.charset !== void 0) {
29
+ let t = i.filter((e) => e.charset !== n.charset);
30
+ t.length > 0 && r.push({
31
+ table: e.name,
32
+ kind: "disagrees-with-declaration",
33
+ columns: t,
34
+ expected: n.charset
35
+ });
36
+ continue;
37
+ }
38
+ if (c(e)) {
39
+ let t = i.filter((e) => e.charset !== s);
40
+ t.length > 0 && r.push({
41
+ table: e.name,
42
+ kind: "json-outruns-text",
43
+ columns: t,
44
+ expected: s
45
+ });
46
+ continue;
47
+ }
48
+ let a = new Set(i.map((e) => e.charset));
49
+ a.size > 1 && r.push({
50
+ table: e.name,
51
+ kind: "mixed",
52
+ columns: i,
53
+ expected: [...a].sort().join(" / ")
54
+ });
55
+ }
56
+ return r;
57
+ }, u = (e) => {
58
+ let t = e.columns.map((e) => `${e.column} (${e.charset})`).join(", ");
59
+ switch (e.kind) {
60
+ case "disagrees-with-declaration": return `${e.table}: declared ${e.expected}, stored otherwise — ${t}`;
61
+ case "json-outruns-text": return `${e.table}: its json column holds every character (utf8mb4); these text columns do not — ${t}`;
62
+ case "mixed": return `${e.table}: its string columns are not in one character set — ${t}`;
63
+ }
64
+ }, d = "declare the store's character set in app.config.ts — store: { dialect: 'mariadb' | 'mysql', charset: 'utf8mb4' } — and run `voltro db plan`: every table the app declares is created with it and converted to it (a table rewrite; foreign keys are re-created around it). `utf8mb3` is accepted too, for a database that must stay there.";
65
+ //#endregion
66
+ export { n as MYSQL_CHARSETS, d as STORE_CHARSET_REMEDY, o as charsetColumnsOf, i as columnTakesCharset, u as describeStoreCharsetFinding, r as isMysqlCharset, a as stampDeclaredCharset, l as storeCharsetFindings };
@@ -0,0 +1,10 @@
1
+ import { Cause as e, Effect as t, Equal as n } from "effect";
2
+ //#region src/migrations/transactionCause.ts
3
+ var r = (r, i) => t.suspend(() => {
4
+ let a;
5
+ return r.withTransaction(i.pipe(t.tapCause((e) => t.sync(() => {
6
+ a = e;
7
+ })))).pipe(t.catchCause((r) => t.failCause(a !== void 0 && !n.equals(a, r) ? e.combine(a, r) : r)));
8
+ });
9
+ //#endregion
10
+ export { r as withMigrationTransaction };
@@ -0,0 +1,40 @@
1
+ import { isFrameworkOwnedLiveTable as e, isSoftDropSnapshotName as t, isStagingTableName as n } from "./frameworkLiveTables.js";
2
+ import { withMigrationLock as r } from "./lock.js";
3
+ import { columnLevelChecksMysql as i } from "./applier.js";
4
+ import { Effect as a } from "effect";
5
+ //#region src/migrations/undeclaredCharset.ts
6
+ var o = "utf8mb4", s = (r, i) => e(r) && !i.has(r) && !r.startsWith("_cloud_") && !r.startsWith("__turso_internal_") && !t(r) && !n(r), c = (e) => e.columnDefault !== null && e.columnDefault.toUpperCase() !== "NULL", l = (e, t, n, r) => {
7
+ if (n !== o) return {
8
+ tables: [],
9
+ left: []
10
+ };
11
+ let i = e.filter((e) => s(e.table, t) && (r === void 0 || r.has(e.table)) && e.charset !== o), a = i.filter((e) => c(e) || e.generated), l = /* @__PURE__ */ new Map();
12
+ for (let e of i) c(e) || e.generated || l.set(e.table, [...l.get(e.table) ?? [], e]);
13
+ return {
14
+ tables: [...l.entries()].sort(([e], [t]) => e.localeCompare(t)).map(([e, t]) => ({
15
+ table: e,
16
+ columns: t
17
+ })),
18
+ left: a
19
+ };
20
+ }, u = (e) => e.tables.length === 0 && e.left.length === 0, d = (e) => [...e.tables.map((e) => `${e.table}: ${e.columns.length} string column${e.columns.length === 1 ? "" : "s"} ${[...new Set(e.columns.map((e) => e.charset))].sort().join("/")} → ${o}`), ...e.left.map((e) => `${e.table}.${e.column} stays ${e.charset}: it has a ${e.generated ? "generation expression" : "default"}, which this step does not rewrite — convert it by hand`)], f = (e) => e.map((e) => Object.fromEntries(Object.entries(e).map(([e, t]) => [e.toLowerCase(), t]))), p = (e) => a.map(e.unsafe("SELECT c.table_name, c.column_name, c.character_set_name, c.column_type, c.is_nullable, c.column_default, c.extra\n FROM information_schema.columns c\n JOIN information_schema.tables t ON t.table_schema = c.table_schema AND t.table_name = c.table_name\n WHERE c.table_schema = DATABASE() AND t.table_type = 'BASE TABLE' AND c.character_set_name IS NOT NULL\n ORDER BY c.table_name, c.ordinal_position"), (e) => f(e).map((e) => ({
21
+ table: String(e.table_name),
22
+ column: String(e.column_name),
23
+ charset: String(e.character_set_name),
24
+ columnType: String(e.column_type),
25
+ nullable: String(e.is_nullable).toUpperCase() === "YES",
26
+ columnDefault: e.column_default === null || e.column_default === void 0 ? null : String(e.column_default),
27
+ generated: /GENERATED/i.test(String(e.extra ?? "")) && !/DEFAULT_GENERATED/i.test(String(e.extra ?? ""))
28
+ }))), m = (e) => `\`${e.replace(/`/g, "``")}\``, h = (e, t = /* @__PURE__ */ new Map()) => e.tables.map((e) => `ALTER TABLE ${m(e.table)} ${e.columns.map((n) => {
29
+ let r = t.get(e.table)?.get(n.column);
30
+ return `MODIFY COLUMN ${m(n.column)} ${n.columnType} CHARACTER SET ${o}${n.nullable ? "" : " NOT NULL"}${r === void 0 ? "" : ` CHECK (${r})`}`;
31
+ }).join(", ")}`), g = (e, t) => a.gen(function* () {
32
+ let n = /* @__PURE__ */ new Map();
33
+ for (let r of t.tables) n.set(r.table, yield* i(e, r.table));
34
+ for (let r of h(t, n)) yield* e.unsafe(r).unprepared;
35
+ }), _ = (e, t) => r(e, a.gen(function* () {
36
+ let n = l(yield* p(e), t.declaredNames, t.charset);
37
+ return yield* g(e, n), n;
38
+ }), { schema: t.lockSchema });
39
+ //#endregion
40
+ export { g as applyUndeclaredCharsetWork, _ as convergeUndeclaredCharset, d as describeUndeclaredCharsetWork, s as isUndeclaredCharsetTable, u as isUndeclaredCharsetWorkEmpty, p as readUndeclaredCharsetColumns, h as undeclaredCharsetStatements, l as undeclaredCharsetWork };
@@ -0,0 +1,39 @@
1
+ //#region src/migrations/uniqueActiveLowering.ts
2
+ var e = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, t = (e) => e.replace(/"/g, "`"), n = (e) => typeof e == "string" ? e : e.name ?? String(e), r = (e, t) => `_ua_${t}_${e}`.slice(0, 64), i = (i, a) => {
3
+ if (a !== "mysql" && a !== "mariadb" || !i.appliedIndexes.some(e)) return i;
4
+ let o = { ...i.fields }, s = [], c = [];
5
+ for (let a of i.appliedIndexes) {
6
+ if (!e(a)) {
7
+ s.push(a);
8
+ continue;
9
+ }
10
+ let l = t(a.where), u = [];
11
+ for (let e of a.fields) {
12
+ let t = n(e);
13
+ if (!(t in i.fields)) throw Error(`@voltro/migrate: uniqueActive '${a.name}' on '${i.tableName}' references unknown column '${t}'.`);
14
+ let s = r(a.name, t);
15
+ u.push(s), o[s] = {
16
+ type: "text",
17
+ nullable: !0,
18
+ unique: !1,
19
+ maxLength: 255,
20
+ generatedAs: {
21
+ expr: `CASE WHEN ${l} THEN CAST(\`${t}\` AS CHAR(255)) ELSE NULL END`,
22
+ stored: !0
23
+ }
24
+ };
25
+ }
26
+ c.push({
27
+ name: a.name,
28
+ fields: u
29
+ });
30
+ }
31
+ return {
32
+ ...i,
33
+ fields: o,
34
+ appliedIndexes: s,
35
+ appliedUniques: [...i.appliedUniques ?? [], ...c]
36
+ };
37
+ };
38
+ //#endregion
39
+ export { i as lowerUniqueActive };
package/dist/mixins.js ADDED
@@ -0,0 +1,22 @@
1
+ import { materializeFields as e } from "./columns.js";
2
+ //#region src/mixins.ts
3
+ var t = (t) => ({
4
+ fields: e(t.fields),
5
+ ...t.id === void 0 ? {} : { id: t.id },
6
+ ...t.requires === void 0 ? {} : { requires: t.requires },
7
+ ...t.indexes === void 0 ? {} : { indexes: t.indexes },
8
+ ...t.behaviors === void 0 ? {} : { behaviors: t.behaviors },
9
+ ...t.policies === void 0 ? {} : { policies: t.policies }
10
+ }), n = t, r = (e) => {
11
+ let t = /* @__PURE__ */ new Set(), n = [], r = (e) => {
12
+ let i = e.id ?? e;
13
+ if (!t.has(i)) {
14
+ if (t.add(i), e.requires !== void 0) for (let t of e.requires) r(t);
15
+ n.push(e);
16
+ }
17
+ };
18
+ for (let t of e) r(t);
19
+ return n;
20
+ };
21
+ //#endregion
22
+ export { n as defineMixin, t as mixin, r as resolveMixinGraph };
@@ -0,0 +1,51 @@
1
+ import { getTable as e } from "./tableRegistry.js";
2
+ import { prepareProjectedColumn as t } from "./projectedColumn.js";
3
+ //#region src/mssqlDecimalDistinct.ts
4
+ var n = (n) => {
5
+ if (!n.distinct && !n.distinctOn?.length || n.aggregations?.length || n.setOp) return;
6
+ let r = t(n), i = n.sourceTable?.tableName === n.table ? n.sourceTable : e(n.table), a = n.joinedProjection ?? (n.projection?.length ? n.projection : Object.keys(i?.fields ?? {})).map((e) => ({
7
+ source: e,
8
+ outputKey: e.split(".").at(-1)
9
+ })), o = {};
10
+ for (let e of a) {
11
+ let t = r(e.source);
12
+ if (!t) return;
13
+ o[e.outputKey] = t;
14
+ }
15
+ if (!Object.values(o).some((e) => e.type === "decimal")) return;
16
+ let s = new Set([
17
+ n.table,
18
+ ...(n.ctes ?? []).map((e) => e.name),
19
+ ...(n.joins ?? []).map((e) => e.table)
20
+ ].map((e) => e.toLowerCase())), c = "__voltro_mssql_decimal_result";
21
+ for (; s.has(c.toLowerCase());) c += "_";
22
+ let l = n.order.length >= 8 && a.length >= 8 ? /* @__PURE__ */ new Map() : void 0;
23
+ if (l) for (let e of a) l.has(e.source) || l.set(e.source, e.outputKey);
24
+ return {
25
+ table: c,
26
+ sourceTable: {
27
+ tableName: c,
28
+ fields: o
29
+ },
30
+ predicate: void 0,
31
+ projection: void 0,
32
+ order: n.order.map((e) => ({
33
+ ...e,
34
+ column: (l === void 0 ? a.find((t) => t.source === e.column)?.outputKey : l.get(e.column)) ?? e.column
35
+ })),
36
+ take: n.take,
37
+ skip: n.skip,
38
+ ctes: [...n.ctes ?? [], {
39
+ name: c,
40
+ descriptor: {
41
+ ...n,
42
+ ctes: [],
43
+ order: [],
44
+ take: void 0,
45
+ skip: void 0
46
+ }
47
+ }]
48
+ };
49
+ };
50
+ //#endregion
51
+ export { n as mssqlDecimalDistinct };
@@ -0,0 +1,42 @@
1
+ //#region src/mssqlJsonValueCheck.ts
2
+ var e = (e) => {
3
+ let t = `(N'{"v":' + ${e} + N'}')`, n = `ISJSON(${t}) = 1`, r = `JSON_MODIFY(CASE WHEN ${n} THEN ${t} ELSE N'{}' END, '$.v', NULL)`;
4
+ return `(${e} IS NULL OR (${n} AND ${[
5
+ 32,
6
+ 9,
7
+ 10,
8
+ 13
9
+ ].reduce((e, t) => `REPLACE(${e}, NCHAR(${t}), N'')`, r)} = N'{}'))`;
10
+ }, t = (e) => {
11
+ let t = [], n = /\s+|N?'(?:''|[^'])*'|\[(?:\]\]|[^\]])*\]|[A-Za-z_][A-Za-z_0-9]*|[0-9]+|[()+,=]/giy, r = 0;
12
+ for (; r < e.length;) {
13
+ n.lastIndex = r;
14
+ let i = n.exec(e);
15
+ if (!i) return;
16
+ let a = i[0];
17
+ /^\s+$/.test(a) || t.push(/^(?:N?')|^\[/i.test(a) ? a.replace(/^n'/, "N'") : a.toLowerCase()), r = n.lastIndex;
18
+ }
19
+ return t;
20
+ }, n = (n, r) => {
21
+ let i = `[${n.replaceAll("]", "]]")}]`, a = `(N'{"v":'+${i})+N'}'`, o = `isjson(${a})=(1)`, s = `json_modify(case when ${o} then ${a} else N'{}' end,'$.v',NULL)`, c = [
22
+ 32,
23
+ 9,
24
+ 10,
25
+ 13
26
+ ].reduce((e, t) => `replace(${e},nchar((${t})),N'')`, s), l = [
27
+ ["value", e(i)],
28
+ ["value", `(${i} IS NULL OR ${o} AND ${c}=N'{}')`],
29
+ ["container", `(${i} IS NULL OR ISJSON(${i}) = 1)`],
30
+ ["container", `(${i} IS NULL OR isjson(${i})=(1))`]
31
+ ], u = t(r);
32
+ if (u) return l.find(([, e]) => {
33
+ let n = t(e);
34
+ return n?.length === u.length && n.every((e, t) => e === u[t]);
35
+ })?.[0];
36
+ }, r = (e) => {
37
+ if (e.length === 0) return;
38
+ let t = e.filter((e) => e.enabled);
39
+ return t.some((e) => e.validation === "container") ? t.some((e) => e.validation === "container" && e.trusted) ? "container" : "unverified" : t.some((e) => e.validation === "value" && e.trusted) ? "value" : "unverified";
40
+ };
41
+ //#endregion
42
+ export { n as classifyMssqlJsonCheck, r as mssqlJsonValidation, e as mssqlJsonValueCheck };
@@ -0,0 +1,9 @@
1
+ //#region src/mssqlTextStorage.ts
2
+ var e = (e, t) => {
3
+ if (e.type === "text" && e.generatedAs === void 0) {
4
+ if (e.maxLength !== void 0) return e.maxLength;
5
+ if (t || e.hasDefault && e.defaultFactory === void 0 || e.oneOf !== void 0 && e.oneOf.length > 0) return 450;
6
+ }
7
+ };
8
+ //#endregion
9
+ export { e as mssqlTextStorageLength };
@@ -0,0 +1,21 @@
1
+ //#region src/namespace.ts
2
+ var e = class extends Error {
3
+ _tag = "TenantNamespaceUnresolved";
4
+ constructor(e) {
5
+ super(e), this.name = "TenantNamespaceUnresolved";
6
+ }
7
+ }, t = class extends Error {
8
+ _tag = "TenantNamespaceInvalid";
9
+ constructor(e) {
10
+ super(e), this.name = "TenantNamespaceInvalid";
11
+ }
12
+ }, n = 63, r = "tenant_", i = (e) => e.toLowerCase().replace(/[^a-z0-9_]/g, "_"), a = (a) => {
13
+ if (a == null || a === "") throw new e("namespace isolation is on but the request has no resolvable tenant (subject.tenantId is null/empty). Refusing to run against a shared/default namespace — this would be a cross-tenant read. Authenticate with a tenant-scoped subject, or disable namespace isolation for this surface.");
14
+ let o = i(a);
15
+ if (o.replace(/_/g, "") === "") throw new t(`tenant id '${a}' has no usable identifier characters after sanitisation — cannot derive a distinct namespace.`);
16
+ let s = `${r}${o}`;
17
+ if (s.length > n) throw new t(`namespace '${s}' for tenant '${a}' exceeds the ${n}-byte identifier limit. Use a shorter tenant id.`);
18
+ return s;
19
+ }, o = (e, t) => e === null ? t : `${e}.${t}`;
20
+ //#endregion
21
+ export { t as TenantNamespaceInvalid, e as TenantNamespaceUnresolved, o as qualifyTable, a as resolveTenantNamespace, i as sanitizeIdentifierFragment };
@@ -27,6 +27,6 @@ var t = class extends e.TaggedError()("VersionConflict", {
27
27
  expected: e.expected,
28
28
  actual: e.current
29
29
  });
30
- }, a = 1, o = e.DateFromNumber, s = e.NullOr(o);
30
+ }, a = 1;
31
31
  //#endregion
32
- export { r as a, t as i, s as n, i as o, a as r, n as s, o as t };
32
+ export { a as INITIAL_VERSION, t as VersionConflict, r as planVersionedUpdate, i as settleVersionedUpdate, n as versionColumnOf };
@@ -0,0 +1,79 @@
1
+ //#region src/pendingAttribution.ts
2
+ var e = 3e4, t = 1e4, n = /* @__PURE__ */ new Map(), r = [], i = (e, t) => {
3
+ let n = r[e];
4
+ r[e] = r[t], r[t] = n, r[e].heapIndex = e, n.heapIndex = t;
5
+ }, a = (e) => {
6
+ for (; e > 0;) {
7
+ let t = Math.floor((e - 1) / 2);
8
+ if (r[t].at <= r[e].at) break;
9
+ i(t, e), e = t;
10
+ }
11
+ return e;
12
+ }, o = (e) => {
13
+ for (; e * 2 + 1 < r.length;) {
14
+ let t = e * 2 + 1;
15
+ if (t + 1 < r.length && r[t + 1].at < r[t].at && t++, r[e].at <= r[t].at) break;
16
+ i(e, t), e = t;
17
+ }
18
+ }, s = (e) => {
19
+ let t = n.get(e.key);
20
+ e.previous ? e.previous.next = e.next : e.next && (t.head = e.next), e.next ? e.next.previous = e.previous : e.previous && (t.tail = e.previous), !e.previous && !e.next && n.delete(e.key);
21
+ let i = e.heapIndex, s = r.pop();
22
+ i < r.length && (r[i] = s, s.heapIndex = i, o(a(i)));
23
+ }, c = (e, t, n) => `${e}\u0000${t}\u0000${String(n)}`, l = (t) => {
24
+ for (; r[0] !== void 0 && t - r[0].at >= e;) s(r[0]);
25
+ }, u = (e, i) => {
26
+ if (i.traceId === void 0 && i.subjectId === void 0 && i.procedure === void 0 && i.via === void 0) return;
27
+ let o = Date.now();
28
+ if (r.length >= t && l(o), r.length >= t) return;
29
+ let s = n.get(e), c = {
30
+ key: e,
31
+ attribution: i,
32
+ at: o,
33
+ heapIndex: r.length,
34
+ previous: s?.tail
35
+ };
36
+ s ? (s.tail.next = c, s.tail = c) : n.set(e, {
37
+ head: c,
38
+ tail: c
39
+ }), r.push(c), a(c.heapIndex);
40
+ }, d = (t) => {
41
+ let r = n.get(t)?.head;
42
+ if (r !== void 0 && (s(r), !(Date.now() - r.at >= e))) return r.attribution;
43
+ }, f = (e) => n.has(e), p = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map(), g = 250, _ = (e) => {
44
+ let t = m.get(e);
45
+ if (t === void 0) return;
46
+ m.delete(e);
47
+ let n = h.get(e);
48
+ n !== void 0 && (clearTimeout(n), h.delete(e));
49
+ for (let e of t) e();
50
+ }, v = (e) => {
51
+ p.set(e, (p.get(e) ?? 0) + 1);
52
+ }, y = (e) => {
53
+ let t = (p.get(e) ?? 0) - 1;
54
+ t > 0 ? p.set(e, t) : (p.delete(e), _(e));
55
+ }, b = (e, t, n, r) => {
56
+ let i = n == null ? void 0 : c(e, t, n), a = () => r(i === void 0 ? void 0 : d(i));
57
+ if (i === void 0 || f(i)) {
58
+ a();
59
+ return;
60
+ }
61
+ let o = m.get(e);
62
+ if (o === void 0 && (p.get(e) ?? 0) === 0) {
63
+ a();
64
+ return;
65
+ }
66
+ if (o !== void 0) {
67
+ o.push(a);
68
+ return;
69
+ }
70
+ m.set(e, [a]);
71
+ let s = setTimeout(() => _(e), g);
72
+ typeof s == "object" && typeof s.unref == "function" && s.unref(), h.set(e, s);
73
+ }, x = () => {
74
+ n.clear(), r.length = 0, p.clear();
75
+ for (let e of h.values()) clearTimeout(e);
76
+ h.clear(), m.clear();
77
+ }, S = () => r.length;
78
+ //#endregion
79
+ export { c as attributionKey, v as beginLocalWrite, d as claimPendingAttribution, x as clearPendingAttribution, y as endLocalWrite, S as pendingAttributionCount, u as registerPendingAttribution, b as resolveEchoAttribution };
@@ -0,0 +1,17 @@
1
+ import { ColumnBuilder as e, text as t } from "./columns.js";
2
+ //#region src/pluginRef.ts
3
+ var n = Symbol.for("@voltro/database/pluginRefSpec"), r = (e) => {
4
+ if (typeof e == "object" && e) return ("__definition" in e && typeof e.__definition == "function" ? e.__definition() : e)[n];
5
+ }, i = (r, i = {}) => {
6
+ let a = {
7
+ target: r,
8
+ orphanPolicy: i.orphanPolicy ?? "keep",
9
+ onSoftDelete: i.onSoftDelete ?? !1
10
+ }, o = {
11
+ ...t().__definition(),
12
+ [n]: a
13
+ };
14
+ return new e(o);
15
+ };
16
+ //#endregion
17
+ export { i as pluginRef, r as pluginRefSpecOf };