@ifc-lite/merge 0.1.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.
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Three-way merge: two runs of the two-way comparison joined on identity,
3
+ * iterated over the union of touched (entity, componentKey) pairs.
4
+ *
5
+ * Inputs: ancestor A = the candidate layer's base, ours O = the target
6
+ * ref's state, theirs T = the candidate applied to A. The plan's autoOps
7
+ * apply on top of O; "keep ours" therefore emits nothing.
8
+ *
9
+ * Decision matrix (05 §5.3):
10
+ *
11
+ * A→O unchanged, A→T changed → take theirs (auto)
12
+ * A→O changed, A→T unchanged → keep ours (auto)
13
+ * both changed, equal sub-hash → fold (auto)
14
+ * both changed, different → conflict: concurrent-edit
15
+ * tombstoned vs changed → conflict: delete-vs-modify
16
+ * changed vs tombstoned → conflict: modify-vs-delete
17
+ * tombstoned vs tombstoned → fold (auto)
18
+ *
19
+ * Relations use the same matrix over `child:<name>` slots; divergent
20
+ * reparenting surfaces as a `hierarchy` conflict.
21
+ */
22
+ import type { IfcxFile } from '@ifc-lite/ifcx';
23
+ import type { ComponentAttributes, ComponentKey, MergeOp, MergePlan } from './types.js';
24
+ import type { StackState } from './component-state.js';
25
+ export interface ThreeWayInputs {
26
+ /** The candidate layer's base, ordered weakest first. */
27
+ ancestor: readonly IfcxFile[];
28
+ /** The target ref's state, ordered weakest first. */
29
+ ours: readonly IfcxFile[];
30
+ /** The candidate applied to its base, ordered weakest first. */
31
+ theirs: readonly IfcxFile[];
32
+ }
33
+ export declare function planThreeWayMerge(inputs: ThreeWayInputs): MergePlan;
34
+ export declare function planFromStates(a: StackState, o: StackState, t: StackState): MergePlan;
35
+ /**
36
+ * Ops that move one component from its ancestor value to the new value.
37
+ *
38
+ * The emitted node applies on top of the TARGET stack, where composition
39
+ * is per-attribute LWW — setting the surviving attributes alone would
40
+ * leave stale opinions (an attribute the candidate removed, or one ours
41
+ * added inside a component being resolved to theirs) shining through.
42
+ * Every key visible on the ancestor or ours side that `next` no longer
43
+ * carries is therefore explicitly nulled.
44
+ */
45
+ export declare function opsForComponentChange(path: string, componentKey: ComponentKey, ancestor: ComponentAttributes | undefined, next: ComponentAttributes | undefined, oursVisible?: ComponentAttributes): MergeOp[];
46
+ //# sourceMappingURL=three-way.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"three-way.d.ts","sourceRoot":"","sources":["../src/three-way.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EAEZ,OAAO,EACP,SAAS,EACV,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAQpE,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,QAAQ,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC9B,qDAAqD;IACrD,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC1B,gEAAgE;IAChE,MAAM,EAAE,SAAS,QAAQ,EAAE,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAoBnE;AAkBD,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,SAAS,CAsCrF;AAuVD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,mBAAmB,GAAG,SAAS,EACzC,IAAI,EAAE,mBAAmB,GAAG,SAAS,EACrC,WAAW,CAAC,EAAE,mBAAmB,GAChC,OAAO,EAAE,CA0BX"}
@@ -0,0 +1,416 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { componentEntries, extractStackState, projectStackStates, snapshotOf, } from './component-state.js';
5
+ export function planThreeWayMerge(inputs) {
6
+ // Fast path (05 §5.7): when both sides extend the ancestor stack, only
7
+ // suffix-touched paths can differ — project those instead of folding
8
+ // and hashing the full model three times. Falls back to the reference
9
+ // extraction for tombstone-bearing stacks (subtree shadowing is global)
10
+ // and for unrelated stacks. Equivalence is enforced by the differential
11
+ // fuzz in fast-path-differential.test.ts.
12
+ if (sharesAncestorPrefix(inputs.ours, inputs.ancestor) && sharesAncestorPrefix(inputs.theirs, inputs.ancestor)) {
13
+ const projected = projectStackStates(inputs.ancestor, inputs.ours.slice(inputs.ancestor.length), inputs.theirs.slice(inputs.ancestor.length));
14
+ if (projected)
15
+ return planFromStates(projected.a, projected.o, projected.t);
16
+ }
17
+ return planFromStates(extractStackState(inputs.ancestor), extractStackState(inputs.ours), extractStackState(inputs.theirs));
18
+ }
19
+ /**
20
+ * True when `stack` starts with the ancestor's layers: same documents by
21
+ * reference, or by content address (equal blake3 ids imply identical
22
+ * canonical bytes; non-blake3 test ids only count when reference-equal).
23
+ */
24
+ function sharesAncestorPrefix(stack, ancestor) {
25
+ if (stack.length < ancestor.length)
26
+ return false;
27
+ for (let i = 0; i < ancestor.length; i++) {
28
+ if (stack[i] === ancestor[i])
29
+ continue;
30
+ const id = ancestor[i].header.id;
31
+ if (id.startsWith('blake3:') && stack[i].header.id === id)
32
+ continue;
33
+ return false;
34
+ }
35
+ return true;
36
+ }
37
+ export function planFromStates(a, o, t) {
38
+ const autoOps = [];
39
+ const conflicts = [];
40
+ let touched = 0;
41
+ // Memoized per plan: with the projection sharing untouched component
42
+ // objects across sides, reference equality + this cache keep hashing
43
+ // proportional to the number of actually-edited components.
44
+ const hashes = new WeakMap();
45
+ const hashOf = (attrs) => {
46
+ if (attrs === undefined)
47
+ return undefined;
48
+ let hash = hashes.get(attrs);
49
+ if (hash === undefined) {
50
+ hash = snapshotOf(attrs).hash;
51
+ hashes.set(attrs, hash);
52
+ }
53
+ return hash;
54
+ };
55
+ const paths = new Set([...a.keys(), ...o.keys(), ...t.keys()]);
56
+ for (const path of paths) {
57
+ const result = mergeEntity(path, a.get(path), o.get(path), t.get(path), hashOf);
58
+ autoOps.push(...result.ops);
59
+ conflicts.push(...result.conflicts);
60
+ touched += result.touched;
61
+ }
62
+ const escalated = escalateShadowedConflicts(a, o, t, autoOps, conflicts);
63
+ return {
64
+ autoOps: escalated.autoOps,
65
+ conflicts: escalated.conflicts,
66
+ stats: {
67
+ touched,
68
+ autoMerged: escalated.autoOps.length,
69
+ conflicting: escalated.conflicts.length,
70
+ },
71
+ };
72
+ }
73
+ /**
74
+ * A conflict on a path that is SHADOW-dead on one side cannot be decided
75
+ * on its own: subtree shadowing beats a child resurrect at composition
76
+ * time, so any per-child resolution against a dead ancestor is a silent
77
+ * no-op. The decision belongs to the tombstoned root:
78
+ *
79
+ * - Theirs tombstoned root R, ours edited descendants → R's auto
80
+ * tombstone is demoted to a `modify-vs-delete` conflict on R and the
81
+ * descendant conflicts fold into it (`subtree`): resolving R = theirs
82
+ * deletes the subtree knowingly; R = ours keeps it, edits and all.
83
+ * - Ours tombstoned root R, theirs edited descendants → R gains a
84
+ * `delete-vs-modify` conflict (it had none: theirs never touched R
85
+ * itself). The descendant conflicts stay — their theirs-resolutions
86
+ * carry the actual edits and become satisfiable once R is resurrected.
87
+ */
88
+ function escalateShadowedConflicts(a, o, t, autoOps, conflicts) {
89
+ const shadowDeadIn = (state, path) => {
90
+ const entity = state.get(path);
91
+ return entity !== undefined && entity.deleted && !entity.explicitDeleted;
92
+ };
93
+ const needsPass = conflicts.some((c) => c.componentKey === undefined && (shadowDeadIn(t, c.path) || shadowDeadIn(o, c.path)));
94
+ if (!needsPass)
95
+ return { autoOps, conflicts };
96
+ const parentMaps = new Map();
97
+ const parentsOf = (state) => {
98
+ let parents = parentMaps.get(state);
99
+ if (!parents) {
100
+ parents = new Map();
101
+ for (const entity of state.values()) {
102
+ for (const child of entity.children.values()) {
103
+ if (!parents.has(child))
104
+ parents.set(child, entity.path);
105
+ }
106
+ }
107
+ parentMaps.set(state, parents);
108
+ }
109
+ return parents;
110
+ };
111
+ const rootIn = (state, path) => {
112
+ // Nearest ancestor (via the state's children graph) whose death is
113
+ // explicit on its own path.
114
+ const parents = parentsOf(state);
115
+ const seen = new Set([path]);
116
+ let current = parents.get(path);
117
+ while (current !== undefined && !seen.has(current)) {
118
+ const entity = state.get(current);
119
+ if (entity?.explicitDeleted)
120
+ return current;
121
+ seen.add(current);
122
+ current = parents.get(current);
123
+ }
124
+ return undefined;
125
+ };
126
+ const keptConflicts = [];
127
+ // Root path → descendant conflict paths folded into its decision.
128
+ const theirsRoots = new Map();
129
+ const oursRoots = new Map();
130
+ for (const conflict of conflicts) {
131
+ if (conflict.componentKey === undefined && shadowDeadIn(t, conflict.path)) {
132
+ const root = rootIn(t, conflict.path);
133
+ if (root !== undefined) {
134
+ // Folded into the root's decision; the ours-side edits need no
135
+ // ops (they are already in the target stack).
136
+ const list = theirsRoots.get(root) ?? [];
137
+ list.push(conflict.path);
138
+ theirsRoots.set(root, list);
139
+ continue;
140
+ }
141
+ }
142
+ if (conflict.componentKey === undefined && shadowDeadIn(o, conflict.path)) {
143
+ const root = rootIn(o, conflict.path);
144
+ if (root !== undefined) {
145
+ const list = oursRoots.get(root) ?? [];
146
+ list.push(conflict.path);
147
+ oursRoots.set(root, list);
148
+ // Kept: its theirs-resolution carries the descendant's edits.
149
+ keptConflicts.push(conflict);
150
+ continue;
151
+ }
152
+ }
153
+ keptConflicts.push(conflict);
154
+ }
155
+ let ops = autoOps;
156
+ for (const [root, subtree] of theirsRoots) {
157
+ ops = ops.filter((op) => !(op.op === 'tombstone-entity' && op.path === root));
158
+ const existing = keptConflicts.find((c) => c.path === root && c.componentKey === undefined);
159
+ if (existing) {
160
+ existing.subtree = [...(existing.subtree ?? []), ...subtree].sort();
161
+ continue;
162
+ }
163
+ const oEntity = o.get(root);
164
+ const aEntity = a.get(root);
165
+ keptConflicts.push({
166
+ kind: 'modify-vs-delete',
167
+ path: root,
168
+ ours: snapshotOf(Object.fromEntries(componentsOf(oEntity).entries())),
169
+ ...(aEntity && !aEntity.deleted
170
+ ? { base: snapshotOf(Object.fromEntries(componentsOf(aEntity).entries())) }
171
+ : {}),
172
+ subtree: subtree.sort(),
173
+ });
174
+ }
175
+ for (const [root, subtree] of oursRoots) {
176
+ const existing = keptConflicts.find((c) => c.path === root && c.componentKey === undefined);
177
+ if (existing) {
178
+ existing.subtree = [...(existing.subtree ?? []), ...subtree].sort();
179
+ continue;
180
+ }
181
+ const tEntity = t.get(root);
182
+ const oEntity = o.get(root);
183
+ const aEntity = a.get(root);
184
+ keptConflicts.push({
185
+ kind: 'delete-vs-modify',
186
+ path: root,
187
+ theirs: snapshotOf(Object.fromEntries(componentsOf(tEntity).entries())),
188
+ ours: snapshotOf(Object.fromEntries(componentsOf(oEntity).entries())),
189
+ ...(aEntity && !aEntity.deleted
190
+ ? { base: snapshotOf(Object.fromEntries(componentsOf(aEntity).entries())) }
191
+ : {}),
192
+ subtree: subtree.sort(),
193
+ });
194
+ }
195
+ return { autoOps: ops, conflicts: keptConflicts };
196
+ }
197
+ function alive(entity) {
198
+ return entity !== undefined && !entity.deleted;
199
+ }
200
+ function componentsOf(entity) {
201
+ return entity ? componentEntries(entity) : new Map();
202
+ }
203
+ function componentsEqual(x, y, hashOf) {
204
+ if (x.size !== y.size)
205
+ return false;
206
+ for (const [key, attrs] of x) {
207
+ const other = y.get(key);
208
+ if (!other)
209
+ return false;
210
+ if (other === attrs)
211
+ continue;
212
+ if (hashOf(other) !== hashOf(attrs))
213
+ return false;
214
+ }
215
+ return true;
216
+ }
217
+ function mergeEntity(path, aEntity, oEntity, tEntity, hashOf) {
218
+ const aAlive = alive(aEntity);
219
+ const oAlive = alive(oEntity);
220
+ const tAlive = alive(tEntity);
221
+ const aComponents = componentsOf(aEntity);
222
+ const oComponents = componentsOf(oEntity);
223
+ const tComponents = componentsOf(tEntity);
224
+ // Both sides agree the entity is gone (or never both created it): fold.
225
+ // Component edits under a double-sided tombstone are unobservable and
226
+ // fold with the deletion.
227
+ if (!oAlive && !tAlive)
228
+ return { ops: [], conflicts: [], touched: aAlive ? 1 : 0 };
229
+ // A change is a component edit OR an alive-state flip: a resurrection
230
+ // carries no component delta but is still a change (05 §5.3) — comparing
231
+ // components alone would silently drop it (or worse, re-delete it).
232
+ const oChanged = oAlive !== aAlive || !componentsEqual(aComponents, oComponents, hashOf);
233
+ const tChanged = tAlive !== aAlive || !componentsEqual(aComponents, tComponents, hashOf);
234
+ // Theirs didn't touch it (same alive-state, same components as the
235
+ // ancestor): whatever ours did stands. Covers ours-only adds, edits,
236
+ // deletes AND resurrections.
237
+ if (!tChanged)
238
+ return { ops: [], conflicts: [], touched: oChanged ? 1 : 0 };
239
+ // Ours didn't touch it: take theirs wholesale.
240
+ if (!oChanged) {
241
+ if (oAlive && !tAlive) {
242
+ // Theirs stripped it to an empty shell (nulled every attribute and
243
+ // slot; the extraction drops such entities, no tombstone): express
244
+ // that as removal opinions. A tombstone here would shadow-kill
245
+ // children theirs kept alive.
246
+ if (tEntity === undefined) {
247
+ return {
248
+ ops: opsForComponentDelta(path, aComponents, new Map(), oComponents, hashOf),
249
+ conflicts: [],
250
+ touched: 1,
251
+ };
252
+ }
253
+ // Shadow-only deaths (a deleted ancestor node, not a tombstone on
254
+ // this path) emit nothing: the parent's own merge decision carries
255
+ // the subtree at composition time. Emitting here would re-delete a
256
+ // child the target reparented, or pre-empt a parent still in
257
+ // conflict.
258
+ if (tEntity.deleted && !tEntity.explicitDeleted) {
259
+ return { ops: [], conflicts: [], touched: 1 };
260
+ }
261
+ return { ops: [{ op: 'tombstone-entity', path }], conflicts: [], touched: 1 };
262
+ }
263
+ // Theirs is alive: added, resurrected, and/or edited.
264
+ const ops = [];
265
+ if (oEntity?.deleted === true || aEntity?.deleted === true) {
266
+ ops.push({ op: 'resurrect-entity', path });
267
+ }
268
+ ops.push(...opsForComponentDelta(path, aComponents, tComponents, oComponents, hashOf));
269
+ return { ops, conflicts: [], touched: 1 };
270
+ }
271
+ // Both changed. Convergent outcomes fold.
272
+ if (oAlive === tAlive && componentsEqual(oComponents, tComponents, hashOf)) {
273
+ return { ops: [], conflicts: [], touched: 1 };
274
+ }
275
+ // Ours deleted (or still dead) while theirs edited/resurrected.
276
+ if (!oAlive && tAlive) {
277
+ return {
278
+ ops: [],
279
+ conflicts: [
280
+ {
281
+ kind: 'delete-vs-modify',
282
+ path,
283
+ theirs: snapshotOf(Object.fromEntries(tComponents.entries())),
284
+ // Ours' opinions stay in the stack under the tombstone and become
285
+ // visible again on resurrect — resolutions need them to null out.
286
+ ours: snapshotOf(Object.fromEntries(oComponents.entries())),
287
+ ...(aAlive ? { base: snapshotOf(Object.fromEntries(aComponents.entries())) } : {}),
288
+ },
289
+ ],
290
+ touched: 1,
291
+ };
292
+ }
293
+ // Ours edited/resurrected while theirs deleted.
294
+ if (oAlive && !tAlive) {
295
+ return {
296
+ ops: [],
297
+ conflicts: [
298
+ {
299
+ kind: 'modify-vs-delete',
300
+ path,
301
+ ours: snapshotOf(Object.fromEntries(oComponents.entries())),
302
+ ...(aAlive ? { base: snapshotOf(Object.fromEntries(aComponents.entries())) } : {}),
303
+ // A shell-strip (no tombstone) records an empty theirs state so
304
+ // a theirs-resolution emits removal opinions, not a tombstone
305
+ // that would shadow-kill children theirs kept alive.
306
+ ...(tEntity === undefined ? { theirs: snapshotOf({}) } : {}),
307
+ },
308
+ ],
309
+ touched: 1,
310
+ };
311
+ }
312
+ // Both alive: component-level matrix over the union of touched keys.
313
+ const ops = [];
314
+ const conflicts = [];
315
+ let touched = 0;
316
+ const keys = new Set([
317
+ ...aComponents.keys(),
318
+ ...oComponents.keys(),
319
+ ...tComponents.keys(),
320
+ ]);
321
+ for (const key of keys) {
322
+ const aAttrs = aComponents.get(key);
323
+ const oAttrs = oComponents.get(key);
324
+ const tAttrs = tComponents.get(key);
325
+ // Reference equality first (shared objects from the projection fast
326
+ // path); only genuinely diverging references pay for hashing.
327
+ if (aAttrs === oAttrs && aAttrs === tAttrs)
328
+ continue;
329
+ const oChanged = aAttrs === oAttrs ? false : hashOf(aAttrs) !== hashOf(oAttrs);
330
+ const tChanged = aAttrs === tAttrs ? false : hashOf(aAttrs) !== hashOf(tAttrs);
331
+ if (!oChanged && !tChanged)
332
+ continue;
333
+ touched += 1;
334
+ if (oChanged && !tChanged)
335
+ continue; // keep ours
336
+ if (oChanged && tChanged && (oAttrs === tAttrs || hashOf(oAttrs) === hashOf(tAttrs)))
337
+ continue; // fold
338
+ if (!oChanged && tChanged) {
339
+ ops.push(...opsForComponentChange(path, key, aAttrs, tAttrs, oAttrs));
340
+ continue;
341
+ }
342
+ // Both changed, different values.
343
+ conflicts.push({
344
+ kind: key.startsWith('child:') || key.startsWith('inherit:') ? 'hierarchy' : 'concurrent-edit',
345
+ path,
346
+ componentKey: key,
347
+ ...(aAttrs ? { base: snapshotOf(aAttrs) } : {}),
348
+ ...(oAttrs ? { ours: snapshotOf(oAttrs) } : {}),
349
+ ...(tAttrs ? { theirs: snapshotOf(tAttrs) } : {}),
350
+ });
351
+ }
352
+ return { ops, conflicts, touched };
353
+ }
354
+ /**
355
+ * Ops that transform an entity's components from the ancestor state to the
356
+ * theirs state, given that ours matches the ancestor per entity-level
357
+ * change detection. Emits only genuinely differing keys.
358
+ */
359
+ function opsForComponentDelta(path, ancestor, theirs, ours, hashOf) {
360
+ const ops = [];
361
+ const keys = new Set([...ancestor.keys(), ...theirs.keys()]);
362
+ for (const key of keys) {
363
+ const aAttrs = ancestor.get(key);
364
+ const tAttrs = theirs.get(key);
365
+ if (aAttrs === tAttrs)
366
+ continue;
367
+ if (aAttrs !== undefined && tAttrs !== undefined && hashOf(aAttrs) === hashOf(tAttrs))
368
+ continue;
369
+ ops.push(...opsForComponentChange(path, key, aAttrs, tAttrs, ours.get(key)));
370
+ }
371
+ return ops;
372
+ }
373
+ /**
374
+ * Ops that move one component from its ancestor value to the new value.
375
+ *
376
+ * The emitted node applies on top of the TARGET stack, where composition
377
+ * is per-attribute LWW — setting the surviving attributes alone would
378
+ * leave stale opinions (an attribute the candidate removed, or one ours
379
+ * added inside a component being resolved to theirs) shining through.
380
+ * Every key visible on the ancestor or ours side that `next` no longer
381
+ * carries is therefore explicitly nulled.
382
+ */
383
+ export function opsForComponentChange(path, componentKey, ancestor, next, oursVisible) {
384
+ if (componentKey.startsWith('child:')) {
385
+ const name = componentKey.slice('child:'.length);
386
+ if (next === undefined)
387
+ return [{ op: 'remove-child', path, name }];
388
+ return [{ op: 'set-child', path, name, child: String(next.child) }];
389
+ }
390
+ if (componentKey.startsWith('inherit:')) {
391
+ const name = componentKey.slice('inherit:'.length);
392
+ if (next === undefined)
393
+ return [{ op: 'remove-inherit', path, name }];
394
+ return [{ op: 'set-inherit', path, name, target: String(next.inherit) }];
395
+ }
396
+ if (next === undefined) {
397
+ const nulled = {};
398
+ for (const attr of Object.keys(ancestor ?? {}))
399
+ nulled[attr] = null;
400
+ for (const attr of Object.keys(oursVisible ?? {}))
401
+ nulled[attr] = null;
402
+ return [{ op: 'tombstone-component', path, componentKey, attributes: nulled }];
403
+ }
404
+ const attributes = {};
405
+ for (const attr of Object.keys(ancestor ?? {})) {
406
+ if (!(attr in next))
407
+ attributes[attr] = null;
408
+ }
409
+ for (const attr of Object.keys(oursVisible ?? {})) {
410
+ if (!(attr in next))
411
+ attributes[attr] = null;
412
+ }
413
+ Object.assign(attributes, next);
414
+ return [{ op: 'set-component', path, componentKey, attributes }];
415
+ }
416
+ //# sourceMappingURL=three-way.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"three-way.js","sourceRoot":"","sources":["../src/three-way.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Layer-merge type vocabulary.
3
+ *
4
+ * Ops are state-based at (entity, componentKey) granularity: a
5
+ * `set-component` carries the full component value, never a transform.
6
+ * Composing is a deterministic fold where stronger layers shadow weaker
7
+ * per (entity, componentKey) — no OT machinery.
8
+ *
9
+ * Spec: docs/architecture/layer-prs/02-layer-format.md §2.2,
10
+ * 05-merge.md §5.3.
11
+ */
12
+ /**
13
+ * Component key vocabulary shared with `@ifc-lite/diff` sub-hash mode:
14
+ * `attr:<group>`, `pset:<PsetName>`, `qset:<QsetName>`, `type-assignment`,
15
+ * `placement`, `geometry:<tier>`, plus `child:<name>` for relation slots.
16
+ */
17
+ export type ComponentKey = string;
18
+ /** A component's merged value: the IFCX attributes that form it. */
19
+ export type ComponentAttributes = Record<string, unknown>;
20
+ /** Semantic reading of a layer's nodes — the op model of 02 §2.2. */
21
+ export type MergeOp = {
22
+ readonly op: 'set-component';
23
+ readonly path: string;
24
+ readonly componentKey: ComponentKey;
25
+ /** Full component value (state-based; LWW within a stack). */
26
+ readonly attributes: ComponentAttributes;
27
+ } | {
28
+ readonly op: 'tombstone-component';
29
+ readonly path: string;
30
+ readonly componentKey: ComponentKey;
31
+ /** Attribute keys to null out (IFCX null = remove opinion). */
32
+ readonly attributes: ComponentAttributes;
33
+ } | {
34
+ readonly op: 'tombstone-entity';
35
+ readonly path: string;
36
+ } | {
37
+ readonly op: 'resurrect-entity';
38
+ readonly path: string;
39
+ } | {
40
+ readonly op: 'set-child';
41
+ readonly path: string;
42
+ readonly name: string;
43
+ readonly child: string;
44
+ } | {
45
+ readonly op: 'remove-child';
46
+ readonly path: string;
47
+ readonly name: string;
48
+ } | {
49
+ readonly op: 'set-inherit';
50
+ readonly path: string;
51
+ readonly name: string;
52
+ readonly target: string;
53
+ } | {
54
+ readonly op: 'remove-inherit';
55
+ readonly path: string;
56
+ readonly name: string;
57
+ };
58
+ /**
59
+ * Conflict taxonomy, lifted from `collab/conflicts/detector.ts` kinds from
60
+ * session level to merge level (05 §5.3).
61
+ */
62
+ export type MergeConflictKind = 'concurrent-edit' | 'delete-vs-modify' | 'modify-vs-delete' | 'hierarchy';
63
+ export interface ComponentSnapshot {
64
+ /** Stable sub-hash of the component value. */
65
+ hash: string;
66
+ attributes: ComponentAttributes;
67
+ }
68
+ export interface MergeConflict {
69
+ kind: MergeConflictKind;
70
+ /** Entity path the conflict is on. */
71
+ path: string;
72
+ /** Component the conflict is scoped to; absent for entity-level kinds. */
73
+ componentKey?: ComponentKey;
74
+ /** Ancestor value (undefined when the component did not exist in A). */
75
+ base?: ComponentSnapshot;
76
+ /** Target-side value (undefined when removed/absent on ours). */
77
+ ours?: ComponentSnapshot;
78
+ /** Candidate-side value (undefined when removed/absent on theirs). */
79
+ theirs?: ComponentSnapshot;
80
+ /**
81
+ * For an entity-level delete conflict whose tombstone shadow-kills
82
+ * descendants the other side touched: their paths. The delete decision
83
+ * on THIS entity carries the whole subtree - per-descendant choices
84
+ * against a dead ancestor would be unsatisfiable (subtree shadowing
85
+ * beats a child resurrect at composition time).
86
+ */
87
+ subtree?: string[];
88
+ }
89
+ export interface MergePlanStats {
90
+ /** (entity, componentKey) pairs touched by either side. */
91
+ touched: number;
92
+ autoMerged: number;
93
+ conflicting: number;
94
+ }
95
+ /**
96
+ * Result of a three-way plan: ops that apply cleanly on top of the target
97
+ * state, plus explicit conflict records awaiting resolution. Zero
98
+ * conflicts + green checks means the merge can complete unattended
99
+ * (subject to ref policy).
100
+ */
101
+ export interface MergePlan {
102
+ autoOps: MergeOp[];
103
+ conflicts: MergeConflict[];
104
+ stats: MergePlanStats;
105
+ }
106
+ /** A reviewer's (or policy's) decision for one conflict. */
107
+ export interface ResolutionInput {
108
+ path: string;
109
+ componentKey?: ComponentKey;
110
+ choice: 'ours' | 'theirs' | 'edited';
111
+ /** Replacement component value; required when `choice === 'edited'`. */
112
+ attributes?: ComponentAttributes;
113
+ }
114
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;+DAE+D"}