@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.
Files changed (169) hide show
  1. package/CHANGELOG.md +666 -0
  2. package/THIRD-PARTY-NOTICES.md +5 -33
  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 +18 -7
  33. package/dist/index.js +81 -2183
  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-CG2j7J3f.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 +27 -6
  129. package/dist/sql.js +41 -6905
  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.js +6 -2
  166. package/dist/writeAttribution.js +16 -0
  167. package/dist/writeRecorder.js +37 -0
  168. package/package.json +3 -3
  169. package/dist/replaceInProgress-DC88Pdiy.js +0 -3735
@@ -0,0 +1,97 @@
1
+ //#region src/migrations/sqliteConstraintIdentity.ts
2
+ var e = (e) => e.replace(/[A-Z]/g, (e) => e.toLowerCase()), t = (t) => JSON.stringify(t.map(e)), n = (e) => {
3
+ let t = [];
4
+ for (let n = 0; n < e.length;) {
5
+ let r = e[n];
6
+ if (/\s/.test(r)) {
7
+ n++;
8
+ continue;
9
+ }
10
+ if (e.startsWith("--", n)) {
11
+ let t = e.indexOf("\n", n + 2);
12
+ n = t < 0 ? e.length : t + 1;
13
+ continue;
14
+ }
15
+ if (e.startsWith("/*", n)) {
16
+ let t = e.indexOf("*/", n + 2);
17
+ if (t < 0) return [];
18
+ n = t + 2;
19
+ continue;
20
+ }
21
+ if (r === "\"" || r === "`" || r === "[" || r === "'") {
22
+ let i = r === "[" ? "]" : r, a = "", o = !1;
23
+ for (n++; n < e.length;) {
24
+ if (e[n] === i) {
25
+ if (r !== "[" && e[n + 1] === i) {
26
+ r !== "'" && (a += i), n += 2;
27
+ continue;
28
+ }
29
+ n++, o = !0;
30
+ break;
31
+ }
32
+ r !== "'" && (a += e[n]), n++;
33
+ }
34
+ if (!o) return [];
35
+ t.push({
36
+ text: a,
37
+ kind: r === "'" ? "literal" : "identifier"
38
+ });
39
+ continue;
40
+ }
41
+ if ("(),;".includes(r)) {
42
+ t.push({
43
+ text: r,
44
+ kind: "punctuation"
45
+ }), n++;
46
+ continue;
47
+ }
48
+ let i = n++;
49
+ for (; n < e.length && !/[\s()\[\],;"'`]/.test(e[n]) && !e.startsWith("--", n) && !e.startsWith("/*", n);) n++;
50
+ t.push({
51
+ text: e.slice(i, n),
52
+ kind: "word"
53
+ });
54
+ }
55
+ return t;
56
+ }, r = (e) => {
57
+ let r = n(e), i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = (e, t) => e?.kind === "word" && e.text.toUpperCase() === t, s = (e) => e !== void 0 && (e.kind === "identifier" || e.kind === "word" && /^[\p{L}_][\p{L}\p{N}_$]*$/u.test(e.text)), c = (e) => {
58
+ let n = o(e[0], "CONSTRAINT") && s(e[1]), r = n ? 2 : 0;
59
+ if (!o(e[r], "UNIQUE") || e[r + 1]?.text !== "(") return;
60
+ let c = [], l = r + 2, u = !1;
61
+ for (; s(e[l]);) {
62
+ if (c.push(e[l++].text), o(e[l], "COLLATE")) {
63
+ if (u = !0, !s(e[l + 1])) return;
64
+ l += 2;
65
+ }
66
+ if ((o(e[l], "ASC") || o(e[l], "DESC")) && (u = !0, l++), e[l]?.text === ")") break;
67
+ if (e[l++]?.text !== ",") return;
68
+ }
69
+ if (!c.length || e[l]?.text !== ")") return;
70
+ let d = e.slice(l + 1);
71
+ if (d.length && !(d.length === 3 && o(d[0], "ON") && o(d[1], "CONFLICT") && [
72
+ "ROLLBACK",
73
+ "ABORT",
74
+ "FAIL",
75
+ "IGNORE",
76
+ "REPLACE"
77
+ ].some((e) => o(d[2], e)))) return;
78
+ let f = t(c);
79
+ a.has(f) || u ? i.delete(f) : n && i.set(f, e[1].text), a.add(f);
80
+ }, l = 0, u = -1;
81
+ for (let e = 0; e < r.length; e++) {
82
+ let t = r[e];
83
+ if (t.kind === "punctuation") {
84
+ if (t.text === "(") l++ === 0 && (u = e + 1);
85
+ else if (t.text === ")") {
86
+ if (--l === 0) {
87
+ c(r.slice(u, e));
88
+ break;
89
+ }
90
+ if (l < 0) return /* @__PURE__ */ new Map();
91
+ } else t.text === "," && l === 1 && (c(r.slice(u, e)), u = e + 1);
92
+ }
93
+ }
94
+ return l === 0 ? i : /* @__PURE__ */ new Map();
95
+ };
96
+ //#endregion
97
+ export { r as sqliteNamedUniqueConstraints, t as sqliteUniqueColumnsKey };
@@ -0,0 +1,22 @@
1
+ import { parseSqliteDecimalStorageType as e, sqliteDecimalStorageShape as t } from "../sqliteDecimalStorage.js";
2
+ import { sqlError as n } from "../sqlError.js";
3
+ import { dialectOf as r } from "./resumeLedger.js";
4
+ import { Effect as i } from "effect";
5
+ //#region src/migrations/sqliteDecimalBoot.ts
6
+ var a = (a, o) => i.gen(function* () {
7
+ if (o.length === 0) return;
8
+ let s = r(a);
9
+ if (s !== "sqlite" && s !== "turso") return;
10
+ let c = yield* a.unsafe("SELECT name FROM sqlite_master WHERE type = 'table' AND sql LIKE '%VOLTRO_DECIMAL_V1_%'"), l = new Set(c.map((e) => e.name));
11
+ for (let r of o) {
12
+ let o = Object.values(r.fields).some((e) => t(e) !== void 0);
13
+ if (!l.has(r.tableName) && !o) continue;
14
+ let s = "\"" + r.tableName.replaceAll("\"", "\"\"") + "\"", c = yield* a.unsafe(`PRAGMA table_info(${s})`), u = new Map(c.map((e) => [e.name, e]));
15
+ for (let [a, o] of Object.entries(r.fields)) {
16
+ let s = t(o), c = e(u.get(a)?.type ?? "");
17
+ if ((s !== void 0 || c !== void 0) && (s?.precision !== c?.precision || s?.scale !== c?.scale)) return yield* i.fail(n(`Decimal storage representation does not match the application schema at ${r.tableName}.${a}; complete the verified storage migration before starting this application`));
18
+ }
19
+ }
20
+ });
21
+ //#endregion
22
+ export { a as verifySqliteDecimalStorage };
@@ -0,0 +1,257 @@
1
+ import { sqlError as e } from "../sqlError.js";
2
+ import { runSqliteMigrationBatch as t } from "./sqliteMigrationBatch.js";
3
+ import { emitCreateTableSqlite as n } from "./applier.js";
4
+ import { assertSqliteTableSchema as r, sqliteTableSchemaMatchesSql as i } from "./sqliteTableSchema.js";
5
+ import { isSqliteRowIdentity as a, readSqliteRowIdentity as o, restoreSqliteSequenceSql as s, sqliteSequenceMatchesSql as c } from "./sqliteRowIdentity.js";
6
+ import { readSqliteTableContents as l } from "./sqliteTableContents.js";
7
+ import { assertSqliteSnapshot as u } from "./sqliteSnapshotGuard.js";
8
+ import { readSqliteSchemaEpoch as d, sqliteSchemaEpochMatchesSql as f } from "./sqliteSchemaEpoch.js";
9
+ import { sqliteDecimalReviewInputWitness as p } from "./sqliteDecimalReviewWitness.js";
10
+ import { dropSqliteWitnessProtectionStatements as m, sqliteWitnessProtectionStatements as h } from "./sqliteWitnessProtection.js";
11
+ import { readSqliteDecimalReviewStore as g } from "./sqliteDecimalReviewStore.js";
12
+ import { sqliteTableCopyDifferenceSql as _ } from "./sqliteTableCopy.js";
13
+ import { sqliteRetainedReviewNames as v, sqliteRetainedSourceNames as y } from "./sqliteRetainedSource.js";
14
+ import { prepareSqliteDecimalStage as b } from "./sqliteDecimalStage.js";
15
+ import { Effect as x } from "effect";
16
+ //#region src/migrations/sqliteDecimalPublication.ts
17
+ var S = (s, p, g, C = []) => x.gen(function* () {
18
+ let j = (t) => x.fail(e(t));
19
+ if (!p.decimalReview) return yield* j("Decimal publication requires reviewed conversion decisions");
20
+ let M = y(p), N = `${M.marker}_stage_owner`, P = `${M.marker}_publication`, F = `${M.marker}_published_rows`, I = `CREATE TABLE ${T(P)} (manifest TEXT NOT NULL, schema TEXT NOT NULL, artifacts TEXT NOT NULL)`, L = yield* k(p, g, C);
21
+ if (new Set(C.map((e) => e.name)).size !== C.length || C.some((e) => !/^CREATE\s+TRIGGER\s/i.test(e.sql)) || p.reviewedSchema.objects.some((e) => e.type === "trigger" && !C.some((t) => t.name === e.name))) return yield* j("Decimal publication requires explicit reviewed definitions for every source trigger");
22
+ let R = yield* s.unsafe("SELECT sql FROM main.sqlite_master WHERE name = ? COLLATE NOCASE", [P]);
23
+ if (R.length === 0) {
24
+ let e = yield* b(s, p, g), r = yield* x.scoped(x.gen(function* () {
25
+ return yield* l(yield* s.reserve, e.stage);
26
+ })), a = yield* x.scoped(x.gen(function* () {
27
+ return yield* o(yield* s.reserve, e.stage);
28
+ })), u = {
29
+ phase: "published",
30
+ sourceInsertColumns: (yield* s.unsafe(`PRAGMA main.table_xinfo(${T(p.source)})`)).filter((e) => e.hidden === 0).map((e) => e.name),
31
+ identity: L,
32
+ sourceManifest: e.sourceManifest,
33
+ stageManifest: e.manifest,
34
+ sourceContents: e.sourceContents,
35
+ sourceRowIdentity: e.sourceRowIdentity,
36
+ imageRowIdentity: a,
37
+ imageContents: r
38
+ }, d = `${M.marker}_publish_guard`, y = [
39
+ i(p.source, p.reviewedSchema),
40
+ i(e.stage, e.schema),
41
+ `NOT EXISTS (${_(p.source, M.copy, [...e.sourceRowIdentity.alias === null ? [] : [e.sourceRowIdentity.alias], ...e.sourceContents.columns])})`,
42
+ f(e.validationEpoch, 2),
43
+ c(p.source, e.sourceRowIdentity),
44
+ c(e.stage, a),
45
+ D(M.marker, e.sourceManifest),
46
+ D(N, e.manifest)
47
+ ].map((e) => `(${e})`).join(" AND "), S = n({
48
+ kind: "create-table",
49
+ table: p.source,
50
+ columns: g.columns,
51
+ indexes: g.indexes,
52
+ ...g.primaryKey ? { primaryKey: g.primaryKey } : {}
53
+ }).slice(1).map((e) => e.replace(/ IF NOT EXISTS /, " ")), w = C.map((e) => e.sql.replace(/^(CREATE\s+TRIGGER)\s+IF\s+NOT\s+EXISTS\s+/i, "$1 ")), O = [`(SELECT COUNT(*) FROM main.sqlite_master WHERE type='trigger' AND tbl_name=${E(p.source)}) = ${C.length}`, ...C.map((e) => `EXISTS (SELECT 1 FROM main.sqlite_master WHERE type='trigger' AND name=${E(e.name)} AND tbl_name=${E(p.source)})`)].join(" AND ");
54
+ yield* t(s, [
55
+ I,
56
+ `CREATE TABLE ${T(d)} (valid INTEGER CHECK(valid = 1))`,
57
+ `INSERT INTO ${T(d)} SELECT CASE WHEN ${y} THEN 1 ELSE 0 END`,
58
+ ...m(N),
59
+ `DROP TABLE ${T(p.source)}`,
60
+ ...e.indexes.map((e) => `DROP INDEX ${T(e)}`),
61
+ `ALTER TABLE ${T(e.stage)} RENAME TO ${T(p.source)}`,
62
+ ...S,
63
+ ...w,
64
+ `INSERT INTO ${T(d)} SELECT CASE WHEN ${O} THEN 1 ELSE 0 END`,
65
+ `CREATE TABLE ${T(F)} AS SELECT * FROM main.${T(p.source)} WHERE 0`,
66
+ `INSERT INTO ${T(F)} (${[...a.alias === null ? [] : [a.alias], ...r.columns].map(T).join(", ")}) SELECT ${[...a.alias === null ? [] : [a.alias], ...r.columns].map(T).join(", ")} FROM main.${T(p.source)}`,
67
+ ...h(F, P),
68
+ `INSERT INTO ${T(P)} SELECT ${E(JSON.stringify(u))}, (SELECT json_group_array(json_object('type',type,'name',name,'sql',sql)) FROM (SELECT type,name,sql FROM main.sqlite_master WHERE tbl_name=${E(p.source)} AND type IN ('table','index','trigger') ORDER BY type COLLATE BINARY,name COLLATE BINARY)), ${A([
69
+ M.marker,
70
+ M.copy,
71
+ ...Object.values(v(p)),
72
+ N,
73
+ F
74
+ ])}`,
75
+ `DROP TABLE ${T(d)}`
76
+ ]);
77
+ } else if (R.length !== 1 || R[0]?.sql !== I) return yield* j("Decimal publication marker is not owned by this conversion");
78
+ let z = yield* s.unsafe(`SELECT manifest,schema,artifacts FROM main.${T(P)}`);
79
+ if (z.length !== 1) return yield* j("Decimal publication receipt is incomplete");
80
+ let B = yield* x.try({
81
+ try: () => {
82
+ let e = JSON.parse(z[0].manifest), t = { objects: JSON.parse(z[0].schema) };
83
+ if (!a(e.sourceRowIdentity) || !a(e.imageRowIdentity) || !["published", "rolled-back"].includes(e.phase) || !Array.isArray(e.sourceInsertColumns) || e.identity !== L || typeof e.sourceManifest != "string" || typeof e.stageManifest != "string" || typeof e.sourceContents?.digest != "string" || !Array.isArray(e.sourceContents.columns) || typeof e.imageContents?.digest != "string" || !Array.isArray(e.imageContents.columns)) throw TypeError("Mismatched publication identity");
84
+ return {
85
+ receipt: e,
86
+ schema: t
87
+ };
88
+ },
89
+ catch: (t) => e("Decimal publication receipt does not match the requested conversion", t)
90
+ });
91
+ if (B.receipt.phase === "rolled-back") {
92
+ yield* w(s, p, g, C);
93
+ let e = `${M.marker}_restart_guard`, n = JSON.stringify({
94
+ ...B.receipt,
95
+ cleaned: !0
96
+ }), r = [
97
+ i(p.source, B.schema),
98
+ `EXISTS (SELECT 1 FROM main.sqlite_master WHERE name = ${E(P)} AND type = 'table' AND sql = ${E(I)})`,
99
+ `(SELECT COUNT(*) FROM ${T(P)}) = 1`,
100
+ `EXISTS (SELECT 1 FROM ${T(P)} WHERE manifest = ${E(n)} AND schema = ${E(z[0].schema)} AND artifacts = ${E(z[0].artifacts)})`
101
+ ].map((e) => `(${e})`).join(" AND ");
102
+ return yield* t(s, [
103
+ `CREATE TABLE ${T(e)} (valid INTEGER CHECK(valid = 1))`,
104
+ `INSERT INTO ${T(e)} SELECT CASE WHEN ${r} THEN 1 ELSE 0 END`,
105
+ `DROP TABLE ${T(P)}`,
106
+ `DROP TABLE ${T(e)}`
107
+ ]), yield* S(s, p, g, C);
108
+ }
109
+ return B.receipt.cleaned === !0 ? (yield* x.scoped(x.gen(function* () {
110
+ yield* r(yield* s.reserve, p.source, B.schema);
111
+ })), {
112
+ marker: P,
113
+ image: F,
114
+ sourceCopy: M.copy
115
+ }) : (yield* s.unsafe(`SELECT 1 WHERE NOT (${D(M.marker, B.receipt.sourceManifest)} AND ${D(N, B.receipt.stageManifest)} AND CAST(${A([
116
+ M.marker,
117
+ M.copy,
118
+ ...Object.values(v(p)),
119
+ N,
120
+ F
121
+ ])} AS TEXT) = ${E(z[0].artifacts)})`)).length > 0 ? yield* j("Retained decimal artifact ownership changed after publication") : (yield* x.scoped(x.gen(function* () {
122
+ let e = yield* s.reserve, t = yield* d(e);
123
+ if (yield* O(e, p), yield* r(e, p.source, B.schema), yield* u(e, M.copy, B.receipt.sourceContents, B.receipt.sourceRowIdentity), yield* u(e, F, B.receipt.imageContents, B.receipt.imageRowIdentity), (yield* d(e)) !== t) return yield* j("Decimal publication artifacts changed during validation");
124
+ })), {
125
+ marker: P,
126
+ image: F,
127
+ sourceCopy: M.copy
128
+ });
129
+ }), C = (n, o, l, p = []) => x.gen(function* () {
130
+ let m = (t) => x.fail(e(t)), h = y(o), g = `${h.marker}_publication`, b = `${h.marker}_published_rows`, C = `${h.marker}_stage_owner`, w = `CREATE TABLE ${T(g)} (manifest TEXT NOT NULL, schema TEXT NOT NULL, artifacts TEXT NOT NULL)`, j = yield* n.unsafe("SELECT sql FROM main.sqlite_master WHERE name = ? COLLATE NOCASE", [g]);
131
+ if (j.length !== 1 || j[0]?.sql !== w) return yield* m("No owned decimal publication to roll back");
132
+ let M = yield* n.unsafe(`SELECT manifest,schema,artifacts FROM main.${T(g)}`);
133
+ if (M.length !== 1) return yield* m("Decimal publication receipt is incomplete");
134
+ let N = yield* k(o, l, p), P = yield* x.try({
135
+ try: () => {
136
+ let e = JSON.parse(M[0].manifest), t = { objects: JSON.parse(M[0].schema) };
137
+ if (!a(e.sourceRowIdentity) || !a(e.imageRowIdentity) || e.identity !== N || !["published", "rolled-back"].includes(e.phase) || !Array.isArray(e.sourceInsertColumns) || e.sourceInsertColumns.length === 0 || e.sourceInsertColumns.some((e) => typeof e != "string")) throw TypeError("Invalid rollback receipt");
138
+ return {
139
+ receipt: e,
140
+ schema: t
141
+ };
142
+ },
143
+ catch: (t) => e("Decimal rollback identity does not match publication", t)
144
+ });
145
+ if (P.receipt.phase === "rolled-back") {
146
+ yield* x.scoped(x.gen(function* () {
147
+ let e = yield* n.reserve, t = yield* d(e);
148
+ if (P.receipt.cleaned !== !0 && (yield* O(e, o)), yield* r(e, o.source, P.schema), (yield* d(e)) !== t) return yield* m("Decimal rollback artifacts changed during validation");
149
+ }));
150
+ return;
151
+ }
152
+ if (P.receipt.cleaned === !0) return yield* m("Decimal rollback is no longer available after artifact cleanup");
153
+ yield* S(n, o, l, p);
154
+ let F = yield* x.scoped(x.gen(function* () {
155
+ let e = yield* n.reserve, t = yield* d(e);
156
+ return yield* O(e, o), yield* u(e, h.copy, P.receipt.sourceContents, P.receipt.sourceRowIdentity), yield* u(e, b, P.receipt.imageContents, P.receipt.imageRowIdentity), t;
157
+ })), I = o.reviewedSchema.objects.find((e) => e.type === "table");
158
+ if (!I?.sql) return yield* m("Original table definition is missing");
159
+ let L = [...P.receipt.sourceRowIdentity.alias === null ? [] : [P.receipt.sourceRowIdentity.alias], ...P.receipt.sourceInsertColumns].map(T).join(", "), R = `${h.marker}_rollback_guard`, z = [
160
+ i(o.source, P.schema),
161
+ `CAST(${A([
162
+ h.marker,
163
+ h.copy,
164
+ ...Object.values(v(o)),
165
+ C,
166
+ b
167
+ ])} AS TEXT) = ${E(M[0].artifacts)}`,
168
+ f(F, 1),
169
+ `NOT EXISTS (${_(o.source, b, [...P.receipt.imageRowIdentity.alias === null ? [] : [P.receipt.imageRowIdentity.alias], ...P.receipt.imageContents.columns])})`,
170
+ c(o.source, P.receipt.imageRowIdentity),
171
+ D(h.marker, P.receipt.sourceManifest),
172
+ D(C, P.receipt.stageManifest),
173
+ `(SELECT COUNT(*) FROM ${T(g)}) = 1`,
174
+ `EXISTS (SELECT 1 FROM ${T(g)} WHERE manifest = ${E(M[0].manifest)} AND schema = ${E(M[0].schema)})`
175
+ ].map((e) => `(${e})`).join(" AND ");
176
+ yield* t(n, [
177
+ `CREATE TABLE ${T(R)} (valid INTEGER CHECK(valid = 1))`,
178
+ `INSERT INTO ${T(R)} SELECT CASE WHEN ${z} THEN 1 ELSE 0 END`,
179
+ `DROP TABLE ${T(o.source)}`,
180
+ I.sql,
181
+ `INSERT INTO ${T(o.source)} (${L}) SELECT ${L} FROM ${T(h.copy)}`,
182
+ ...s(o.source, P.receipt.sourceRowIdentity),
183
+ ...o.reviewedSchema.objects.filter((e) => e.type !== "table" && e.sql !== null).map((e) => e.sql),
184
+ `INSERT INTO ${T(R)} SELECT CASE WHEN NOT EXISTS (${_(o.source, h.copy, P.receipt.sourceContents.columns)}) THEN 1 ELSE 0 END`,
185
+ `UPDATE ${T(g)} SET manifest = ${E(JSON.stringify({
186
+ ...P.receipt,
187
+ phase: "rolled-back"
188
+ }))}, schema = (SELECT json_group_array(json_object('type',type,'name',name,'sql',sql)) FROM (SELECT type,name,sql FROM main.sqlite_master WHERE tbl_name=${E(o.source)} AND type IN ('table','index','trigger') ORDER BY type COLLATE BINARY,name COLLATE BINARY))`,
189
+ `DROP TABLE ${T(R)}`
190
+ ]);
191
+ }), w = (n, r, o, s = []) => x.gen(function* () {
192
+ let c = (t) => x.fail(e(t)), l = y(r), p = `${l.marker}_publication`, m = `${l.marker}_published_rows`, h = `${l.marker}_stage_owner`, g = [
193
+ l.marker,
194
+ l.copy,
195
+ ...Object.values(v(r)),
196
+ h,
197
+ m
198
+ ], _ = `CREATE TABLE ${T(p)} (manifest TEXT NOT NULL, schema TEXT NOT NULL, artifacts TEXT NOT NULL)`, b = yield* n.unsafe("SELECT sql FROM main.sqlite_master WHERE name = ? COLLATE NOCASE", [p]);
199
+ if (b.length !== 1 || b[0]?.sql !== _) return yield* c("No owned decimal publication to clean up");
200
+ let w = yield* n.unsafe(`SELECT manifest,schema,artifacts FROM main.${T(p)}`);
201
+ if (w.length !== 1) return yield* c("Decimal publication receipt is incomplete");
202
+ let j = yield* k(r, o, s), M = yield* x.try({
203
+ try: () => {
204
+ let e = JSON.parse(w[0].manifest), t = { objects: JSON.parse(w[0].schema) };
205
+ if (!a(e.sourceRowIdentity) || !a(e.imageRowIdentity) || e.identity !== j || !["published", "rolled-back"].includes(e.phase)) throw TypeError("Invalid cleanup receipt");
206
+ return {
207
+ receipt: e,
208
+ schema: t
209
+ };
210
+ },
211
+ catch: (t) => e("Decimal cleanup identity does not match publication", t)
212
+ });
213
+ if (M.receipt.phase === "published" ? yield* S(n, r, o, s) : yield* C(n, r, o, s), M.receipt.cleaned === !0) return;
214
+ let N = yield* x.scoped(x.gen(function* () {
215
+ let e = yield* n.reserve, t = yield* d(e);
216
+ return yield* O(e, r), yield* u(e, l.copy, M.receipt.sourceContents, M.receipt.sourceRowIdentity), yield* u(e, m, M.receipt.imageContents, M.receipt.imageRowIdentity), t;
217
+ })), P = `${l.marker}_cleanup_guard`, F = [
218
+ i(r.source, M.schema),
219
+ f(N, 1),
220
+ `CAST(${A(g)} AS TEXT) = ${E(w[0].artifacts)}`,
221
+ D(l.marker, M.receipt.sourceManifest),
222
+ D(h, M.receipt.stageManifest),
223
+ `(SELECT COUNT(*) FROM ${T(p)}) = 1`,
224
+ `EXISTS (SELECT 1 FROM ${T(p)} WHERE manifest = ${E(w[0].manifest)} AND schema = ${E(w[0].schema)} AND artifacts = ${E(w[0].artifacts)})`
225
+ ].map((e) => `(${e})`).join(" AND ");
226
+ yield* t(n, [
227
+ `CREATE TABLE ${T(P)} (valid INTEGER CHECK(valid = 1))`,
228
+ `INSERT INTO ${T(P)} SELECT CASE WHEN ${F} THEN 1 ELSE 0 END`,
229
+ ...g.map((e) => `DROP TABLE ${T(e)}`),
230
+ `UPDATE ${T(p)} SET manifest = ${E(JSON.stringify({
231
+ ...M.receipt,
232
+ cleaned: !0
233
+ }))}`,
234
+ `DROP TABLE ${T(P)}`
235
+ ]);
236
+ }), T = (e) => "\"" + e.replaceAll("\"", "\"\"") + "\"", E = (e) => "'" + e.replaceAll("'", "''") + "'", D = (e, t) => `(SELECT COUNT(*) FROM main.${T(e)}) = 1 AND EXISTS (SELECT 1 FROM main.${T(e)} WHERE manifest=${E(t)})`, O = (t, n) => x.gen(function* () {
237
+ let r = yield* x.try({
238
+ try: () => p(n.decimalReview.cells),
239
+ catch: (t) => e("Invalid decimal publication review", t)
240
+ }), i = y(n), a = v(n);
241
+ yield* g(t, a.table, i.marker, r);
242
+ }), k = (t, n, r) => x.try({
243
+ try: () => JSON.stringify({
244
+ migrationId: t.migrationId,
245
+ source: t.source,
246
+ targetIdentity: t.targetIdentity,
247
+ reviewedSchema: t.reviewedSchema,
248
+ keys: t.decimalReview.keys,
249
+ columns: t.decimalReview.columns,
250
+ review: p(t.decimalReview.cells),
251
+ target: n,
252
+ triggers: r
253
+ }),
254
+ catch: (t) => e("Invalid decimal publication review", t)
255
+ }), A = (e) => `(SELECT json_group_array(json_object('type',type,'name',name,'sql',sql,'table',tbl_name)) FROM (SELECT type,name,sql,tbl_name FROM main.sqlite_master WHERE tbl_name IN (${e.map(E).join(", ")}) AND type IN ('table','index','trigger') ORDER BY tbl_name COLLATE BINARY,type COLLATE BINARY,name COLLATE BINARY))`;
256
+ //#endregion
257
+ export { w as cleanupSqliteDecimalPublication, S as publishSqliteDecimalStage, C as rollbackSqliteDecimalPublication };
@@ -0,0 +1,30 @@
1
+ import { convertSqliteDecimalValue as e } from "../sqliteDecimalConversion.js";
2
+ //#region src/migrations/sqliteDecimalReview.ts
3
+ var t = (e) => {
4
+ let t = e.value;
5
+ return JSON.stringify({
6
+ kind: e.kind,
7
+ observed: t === null ? ["null"] : [typeof t, typeof t == "number" && Object.is(t, -0) ? "-0" : String(t)],
8
+ shape: e.kind === "sortable-v1" ? e.shape : null
9
+ });
10
+ }, n = (t) => {
11
+ if (!t.rowIdentity || !t.column) throw TypeError("Decimal review requires row and column identities");
12
+ let n = e(t.source, t.target), r = t.source.value, i = r === null ? ["null"] : [typeof r, typeof r == "number" && Object.is(r, -0) ? "-0" : String(r)], a = JSON.stringify({
13
+ kind: t.source.kind,
14
+ observed: i,
15
+ shape: t.source.kind === "sortable-v1" ? t.source.shape : null,
16
+ resolution: t.source.kind === "numeric" ? t.source.resolution ?? null : null
17
+ });
18
+ return {
19
+ rowIdentity: t.rowIdentity,
20
+ column: t.column,
21
+ encoded: n,
22
+ sourceIdentity: a,
23
+ target: {
24
+ precision: t.target.precision,
25
+ scale: t.target.scale
26
+ }
27
+ };
28
+ }, r = (e) => JSON.stringify([e.rowIdentity, e.column]);
29
+ //#endregion
30
+ export { n as normalizeSqliteDecimalCell, r as sqliteDecimalDecisionIdentity, t as sqliteDecimalObservationIdentity };
@@ -0,0 +1,188 @@
1
+ import { sqlError as e } from "../sqlError.js";
2
+ import { runSqliteMigrationStatement as t } from "./sqliteMigrationBatch.js";
3
+ import { assertSqliteTableSchema as n, readSqliteTableSchema as r } from "./sqliteTableSchema.js";
4
+ import { forEachSqliteDecimalSourcePage as i } from "./sqliteDecimalSource.js";
5
+ import { readSqliteSchemaEpoch as a } from "./sqliteSchemaEpoch.js";
6
+ import { normalizeSqliteDecimalCell as o, sqliteDecimalDecisionIdentity as s, sqliteDecimalObservationIdentity as c } from "./sqliteDecimalReview.js";
7
+ import { createSqliteDecimalReviewWitness as l } from "./sqliteDecimalReviewWitness.js";
8
+ import { sqliteWitnessProtectionStatements as u } from "./sqliteWitnessProtection.js";
9
+ import { Effect as d, Option as f } from "effect";
10
+ import { SqlClient as p } from "effect/sql";
11
+ //#region src/migrations/sqliteDecimalReviewStore.ts
12
+ var m = (n, i, a) => d.gen(function* () {
13
+ let s = (t) => e("Invalid stored decimal review", t), l = yield* p.SqlClient, m = yield* d.serviceOption(l.transactionService);
14
+ if (f.isNone(m)) return yield* d.fail(e("Decimal review import requires a pinned transaction"));
15
+ if (!n.startsWith("_voltro_review_") || !i) return yield* d.fail(s("Missing review artifact identity"));
16
+ let h = m.value[0], g = `${n}_owner`;
17
+ yield* t(h, `CREATE TABLE main.${w(g)} (manifest TEXT NOT NULL, schema TEXT NOT NULL)`), yield* t(h, `CREATE TABLE main.${w(n)} (sort_key TEXT NOT NULL PRIMARY KEY, payload TEXT NOT NULL, observation TEXT NOT NULL)`);
18
+ let _ = yield* d.try({
19
+ try: () => a[Symbol.iterator](),
20
+ catch: s
21
+ });
22
+ yield* d.acquireUseRelease(d.succeed(_), (e) => d.gen(function* () {
23
+ for (;;) {
24
+ let t = yield* d.try({
25
+ try: () => e.next(),
26
+ catch: s
27
+ });
28
+ if (t.done) break;
29
+ let r = yield* d.try({
30
+ try: () => o(t.value),
31
+ catch: s
32
+ }), i = C(r);
33
+ yield* h.executeUnprepared(`INSERT INTO main.${w(n)} (sort_key,payload,observation) VALUES (?,?,?)`, [
34
+ i,
35
+ JSON.stringify(r),
36
+ c(t.value.source)
37
+ ], void 0);
38
+ }
39
+ }), (e) => d.sync(() => {
40
+ e.return?.();
41
+ }));
42
+ let v = yield* S(h, n);
43
+ for (let e of u(n, g)) yield* t(h, e);
44
+ let y = yield* r(h, n), b = JSON.stringify({
45
+ version: 1,
46
+ owner: i,
47
+ review: v
48
+ });
49
+ yield* h.executeUnprepared(`INSERT INTO main.${w(g)} (manifest,schema) VALUES (?,?)`, [b, JSON.stringify(y)], void 0);
50
+ for (let e of u(g, `${g}_receipt`)) yield* t(h, e);
51
+ return {
52
+ table: n,
53
+ marker: g,
54
+ manifest: b,
55
+ schema: y,
56
+ receiptSchema: y,
57
+ markerSchema: yield* r(h, g),
58
+ witness: v
59
+ };
60
+ }), h = (t, n, r) => d.gen(function* () {
61
+ let i = yield* p.SqlClient, a = yield* d.serviceOption(i.transactionService);
62
+ return f.isNone(a) ? yield* d.fail(e("Decimal review reopening requires a pinned transaction")) : yield* g(a.value[0], t, n, r);
63
+ }), g = (t, n, i, a) => d.gen(function* () {
64
+ if (!n.startsWith("_voltro_review_") || !i) return yield* d.fail(e("Missing review artifact identity"));
65
+ let o = `${n}_owner`, s = [
66
+ "sqlite",
67
+ "turso",
68
+ "turso-renamed"
69
+ ], c = s.map((e) => _(n, o, !1, e)), l = s.map((e) => _(o, `${o}_receipt`, !0, e)), u = yield* r(t, n), f = yield* r(t, o), p = c.find((e) => JSON.stringify(e) === JSON.stringify(u)), m = l.find((e) => JSON.stringify(e) === JSON.stringify(f)), h = yield* t.executeUnprepared(`SELECT schema FROM main.${w(o)}`, [], void 0), g = h.length === 1 ? c.find((e) => JSON.stringify(e) === h[0].schema) : void 0;
70
+ if (!p || !m || !g) return yield* d.fail(e("Stored decimal review schema is not an owned definition"));
71
+ let v = {
72
+ table: n,
73
+ marker: o,
74
+ schema: p,
75
+ receiptSchema: g,
76
+ markerSchema: m,
77
+ witness: a,
78
+ manifest: JSON.stringify({
79
+ version: 1,
80
+ owner: i,
81
+ review: a
82
+ })
83
+ };
84
+ return yield* y(t, v), v;
85
+ }), _ = (e, t, n, r) => {
86
+ let i = [{
87
+ type: "table",
88
+ name: e,
89
+ sql: `CREATE TABLE ${w(e)} (${n ? "manifest TEXT NOT NULL, schema TEXT NOT NULL" : "sort_key TEXT NOT NULL PRIMARY KEY, payload TEXT NOT NULL, observation TEXT NOT NULL"})`
90
+ }];
91
+ n || i.push({
92
+ type: "index",
93
+ name: `sqlite_autoindex_${e}_1`,
94
+ sql: null
95
+ });
96
+ let a = u(e, t);
97
+ for (let [e, n] of [
98
+ "insert",
99
+ "update",
100
+ "delete"
101
+ ].entries()) {
102
+ let o = a[e];
103
+ r !== "sqlite" && (o = o.replace("BEGIN SELECT RAISE(", "BEGIN SELECT RAISE (")), r === "turso-renamed" && (o = o.replace(" BEGIN SELECT ", " BEGIN\nSELECT ").replace("; END", ";\nEND")), i.push({
104
+ type: "trigger",
105
+ name: `${t}_protect_${n}`,
106
+ sql: o
107
+ });
108
+ }
109
+ return i.sort((e, t) => e.type < t.type ? -1 : e.type > t.type ? 1 : e.name < t.name ? -1 : +(e.name > t.name)), { objects: i };
110
+ }, v = (t) => d.gen(function* () {
111
+ let n = yield* p.SqlClient, r = yield* d.serviceOption(n.transactionService);
112
+ if (f.isNone(r)) return yield* d.fail(e("Decimal review verification requires a pinned transaction"));
113
+ yield* y(r.value[0], t);
114
+ }), y = (t, r) => d.gen(function* () {
115
+ let i = yield* a(t);
116
+ yield* n(t, r.table, r.schema), yield* n(t, r.marker, r.markerSchema);
117
+ let o = yield* t.executeUnprepared(`SELECT manifest,schema FROM main.${w(r.marker)}`, [], void 0);
118
+ if (o.length !== 1 || o[0]?.manifest !== r.manifest || o[0]?.schema !== JSON.stringify(r.receiptSchema)) return yield* d.fail(e("Stored decimal review ownership does not match its receipt"));
119
+ let s = yield* S(t, r.table);
120
+ if (JSON.stringify(s) !== JSON.stringify(r.witness) || (yield* a(t)) !== i) return yield* d.fail(e("Stored decimal review changed after acceptance"));
121
+ }), b = (t, n, r, o) => d.gen(function* () {
122
+ let s = yield* p.SqlClient, l = yield* d.serviceOption(s.transactionService), u = (t) => d.fail(e(t));
123
+ if (f.isNone(l)) return yield* u("Decimal review coverage requires a pinned transaction");
124
+ let m = l.value[0], h = yield* a(m);
125
+ yield* v(t);
126
+ let g = 0;
127
+ if (yield* i(m, n, r, o, (n) => d.gen(function* () {
128
+ for (let r = 0; r < n.length; r += 128) {
129
+ let i = n.slice(r, r + 128), a = i.map(C), o = yield* m.executeUnprepared(`SELECT sort_key,payload,observation FROM main.${w(t.table)} WHERE sort_key IN (${a.map(() => "?").join(",")})`, a, void 0), s = new Map(o.map((e) => [e.sort_key, e]));
130
+ for (let t of i) {
131
+ let n = s.get(C(t));
132
+ if (!n) return yield* u("Decimal review is missing a retained source cell");
133
+ let r = yield* d.try({
134
+ try: () => JSON.parse(n.payload),
135
+ catch: (t) => e("Invalid stored decimal decision", t)
136
+ });
137
+ if (n.observation !== c(t.source) || r.target.precision !== t.target.precision || r.target.scale !== t.target.scale) return yield* u("Decimal review does not match the retained source cell");
138
+ g += 1;
139
+ }
140
+ }
141
+ })), g !== t.witness.cellCount) return yield* u("Decimal review contains cells outside the retained source");
142
+ if ((yield* a(m)) !== h) return yield* u("Decimal review changed during source coverage");
143
+ }), x = (t, n) => d.gen(function* () {
144
+ let r = yield* p.SqlClient, i = yield* d.serviceOption(r.transactionService), o = (t) => d.fail(e(t));
145
+ if (f.isNone(i)) return yield* o("Decimal review row consumption requires a pinned transaction");
146
+ let s = i.value[0], c = yield* a(s);
147
+ yield* v(t);
148
+ let l, u = /* @__PURE__ */ new Map(), m = yield* S(s, t.table, (e) => d.gen(function* () {
149
+ l !== void 0 && l !== e.rowIdentity && (yield* n({
150
+ identity: l,
151
+ values: u
152
+ }), u = /* @__PURE__ */ new Map()), l = e.rowIdentity, u.set(e.column, e.encoded);
153
+ }));
154
+ if (l !== void 0 && (yield* n({
155
+ identity: l,
156
+ values: u
157
+ })), JSON.stringify(m) !== JSON.stringify(t.witness) || (yield* a(s)) !== c) return yield* o("Decimal review changed during row consumption");
158
+ }), S = (t, n, r) => d.gen(function* () {
159
+ let i = (t) => e("Invalid stored decimal decision", t), a = l(), o;
160
+ for (;;) {
161
+ let e = o === void 0 ? "" : " WHERE sort_key > ? COLLATE BINARY", s = yield* t.executeUnprepared(`SELECT sort_key,payload,observation FROM main.${w(n)}${e} ORDER BY sort_key COLLATE BINARY LIMIT 256`, o === void 0 ? [] : [o], void 0);
162
+ if (s.length === 0) break;
163
+ for (let e of s) {
164
+ let t = yield* d.try({
165
+ try: () => {
166
+ let t = JSON.parse(e.payload);
167
+ if (e.payload !== JSON.stringify(t) || e.sort_key !== C(t)) throw TypeError("Noncanonical stored decision");
168
+ let n = JSON.parse(t.sourceIdentity);
169
+ if (e.observation !== JSON.stringify({
170
+ kind: n.kind,
171
+ observed: n.observed,
172
+ shape: n.shape
173
+ })) throw TypeError("Stored observation does not match the reviewed decision");
174
+ return a.append(t), t;
175
+ },
176
+ catch: i
177
+ });
178
+ r && (yield* r(t));
179
+ }
180
+ o = s[s.length - 1].sort_key;
181
+ }
182
+ return yield* d.try({
183
+ try: () => a.finish(),
184
+ catch: i
185
+ });
186
+ }), C = (e) => Buffer.from(s(e), "utf16le").swap16().toString("hex"), w = (e) => "\"" + e.replaceAll("\"", "\"\"") + "\"";
187
+ //#endregion
188
+ export { x as forEachSqliteDecimalReviewRow, m as importSqliteDecimalReview, g as readSqliteDecimalReviewStore, h as reopenSqliteDecimalReview, b as verifySqliteDecimalReviewCoverage, v as verifySqliteDecimalReviewStore };
@@ -0,0 +1,38 @@
1
+ import { normalizeSqliteDecimalCell as e, sqliteDecimalDecisionIdentity as t } from "./sqliteDecimalReview.js";
2
+ import { createHash as n } from "node:crypto";
3
+ //#region src/migrations/sqliteDecimalReviewWitness.ts
4
+ var r = () => {
5
+ let e = n("sha256").update("["), r = 0, i, a = !1, o = !1;
6
+ return {
7
+ append(n) {
8
+ if (a) throw TypeError("Decimal review witness is already finalized");
9
+ if (o) throw TypeError("Decimal review witness contains invalid decisions");
10
+ let s = t(n);
11
+ if (i !== void 0 && s <= i) throw o = !0, TypeError("Decimal decisions require unique canonical order");
12
+ r > 0 && e.update(","), e.update(JSON.stringify(n)), i = s, r++;
13
+ },
14
+ finish() {
15
+ if (a) throw TypeError("Decimal review witness is already finalized");
16
+ if (o) throw TypeError("Decimal review witness contains invalid decisions");
17
+ return a = !0, {
18
+ version: 1,
19
+ cellCount: r,
20
+ digest: e.update("]").digest("hex")
21
+ };
22
+ }
23
+ };
24
+ }, i = (t) => {
25
+ let n = t[Symbol.iterator](), i = r();
26
+ try {
27
+ for (;;) {
28
+ let t = n.next();
29
+ if (t.done) break;
30
+ i.append(e(t.value));
31
+ }
32
+ return i.finish();
33
+ } finally {
34
+ n.return?.();
35
+ }
36
+ };
37
+ //#endregion
38
+ export { r as createSqliteDecimalReviewWitness, i as sqliteDecimalReviewInputWitness };