@bjornpagen/bumbledb-log 1.2.1 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -63
- package/dist/admin.d.ts +1 -1
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +13 -0
- package/dist/bin.js.map +1 -0
- package/dist/codes.d.ts +1 -1
- package/dist/codes.d.ts.map +1 -1
- package/dist/codes.js +1 -8
- package/dist/codes.js.map +1 -1
- package/dist/errors.d.ts +7 -21
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +11 -45
- package/dist/errors.js.map +1 -1
- package/dist/identity.d.ts +0 -8
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +0 -5
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/machine.d.ts +4 -28
- package/dist/machine.d.ts.map +1 -1
- package/dist/machine.js +183 -246
- package/dist/machine.js.map +1 -1
- package/dist/native.d.ts +59 -154
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js.map +1 -1
- package/dist/options.d.ts +2 -11
- package/dist/options.d.ts.map +1 -1
- package/dist/outcome.d.ts +1 -85
- package/dist/outcome.d.ts.map +1 -1
- package/dist/schema-files.d.ts +16 -0
- package/dist/schema-files.d.ts.map +1 -0
- package/dist/schema-files.js +77 -0
- package/dist/schema-files.js.map +1 -0
- package/dist/schema.d.ts +6 -9
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +8 -8
- package/dist/schema.js.map +1 -1
- package/dist/transition.d.ts +75 -0
- package/dist/transition.d.ts.map +1 -0
- package/dist/transition.js +3 -0
- package/dist/transition.js.map +1 -0
- package/pack-provenance.json +4 -4
- package/package.json +4 -8
- package/dist/migration-ops.d.ts +0 -20
- package/dist/migration-ops.d.ts.map +0 -1
- package/dist/migration-ops.js +0 -7
- package/dist/migration-ops.js.map +0 -1
- package/dist/migrations/bin.d.ts.map +0 -1
- package/dist/migrations/bin.js +0 -30
- package/dist/migrations/bin.js.map +0 -1
- package/dist/migrations/canonical.d.ts +0 -40
- package/dist/migrations/canonical.d.ts.map +0 -1
- package/dist/migrations/canonical.js +0 -156
- package/dist/migrations/canonical.js.map +0 -1
- package/dist/migrations/cli.d.ts +0 -29
- package/dist/migrations/cli.d.ts.map +0 -1
- package/dist/migrations/cli.js +0 -124
- package/dist/migrations/cli.js.map +0 -1
- package/dist/migrations/codec.d.ts +0 -74
- package/dist/migrations/codec.d.ts.map +0 -1
- package/dist/migrations/codec.js +0 -2
- package/dist/migrations/codec.js.map +0 -1
- package/dist/migrations/decode.d.ts +0 -16
- package/dist/migrations/decode.d.ts.map +0 -1
- package/dist/migrations/decode.js +0 -302
- package/dist/migrations/decode.js.map +0 -1
- package/dist/migrations/diff.d.ts +0 -39
- package/dist/migrations/diff.d.ts.map +0 -1
- package/dist/migrations/diff.js +0 -385
- package/dist/migrations/diff.js.map +0 -1
- package/dist/migrations/expr.d.ts +0 -22
- package/dist/migrations/expr.d.ts.map +0 -1
- package/dist/migrations/expr.js +0 -219
- package/dist/migrations/expr.js.map +0 -1
- package/dist/migrations/fail.d.ts +0 -22
- package/dist/migrations/fail.d.ts.map +0 -1
- package/dist/migrations/fail.js +0 -52
- package/dist/migrations/fail.js.map +0 -1
- package/dist/migrations/fsops.d.ts +0 -37
- package/dist/migrations/fsops.d.ts.map +0 -1
- package/dist/migrations/fsops.js +0 -222
- package/dist/migrations/fsops.js.map +0 -1
- package/dist/migrations/generate.d.ts +0 -11
- package/dist/migrations/generate.d.ts.map +0 -1
- package/dist/migrations/generate.js +0 -455
- package/dist/migrations/generate.js.map +0 -1
- package/dist/migrations/index.d.ts +0 -23
- package/dist/migrations/index.d.ts.map +0 -1
- package/dist/migrations/index.js +0 -6
- package/dist/migrations/index.js.map +0 -1
- package/dist/migrations/intent.d.ts +0 -86
- package/dist/migrations/intent.d.ts.map +0 -1
- package/dist/migrations/intent.js +0 -97
- package/dist/migrations/intent.js.map +0 -1
- package/dist/migrations/lock.d.ts +0 -27
- package/dist/migrations/lock.d.ts.map +0 -1
- package/dist/migrations/lock.js +0 -14
- package/dist/migrations/lock.js.map +0 -1
- package/dist/migrations/native.d.ts +0 -26
- package/dist/migrations/native.d.ts.map +0 -1
- package/dist/migrations/native.js +0 -124
- package/dist/migrations/native.js.map +0 -1
- package/dist/migrations/repo.d.ts +0 -38
- package/dist/migrations/repo.d.ts.map +0 -1
- package/dist/migrations/repo.js +0 -191
- package/dist/migrations/repo.js.map +0 -1
- package/dist/migrations/theory.d.ts +0 -21
- package/dist/migrations/theory.d.ts.map +0 -1
- package/dist/migrations/theory.js +0 -107
- package/dist/migrations/theory.js.map +0 -1
- package/dist/migrations/types.d.ts +0 -242
- package/dist/migrations/types.d.ts.map +0 -1
- package/dist/migrations/types.js +0 -2
- package/dist/migrations/types.js.map +0 -1
- package/dist/migrations/workflow.d.ts +0 -11
- package/dist/migrations/workflow.d.ts.map +0 -1
- package/dist/migrations/workflow.js +0 -14
- package/dist/migrations/workflow.js.map +0 -1
- /package/dist/{migrations/bin.d.ts → bin.d.ts} +0 -0
package/dist/migrations/diff.js
DELETED
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The pure schema diff: previous canonical snapshot versus current canonical
|
|
3
|
-
* snapshot, plus declared typed intent. Structural inference happens ONLY
|
|
4
|
-
* where one safe interpretation exists (unchanged relations/fields carried by
|
|
5
|
-
* identity projections, whole-relation additions, reorders); ambiguous
|
|
6
|
-
* rename-versus-drop, data destruction, required backfills and type changes
|
|
7
|
-
* REQUIRE typed intent or the diff returns the complete finite requirement
|
|
8
|
-
* list — generation never guesses from matching shapes and never fabricates
|
|
9
|
-
* a zero/null.
|
|
10
|
-
*
|
|
11
|
-
* Output is inert plan data with TOTAL ordinary-relation coverage:
|
|
12
|
-
* every ordinary source relation becomes exactly one `map-relation` or
|
|
13
|
-
* `drop-relation`; every ordinary target relation exactly one
|
|
14
|
-
* `map-relation`/`empty-relation`. A source field no expression references is
|
|
15
|
-
* data loss and appears in `destructive` exactly once. Closed relations are
|
|
16
|
-
* sealed schema axioms — unnameable by data operations and exempt from
|
|
17
|
-
* coverage; their evolution is the schema change itself.
|
|
18
|
-
*/
|
|
19
|
-
import { fieldExpression, planExpressionOf } from "#migrations/expr.ts";
|
|
20
|
-
function requirement(code, relation, field, detail) {
|
|
21
|
-
return { code, relation, field, detail };
|
|
22
|
-
}
|
|
23
|
-
function labelToken(text) {
|
|
24
|
-
let out = "";
|
|
25
|
-
for (const ch of text.toLowerCase()) {
|
|
26
|
-
out += (ch >= "a" && ch <= "z") || (ch >= "0" && ch <= "9") ? ch : "-";
|
|
27
|
-
}
|
|
28
|
-
return out.replaceAll(/-+/g, "-").replaceAll(/^-|-$/g, "");
|
|
29
|
-
}
|
|
30
|
-
export function diffSchemas(prev, next, entries) {
|
|
31
|
-
const requirements = [];
|
|
32
|
-
const intents = entries.map((entry) => ({ entry, consumed: false }));
|
|
33
|
-
const prevByName = new Map(prev.relations.map((relation) => [relation.name, relation]));
|
|
34
|
-
const nextByName = new Map(next.relations.map((relation) => [relation.name, relation]));
|
|
35
|
-
// --- Relation renames -----------------------------------------------------
|
|
36
|
-
const relationRename = new Map(); // prev name -> next name
|
|
37
|
-
const renameTargets = new Set();
|
|
38
|
-
for (const intent of intents) {
|
|
39
|
-
if (intent.entry.kind !== "rename-relation") {
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
const { from, to } = intent.entry;
|
|
43
|
-
intent.consumed = true;
|
|
44
|
-
if (relationRename.has(from) || renameTargets.has(to)) {
|
|
45
|
-
requirements.push(requirement("conflicting-intent", from, null, `two renameRelation intents touch ${from} or ${to}`));
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
if (!prevByName.has(from)) {
|
|
49
|
-
requirements.push(requirement("stale-intent", from, null, `renameRelation: no previous relation named ${from}`));
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
if (!nextByName.has(to)) {
|
|
53
|
-
requirements.push(requirement("stale-intent", to, null, `renameRelation: no current relation named ${to}`));
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
if (nextByName.has(from)) {
|
|
57
|
-
requirements.push(requirement("conflicting-intent", from, null, `renameRelation: ${from} still exists in the current schema`));
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
if (prevByName.has(to)) {
|
|
61
|
-
requirements.push(requirement("conflicting-intent", to, null, `renameRelation: ${to} already existed in the previous schema`));
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
relationRename.set(from, to);
|
|
65
|
-
renameTargets.add(to);
|
|
66
|
-
}
|
|
67
|
-
// --- Field renames, keyed by the current (next) relation name -------------
|
|
68
|
-
const fieldRename = new Map();
|
|
69
|
-
for (const intent of intents) {
|
|
70
|
-
if (intent.entry.kind !== "rename-field") {
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
intent.consumed = true;
|
|
74
|
-
const { relation, from, to } = intent.entry;
|
|
75
|
-
let table = fieldRename.get(relation);
|
|
76
|
-
if (table === undefined) {
|
|
77
|
-
table = new Map();
|
|
78
|
-
fieldRename.set(relation, table);
|
|
79
|
-
}
|
|
80
|
-
if (table.has(from) || [...table.values()].includes(to)) {
|
|
81
|
-
requirements.push(requirement("conflicting-intent", relation, from, `two renameField intents touch ${relation}.${from} or .${to}`));
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
table.set(from, to);
|
|
85
|
-
}
|
|
86
|
-
// --- Pair relations ---------------------------------------------------------
|
|
87
|
-
const pairs = [];
|
|
88
|
-
const pairedNext = new Set();
|
|
89
|
-
const droppedSource = [];
|
|
90
|
-
for (const source of prev.relations) {
|
|
91
|
-
const targetName = relationRename.get(source.name) ?? source.name;
|
|
92
|
-
const target = nextByName.get(targetName);
|
|
93
|
-
if (target !== undefined) {
|
|
94
|
-
if (source.closed !== target.closed) {
|
|
95
|
-
requirements.push(requirement("unsupported", target.name, null, `changing ${target.name} between closed and ordinary is not a supported transform; drop the old relation and declare the new one with explicit intent`));
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
pairs.push({ source, target });
|
|
99
|
-
pairedNext.add(target.name);
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
if (source.closed) {
|
|
103
|
-
// A removed closed relation is pure schema change: its extension is
|
|
104
|
-
// declared data, unnameable by plan operations, and nothing user-owned
|
|
105
|
-
// is discarded by data machinery.
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
const drop = intents.find((intent) => !intent.consumed && intent.entry.kind === "drop-relation" && intent.entry.relation === source.name);
|
|
109
|
-
if (drop !== undefined) {
|
|
110
|
-
drop.consumed = true;
|
|
111
|
-
droppedSource.push(source.name);
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
const candidates = next.relations
|
|
115
|
-
.filter((candidate) => !candidate.closed && !prevByName.has(candidate.name) && !renameTargets.has(candidate.name))
|
|
116
|
-
.map((candidate) => candidate.name);
|
|
117
|
-
const hint = candidates.length > 0
|
|
118
|
-
? ` If this is a rename, declare renameRelation("${source.name}", ${candidates.join(" | ")}) instead.`
|
|
119
|
-
: "";
|
|
120
|
-
requirements.push(requirement("destructive", source.name, null, `relation ${source.name} was removed; discarding its data requires dropRelation("${source.name}").${hint}`));
|
|
121
|
-
}
|
|
122
|
-
// --- Walk ordinary pairs ------------------------------------------------------
|
|
123
|
-
const mapOperations = [];
|
|
124
|
-
const destructive = [];
|
|
125
|
-
for (const { source, target } of pairs) {
|
|
126
|
-
if (source.closed) {
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
const renames = fieldRename.get(target.name) ?? new Map();
|
|
130
|
-
const targetFields = new Map(target.fields.map((field) => [field.name, field]));
|
|
131
|
-
const sourceFields = new Map(source.fields.map((field) => [field.name, field]));
|
|
132
|
-
for (const [from, to] of renames) {
|
|
133
|
-
// Staleness preempts conflict: a rename whose `from` no longer exists
|
|
134
|
-
// (typically an intent already consumed by a recorded migration — after
|
|
135
|
-
// it applied, `to` exists on BOTH sides) matches no change between
|
|
136
|
-
// these schemas. It must classify stale with its remediation, never as
|
|
137
|
-
// a contradiction with a live intent.
|
|
138
|
-
if (!sourceFields.has(from) || !targetFields.has(to)) {
|
|
139
|
-
if (!sourceFields.has(from)) {
|
|
140
|
-
requirements.push(requirement("stale-intent", target.name, from, `renameField: no previous field ${from}; an intent already recorded by a generated migration must be removed`));
|
|
141
|
-
}
|
|
142
|
-
if (!targetFields.has(to)) {
|
|
143
|
-
requirements.push(requirement("stale-intent", target.name, to, `renameField: no current field ${to}; an intent already recorded by a generated migration must be removed`));
|
|
144
|
-
}
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
if (targetFields.has(from)) {
|
|
148
|
-
requirements.push(requirement("conflicting-intent", target.name, from, `renameField: ${from} still exists in the current schema`));
|
|
149
|
-
}
|
|
150
|
-
if (sourceFields.has(to)) {
|
|
151
|
-
requirements.push(requirement("conflicting-intent", target.name, to, `renameField: ${to} already existed in the previous schema`));
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
// Pair fields: renamed or same-named survivors.
|
|
155
|
-
const sourceOfTarget = new Map(); // target field -> source field
|
|
156
|
-
const acknowledged = new Set(); // source fields with explicit replace/drop intent
|
|
157
|
-
for (const field of source.fields) {
|
|
158
|
-
const survivor = renames.get(field.name) ?? field.name;
|
|
159
|
-
if (targetFields.has(survivor)) {
|
|
160
|
-
sourceOfTarget.set(survivor, field.name);
|
|
161
|
-
continue;
|
|
162
|
-
}
|
|
163
|
-
const drop = intents.find((intent) => !intent.consumed &&
|
|
164
|
-
intent.entry.kind === "drop-field" &&
|
|
165
|
-
intent.entry.relation === target.name &&
|
|
166
|
-
intent.entry.field === field.name);
|
|
167
|
-
if (drop !== undefined) {
|
|
168
|
-
drop.consumed = true;
|
|
169
|
-
acknowledged.add(field.name);
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
const added = target.fields
|
|
173
|
-
.filter((candidate) => !sourceFields.has(candidate.name))
|
|
174
|
-
.map((candidate) => candidate.name);
|
|
175
|
-
const hint = added.length > 0
|
|
176
|
-
? ` If this is a rename, declare renameField(${target.name}, "${field.name}", "${added.join('" | "')}").`
|
|
177
|
-
: "";
|
|
178
|
-
requirements.push(requirement("destructive", target.name, field.name, `field ${target.name}.${field.name} was removed; discarding its values requires dropField(${target.name}, "${field.name}").${hint}`));
|
|
179
|
-
}
|
|
180
|
-
// Build the complete target projection in target declaration order.
|
|
181
|
-
const projections = [];
|
|
182
|
-
const referenced = new Set();
|
|
183
|
-
let identity = source.name === target.name &&
|
|
184
|
-
source.fields.length === target.fields.length &&
|
|
185
|
-
source.fields.every((field, ordinal) => target.fields[ordinal]?.name === field.name);
|
|
186
|
-
for (const field of target.fields) {
|
|
187
|
-
const sourceName = sourceOfTarget.get(field.name);
|
|
188
|
-
const convert = intents.find((intent) => !intent.consumed &&
|
|
189
|
-
intent.entry.kind === "convert" &&
|
|
190
|
-
intent.entry.relation === target.name &&
|
|
191
|
-
intent.entry.field === field.name);
|
|
192
|
-
const fill = intents.find((intent) => !intent.consumed &&
|
|
193
|
-
intent.entry.kind === "backfill" &&
|
|
194
|
-
intent.entry.relation === target.name &&
|
|
195
|
-
intent.entry.field === field.name);
|
|
196
|
-
if (sourceName !== undefined) {
|
|
197
|
-
const sourceField = sourceFields.get(sourceName);
|
|
198
|
-
// Staleness preempts conflict: an intent targeting a field that is
|
|
199
|
-
// UNCHANGED between these schemas (same name, same type, no rename in
|
|
200
|
-
// play) matches no change — the signature of an intent already
|
|
201
|
-
// consumed by a recorded migration. `conflicting-intent` is reserved
|
|
202
|
-
// for intents contradicting a live change on the field.
|
|
203
|
-
const fieldUnchanged = sourceName === field.name && sourceField !== undefined && sourceField.type === field.type;
|
|
204
|
-
// Backfill is only for new fields. On an unchanged existing field it
|
|
205
|
-
// is stale (already recorded, or the wrong constructor). Convert on
|
|
206
|
-
// the same field is an explicit meaning change — record it even when
|
|
207
|
-
// the schema types match (L18 units+1), never drop as identity.
|
|
208
|
-
if (fieldUnchanged && fill !== undefined) {
|
|
209
|
-
fill.consumed = true;
|
|
210
|
-
requirements.push(requirement("stale-intent", target.name, field.name, `backfill targets ${target.name}.${field.name}, which is unchanged between these schemas; an intent already recorded by a generated migration must be removed`));
|
|
211
|
-
referenced.add(sourceName);
|
|
212
|
-
projections.push({ target: field.name, expression: fieldExpression(sourceName) });
|
|
213
|
-
continue;
|
|
214
|
-
}
|
|
215
|
-
if (fill !== undefined) {
|
|
216
|
-
fill.consumed = true;
|
|
217
|
-
requirements.push(requirement("conflicting-intent", target.name, field.name, `backfill targets the existing field ${target.name}.${field.name}; use convert for existing fields`));
|
|
218
|
-
continue;
|
|
219
|
-
}
|
|
220
|
-
if (convert !== undefined) {
|
|
221
|
-
convert.consumed = true;
|
|
222
|
-
if (convert.entry.kind !== "convert") {
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
const serialized = planExpressionOf(convert.entry.expression);
|
|
226
|
-
if (!serialized.ok) {
|
|
227
|
-
requirements.push(requirement("unsupported", target.name, field.name, serialized.detail));
|
|
228
|
-
continue;
|
|
229
|
-
}
|
|
230
|
-
const unknown = serialized.fields.filter((name) => !sourceFields.has(name));
|
|
231
|
-
if (unknown.length > 0) {
|
|
232
|
-
requirements.push(requirement("unsupported", target.name, field.name, `convert references unknown source fields ${unknown.join(", ")} of ${source.name}`));
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
for (const name of serialized.fields) {
|
|
236
|
-
referenced.add(name);
|
|
237
|
-
}
|
|
238
|
-
acknowledged.add(sourceName);
|
|
239
|
-
projections.push({ target: field.name, expression: serialized.expression });
|
|
240
|
-
identity = false;
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
if (sourceField !== undefined && sourceField.type !== field.type) {
|
|
244
|
-
requirements.push(requirement("type-change", target.name, field.name, `field ${target.name}.${field.name} changed type from ${sourceField.type} to ${field.type}; declare convert(${target.name}, "${field.name}", <checked cast expression>)`));
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
referenced.add(sourceName);
|
|
248
|
-
projections.push({ target: field.name, expression: fieldExpression(sourceName) });
|
|
249
|
-
if (sourceName !== field.name) {
|
|
250
|
-
identity = false;
|
|
251
|
-
}
|
|
252
|
-
continue;
|
|
253
|
-
}
|
|
254
|
-
// A new field on an existing relation.
|
|
255
|
-
if (convert !== undefined) {
|
|
256
|
-
convert.consumed = true;
|
|
257
|
-
requirements.push(requirement("conflicting-intent", target.name, field.name, `convert targets the new field ${target.name}.${field.name}; use backfill for new fields`));
|
|
258
|
-
continue;
|
|
259
|
-
}
|
|
260
|
-
if (fill === undefined) {
|
|
261
|
-
requirements.push(requirement("missing-backfill", target.name, field.name, `new required field ${target.name}.${field.name} needs backfill(${target.name}, "${field.name}", <typed expression over the old row>); no zero/null is fabricated`));
|
|
262
|
-
continue;
|
|
263
|
-
}
|
|
264
|
-
fill.consumed = true;
|
|
265
|
-
if (fill.entry.kind !== "backfill") {
|
|
266
|
-
continue;
|
|
267
|
-
}
|
|
268
|
-
const serialized = planExpressionOf(fill.entry.expression);
|
|
269
|
-
if (!serialized.ok) {
|
|
270
|
-
requirements.push(requirement("unsupported", target.name, field.name, serialized.detail));
|
|
271
|
-
continue;
|
|
272
|
-
}
|
|
273
|
-
const unknown = serialized.fields.filter((name) => !sourceFields.has(name));
|
|
274
|
-
if (unknown.length > 0) {
|
|
275
|
-
requirements.push(requirement("unsupported", target.name, field.name, `backfill references unknown source fields ${unknown.join(", ")} of ${source.name}`));
|
|
276
|
-
continue;
|
|
277
|
-
}
|
|
278
|
-
for (const name of serialized.fields) {
|
|
279
|
-
referenced.add(name);
|
|
280
|
-
}
|
|
281
|
-
projections.push({ target: field.name, expression: serialized.expression });
|
|
282
|
-
identity = false;
|
|
283
|
-
}
|
|
284
|
-
// Losses: source fields no expression references. Each needs the
|
|
285
|
-
// explicit intent gathered above; the plan records each exactly once.
|
|
286
|
-
for (const field of source.fields) {
|
|
287
|
-
if (referenced.has(field.name)) {
|
|
288
|
-
continue;
|
|
289
|
-
}
|
|
290
|
-
if (!acknowledged.has(field.name)) {
|
|
291
|
-
// Reachable only when the pairing above already refused; keep the
|
|
292
|
-
// requirement complete rather than emitting an unacknowledged loss.
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
|
-
destructive.push({ relation: source.name, field: field.name });
|
|
296
|
-
}
|
|
297
|
-
mapOperations.push({
|
|
298
|
-
op: { kind: "map-relation", source: source.name, target: target.name, fields: projections },
|
|
299
|
-
identity
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
// --- New relations ------------------------------------------------------------
|
|
303
|
-
const emptyOperations = [];
|
|
304
|
-
for (const relation of next.relations) {
|
|
305
|
-
if (relation.closed || pairedNext.has(relation.name)) {
|
|
306
|
-
continue;
|
|
307
|
-
}
|
|
308
|
-
emptyOperations.push({ kind: "empty-relation", target: relation.name });
|
|
309
|
-
}
|
|
310
|
-
// --- Drops ----------------------------------------------------------------------
|
|
311
|
-
const dropOperations = [];
|
|
312
|
-
for (const name of droppedSource) {
|
|
313
|
-
dropOperations.push({ kind: "drop-relation", source: name });
|
|
314
|
-
destructive.push({ relation: name });
|
|
315
|
-
}
|
|
316
|
-
// --- Seeds -----------------------------------------------------------------------
|
|
317
|
-
const seedRelations = [];
|
|
318
|
-
for (const intent of intents) {
|
|
319
|
-
if (intent.entry.kind !== "seed") {
|
|
320
|
-
continue;
|
|
321
|
-
}
|
|
322
|
-
intent.consumed = true;
|
|
323
|
-
const target = nextByName.get(intent.entry.relation);
|
|
324
|
-
if (target === undefined) {
|
|
325
|
-
requirements.push(requirement("stale-intent", intent.entry.relation, null, `seed: no current relation named ${intent.entry.relation}`));
|
|
326
|
-
continue;
|
|
327
|
-
}
|
|
328
|
-
if (target.closed) {
|
|
329
|
-
requirements.push(requirement("unsupported", intent.entry.relation, null, `seed targets the closed relation ${intent.entry.relation}; closed extensions are declared in the schema`));
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
if (!seedRelations.includes(target.name)) {
|
|
333
|
-
seedRelations.push(target.name);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
const nextOrder = next.relations.map((relation) => relation.name);
|
|
337
|
-
seedRelations.sort((a, b) => nextOrder.indexOf(a) - nextOrder.indexOf(b));
|
|
338
|
-
// --- Leftover (stale) intent --------------------------------------------------------
|
|
339
|
-
for (const intent of intents) {
|
|
340
|
-
if (intent.consumed) {
|
|
341
|
-
continue;
|
|
342
|
-
}
|
|
343
|
-
const entry = intent.entry;
|
|
344
|
-
const subject = "relation" in entry ? entry.relation : entry.from;
|
|
345
|
-
const field = "field" in entry ? entry.field : null;
|
|
346
|
-
requirements.push(requirement("stale-intent", subject, field, `${entry.kind} intent matches no change between these schemas`));
|
|
347
|
-
}
|
|
348
|
-
// --- Deterministic label tokens --------------------------------------------------------
|
|
349
|
-
const labelTokens = [];
|
|
350
|
-
if (prev.relations.length === 0) {
|
|
351
|
-
labelTokens.push("initialize");
|
|
352
|
-
}
|
|
353
|
-
else {
|
|
354
|
-
for (const op of emptyOperations) {
|
|
355
|
-
if (op.kind === "empty-relation") {
|
|
356
|
-
labelTokens.push(`create-${labelToken(op.target)}`);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
for (const entry of mapOperations) {
|
|
360
|
-
if (!entry.identity && entry.op.kind === "map-relation") {
|
|
361
|
-
labelTokens.push(labelToken(entry.op.target));
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
for (const name of seedRelations) {
|
|
365
|
-
labelTokens.push(`seed-${labelToken(name)}`);
|
|
366
|
-
}
|
|
367
|
-
for (const op of dropOperations) {
|
|
368
|
-
if (op.kind === "drop-relation") {
|
|
369
|
-
labelTokens.push(`drop-${labelToken(op.source)}`);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
if (labelTokens.length === 0) {
|
|
373
|
-
labelTokens.push("laws");
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
return {
|
|
377
|
-
operations: [...mapOperations.map((entry) => entry.op), ...emptyOperations, ...dropOperations],
|
|
378
|
-
destructive,
|
|
379
|
-
seedRelations,
|
|
380
|
-
labelTokens,
|
|
381
|
-
requirements,
|
|
382
|
-
identity: mapOperations.every((entry) => entry.identity) && emptyOperations.length === 0 && dropOperations.length === 0
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
|
-
//# sourceMappingURL=diff.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/migrations/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { PlanExpression, PlanValue } from "./types.js";
|
|
2
|
-
export type ExprResult = {
|
|
3
|
-
readonly ok: true;
|
|
4
|
-
readonly expression: PlanExpression;
|
|
5
|
-
readonly fields: readonly string[];
|
|
6
|
-
} | {
|
|
7
|
-
readonly ok: false;
|
|
8
|
-
readonly detail: string;
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* Bounded structural check of one literal payload into the canonical
|
|
12
|
-
* one-arm value spelling.
|
|
13
|
-
*/
|
|
14
|
-
export declare function planValueOf(value: unknown): PlanValue | string;
|
|
15
|
-
/**
|
|
16
|
-
* Serialize one core scalar expression into canonical plan data, collecting
|
|
17
|
-
* the referenced source field names for loss accounting.
|
|
18
|
-
*/
|
|
19
|
-
export declare function planExpressionOf(expression: unknown): ExprResult;
|
|
20
|
-
/** The identity projection every carried field lowers to. */
|
|
21
|
-
export declare function fieldExpression(name: string): PlanExpression;
|
|
22
|
-
//# sourceMappingURL=expr.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"expr.d.ts","sourceRoot":"","sources":["../../src/migrations/expr.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAErE,MAAM,MAAM,UAAU,GACnB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC9F;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAuElD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CA6D9D;AAsED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,OAAO,GAAG,UAAU,CAOhE;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAE5D"}
|
package/dist/migrations/expr.js
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core `ScalarExpr` → canonical migration-plan expression data.
|
|
3
|
-
* The generator SERIALIZES the core's typed scalar AST; it never evaluates
|
|
4
|
-
* it — the native executor lowers the plan onto `bumbledb::ScalarExpr` and
|
|
5
|
-
* the core `ScalarEvaluator` executes it with the core's exact numeric
|
|
6
|
-
* semantics, and native plan compilation re-judges every node and type. The
|
|
7
|
-
* walk below is a bounded structural check with the same depth fence as the
|
|
8
|
-
* native codec (`MAX_EXPR_DEPTH = 128`); any node outside the frozen core
|
|
9
|
-
* roster (closure, module path, unknown kind) is an unsupported-transform
|
|
10
|
-
* refusal, never a fallback.
|
|
11
|
-
* Literal payloads accept canonical wire values and the bigint, number,
|
|
12
|
-
* and Uint8Array values retained by core SDK constructors. The serialized
|
|
13
|
-
* form is checked again by the native migration-plan decoder.
|
|
14
|
-
*/
|
|
15
|
-
import { Uuid } from "@bjornpagen/bumbledb";
|
|
16
|
-
import { bytesHex, f64Bits } from "#migrations/canonical.ts";
|
|
17
|
-
const MAX_DEPTH = 128;
|
|
18
|
-
const MAX_NODES = 4096;
|
|
19
|
-
const MAX_TEXT = 65536;
|
|
20
|
-
function refuse(detail) {
|
|
21
|
-
return { ok: false, detail };
|
|
22
|
-
}
|
|
23
|
-
function isRecord(value) {
|
|
24
|
-
return typeof value === "object" && value !== null;
|
|
25
|
-
}
|
|
26
|
-
function isCanonicalHex(text, length) {
|
|
27
|
-
if (text.length !== length) {
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
for (let index = 0; index < text.length; index += 1) {
|
|
31
|
-
const code = text.charCodeAt(index);
|
|
32
|
-
if (!((code >= 48 && code <= 57) || (code >= 97 && code <= 102))) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
const U64_MAX = 0xffffffffffffffffn;
|
|
39
|
-
const I64_MIN = -0x8000000000000000n;
|
|
40
|
-
const I64_MAX = 0x7fffffffffffffffn;
|
|
41
|
-
function decimalU64(value) {
|
|
42
|
-
if (typeof value === "bigint" && value >= 0n && value <= U64_MAX) {
|
|
43
|
-
return value.toString(10);
|
|
44
|
-
}
|
|
45
|
-
if (typeof value === "string" && value.length > 0 && value.length <= 20 && /^(0|[1-9][0-9]*)$/.test(value)) {
|
|
46
|
-
return BigInt(value) <= U64_MAX ? value : null;
|
|
47
|
-
}
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
function decimalI64(value) {
|
|
51
|
-
if (typeof value === "bigint" && value >= I64_MIN && value <= I64_MAX) {
|
|
52
|
-
return value.toString(10);
|
|
53
|
-
}
|
|
54
|
-
if (typeof value === "string" && value.length > 0 && value.length <= 21 && /^(0|-?[1-9][0-9]*)$/.test(value)) {
|
|
55
|
-
const parsed = BigInt(value);
|
|
56
|
-
return parsed >= I64_MIN && parsed <= I64_MAX ? value : null;
|
|
57
|
-
}
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
function bitsOf(value) {
|
|
61
|
-
if (typeof value === "number") {
|
|
62
|
-
return f64Bits(value);
|
|
63
|
-
}
|
|
64
|
-
if (typeof value === "string" && isCanonicalHex(value, 16)) {
|
|
65
|
-
return value;
|
|
66
|
-
}
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
function pairOf(value, one) {
|
|
70
|
-
if (!Array.isArray(value) || value.length !== 2) {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
const start = one(value[0]);
|
|
74
|
-
const end = one(value[1]);
|
|
75
|
-
return start === null || end === null ? null : [start, end];
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Bounded structural check of one literal payload into the canonical
|
|
79
|
-
* one-arm value spelling.
|
|
80
|
-
*/
|
|
81
|
-
export function planValueOf(value) {
|
|
82
|
-
if (!isRecord(value)) {
|
|
83
|
-
return "a literal payload must be a one-arm tagged core value";
|
|
84
|
-
}
|
|
85
|
-
const keys = Object.keys(value);
|
|
86
|
-
if (keys.length !== 1) {
|
|
87
|
-
return "a literal payload must have exactly one value arm";
|
|
88
|
-
}
|
|
89
|
-
const arm = keys[0];
|
|
90
|
-
const body = value[arm];
|
|
91
|
-
switch (arm) {
|
|
92
|
-
case "bool":
|
|
93
|
-
return typeof body === "boolean" ? { bool: body } : "bool literal needs a boolean";
|
|
94
|
-
case "u64": {
|
|
95
|
-
const decimal = decimalU64(body);
|
|
96
|
-
return decimal === null ? "u64 literal needs a canonical in-range integer" : { u64: decimal };
|
|
97
|
-
}
|
|
98
|
-
case "i64": {
|
|
99
|
-
const decimal = decimalI64(body);
|
|
100
|
-
return decimal === null ? "i64 literal needs a canonical in-range integer" : { i64: decimal };
|
|
101
|
-
}
|
|
102
|
-
case "$f64":
|
|
103
|
-
case "f64": {
|
|
104
|
-
const bits = bitsOf(body);
|
|
105
|
-
return bits === null ? "f64 literal needs a number or 16 lowercase hex bits" : { $f64: bits };
|
|
106
|
-
}
|
|
107
|
-
case "uuid":
|
|
108
|
-
return Uuid.isUuid(body) ? { uuid: body } : "uuid literal needs a canonical UUID";
|
|
109
|
-
case "string":
|
|
110
|
-
return typeof body === "string" && body.length <= MAX_TEXT && body.isWellFormed()
|
|
111
|
-
? { string: body }
|
|
112
|
-
: "string literal needs bounded well-formed text";
|
|
113
|
-
case "fixedBytes": {
|
|
114
|
-
if (body instanceof Uint8Array && body.length <= MAX_TEXT) {
|
|
115
|
-
return { fixedBytes: bytesHex(body) };
|
|
116
|
-
}
|
|
117
|
-
if (typeof body === "string" &&
|
|
118
|
-
body.length <= 2 * MAX_TEXT &&
|
|
119
|
-
body.length % 2 === 0 &&
|
|
120
|
-
isCanonicalHex(body, body.length)) {
|
|
121
|
-
return { fixedBytes: body };
|
|
122
|
-
}
|
|
123
|
-
return "fixedBytes literal needs a bounded Uint8Array or lowercase hex";
|
|
124
|
-
}
|
|
125
|
-
case "intervalU64": {
|
|
126
|
-
const pair = pairOf(body, decimalU64);
|
|
127
|
-
return pair === null ? "intervalU64 literal needs two canonical integers" : { intervalU64: pair };
|
|
128
|
-
}
|
|
129
|
-
case "intervalI64": {
|
|
130
|
-
const pair = pairOf(body, decimalI64);
|
|
131
|
-
return pair === null ? "intervalI64 literal needs two canonical integers" : { intervalI64: pair };
|
|
132
|
-
}
|
|
133
|
-
case "intervalF64": {
|
|
134
|
-
const pair = pairOf(body, bitsOf);
|
|
135
|
-
return pair === null ? "intervalF64 literal needs two float endpoints" : { intervalF64: pair };
|
|
136
|
-
}
|
|
137
|
-
default:
|
|
138
|
-
return `unknown literal arm ${arm}`;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
const CASTS = ["toF64", "toF64Exact", "toI64Exact", "toU64Exact"];
|
|
142
|
-
function walk(node, depth, budget, fields) {
|
|
143
|
-
if (depth > MAX_DEPTH) {
|
|
144
|
-
return `expression deeper than ${MAX_DEPTH}`;
|
|
145
|
-
}
|
|
146
|
-
budget.nodes += 1;
|
|
147
|
-
if (budget.nodes > MAX_NODES) {
|
|
148
|
-
return `expression larger than ${MAX_NODES} nodes`;
|
|
149
|
-
}
|
|
150
|
-
if (!isRecord(node) || typeof node.kind !== "string") {
|
|
151
|
-
return "an expression node must be a tagged core ScalarExpr value — functions, promises and plain hosts are not plan data";
|
|
152
|
-
}
|
|
153
|
-
switch (node.kind) {
|
|
154
|
-
case "field": {
|
|
155
|
-
if (typeof node.name !== "string" || node.name.length === 0 || node.name.length > 255) {
|
|
156
|
-
return "a field reference needs a bounded source field name";
|
|
157
|
-
}
|
|
158
|
-
fields.add(node.name);
|
|
159
|
-
return { kind: "field", name: node.name };
|
|
160
|
-
}
|
|
161
|
-
case "literal": {
|
|
162
|
-
const value = planValueOf(node.value);
|
|
163
|
-
return typeof value === "string" ? value : { kind: "literal", value };
|
|
164
|
-
}
|
|
165
|
-
case "negate":
|
|
166
|
-
case "isNaN":
|
|
167
|
-
case "isFinite": {
|
|
168
|
-
const inner = walk(node.expr, depth + 1, budget, fields);
|
|
169
|
-
if (typeof inner === "string") {
|
|
170
|
-
return inner;
|
|
171
|
-
}
|
|
172
|
-
return { kind: node.kind, expr: inner };
|
|
173
|
-
}
|
|
174
|
-
case "add":
|
|
175
|
-
case "subtract":
|
|
176
|
-
case "multiply":
|
|
177
|
-
case "divide": {
|
|
178
|
-
const left = walk(node.left, depth + 1, budget, fields);
|
|
179
|
-
if (typeof left === "string") {
|
|
180
|
-
return left;
|
|
181
|
-
}
|
|
182
|
-
const right = walk(node.right, depth + 1, budget, fields);
|
|
183
|
-
if (typeof right === "string") {
|
|
184
|
-
return right;
|
|
185
|
-
}
|
|
186
|
-
return { kind: node.kind, left, right };
|
|
187
|
-
}
|
|
188
|
-
case "cast": {
|
|
189
|
-
const cast = CASTS.find((name) => name === node.cast);
|
|
190
|
-
if (cast === undefined) {
|
|
191
|
-
return `unknown cast ${String(node.cast)} — the checked roster is toF64/toF64Exact/toI64Exact/toU64Exact`;
|
|
192
|
-
}
|
|
193
|
-
const inner = walk(node.expr, depth + 1, budget, fields);
|
|
194
|
-
if (typeof inner === "string") {
|
|
195
|
-
return inner;
|
|
196
|
-
}
|
|
197
|
-
return { kind: "cast", cast, expr: inner };
|
|
198
|
-
}
|
|
199
|
-
default:
|
|
200
|
-
return `unsupported expression node ${node.kind} — the finite supported grammar is field/literal/negate/add/subtract/multiply/divide/cast/isNaN/isFinite`;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Serialize one core scalar expression into canonical plan data, collecting
|
|
205
|
-
* the referenced source field names for loss accounting.
|
|
206
|
-
*/
|
|
207
|
-
export function planExpressionOf(expression) {
|
|
208
|
-
const fields = new Set();
|
|
209
|
-
const outcome = walk(expression, 0, { nodes: 0 }, fields);
|
|
210
|
-
if (typeof outcome === "string") {
|
|
211
|
-
return refuse(outcome);
|
|
212
|
-
}
|
|
213
|
-
return { ok: true, expression: outcome, fields: [...fields] };
|
|
214
|
-
}
|
|
215
|
-
/** The identity projection every carried field lowers to. */
|
|
216
|
-
export function fieldExpression(name) {
|
|
217
|
-
return { kind: "field", name };
|
|
218
|
-
}
|
|
219
|
-
//# sourceMappingURL=expr.js.map
|