@voltro/data-transfer 0.86.0 → 0.88.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 (43) hide show
  1. package/CHANGELOG.md +5484 -0
  2. package/THIRD-PARTY-NOTICES.md +2503 -690
  3. package/dist/assetAdmission.js +91 -0
  4. package/dist/assets.js +62 -42
  5. package/dist/blobStorage.js +55 -32
  6. package/dist/bundleArchive.js +249 -105
  7. package/dist/bundleCrypto.js +1 -2
  8. package/dist/bundlePaths.js +3 -0
  9. package/dist/casAssetPhase.js +78 -35
  10. package/dist/compress.js +4 -5
  11. package/dist/consistency.js +1 -2
  12. package/dist/crossDialect.js +1 -2
  13. package/dist/driftClassification.js +1 -2
  14. package/dist/environmentLocal.js +267 -4
  15. package/dist/errors.js +13 -7
  16. package/dist/exporter.js +146 -133
  17. package/dist/filesystemAdmission.js +32 -0
  18. package/dist/importer.js +326 -287
  19. package/dist/index.d.ts +200 -46
  20. package/dist/index.js +28 -26
  21. package/dist/ledger.js +1 -2
  22. package/dist/liveGuard.js +1 -2
  23. package/dist/manifest.js +45 -42
  24. package/dist/masking.js +1 -2
  25. package/dist/maskingPreview.js +1 -2
  26. package/dist/nativeDump.js +134 -86
  27. package/dist/ndjson.js +1 -2
  28. package/dist/physicalRequest.js +9 -0
  29. package/dist/profile.js +1 -2
  30. package/dist/progress.js +1 -2
  31. package/dist/readme.js +1 -2
  32. package/dist/replacePreflight.js +1 -2
  33. package/dist/rollbackCapture.js +1 -2
  34. package/dist/rowFailureReason.js +1 -2
  35. package/dist/schemaDrift.js +1 -2
  36. package/dist/scope.js +1 -2
  37. package/dist/sealedKeys.js +39 -0
  38. package/dist/stagedSwap.js +1 -2
  39. package/dist/storageAssetMetadata.js +46 -0
  40. package/dist/subset.js +1 -2
  41. package/dist/topo.js +1 -2
  42. package/dist/typedCodec.js +1 -2
  43. package/package.json +4 -4
package/dist/importer.js CHANGED
@@ -1,27 +1,29 @@
1
- import { environmentLocalNotice as e, isEnvironmentLocal as t } from "./environmentLocal.js";
2
- import { BundleError as n, CrossDialectError as r, ImportModeError as i, IntegrityError as a, RowsRefusedError as o, SchemaDriftError as s } from "./errors.js";
3
- import { restoreAssetsFromCas as c } from "./casAssetPhase.js";
1
+ import { nullUnreadableSealed as e } from "./sealedKeys.js";
2
+ import { environmentLocalNotice as t, isEnvironmentLocal as n } from "./environmentLocal.js";
3
+ import { BundleError as r, CrossDialectError as i, FieldKeysMissingError as a, ImportModeError as o, IntegrityError as s, RowsRefusedError as c, SchemaDriftError as l } from "./errors.js";
4
+ import { ASSETS_DIR as u, MANIFEST_FILE as d, decodeManifest as f } from "./manifest.js";
5
+ import { prepareAssetsFromCas as p, restoreAssetsFromCas as m } from "./casAssetPhase.js";
4
6
  import { makeDecompressor as ee } from "./compress.js";
5
- import { ASSETS_DIR as l, MANIFEST_FILE as u, decodeManifest as d } from "./manifest.js";
6
- import { reportProgress as f, withTableSpan as p } from "./progress.js";
7
- import { readLedger as te, tableDone as m, writeLedger as h } from "./ledger.js";
7
+ import { reportProgress as h, withTableSpan as te } from "./progress.js";
8
+ import { readLedger as g, tableDone as _, writeLedger as v } from "./ledger.js";
8
9
  import { ndjsonToRows as ne } from "./ndjson.js";
9
- import { outsideReferenceRefusal as g, outsideReferencesInto as _ } from "./replacePreflight.js";
10
- import { checkPortability as v, formatIssue as re } from "./crossDialect.js";
11
- import { rowFailureDiagnosis as ie, tableFailureReason as ae } from "./rowFailureReason.js";
12
- import { canStage as oe, createStagingSql as se, danglingReport as ce, decideStaging as le, dropStagingSql as ue, execStatements as y, findDangling as de, registerStagingClones as fe, runSwap as pe, stagedReferences as me, stagingNameFor as he, stagingUnavailable as ge } from "./stagedSwap.js";
13
- import { captureRollback as _e, rollbackNotice as ve } from "./rollbackCapture.js";
14
- import { checkSchemaDrift as ye } from "./schemaDrift.js";
15
- import { Cause as b, Effect as x, Exit as S, Option as C, Stream as be } from "effect";
16
- import { DATA_TRANSFERS_TABLE as w, REPLACE_IN_PROGRESS_TABLE as T, _voltroDataTransfersTable as xe, derivedRowId as E, ensureTableRegistered as Se, getTable as D, isNotNull as Ce, recordsTable as we, registerTable as Te, suspendWriteRecorders as Ee, suspendWriteRecordersEffect as De, unregisterTable as Oe } from "@voltro/database";
17
- import { createReadStream as ke } from "node:fs";
18
- import { fromNodeReadable as Ae } from "@voltro/plugin-storage";
19
- //#region src/importer.ts
20
- var je = 2e3, Me = 2e3, O = 200, k = /* @__PURE__ */ new Set([
10
+ import { outsideReferenceRefusal as re, outsideReferencesInto as ie } from "./replacePreflight.js";
11
+ import { checkPortability as ae, formatIssue as oe } from "./crossDialect.js";
12
+ import { rowFailureDiagnosis as se, tableFailureReason as ce } from "./rowFailureReason.js";
13
+ import { canStage as le, createStagingSql as ue, danglingReport as de, decideStaging as fe, dropStagingSql as pe, execStatements as y, findDangling as me, registerStagingClones as he, runSwap as ge, stagedReferences as _e, stagingNameFor as ve, stagingUnavailable as ye } from "./stagedSwap.js";
14
+ import { captureRollback as be, rollbackNotice as xe } from "./rollbackCapture.js";
15
+ import { checkSchemaDrift as Se } from "./schemaDrift.js";
16
+ import { Cause as b, Effect as x, Exit as S, Option as C, Stream as Ce } from "effect";
17
+ import { DATA_TRANSFERS_TABLE as w, REPLACE_IN_PROGRESS_TABLE as T, _voltroDataTransfersTable as we, derivedRowId as E, ensureTableRegistered as Te, getTable as D, isNotNull as Ee, recordsTable as De, registerTable as Oe, suspendWriteRecorders as ke, suspendWriteRecordersEffect as Ae, unregisterTable as je } from "@voltro/database";
18
+ import { createReadStream as Me } from "node:fs";
19
+ import { fromNodeReadable as Ne } from "@voltro/plugin-storage";
20
+ // src/importer.ts
21
+ var Pe = 2e3, Fe = 2e3, O = 200, k = /* @__PURE__ */ new Set([
21
22
  "BundleError",
22
23
  "CodecError",
23
24
  "IntegrityError",
24
25
  "CrossDialectError",
26
+ "FieldKeysMissingError",
25
27
  "ImportModeError",
26
28
  "RowsRefusedError",
27
29
  "SchemaDriftError",
@@ -36,30 +38,35 @@ var je = 2e3, Me = 2e3, O = 200, k = /* @__PURE__ */ new Set([
36
38
  if (e) return e;
37
39
  }
38
40
  }
39
- }, Ne = (e) => C.getOrUndefined(b.findErrorOption(e)) ?? Error(b.pretty(e)), Pe = (e) => x.tryPromise({
41
+ }, Ie = (e) => C.getOrUndefined(b.findErrorOption(e)) ?? Error(b.pretty(e)), Le = (e) => x.tryPromise({
40
42
  try: async () => {
41
- let t = await import("node:fs/promises"), n = await import("node:path"), r = await t.readFile(n.join(e, u), "utf8");
42
- return d(r);
43
+ let t = await import("node:fs/promises"), n = await import("node:path"), r = await t.readFile(n.join(e, d), "utf8");
44
+ return f(r);
43
45
  },
44
- catch: (e) => new n({
46
+ catch: (e) => new r({
45
47
  reason: `manifest read/parse failed: ${String(e?.message ?? e)}`,
46
- path: u
48
+ path: d
47
49
  })
48
- }), Fe = (u) => {
49
- let d;
50
+ }), j = (d) => {
51
+ let f;
50
52
  return x.gen(function* () {
51
- let b = yield* x.promise(() => import("node:path")), C = yield* Pe(u.bundleDir);
52
- if (C.formatVersion !== 1) return yield* x.fail(new n({ reason: `unsupported bundle formatVersion ${C.formatVersion} (expected 1)` }));
53
- if (u.tables !== void 0) {
54
- let e = new Set(C.tables.map((e) => e.name)), t = u.tables.filter((t) => !e.has(t));
55
- if (t.length > 0) return yield* x.fail(new n({ reason: `--tables names ${t.length} table(s) this bundle does not carry: ${t.join(", ")}. The bundle carries: ${[...e].sort().join(", ")}.` }));
53
+ let b = yield* x.promise(() => import("node:path")), C = yield* Le(d.bundleDir);
54
+ if (C.formatVersion !== 2) return yield* x.fail(new r({ reason: `unsupported bundle formatVersion ${C.formatVersion} (expected 2)` }));
55
+ let O = d.assets && C.assets.index ? yield* p({
56
+ sink: d.assets,
57
+ assetsDir: b.join(d.bundleDir, u),
58
+ indexPath: b.join(d.bundleDir, C.assets.index)
59
+ }) : void 0;
60
+ if (d.tables !== void 0) {
61
+ let e = new Set(C.tables.map((e) => e.name)), t = d.tables.filter((t) => !e.has(t));
62
+ if (t.length > 0) return yield* x.fail(new r({ reason: `--tables names ${t.length} table(s) this bundle does not carry: ${t.join(", ")}. The bundle carries: ${[...e].sort().join(", ")}.` }));
56
63
  }
57
- let O = u.tables === void 0 ? void 0 : new Set(u.tables), k = O === void 0 ? C : {
64
+ let k = d.tables === void 0 ? void 0 : new Set(d.tables), j = k === void 0 ? C : {
58
65
  ...C,
59
- tables: C.tables.filter((e) => O.has(e.name))
66
+ tables: C.tables.filter((e) => k.has(e.name))
60
67
  };
61
- if (u.targetSnapshot) {
62
- let e = { tables: k.tables.map((e) => ({
68
+ if (d.targetSnapshot) {
69
+ let e = { tables: j.tables.map((e) => ({
63
70
  name: e.name,
64
71
  indexes: [],
65
72
  columns: Object.entries(e.columnTypes).map(([e, t]) => ({
@@ -69,43 +76,43 @@ var je = 2e3, Me = 2e3, O = 200, k = /* @__PURE__ */ new Set([
69
76
  unique: !1,
70
77
  hasDefault: !1
71
78
  }))
72
- })) }, t = ye(k.source.schemaFingerprint, u.targetSnapshot, e);
79
+ })) }, t = Se(j.source.schemaFingerprint, d.targetSnapshot, e);
73
80
  if (t.drifted) {
74
- if (!u.force) return yield* x.fail(new s({
81
+ if (!d.force) return yield* x.fail(new l({
75
82
  bundleFingerprint: t.bundleFingerprint,
76
83
  targetFingerprint: t.targetFingerprint,
77
84
  diff: t.diff
78
85
  }));
79
- u.onWarn?.(`schema drift: the target schema (fingerprint ${t.targetFingerprint.slice(0, 16)}) differs from the bundle's source (${t.bundleFingerprint.slice(0, 16)}); importing anyway (--force). ${t.diff.join("; ")}`);
86
+ d.onWarn?.(`schema drift: the target schema (fingerprint ${t.targetFingerprint.slice(0, 16)}) differs from the bundle's source (${t.bundleFingerprint.slice(0, 16)}); importing anyway (--force). ${t.diff.join("; ")}`);
80
87
  }
81
88
  }
82
- if (u.targetDialect && u.targetDialect !== k.source.dialect) {
83
- let e = v(k.tables, k.source.dialect, u.targetDialect).filter((e) => e.severity === "block");
84
- if (e.length > 0 && !u.allowIncompatible) return yield* x.fail(new r({
85
- sourceDialect: k.source.dialect,
86
- targetDialect: u.targetDialect,
87
- blocking: e.map(re)
89
+ if (d.targetDialect && d.targetDialect !== j.source.dialect) {
90
+ let e = ae(j.tables, j.source.dialect, d.targetDialect).filter((e) => e.severity === "block");
91
+ if (e.length > 0 && !d.allowIncompatible) return yield* x.fail(new i({
92
+ sourceDialect: j.source.dialect,
93
+ targetDialect: d.targetDialect,
94
+ blocking: e.map(oe)
88
95
  }));
89
96
  }
90
- let Fe = u.verify ?? !0, j = u.mode ?? "upsert", M = u.atomic ?? j === "replace", Ie = u.onConflict ?? "skip", N = u.ledgerPath ?? b.join(u.bundleDir, ".import..ledger.json"), P = yield* te(N);
91
- if (j === "replace" && k.scope.kind !== "all") return yield* x.fail(new i({
92
- mode: j,
93
- reason: `replace refuses a partial bundle (scope='${k.scope.kind}') — truncating would delete rows not in the bundle. Use --mode upsert, or re-export with full scope. To leave specific tables out of a FULL export, use \`--exclude a,b\`: it keeps the scope \`all\` and records what it left out.`
97
+ let Re = d.verify ?? !0, M = d.mode ?? "upsert", N = d.atomic ?? M === "replace", ze = d.onConflict ?? "skip", P = d.ledgerPath ?? b.join(d.bundleDir, ".import..ledger.json"), F = yield* g(P);
98
+ if (M === "replace" && j.scope.kind !== "all") return yield* x.fail(new o({
99
+ mode: M,
100
+ reason: `replace refuses a partial bundle (scope='${j.scope.kind}') — truncating would delete rows not in the bundle. Use --mode upsert, or re-export with full scope. To leave specific tables out of a FULL export, use \`--exclude a,b\`: it keeps the scope \`all\` and records what it left out.`
94
101
  }));
95
- if (j === "replace" && (k.scope.exclude?.length ?? 0) > 0) {
96
- let e = k.scope.exclude;
97
- u.onWarn?.(`this bundle was exported with ${e.length} table(s) excluded: ${e.join(", ")}.\n A replace empties and refills the tables the bundle CARRIES, so those keep whatever rows the
102
+ if (M === "replace" && (j.scope.exclude?.length ?? 0) > 0) {
103
+ let e = j.scope.exclude;
104
+ d.onWarn?.(`this bundle was exported with ${e.length} table(s) excluded: ${e.join(", ")}.\n A replace empties and refills the tables the bundle CARRIES, so those keep whatever rows the
98
105
  target already holds. That is not "everything the bundle says" — check it is what you meant.`);
99
106
  }
100
- if (j === "replace") {
101
- let e = k.tables.map((e) => e.name), t = u.store.incomingForeignKeys ? yield* x.tryPromise({
102
- try: () => u.store.incomingForeignKeys(e),
103
- catch: (e) => new n({ reason: `foreign-key pre-flight failed: ${ae(e)}` })
104
- }) : u.targetSnapshot === void 0 ? [] : _(u.targetSnapshot, e), r = [], a = /* @__PURE__ */ new Map();
107
+ if (M === "replace") {
108
+ let e = j.tables.map((e) => e.name), t = d.store.incomingForeignKeys ? yield* x.tryPromise({
109
+ try: () => d.store.incomingForeignKeys(e),
110
+ catch: (e) => new r({ reason: `foreign-key pre-flight failed: ${ce(e)}` })
111
+ }) : d.targetSnapshot === void 0 ? [] : ie(d.targetSnapshot, e), n = [], i = /* @__PURE__ */ new Map();
105
112
  for (let e of t) {
106
- if (!a.has(e.from)) {
113
+ if (!i.has(e.from)) {
107
114
  let t = yield* x.tryPromise({
108
- try: () => u.store.query({
115
+ try: () => d.store.query({
109
116
  table: e.from,
110
117
  predicate: void 0,
111
118
  order: [],
@@ -113,68 +120,98 @@ var je = 2e3, Me = 2e3, O = 200, k = /* @__PURE__ */ new Set([
113
120
  skip: void 0,
114
121
  projection: []
115
122
  }),
116
- catch: () => new n({ reason: `unreadable: ${e.from}` })
123
+ catch: () => new r({ reason: `unreadable: ${e.from}` })
117
124
  }).pipe(x.map((e) => e.length), x.orElseSucceed(() => 0));
118
- a.set(e.from, t);
125
+ i.set(e.from, t);
119
126
  }
120
- let t = a.get(e.from) ?? 0;
121
- t > 0 && r.push({
127
+ let t = i.get(e.from) ?? 0;
128
+ t > 0 && n.push({
122
129
  ...e,
123
130
  rowCount: t
124
131
  });
125
132
  }
126
- if (r.length > 0) return yield* x.fail(new i({
127
- mode: j,
128
- reason: g(r)
133
+ if (n.length > 0) return yield* x.fail(new o({
134
+ mode: M,
135
+ reason: re(n)
129
136
  }));
130
137
  }
131
- if (u.dryRun === !0) return u.traceId !== void 0 && (yield* x.promise(() => u.store.update(w, u.traceId, {
138
+ let I = {
139
+ nulled: /* @__PURE__ */ new Map(),
140
+ unreadable: /* @__PURE__ */ new Map()
141
+ };
142
+ if (d.fieldKeys !== void 0 && j.fieldKeys !== void 0) {
143
+ let e = new Set(d.fieldKeys.held), t = j.fieldKeys.keyIds.filter((t) => !e.has(t));
144
+ if (t.length > 0 && d.fieldKeys.nullSealed !== !0) return yield* x.fail(new a({
145
+ missing: t,
146
+ held: [...e]
147
+ }));
148
+ t.length > 0 && d.onWarn?.(`field encryption: values under ${t.join(", ")} are written as NULL where they are a whole value — this environment does not hold those keys`);
149
+ }
150
+ let Be = (t, n) => {
151
+ if (d.fieldKeys?.nullSealed !== !0) return n;
152
+ let r = {
153
+ nulled: I.nulled.get(t) ?? I.nulled.set(t, /* @__PURE__ */ new Map()).get(t),
154
+ unreadable: I.unreadable.get(t) ?? I.unreadable.set(t, /* @__PURE__ */ new Map()).get(t)
155
+ };
156
+ return e(t, n, d.fieldKeys, r);
157
+ }, Ve = () => {
158
+ let e = (e) => [...e].flatMap(([e, t]) => [...t].filter(([, e]) => e > 0).map(([t, n]) => ({
159
+ table: e,
160
+ column: t,
161
+ count: n
162
+ })));
163
+ return {
164
+ nulled: e(I.nulled),
165
+ unreadable: e(I.unreadable)
166
+ };
167
+ };
168
+ if (d.dryRun === !0) return d.traceId !== void 0 && (yield* x.promise(() => d.store.update(w, d.traceId, {
132
169
  finishedAt: /* @__PURE__ */ new Date(),
133
170
  tablesWritten: 0,
134
171
  rowsWritten: 0,
135
172
  failure: null
136
173
  }).then(() => void 0, () => void 0))), {
137
- manifest: k,
174
+ manifest: j,
138
175
  tablesWritten: 0,
139
176
  rowsWritten: 0,
140
177
  tablesSkipped: 0,
141
178
  rowsSkipped: 0,
142
179
  fullyResumed: !1
143
180
  };
144
- let Le = /* @__PURE__ */ new Map();
145
- for (let e of u.targetSnapshot?.tables ?? []) {
181
+ let He = /* @__PURE__ */ new Map();
182
+ for (let e of d.targetSnapshot?.tables ?? []) {
146
183
  let t = e.columns.filter((e) => e.generatedAs !== void 0).map((e) => e.name);
147
- t.length > 0 && Le.set(e.name, t);
184
+ t.length > 0 && He.set(e.name, t);
148
185
  }
149
- let Re = (e, t) => {
150
- let n = Le.get(e);
186
+ let Ue = (e, t) => {
187
+ let n = He.get(e);
151
188
  if (n === void 0) return t;
152
189
  let r;
153
190
  for (let e of n) e in t && (r ??= { ...t }, delete r[e]);
154
191
  return r ?? t;
155
- }, F = (e, t, n, r = !1) => {
156
- let i = H ? he(t.name) : t.name, a = t.primaryKey, o = Be(t.name, Re(t.name, n), t.columnTypes);
157
- return j === "append" ? Ie === "fail" ? e.insert(i, o) : e.insertIgnore(i, o, { conflictColumns: [a] }) : j === "replace" ? r ? e.upsert(i, o, { conflictColumns: [a] }) : e.insert(i, o) : e.upsert(i, o, { conflictColumns: [a] });
158
- }, ze = u.targetDialect !== void 0 && u.targetDialect !== "memory", Be = (e, t, n) => {
159
- if (!ze || n === void 0 || D(e) !== void 0) return t;
192
+ }, L = (e, t, n, r = !1) => {
193
+ let i = W ? ve(t.name) : t.name, a = t.primaryKey, o = Ge(t.name, Ue(t.name, n), t.columnTypes);
194
+ return M === "append" ? ze === "fail" ? e.insert(i, o) : e.insertIgnore(i, o, { conflictColumns: [a] }) : M === "replace" ? r ? e.upsert(i, o, { conflictColumns: [a] }) : e.insert(i, o) : e.upsert(i, o, { conflictColumns: [a] });
195
+ }, We = d.targetDialect !== void 0 && d.targetDialect !== "memory", Ge = (e, t, n) => {
196
+ if (!We || n === void 0 || D(e) !== void 0) return t;
160
197
  let r = null;
161
198
  for (let [e, i] of Object.entries(n)) {
162
199
  let n = t[e];
163
200
  i === "json" && n != null && (r === null && (r = { ...t }), r[e] = JSON.stringify(n));
164
201
  }
165
202
  return r ?? t;
166
- }, I = (e, t) => e.savepoint ? e.savepoint(t) : t(), L = 0, Ve = (e, t, n) => {
167
- n.unclassified && (L++, !(L > 3) && u.onWarn?.(`row refused with no driver detail — table '${e.name}', row '${String(t.id ?? "?")}'. The full rendering follows so the LAYER that refused is on the record; it is logged, never returned. ${n.raw}` + (L === 3 ? " (further unclassified refusals are counted, not logged)" : "")));
168
- }, R = (e, t, n = !0) => x.tryPromise({
203
+ }, R = (e, t) => e.savepoint ? e.savepoint(t) : t(), z = 0, Ke = (e, t, n) => {
204
+ n.unclassified && (z++, !(z > 3) && d.onWarn?.(`row refused with no driver detail — table '${e.name}', row '${String(t.id ?? "?")}'. The full rendering follows so the LAYER that refused is on the record; it is logged, never returned. ${n.raw}` + (z === 3 ? " (further unclassified refusals are counted, not logged)" : "")));
205
+ }, B = (e, t, n = !0) => x.tryPromise({
169
206
  try: e,
170
- catch: (e) => ie(e)
171
- }).pipe(x.map(() => !0), x.catch((e) => x.sync(() => (n && (t.reason = e.reason, Ve(t.entry, t.row, e)), !1)))), He = (e) => {
207
+ catch: (e) => se(e)
208
+ }).pipe(x.map(() => !0), x.catch((e) => x.sync(() => (n && (t.reason = e.reason, Ke(t.entry, t.row, e)), !1)))), qe = (e) => {
172
209
  let t = Object.entries(e.entry.columnTypes).filter(([t, n]) => n === "reference" && e.row[t] !== null && e.row[t] !== void 0).map(([e]) => e);
173
210
  if (t.length !== 0) return {
174
211
  ...e.row,
175
212
  ...Object.fromEntries(t.map((e) => [e, null]))
176
213
  };
177
- }, Ue = (e) => {
214
+ }, Je = (e) => {
178
215
  let t = new Set(e.map((e) => String(e.row[e.entry.primaryKey]))), n = (e) => Object.entries(e.entry.columnTypes).some(([n, r]) => {
179
216
  if (r !== "reference") return !1;
180
217
  let i = e.row[n];
@@ -192,7 +229,7 @@ var je = 2e3, Me = 2e3, O = 200, k = /* @__PURE__ */ new Set([
192
229
  };
193
230
  t.refused++, e.derived || t.primary++, a.set(e.table, t);
194
231
  }
195
- return new o({
232
+ return new c({
196
233
  rows: i.slice(0, 20),
197
234
  primaryCount: r.filter((e) => !e.derived).length,
198
235
  totalCount: e.length,
@@ -202,104 +239,104 @@ var je = 2e3, Me = 2e3, O = 200, k = /* @__PURE__ */ new Set([
202
239
  primary: t.primary
203
240
  })).sort((e, t) => t.refused - e.refused || e.table.localeCompare(t.table)).slice(0, 100)
204
241
  });
205
- }, We = (e, t) => x.gen(function* () {
242
+ }, Ye = (e, t) => x.gen(function* () {
206
243
  let n = t, r = [], i = !0;
207
244
  for (; n.length > 0 && i;) {
208
245
  i = !1;
209
246
  let t = [];
210
- for (let r of n) (yield* R(() => I(e, () => F(e, r.entry, r.row, !0)), r)) ? i = !0 : t.push(r);
247
+ for (let r of n) (yield* B(() => R(e, () => L(e, r.entry, r.row, !0)), r)) ? i = !0 : t.push(r);
211
248
  if (!i && t.length > 0) for (let n = t.length - 1; n >= 0; n--) {
212
- let a = t[n], o = He(a);
213
- o !== void 0 && (yield* R(() => I(e, () => F(e, a.entry, o, !0)), a, !1)) && (r.push(a), t.splice(n, 1), i = !0);
249
+ let a = t[n], o = qe(a);
250
+ o !== void 0 && (yield* B(() => R(e, () => L(e, a.entry, o, !0)), a, !1)) && (r.push(a), t.splice(n, 1), i = !0);
214
251
  }
215
252
  n = t;
216
253
  }
217
- for (let t of r) (yield* R(() => I(e, () => e.upsert(t.entry.name, Be(t.entry.name, t.row, t.entry.columnTypes), { conflictColumns: [t.entry.primaryKey] })), t)) || (n = [...n, t]);
218
- if (n.length > 0) return yield* x.fail(Ue(n));
219
- }), z = (() => {
220
- let e = u.targetDialect;
254
+ for (let t of r) (yield* B(() => R(e, () => e.upsert(t.entry.name, Ge(t.entry.name, t.row, t.entry.columnTypes), { conflictColumns: [t.entry.primaryKey] })), t)) || (n = [...n, t]);
255
+ if (n.length > 0) return yield* x.fail(Je(n));
256
+ }), V = (() => {
257
+ let e = d.targetDialect;
221
258
  return e === "postgres" || e === "mysql" || e === "mariadb" || e === "sqlite" || e === "mssql" ? e : void 0;
222
- })(), B = le({
223
- mode: j,
224
- ...u.targetDialect === void 0 ? {} : { targetDialect: u.targetDialect },
225
- ...u.targetSnapshot === void 0 ? {} : { targetSnapshot: u.targetSnapshot },
226
- bundleTables: k.tables.map((e) => e.name),
227
- isSkipped: t,
228
- canRunSql: oe(u.store)
229
- }), V = B.tables, Ge = k.tables.filter((e) => !t(e.name) && we(e.name)).map((e) => e.name), H = B.active, Ke = !1, U = 0, W = 0, qe, G, Je = 0, K = 0, q = (r, i) => x.gen(function* () {
230
- if (j === "replace" && !H && !(i && P.truncated)) {
231
- u.recordInterruption === !0 && (yield* x.tryPromise({
232
- try: () => r.insert(T, {
233
- id: E("repl", Ye),
234
- startedAt: J,
235
- tables: String(k.tables.length),
236
- capture: Y?.dir ?? null,
237
- via: u.via ?? "direct"
259
+ })(), H = fe({
260
+ mode: M,
261
+ ...d.targetDialect === void 0 ? {} : { targetDialect: d.targetDialect },
262
+ ...d.targetSnapshot === void 0 ? {} : { targetSnapshot: d.targetSnapshot },
263
+ bundleTables: j.tables.map((e) => e.name),
264
+ isSkipped: n,
265
+ canRunSql: le(d.store)
266
+ }), U = H.tables, Xe = j.tables.filter((e) => !n(e.name) && De(e.name)).map((e) => e.name), W = H.active, Ze = !1, G = 0, K = 0, Qe, q, $e = 0, J = 0, Y = (e, i) => x.gen(function* () {
267
+ if (M === "replace" && !W && !(i && F.truncated)) {
268
+ d.recordInterruption === !0 && (yield* x.tryPromise({
269
+ try: () => e.insert(T, {
270
+ id: E("repl", et),
271
+ startedAt: X,
272
+ tables: String(j.tables.length),
273
+ capture: Z?.dir ?? null,
274
+ via: d.via ?? "direct"
238
275
  }),
239
- catch: (e) => new n({ reason: `could not record that this replace started: ${String(e?.message ?? e)}\n The marker is what makes an interrupted run visible instead of silent, so the run does
276
+ catch: (e) => new r({ reason: `could not record that this replace started: ${String(e?.message ?? e)}\n The marker is what makes an interrupted run visible instead of silent, so the run does
240
277
  not proceed without it.` })
241
278
  }));
242
- let e = [...k.tables].reverse().map((e) => e.name).filter((e) => !t(e)), a = !i, o = r.emptyTables ? () => r.emptyTables(e) : a ? async () => {
243
- for (let e of [...k.tables].reverse()) await r.deleteMany(e.name, { where: Ce(e.primaryKey) });
244
- } : () => r.transactional(async (e) => {
245
- for (let t of [...k.tables].reverse()) await e.deleteMany(t.name, { where: Ce(t.primaryKey) });
279
+ let t = [...j.tables].reverse().map((e) => e.name).filter((e) => !n(e)), a = !i, o = e.emptyTables ? () => e.emptyTables(t) : a ? async () => {
280
+ for (let t of [...j.tables].reverse()) await e.deleteMany(t.name, { where: Ee(t.primaryKey) });
281
+ } : () => e.transactional(async (e) => {
282
+ for (let t of [...j.tables].reverse()) await e.deleteMany(t.name, { where: Ee(t.primaryKey) });
246
283
  });
247
284
  yield* x.tryPromise({
248
285
  try: o,
249
- catch: (e) => new n({ reason: `emptying the target for --mode replace failed (nothing was deleted): ${ae(e)}` })
250
- }), i && (P.truncated = !0, yield* h(N, P));
286
+ catch: (e) => new r({ reason: `emptying the target for --mode replace failed (nothing was deleted): ${ce(e)}` })
287
+ }), i && (F.truncated = !0, yield* v(P, F));
251
288
  }
252
- let o = [], s = [], c = [], l = [], d = k.tables.length;
253
- for (let e = 0; e < k.tables.length; e++) {
254
- let n = k.tables[e];
255
- if (t(n.name)) {
256
- l.push(n.name);
289
+ let a = [], o = [], c = [], l = [], u = j.tables.length;
290
+ for (let t = 0; t < j.tables.length; t++) {
291
+ let r = j.tables[t];
292
+ if (n(r.name)) {
293
+ l.push(r.name);
257
294
  continue;
258
295
  }
259
- if (i && n.name in P.tables) {
260
- c.push(n.name), K++, Je += P.tables[n.name].rowCount, f(u.onProgress, {
296
+ if (i && r.name in F.tables) {
297
+ c.push(r.name), J++, $e += F.tables[r.name].rowCount, h(d.onProgress, {
261
298
  phase: "import",
262
- table: n.name,
263
- index: e,
264
- tableCount: d,
299
+ table: r.name,
300
+ index: t,
301
+ tableCount: u,
265
302
  event: "done",
266
- rowsDone: P.tables[n.name].rowCount,
267
- total: n.rowCount
303
+ rowsDone: F.tables[r.name].rowCount,
304
+ total: r.rowCount
268
305
  });
269
306
  continue;
270
307
  }
271
- let te = b.join(u.bundleDir, n.file);
272
- f(u.onProgress, {
308
+ let f = b.join(d.bundleDir, r.file);
309
+ h(d.onProgress, {
273
310
  phase: "import",
274
- table: n.name,
275
- index: e,
276
- tableCount: d,
311
+ table: r.name,
312
+ index: t,
313
+ tableCount: u,
277
314
  event: "start",
278
315
  rowsDone: 0,
279
- total: n.rowCount
316
+ total: r.rowCount
280
317
  });
281
- let m = o.length, g = x.gen(function* () {
282
- let { createHash: e } = yield* x.promise(() => import("node:crypto")), t = e("sha256"), i = 0, a = Ae("bundle", () => ke(te).pipe(ee(k.compression))).pipe(be.tap((e) => x.sync(() => t.update(e)))), s = async (e) => {
283
- let t = {
284
- entry: n,
285
- row: e,
318
+ let p = a.length, m = x.gen(function* () {
319
+ let { createHash: t } = yield* x.promise(() => import("node:crypto")), n = t("sha256"), i = 0, o = Ne("bundle", () => Me(f).pipe(ee(j.compression))).pipe(Ce.tap((e) => x.sync(() => n.update(e)))), s = async (t) => {
320
+ let n = {
321
+ entry: r,
322
+ row: t,
286
323
  reason: ""
287
324
  };
288
325
  try {
289
- await I(r, () => F(r, n, e));
290
- } catch (r) {
291
- let i = ie(r);
292
- t.reason = i.reason, Ve(n, e, i), o.push(t);
326
+ await R(e, () => L(e, r, t));
327
+ } catch (e) {
328
+ let i = se(e);
329
+ n.reason = i.reason, Ke(r, t, i), a.push(n);
293
330
  }
294
331
  }, c = yield* x.promise(async () => {
295
- let e = u.copyLoader;
296
- if (!e || e.dialect !== "postgres") return !1;
297
- if (M) return Ke || (Ke = !0, u.onWarn?.("bulk COPY is off for this run: it needs its own connection and this import runs in ONE transaction (the default for --mode replace, so a failure mid-load cannot leave the target emptied and unfilled). Pass --no-atomic to trade that guarantee back for COPY.")), !1;
298
- if (j === "replace") return !0;
299
- if (j !== "upsert") return !1;
332
+ let t = d.copyLoader;
333
+ if (!t || t.dialect !== "postgres") return !1;
334
+ if (N) return Ze || (Ze = !0, d.onWarn?.("bulk COPY is off for this run: it needs its own connection and this import runs in ONE transaction (the default for --mode replace, so a failure mid-load cannot leave the target emptied and unfilled). Pass --no-atomic to trade that guarantee back for COPY.")), !1;
335
+ if (M === "replace") return !0;
336
+ if (M !== "upsert") return !1;
300
337
  try {
301
- return (await r.query({
302
- table: n.name,
338
+ return (await e.query({
339
+ table: r.name,
303
340
  predicate: void 0,
304
341
  order: [],
305
342
  take: 1,
@@ -309,228 +346,230 @@ var je = 2e3, Me = 2e3, O = 200, k = /* @__PURE__ */ new Set([
309
346
  } catch {
310
347
  return !1;
311
348
  }
312
- }), l = Object.keys(n.columnTypes), d = Math.max(1, u.copyBatchSize ?? 5e3), f = [], p = async () => {
313
- if (f.length === 0) return;
314
- let e = f;
315
- f = [];
349
+ }), l = Object.keys(r.columnTypes), u = Math.max(1, d.copyBatchSize ?? 5e3), p = [], m = async () => {
350
+ if (p.length === 0) return;
351
+ let e = p;
352
+ p = [];
316
353
  try {
317
- await u.copyLoader.copyInto({
318
- table: n.name,
354
+ await d.copyLoader.copyInto({
355
+ table: r.name,
319
356
  columns: l,
320
- columnTypes: n.columnTypes,
357
+ columnTypes: r.columnTypes,
321
358
  rows: e
322
359
  });
323
360
  } catch (t) {
324
- c = !1, u.onWarn?.(`bulk COPY into ${n.name} failed (${String(t?.message ?? t)}); falling back to per-row writes for this table`);
361
+ c = !1, d.onWarn?.(`bulk COPY into ${r.name} failed (${String(t?.message ?? t)}); falling back to per-row writes for this table`);
325
362
  for (let t of e) await s(t);
326
363
  }
327
- }, m = Math.max(1, u.savepointBatchSize ?? 200), h = typeof r.savepoint == "function", g = [], _ = async () => {
364
+ }, h = Math.max(1, d.savepointBatchSize ?? 200), te = typeof e.savepoint == "function", g = [], _ = async () => {
328
365
  if (g.length === 0) return;
329
- let e = g;
366
+ let t = g;
330
367
  g = [];
331
368
  try {
332
- await r.savepoint(async () => {
333
- for (let t of e) await F(r, n, t);
369
+ await e.savepoint(async () => {
370
+ for (let n of t) await L(e, r, n);
334
371
  });
335
372
  } catch {
336
- for (let t of e) await s(t);
373
+ for (let e of t) await s(e);
337
374
  }
338
375
  };
339
- return yield* be.runForEach(ne(a, n.name, n.columnTypes), (e) => x.promise(async () => {
340
- i++, G?.(), c ? (f.push(e), f.length >= d && await p()) : h ? (g.push(e), g.length >= m && await _()) : await s(e);
341
- })), yield* x.promise(_), yield* x.promise(p), {
376
+ return yield* Ce.runForEach(ne(o, r.name, r.columnTypes), (e) => x.promise(async () => {
377
+ let t = Be(r.name, e);
378
+ i++, q?.(), c ? (p.push(t), p.length >= u && await m()) : te ? (g.push(t), g.length >= h && await _()) : await s(t);
379
+ })), yield* x.promise(_), yield* x.promise(m), {
342
380
  rowCount: i,
343
- checksum: t.digest("hex")
381
+ checksum: n.digest("hex")
344
382
  };
345
- }), { rowCount: _, checksum: v } = yield* p("import", n.name, e, d, (e) => e.rowCount, g);
346
- if (Fe) {
347
- if (v !== n.checksum) return yield* x.fail(new a({
348
- what: `table ${n.name} checksum`,
349
- expected: n.checksum,
350
- actual: v
383
+ }), { rowCount: g, checksum: _ } = yield* te("import", r.name, t, u, (e) => e.rowCount, m);
384
+ if (Re) {
385
+ if (_ !== r.checksum) return yield* x.fail(new s({
386
+ what: `table ${r.name} checksum`,
387
+ expected: r.checksum,
388
+ actual: _
351
389
  }));
352
- if (_ !== n.rowCount) return yield* x.fail(new a({
353
- what: `table ${n.name} rowCount`,
354
- expected: String(n.rowCount),
355
- actual: String(_)
390
+ if (g !== r.rowCount) return yield* x.fail(new s({
391
+ what: `table ${r.name} rowCount`,
392
+ expected: String(r.rowCount),
393
+ actual: String(g)
356
394
  }));
357
395
  }
358
- f(u.onProgress, {
396
+ h(d.onProgress, {
359
397
  phase: "import",
360
- table: n.name,
361
- index: e,
362
- tableCount: d,
398
+ table: r.name,
399
+ index: t,
400
+ tableCount: u,
363
401
  event: "done",
364
- rowsDone: _,
365
- total: n.rowCount
366
- }), W++, U += _, qe?.(), G?.(), i && (o.length > m ? s.push({
367
- name: n.name,
368
- rowCount: _
369
- }) : (P.tables[n.name] = {
370
- rowCount: _,
371
- checksum: n.checksum
372
- }, yield* h(N, P)));
402
+ rowsDone: g,
403
+ total: r.rowCount
404
+ }), K++, G += g, Qe?.(), q?.(), i && (a.length > p ? o.push({
405
+ name: r.name,
406
+ rowCount: g
407
+ }) : (F.tables[r.name] = {
408
+ rowCount: g,
409
+ checksum: r.checksum
410
+ }, yield* v(P, F)));
373
411
  }
374
- if (o.length > 0 && (yield* We(r, o)), j === "replace" && (yield* x.promise(() => r.deleteMany(T, { where: {
412
+ if (a.length > 0 && (yield* Ye(e, a)), M === "replace" && (yield* x.promise(() => e.deleteMany(T, { where: {
375
413
  column: "startedAt",
376
414
  op: "lte",
377
- value: J
378
- } }).then(() => void 0, () => void 0))), i && s.length > 0) {
379
- for (let e of s) {
380
- let t = k.tables.find((t) => t.name === e.name);
381
- P.tables[e.name] = {
415
+ value: X
416
+ } }).then(() => void 0, () => void 0))), i && o.length > 0) {
417
+ for (let e of o) {
418
+ let t = j.tables.find((t) => t.name === e.name);
419
+ F.tables[e.name] = {
382
420
  rowCount: e.rowCount,
383
421
  checksum: t.checksum
384
422
  };
385
423
  }
386
- yield* h(N, P);
424
+ yield* v(P, F);
387
425
  }
388
426
  {
389
- let t = e(l, "skipped");
390
- t !== void 0 && u.onWarn?.(t);
427
+ let e = t(l, "skipped");
428
+ e !== void 0 && d.onWarn?.(e);
391
429
  }
392
430
  if (c.length > 0) {
393
- let e = c.length === k.tables.length;
394
- u.onWarn?.(`resume: ${c.length} of ${k.tables.length} table(s) were already applied by an earlier run of THIS bundle directory, so this run wrote NO rows for them${e ? " — that is every table in the bundle, so nothing was written at all" : ""}. Tables: ${c.join(", ")}. Delete ${N} to force a full re-import.`);
431
+ let e = c.length === j.tables.length;
432
+ d.onWarn?.(`resume: ${c.length} of ${j.tables.length} table(s) were already applied by an earlier run of THIS bundle directory, so this run wrote NO rows for them${e ? " — that is every table in the bundle, so nothing was written at all" : ""}. Tables: ${c.join(", ")}. Delete ${P} to force a full re-import.`);
395
433
  }
396
- }), Ye = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`, J = /* @__PURE__ */ new Date(), Y = yield* _e({
397
- store: u.store,
398
- mode: j,
399
- dir: u.rollbackDir,
400
- snapshot: u.targetSnapshot,
401
- dialect: u.targetDialect,
402
- tables: k.tables.map((e) => e.name).filter((e) => !t(e)),
403
- onWarn: u.onWarn
434
+ }), et = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`, X = /* @__PURE__ */ new Date(), Z = yield* be({
435
+ store: d.store,
436
+ mode: M,
437
+ dir: d.rollbackDir,
438
+ snapshot: d.targetSnapshot,
439
+ dialect: d.targetDialect,
440
+ tables: j.tables.map((e) => e.name).filter((e) => !n(e)),
441
+ onWarn: d.onWarn
404
442
  });
405
- Y !== void 0 && (u.onRollbackCaptured !== void 0 && (yield* x.tryPromise({
406
- try: () => u.onRollbackCaptured(Y),
407
- catch: (e) => new n({
443
+ Z !== void 0 && (d.onRollbackCaptured !== void 0 && (yield* x.tryPromise({
444
+ try: () => d.onRollbackCaptured(Z),
445
+ catch: (e) => new r({
408
446
  reason: `the rollback capture could not be stored durably, so the import did not start and the target is untouched: ${String(e?.message ?? e)}\n The capture only helps if it outlives this process — that is the failure it exists for.`,
409
- path: Y.dir
447
+ path: Z.dir
410
448
  })
411
- })), u.onWarn?.(ve(Y)));
412
- let Xe = (e) => j === "replace" ? Ee(e) : e(), X = (e) => j === "replace" ? De(e) : e, Z = u.traceId ?? E("dimp", `${Date.now()}-${k.source.schemaFingerprint ?? ""}`), Q = u.traceId !== void 0, $ = (u.targetSnapshot?.tables.some((e) => e.name === w) ?? !1) || D(w) !== void 0;
413
- $ && Se(xe), $ && u.traceId === void 0 && (yield* x.promise(() => u.store.insert(w, {
414
- id: Z,
415
- mode: j,
416
- via: u.via ?? "direct",
449
+ })), d.onWarn?.(xe(Z)));
450
+ let tt = (e) => M === "replace" ? ke(e) : e(), nt = (e) => M === "replace" ? Ae(e) : e, Q = d.traceId ?? E("dimp", `${Date.now()}-${j.source.schemaFingerprint ?? ""}`), rt = d.traceId !== void 0, $ = (d.targetSnapshot?.tables.some((e) => e.name === w) ?? !1) || D(w) !== void 0;
451
+ $ && Te(we), $ && d.traceId === void 0 && (yield* x.promise(() => d.store.insert(w, {
452
+ id: Q,
453
+ mode: M,
454
+ via: d.via ?? "direct",
417
455
  direction: "import",
418
- bundle: u.bundleDir,
419
- sourceFingerprint: k.source.schemaFingerprint ?? null,
456
+ bundle: d.bundleDir,
457
+ sourceFingerprint: j.source.schemaFingerprint ?? null,
420
458
  tablesWritten: 0,
421
459
  rowsWritten: 0,
422
- staged: j === "replace" ? H : null
460
+ staged: M === "replace" ? W : null
423
461
  }).then(() => {
424
- Q = !0;
462
+ rt = !0;
425
463
  }, (e) => {
426
- u.onWarn?.(`the import trace could not be written (${String(e?.message ?? e)}).\n The import continues — this is a record of what happened, not a safety check. Run
464
+ d.onWarn?.(`the import trace could not be written (${String(e?.message ?? e)}).\n The import continues — this is a record of what happened, not a safety check. Run
427
465
  \`voltro db apply\` so the next one is recorded.`);
428
- }))), u.traceId !== void 0 && $ && (yield* x.promise(() => u.store.update(w, Z, {
429
- staged: j === "replace" ? H : null,
430
- sourceFingerprint: k.source.schemaFingerprint ?? null
466
+ }))), d.traceId !== void 0 && $ && (yield* x.promise(() => d.store.update(w, Q, {
467
+ staged: M === "replace" ? W : null,
468
+ sourceFingerprint: j.source.schemaFingerprint ?? null
431
469
  }).then(() => void 0, () => void 0)));
432
- let Ze = 0, Qe = !1;
433
- qe = () => {
434
- if (!Q || Qe) return;
470
+ let it = 0, at = !1;
471
+ Qe = () => {
472
+ if (!rt || at) return;
435
473
  let e = Date.now();
436
- e - Ze < je || (Ze = e, u.store.update(w, Z, {
437
- tablesWritten: W,
438
- rowsWritten: U
474
+ e - it < Pe || (it = e, d.store.update(w, Q, {
475
+ tablesWritten: K,
476
+ rowsWritten: G
439
477
  }).then(() => void 0, () => {
440
- Qe = !0;
478
+ at = !0;
441
479
  }));
442
480
  };
443
- let $e = (e) => Q ? u.store.update(w, Z, {
481
+ let ot = (e) => rt ? d.store.update(w, Q, {
444
482
  finishedAt: e === null ? /* @__PURE__ */ new Date() : null,
445
- tablesWritten: W,
446
- rowsWritten: U,
483
+ tablesWritten: K,
484
+ rowsWritten: G,
447
485
  failure: e
448
486
  }).then(() => void 0, () => void 0) : Promise.resolve();
449
- if (d = (e) => $e(e), j === "replace" && !H && B.blocker !== void 0 && u.onWarn?.(ge(B.blocker)), j === "replace" && Ge.length > 0 && u.onWarn?.(`write recorders are SUSPENDED for this replace (${Ge.length} table(s) have one).\n A replace sets a state rather than changing rows, so a per-row history entry would describe
487
+ if (f = (e) => ot(e), M === "replace" && !W && H.blocker !== void 0 && d.onWarn?.(ye(H.blocker)), M === "replace" && Xe.length > 0 && d.onWarn?.(`write recorders are SUSPENDED for this replace (${Xe.length} table(s) have one).\n A replace sets a state rather than changing rows, so a per-row history entry would describe
450
488
  something that did not happen — and this path already writes through the raw store, without
451
- tenant scoping or \`audit()\` stamping, for the same reason.`), H) {
452
- u.onWarn?.(`staging ${V.length} table(s) before the swap — the target keeps its rows until the load stands.\n The destructive step is one server-side transaction at the end, not the whole load.`);
453
- let e = u.store, t = V.map((e) => e.name), r = E("repl", `staging-${Ye}`), i = !1;
454
- if (u.recordInterruption === !0) {
455
- yield* x.promise(() => u.store.insert(T, {
456
- id: r,
457
- startedAt: J,
489
+ tenant scoping or \`audit()\` stamping, for the same reason.`), W) {
490
+ d.onWarn?.(`staging ${U.length} table(s) before the swap — the target keeps its rows until the load stands.\n The destructive step is one server-side transaction at the end, not the whole load.`);
491
+ let e = d.store, t = U.map((e) => e.name), n = E("repl", `staging-${et}`), i = !1;
492
+ if (d.recordInterruption === !0) {
493
+ yield* x.promise(() => d.store.insert(T, {
494
+ id: n,
495
+ startedAt: X,
458
496
  kind: "staging",
459
- tables: String(V.length),
460
- capture: Y?.dir ?? null,
461
- via: u.via ?? "direct",
462
- staging: t.map(he).join(","),
497
+ tables: String(U.length),
498
+ capture: Z?.dir ?? null,
499
+ via: d.via ?? "direct",
500
+ staging: t.map(ve).join(","),
463
501
  heartbeatAt: /* @__PURE__ */ new Date(),
464
- resumable: !M
502
+ resumable: !N
465
503
  }).then(() => {
466
504
  i = !0;
467
505
  }, (e) => {
468
- u.onWarn?.(`the staging tables could not be recorded (${String(e?.message ?? e)}).\n The import continues and the target is unaffected — but if this run dies before the swap,
506
+ d.onWarn?.(`the staging tables could not be recorded (${String(e?.message ?? e)}).\n The import continues and the target is unaffected — but if this run dies before the swap,
469
507
  nothing at boot will mention the scratch tables it leaves. \`voltro data clear-staging\` finds
470
508
  them by introspection.`);
471
509
  }));
472
510
  let e = Date.now();
473
- G = () => {
511
+ q = () => {
474
512
  if (!i) return;
475
513
  let t = Date.now();
476
- t - e < Me || (e = t, u.store.update(T, r, { heartbeatAt: /* @__PURE__ */ new Date() }).then(() => void 0, () => void 0));
514
+ t - e < Fe || (e = t, d.store.update(T, n, { heartbeatAt: /* @__PURE__ */ new Date() }).then(() => void 0, () => void 0));
477
515
  };
478
516
  }
479
- let a = () => i ? u.store.delete(T, r).then(() => void 0, () => void 0) : Promise.resolve(), o = fe(t, {
517
+ let a = () => i ? d.store.delete(T, n).then(() => void 0, () => void 0) : Promise.resolve(), o = he(t, {
480
518
  getTable: (e) => D(e),
481
519
  registerTable: (e) => {
482
- Te(e);
520
+ Oe(e);
483
521
  },
484
- unregisterTable: Oe
522
+ unregisterTable: je
485
523
  }), s = !1;
486
524
  try {
487
- let r = M ? t : t.filter((e) => !m(P, e));
525
+ let n = N ? t : t.filter((e) => !_(F, e));
488
526
  yield* x.tryPromise({
489
527
  try: async () => {
490
- await y(e, r.map((e) => ue(e, z))), await y(e, r.map((e) => se(e, z)));
528
+ await y(e, n.map((e) => pe(e, V))), await y(e, n.map((e) => ue(e, V)));
491
529
  },
492
- catch: (e) => new n({ reason: `could not prepare the staging tables, so the import did not start and the target is untouched: ${String(e?.message ?? e)}` })
493
- }), yield* X(q(u.store, !M)), !M && P.truncated === !0 ? s = !0 : yield* x.tryPromise({
494
- try: () => pe(e, V, z).then(() => {
530
+ catch: (e) => new r({ reason: `could not prepare the staging tables, so the import did not start and the target is untouched: ${String(e?.message ?? e)}` })
531
+ }), yield* nt(Y(d.store, !N)), !N && F.truncated === !0 ? s = !0 : yield* x.tryPromise({
532
+ try: () => ge(e, U, V).then(() => {
495
533
  s = !0;
496
534
  }),
497
- catch: (e) => new n({ reason: String(e?.message ?? e) })
498
- }).pipe(x.catch((r) => x.gen(function* () {
499
- let i = yield* x.promise(() => de(e, me(u.targetSnapshot, t), z).then((e) => e, () => [])), a = ce(i);
500
- return yield* x.fail(new n({ reason: a ?? `the swap failed and the target is UNCHANGED: ${r.reason}` }));
501
- }))), !M && s && P.truncated !== !0 && (P.truncated = !0, yield* h(N, P));
535
+ catch: (e) => new r({ reason: String(e?.message ?? e) })
536
+ }).pipe(x.catch((n) => x.gen(function* () {
537
+ let i = yield* x.promise(() => me(e, _e(d.targetSnapshot, t), V).then((e) => e, () => [])), a = de(i);
538
+ return yield* x.fail(new r({ reason: a ?? `the swap failed and the target is UNCHANGED: ${n.reason}` }));
539
+ }))), !N && s && F.truncated !== !0 && (F.truncated = !0, yield* v(P, F));
502
540
  } finally {
503
- o.undo(), s || M ? (G = void 0, yield* x.promise(() => y(e, t.map((e) => ue(e, z))).then(() => void 0, () => void 0)), yield* x.promise(a)) : u.onWarn?.("the staged rows are KEPT so a re-run can continue from them rather than reload.\n If you are not going to re-run this bundle, drop them: voltro data clear-staging --yes");
541
+ o.undo(), s || N ? (q = void 0, yield* x.promise(() => y(e, t.map((e) => pe(e, V))).then(() => void 0, () => void 0)), yield* x.promise(a)) : d.onWarn?.("the staged rows are KEPT so a re-run can continue from them rather than reload.\n If you are not going to re-run this bundle, drop them: voltro data clear-staging --yes");
504
542
  }
505
- } else M ? yield* x.tryPromise({
506
- try: () => u.store.transactional(async (e) => {
507
- let t = await Xe(() => x.runPromiseExit(q(e, !1)));
508
- if (S.isFailure(t)) throw Ne(t.cause);
543
+ } else N ? yield* x.tryPromise({
544
+ try: () => d.store.transactional(async (e) => {
545
+ let t = await tt(() => x.runPromiseExit(Y(e, !1)));
546
+ if (S.isFailure(t)) throw Ie(t.cause);
509
547
  }),
510
- catch: (e) => A(e) ?? new n({ reason: `atomic import failed (rolled back): ${String(e?.message ?? e)}` })
511
- }) : yield* X(q(u.store, !0));
512
- if (u.assets && k.assets.index && !u.assetsAlreadyRestored) {
513
- let e = u.assets, t = b.join(u.bundleDir, l), n = b.join(u.bundleDir, k.assets.index ?? "assets/index.ndjson");
514
- yield* c({
548
+ catch: (e) => A(e) ?? new r({ reason: `atomic import failed (rolled back): ${String(e?.message ?? e)}` })
549
+ }) : yield* nt(Y(d.store, !0));
550
+ if (d.assets && j.assets.index) {
551
+ let e = d.assets, t = b.join(d.bundleDir, u), n = b.join(d.bundleDir, j.assets.index ?? "assets/index.ndjson");
552
+ yield* m({
515
553
  sink: e,
516
554
  assetsDir: t,
517
555
  indexPath: n,
556
+ ...O === void 0 ? {} : { prepared: O },
518
557
  progress: {
519
- done: (e) => e in P.assets,
520
- mark: (e) => (P.assets[e] = !0, h(N, P))
558
+ done: (e) => e in F.assets,
559
+ mark: (e) => (F.assets[e] = !0, v(P, F))
521
560
  }
522
561
  });
523
562
  }
524
- return yield* x.promise(() => $e(null)), {
525
- manifest: k,
526
- tablesWritten: W,
527
- rowsWritten: U,
528
- tablesSkipped: K,
529
- rowsSkipped: Je,
530
- fullyResumed: W === 0 && K > 0,
531
- ...Y === void 0 ? {} : { rollback: Y }
563
+ return yield* x.promise(() => ot(null)), {
564
+ manifest: j,
565
+ tablesWritten: K,
566
+ rowsWritten: G,
567
+ tablesSkipped: J,
568
+ rowsSkipped: $e,
569
+ fullyResumed: K === 0 && J > 0,
570
+ ...Z === void 0 ? {} : { rollback: Z },
571
+ ...d.fieldKeys?.nullSealed === !0 ? { sealed: Ve() } : {}
532
572
  };
533
- }).pipe(x.tapError((e) => x.promise(() => d?.(e._tag === "RowsRefusedError" ? e.message : e?.reason ?? e?._tag ?? "the import did not finish") ?? Promise.resolve())));
573
+ }).pipe(x.scoped, x.tapError((e) => x.promise(() => f?.(e._tag === "RowsRefusedError" ? e.message : e?.reason ?? e?._tag ?? "the import did not finish") ?? Promise.resolve())));
534
574
  };
535
- //#endregion
536
- export { O as SAVEPOINT_BATCH_SIZE, A as asImportError, Fe as runImport };
575
+ export { O as SAVEPOINT_BATCH_SIZE, A as asImportError, j as runImport };