@ibgib/vcs-gib 0.0.21 → 0.0.26

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 (93) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/VCS_CLI_USER_GUIDE.md +94 -89
  3. package/dist/AUTO-GENERATED-version.d.mts +1 -1
  4. package/dist/AUTO-GENERATED-version.mjs +1 -1
  5. package/dist/bootstrap/node-bootstrap.mjs +1 -1
  6. package/dist/cli/cli-arg-parser.d.mts +1 -0
  7. package/dist/cli/cli-arg-parser.d.mts.map +1 -1
  8. package/dist/cli/cli-arg-parser.mjs +5 -1
  9. package/dist/cli/cli-arg-parser.mjs.map +1 -1
  10. package/dist/cli/cli-constants.d.mts +6 -0
  11. package/dist/cli/cli-constants.d.mts.map +1 -1
  12. package/dist/cli/cli-constants.mjs +12 -0
  13. package/dist/cli/cli-constants.mjs.map +1 -1
  14. package/dist/cli/commands/add-cmd.d.mts.map +1 -1
  15. package/dist/cli/commands/add-cmd.mjs +5 -2
  16. package/dist/cli/commands/add-cmd.mjs.map +1 -1
  17. package/dist/cli/commands/commit-cmd.d.mts +5 -4
  18. package/dist/cli/commands/commit-cmd.d.mts.map +1 -1
  19. package/dist/cli/commands/commit-cmd.mjs +149 -33
  20. package/dist/cli/commands/commit-cmd.mjs.map +1 -1
  21. package/dist/cli/commands/generate-comment-cmd.d.mts +19 -0
  22. package/dist/cli/commands/generate-comment-cmd.d.mts.map +1 -0
  23. package/dist/cli/commands/generate-comment-cmd.mjs +140 -0
  24. package/dist/cli/commands/generate-comment-cmd.mjs.map +1 -0
  25. package/dist/cli/commands/log-cmd.d.mts +12 -3
  26. package/dist/cli/commands/log-cmd.d.mts.map +1 -1
  27. package/dist/cli/commands/log-cmd.mjs +236 -38
  28. package/dist/cli/commands/log-cmd.mjs.map +1 -1
  29. package/dist/cli/commands/merge-cmd.d.mts +21 -8
  30. package/dist/cli/commands/merge-cmd.d.mts.map +1 -1
  31. package/dist/cli/commands/merge-cmd.mjs +138 -70
  32. package/dist/cli/commands/merge-cmd.mjs.map +1 -1
  33. package/dist/cli/commands/status-cmd.d.mts +5 -6
  34. package/dist/cli/commands/status-cmd.d.mts.map +1 -1
  35. package/dist/cli/commands/status-cmd.mjs +50 -205
  36. package/dist/cli/commands/status-cmd.mjs.map +1 -1
  37. package/dist/cli/vcs-cli-main.d.mts.map +1 -1
  38. package/dist/cli/vcs-cli-main.mjs +27 -6
  39. package/dist/cli/vcs-cli-main.mjs.map +1 -1
  40. package/dist/engine/index/index-helper.d.mts.map +1 -1
  41. package/dist/engine/index/index-helper.mjs +3 -0
  42. package/dist/engine/index/index-helper.mjs.map +1 -1
  43. package/dist/engine/item/item-helper.d.mts +31 -1
  44. package/dist/engine/item/item-helper.d.mts.map +1 -1
  45. package/dist/engine/item/item-helper.mjs +44 -2
  46. package/dist/engine/item/item-helper.mjs.map +1 -1
  47. package/dist/engine/merge/b2tfs-3way-graft-strategy.d.mts +74 -0
  48. package/dist/engine/merge/b2tfs-3way-graft-strategy.d.mts.map +1 -0
  49. package/dist/engine/merge/{b2tfs-3way-merge-strategy.mjs → b2tfs-3way-graft-strategy.mjs} +133 -304
  50. package/dist/engine/merge/b2tfs-3way-graft-strategy.mjs.map +1 -0
  51. package/dist/engine/merge/{b2tfs-3way-merge-types.d.mts → b2tfs-3way-graft-types.d.mts} +2 -9
  52. package/dist/engine/merge/b2tfs-3way-graft-types.d.mts.map +1 -0
  53. package/dist/engine/merge/b2tfs-3way-graft-types.mjs +2 -0
  54. package/dist/engine/merge/b2tfs-3way-graft-types.mjs.map +1 -0
  55. package/dist/engine/status/status-helper.d.mts +89 -0
  56. package/dist/engine/status/status-helper.d.mts.map +1 -0
  57. package/dist/engine/status/status-helper.mjs +285 -0
  58. package/dist/engine/status/status-helper.mjs.map +1 -0
  59. package/dist/test/test-helpers.d.mts +51 -0
  60. package/dist/test/test-helpers.d.mts.map +1 -0
  61. package/dist/test/test-helpers.mjs +135 -0
  62. package/dist/test/test-helpers.mjs.map +1 -0
  63. package/package.json +4 -4
  64. package/src/AUTO-GENERATED-version.mts +1 -1
  65. package/src/bootstrap/node-bootstrap.mts +1 -1
  66. package/src/cli/cli-arg-parser.mts +5 -0
  67. package/src/cli/cli-constants.mts +13 -0
  68. package/src/cli/commands/add-cmd.mts +5 -2
  69. package/src/cli/commands/branch-checkout-cmd.respec.log +8 -101
  70. package/src/cli/commands/branch-checkout-cmd.respec.mts +11 -10
  71. package/src/cli/commands/commit-cmd.mts +165 -42
  72. package/src/cli/commands/commit-log-cmd.respec.mts +216 -3
  73. package/src/cli/commands/generate-comment-cmd.mts +171 -0
  74. package/src/cli/commands/log-cmd.mts +288 -41
  75. package/src/cli/commands/merge-cmd.mts +154 -76
  76. package/src/cli/commands/status-cmd.mts +57 -256
  77. package/src/cli/vcs-cli-main.mts +28 -7
  78. package/src/engine/index/index-helper.mts +3 -0
  79. package/src/engine/item/item-helper.mts +76 -3
  80. package/src/engine/merge/{b2tfs-3way-merge-strategy.mts → b2tfs-3way-graft-strategy.mts} +152 -374
  81. package/src/engine/merge/{b2tfs-3way-merge-strategy.respec.mts → b2tfs-3way-graft-strategy.respec.mts} +27 -122
  82. package/src/engine/merge/{b2tfs-3way-merge-types.mts → b2tfs-3way-graft-types.mts} +34 -42
  83. package/src/engine/merge/b2tfs-sync-comments.respec.mts +399 -0
  84. package/src/engine/status/status-helper.mts +380 -0
  85. package/src/test/test-helpers.mts +168 -0
  86. package/tsconfig.test.tsbuildinfo +1 -1
  87. package/tsconfig.tsbuildinfo +1 -1
  88. package/dist/engine/merge/b2tfs-3way-merge-strategy.d.mts +0 -48
  89. package/dist/engine/merge/b2tfs-3way-merge-strategy.d.mts.map +0 -1
  90. package/dist/engine/merge/b2tfs-3way-merge-strategy.mjs.map +0 -1
  91. package/dist/engine/merge/b2tfs-3way-merge-types.d.mts.map +0 -1
  92. package/dist/engine/merge/b2tfs-3way-merge-types.mjs +0 -2
  93. package/dist/engine/merge/b2tfs-3way-merge-types.mjs.map +0 -1
@@ -1,24 +1,43 @@
1
1
  /**
2
- * @module b2tfs-3way-merge-strategy
2
+ * @module b2tfs-3way-graft-strategy
3
3
  *
4
- * Extensible Graft Merge Strategy for 3-way B2tFS filesystem snapshot trees and text files.
4
+ * ============================================================================
5
+ * ⚠️ CRITICAL GRAFT STRATEGY GUIDANCE WARNING ⚠️
6
+ * BEFORE MAKING ANY CHANGES TO THIS FILE, YOU MUST CONSULT AND CAREFULLY READ:
7
+ * libs/core-gib/src/sync/GRAFT_STRATEGY_GUIDANCE.md
8
+ *
9
+ * Graft strategies must strictly fulfill the `GraftTimelinesResult` contract,
10
+ * ensure timeline `n` monotonicity (using Math.max over base/orphan branch frames),
11
+ * and include ALL newly referenced ancillary dependency nodes (comments, binary
12
+ * stones, DNAs) in `ancillaryIbGibsCreated` so that the destination branch
13
+ * space is completely self-contained.
14
+ * ============================================================================
15
+ *
16
+ * 3-way text line diff graft strategy for B2tFS file item timelines.
17
+ * Reconciles diverging file content via 3-way line diff (LCA, Base, Orphan)
18
+ * and inserts Git conflict markers when line edits collide.
19
+ *
20
+ * Non-text binaries and non-file items return early / false in `canGraft` and
21
+ * fall through to `DefaultDnaReplayGraftStrategy`.
22
+ * Folder hierarchies are re-synchronized post-merge via `reifyB2tFSHierarchy`.
5
23
  */
6
24
  import { extractErrorMsg, hash } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
7
25
  import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
8
- import { getGib } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';
26
+ import { getGib, isDna } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';
9
27
  import { rel8 } from '@ibgib/ts-gib/dist/V1/transforms/rel8.mjs';
10
28
  import { GraftMergeStrategyBase_V1 } from '@ibgib/core-gib/dist/sync/graft-info/graft-merge-strategy-base-v1.mjs';
11
29
  import { getFromSpace, persistTransformResult, registerNewIbGib, putInSpace } from '@ibgib/core-gib/dist/witness/space/space-helper.mjs';
12
- import { getBinIb, getIbGibsFromCache_fallbackToSpaces } from '@ibgib/core-gib/dist/common/other/ibgib-helper.mjs';
30
+ import { getBinIb, getIbGibsFromCache_fallbackToSpaces, splitPerTjpAndOrDna, getTimelinesGroupedByTjp } from '@ibgib/core-gib/dist/common/other/ibgib-helper.mjs';
31
+ import { getDependencyGraph } from '@ibgib/core-gib/dist/common/other/graph-helper.mjs';
13
32
  import { createGraftInfo } from '@ibgib/core-gib/dist/sync/graft-info/graft-info-helpers.mjs';
14
33
  import { GRAFT_INFO_REL8N_NAME } from '@ibgib/core-gib/dist/sync/graft-info/graft-info-constants.mjs';
15
34
  import { SyncConflictStrategy } from '@ibgib/core-gib/dist/sync/sync-constants.mjs';
16
35
  import { GLOBAL_LOG_A_LOT } from '../../vcs-gib-constants.mjs';
17
36
  import { isBinaryBuffer, decodeToLines, computeLineLcsDiff } from '../diff/line-diff-helper.mjs';
18
- import { B2TFS_CHILD_ITEM_REL8N_NAME, BINARY_REL8N_NAME, B2tFSType } from '../item/item-types.mjs';
37
+ import { BINARY_REL8N_NAME, B2tFSType } from '../item/item-types.mjs';
19
38
  import { evolveB2tFSItemIbGib, isB2tFSItemIbGib } from '../item/item-helper.mjs';
20
- const lcFile = `[b2tfs-3way-merge-strategy]`;
21
- const logalot = GLOBAL_LOG_A_LOT || true;
39
+ const lcFile = `[b2tfs-3way-graft-strategy]`;
40
+ const logalot = GLOBAL_LOG_A_LOT;
22
41
  const mergeDiag = `[MERGE DIAGNOSTIC]`;
23
42
  /**
24
43
  * Performs 3-way line diff merging across LCA, Base, and Orphan text lines.
@@ -26,9 +45,6 @@ const mergeDiag = `[MERGE DIAGNOSTIC]`;
26
45
  * line changes conflict.
27
46
  */
28
47
  export function perform3WayTextLineMerge({ textLCA, textBase, textOrphan, }) {
29
- console.log(`[DEBUG 3WAY] textLCA: ${JSON.stringify(textLCA)}`);
30
- console.log(`[DEBUG 3WAY] textBase: ${JSON.stringify(textBase)}`);
31
- console.log(`[DEBUG 3WAY] textOrphan: ${JSON.stringify(textOrphan)}`);
32
48
  if (textBase === textOrphan) {
33
49
  return { mergedText: textBase, hasConflict: false };
34
50
  }
@@ -114,38 +130,36 @@ export function perform3WayTextLineMerge({ textLCA, textBase, textOrphan, }) {
114
130
  hasConflict,
115
131
  };
116
132
  }
133
+ /**
134
+ * 3-way text line diff graft strategy for B2tFS file item timelines.
135
+ *
136
+ * ⚠️ **IMPORTANT**: Before making ANY changes to this class or its methods, consult:
137
+ * `libs/core-gib/src/sync/GRAFT_STRATEGY_GUIDANCE.md`.
138
+ */
117
139
  export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
118
140
  strategyId = 'B2tFS3WayGraftStrategy';
119
141
  lc = '[B2tFS3WayGraftStrategy]';
120
142
  /**
121
143
  * Returns true only if the graft context has two tips that are text-based file b2tfs item ibgibs.
122
144
  *
123
- * ## notes
124
- *
125
- * atow (08/12/2026) implementation is guantlet style: if cannot graft, return early
126
- *
127
145
  * @param context info about the divergent timelines {@link GraftContext}
128
- *
129
146
  * @returns true if it's a text file item ibgib, else false
130
147
  */
131
148
  async canGraft(context) {
132
149
  const lc = `${this.lc}[${this.canGraft.name}]`;
133
150
  try {
134
151
  const { conflictStrategy, timelineAddrsA, timelineAddrsB, ibGibReadCache, space } = context;
135
- // todo: refactor conflict strategy to be more generic: 'graft' | 'abort' | maybe something else.
136
152
  const hasRelevantStrategy = conflictStrategy === SyncConflictStrategy.optimisticWithLCS || conflictStrategy === 'b2tfs3WayMerge';
137
153
  if (!hasRelevantStrategy) {
138
- // immediately return false because we are not the chosen strategy.
139
- // todo: after refactor, really this should be out of the hands of the implementation and we should have a discriminator as part of the strategy interface. So the graft strategy pipeline executor can just check that first, and then if multiple found, it will delegate to this `canGraft` method.
140
- return false; /* <<<< returns early */
154
+ return false;
141
155
  }
142
156
  const tipAddrA = timelineAddrsA.at(-1);
143
157
  const tipAddrB = timelineAddrsB.at(-1);
144
158
  if (!tipAddrA || !tipAddrB) {
145
159
  if (logalot) {
146
- console.log(`${lc} we don't have two tip addrs? how was a graft decided upon? (I: b20b6de462c35e0e74360cc8d317f126)`);
160
+ console.log(`${lc} we don't have two tip addrs? (I: b20b6de462c35e0e74360cc8d317f126)`);
147
161
  }
148
- return false; /* <<<< returns early */
162
+ return false;
149
163
  }
150
164
  const [tipA, tipB] = await getIbGibsFromCache_fallbackToSpaces({
151
165
  addrs: [tipAddrA, tipAddrB],
@@ -153,28 +167,26 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
153
167
  space,
154
168
  });
155
169
  if (!tipA) {
156
- throw new Error(`(UNEXPECTED) tipA falsy? couldn't get tipA? should have been available to us in the temp space or cache.(E: 752101026888140f074614e893531826)`);
170
+ throw new Error(`(UNEXPECTED) tipA falsy? (E: 752101026888140f074614e893531826)`);
157
171
  }
158
172
  if (!tipB) {
159
- throw new Error(`(UNEXPECTED) tipB falsy? couldn't get tipB? should have been available to us in the temp space or cache. (E: d4d4a876cad8c7869830d33832bfde26)`);
173
+ throw new Error(`(UNEXPECTED) tipB falsy? (E: d4d4a876cad8c7869830d33832bfde26)`);
160
174
  }
161
175
  const bothTipsAreB2tFSNodes = isB2tFSItemIbGib(tipA) && isB2tFSItemIbGib(tipB);
162
176
  if (!bothTipsAreB2tFSNodes) {
163
- // at this point, we're returning false. But I'm being extra defensive since this algorithm is so difficult to implement. So throw if somehow only one is a b2tfs item
164
177
  if (isB2tFSItemIbGib(tipA) || isB2tFSItemIbGib(tipB)) {
165
178
  console.error(`${lc}${mergeDiag} (UNEXPECTED)(NOT THROWN) only tipA or tipB but not both are b2tfs items? (E: cacb38796da881268898e9d1af245826)`);
166
179
  }
167
- return false; /* <<<< returns early */
180
+ return false;
168
181
  }
169
182
  if (tipA.data.fsType !== tipB.data.fsType) {
170
- throw new Error(`(UNEXPECTED) tipA.data.fsType (${tipA.data.fsType}) !== tipB.data.fsType (${tipB.data.fsType})? both tips are expected to be the same B2tFSType. (E: c01c1885ac738f679813117852c48426)`);
183
+ throw new Error(`(UNEXPECTED) tipA.data.fsType (${tipA.data.fsType}) !== tipB.data.fsType (${tipB.data.fsType})? (E: c01c1885ac738f679813117852c48426)`);
171
184
  }
172
- // only do files. folders can use the replay dna strategy.
185
+ // only do files. folders and other containers fall back to DefaultDnaReplayGraftStrategy.
173
186
  const isFile = tipA.data.fsType === B2tFSType.file;
174
187
  if (!isFile) {
175
- return false; /* <<<< returns early */
188
+ return false;
176
189
  }
177
- // passed gauntlet, we have a b2tfs file item that we can merge
178
190
  return true;
179
191
  }
180
192
  catch (error) {
@@ -182,6 +194,16 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
182
194
  return false;
183
195
  }
184
196
  }
197
+ /**
198
+ * Executes 3-way line diff text graft across LCA, Base, and Orphan file items.
199
+ *
200
+ * ⚠️ **CRITICAL CONTRACT**: Before modifying this method, review:
201
+ * `libs/core-gib/src/sync/GRAFT_STRATEGY_GUIDANCE.md`
202
+ * Ensure:
203
+ * 1. Monotonic `n` counter (`highestDataN = Math.max(...)`)
204
+ * 2. Full dependency graph inclusion in `ancillaryIbGibsCreated` (comments, bin stones, DNAs)
205
+ * 3. Self-contained destination branch space
206
+ */
185
207
  async graft(context) {
186
208
  const lc = `${lcFile}[${this.strategyId}][${this.graft.name}]`;
187
209
  try {
@@ -206,7 +228,7 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
206
228
  space,
207
229
  });
208
230
  const tipB_receiver = branchB_receiver_sinceLCA.at(-1);
209
- // 2. Base & Orphan tip determination (directional preference) via DRY base helper
231
+ // 2. Base & Orphan resolution via DRY helper
210
232
  const { baseTip, baseBranch, orphanTip, orphanBranch, } = this.resolveBaseAndOrphan({
211
233
  graftPreference,
212
234
  tipA_sender,
@@ -219,103 +241,10 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
219
241
  const orphanTipAddr = getIbGibAddr({ ibGib: orphanTip });
220
242
  const orphanBranchAddrs = orphanBranch.map(x => getIbGibAddr({ ibGib: x }));
221
243
  if (logalot) {
222
- console.log(`${lc} baseBranchAddrs:\n${baseBranchAddrs.join('\n')}\n(I: 2cad420d7bc822f798b8a8785f1f8c26)`);
244
+ console.log(`${lc} baseBranchAddrs:\n${baseBranchAddrs.join('\n')} (I: 2cad420d7bc822f798b8a8785f1f8c26)`);
245
+ console.log(`${lc} orphanBranchAddrs:\n${orphanBranchAddrs.join('\n')} (I: cc86489d6737e2aced42b585cba13526)`);
223
246
  }
224
- if (logalot) {
225
- console.log(`${lc} orphanBranchAddrs:\n${orphanBranchAddrs.join('\n')}\n(I: cc86489d6737e2aced42b585cba13526)`);
226
- }
227
- // 3. Replay orphan branch transforms onto base tip
228
- const [latestCommonFrameIbGib] = await getIbGibsFromCache_fallbackToSpaces({
229
- addrs: [latestCommonFrameAddr],
230
- space,
231
- });
232
- // It is non-trivial and not at all obvious, but the following approach is WRONG!!
233
- //
234
- // This is not a generic timeline, rather, this is a timeline that
235
- // is restricted to a b2tfs node, which itself has two
236
- // possibilities: file or folder. So we can't replay dna blindly
237
- // between the two branches and then try to do some kind of text
238
- // merge later. We must analyze each branch and decide how to handle
239
- // each change.
240
- //
241
- // NOTE: I have tweaked canGraft to only return true on
242
- // B2tFSType.file and not folders, to see if the dna replay is good
243
- // enough for folders, so we can concentrate on just files. Keep
244
- // that in mind when I discuss the following notes.
245
- //
246
- // what we know at this point:
247
- // * graft was invoked, so the sync engine detected divergence in
248
- // the two spaces, i.e., our two branches (branch-per-space)
249
- // * IOW, this is NOT a FF merge. That would have already been
250
- // applied and not triggered this graft.
251
- // * This is either a file or a folder b2tfs item.
252
- // * If it is a folder...
253
- // * How does git handle two folders merging, or does it?
254
- // * git is file-based, and handles folders only secondarily.
255
- // * How does our current vcs-gib diffing engine even detect if a
256
- // folder has moved? does it?
257
- // * If it is a file...
258
- // * Is there anything that can happen besides the related binary file changing?
259
- // * If there are multiple changes to the binary file, should we
260
- // do each of those file changes in the graft?
261
- // * we need to game out multiple scenarios to answer this.
262
- // * What about multiple changes to each branch? Do we squash
263
- // the orphan to a single change and then merge the final?
264
- // * It is possible we can even parameterize this in this
265
- // strategy object, but the caller would need to configure
266
- // this strategy ahead of each sync call if that is the case I
267
- // think.
268
- // * One thing to parameterize would be how to handle graft
269
- // points, as I just realized in the context of version
270
- // control systems, it is possible that we may want to
271
- // configure the sync/merge to drop/do something with large
272
- // binaries (or just files in general) in a specific way.
273
- // const dnaAddrsAlreadyAccountedFor: IbGibAddr[] = (latestCommonFrameIbGib?.rel8ns?.dna ?? []).concat();
274
- // const dnaAddrsToApply: IbGibAddr[] = [];
275
- // for (const orphanFrame of orphanBranch) {
276
- // if (!orphanFrame.rel8ns) { throw new Error(`(UNEXPECTED) orphanFrame.rel8ns falsy? (E: bc9a78ef8dbcd9748305d898bf1b2826)`); }
277
- // // I don't know if this is expected or not, but seems like if
278
- // // we're doing a merge, we are expecting the ibgib frames to
279
- // // have dna
280
- // if (!orphanFrame.rel8ns.dna || orphanFrame.rel8ns.dna.length === 0) {
281
- // throw new Error(`(UNEXPECTED) !orphanFrame.rel8ns.dna || orphanFrame.rel8ns.dna.length === 0? How can we be grafting when the orphan slice has no dna? (E: 7e58797aa2f98dfa811e8fa88c693826)`);
282
- // }
283
- // const orphanDnaAddrsToApply = getUniqueDnas({
284
- // base: dnaAddrsAlreadyAccountedFor,
285
- // extended: orphanFrame.rel8ns.dna,
286
- // throwIfExtendedDoesntContainBase: true,
287
- // });
288
- // orphanDnaAddrsToApply.forEach(x => dnaAddrsAlreadyAccountedFor.push(x));
289
- // orphanDnaAddrsToApply.forEach(x => dnaAddrsToApply.push(x));
290
- // }
291
- // const dnaIbGibsToApply = await getIbGibsFromCache_fallbackToSpaces({
292
- // addrs: dnaAddrsToApply,
293
- // readCache_graph: ibGibReadCache,
294
- // space,
295
- // });
296
- // if (logalot) { console.log(`${lc}${mergeDiag} dnaAddrsToApply addrs (${dnaAddrsToApply.length}): ${dnaAddrsToApply} (I: 78a8a82f540d520682664aa806f1b826)`); }
297
- // const createdIbGibs_Running: IbGib_V1[] = [];
298
- // const newGraftedIntermediateIbGibs_ordered: IbGib_V1[] = [];
299
- // const newGraftDnaIbGibs: IbGib_V1[] = [];
300
- // let currentGraftTip = await applyTransforms({
301
- // src: baseTip,
302
- // dnaAddrsToApplyToStoreVersion_MUTATES_IN_PLACE: dnaAddrsToApply.concat(),
303
- // allLocalIbGibs: dnaIbGibsToApply,
304
- // createdIbGibs_Running,
305
- // });
306
- // if (createdIbGibs_Running.length > 0) {
307
- // await putInSpace({ space, ibGibs: createdIbGibs_Running });
308
- // const { mapWithTjp_YesDna: newGraftedIbGibsMap } = splitPerTjpAndOrDna({ ibGibs: createdIbGibs_Running });
309
- // const newGraftedIbGibs_orderNotGuaranteed = Object.values(newGraftedIbGibsMap);
310
- // const newGraftedIbGibsByTjp = getTimelinesGroupedByTjp({ ibGibs: newGraftedIbGibs_orderNotGuaranteed });
311
- // if (Object.keys(newGraftedIbGibsByTjp).length > 0) {
312
- // Object.values(newGraftedIbGibsByTjp)[0].forEach(x => newGraftedIntermediateIbGibs_ordered.push(x));
313
- // for (const item of newGraftedIntermediateIbGibs_ordered) {
314
- // await registerNewIbGib({ ibGib: item, space });
315
- // }
316
- // }
317
- // }
318
- // 4. Perform 3-way filesystem tree merge across lcaItem, baseItem, orphanItem
247
+ // 3. Perform 3-way filesystem tree merge across lcaItem, baseItem, orphanItem
319
248
  const lcaNode = await this.fetchIbGib({ addr: latestCommonFrameAddr, space, readCache_graph: ibGibReadCache });
320
249
  if (!lcaNode) {
321
250
  throw new Error(`(UNEXPECTED) lcaNode falsy? (E: a8b2d80dc4f8ba1448fa280d89dfb626)`);
@@ -338,70 +267,47 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
338
267
  if (lcaItem.data.fsType !== orphanItem.data.fsType) {
339
268
  throw new Error(`(UNEXPECTED) lcaItem.data.fsType !== orphanItem.data.fsType? (E: 2813981c8c422b41f85a02fd8aa88226)`);
340
269
  }
341
- // all three fsTypes are equal
342
270
  const fsType = lcaItem.data.fsType;
343
271
  if (fsType === B2tFSType.folder) {
344
- throw new Error(`(UNEXPECTED) fsType === B2tFSType.folder? I have tweaked the canGraft so we should only be handling files atow (08/11/2026) (E: b282b8f77b18575378edb902bd80a826)`);
272
+ throw new Error(`(UNEXPECTED) fsType === B2tFSType.folder? Folders fall back to DefaultDnaReplayGraftStrategy and reification. (E: b282b8f77b18575378edb902bd80a826)`);
345
273
  }
346
274
  if (fsType !== B2tFSType.file) {
347
275
  throw new Error(`(UNEXPECTED) fsType (${fsType}) is not a file? (E: 272418fe2067ea3e16dac028e86d1a26)`);
348
276
  }
349
- const lcaPayload = await this.getFilePayloadBuffer({
350
- fileItem: lcaItem, space, readCache_graph: ibGibReadCache
351
- });
352
- if (lcaPayload === undefined) {
353
- if (logalot) {
354
- console.log(`${lc}${mergeDiag} lcaPayload undefined? (I: 59b25835cce856cea883cf989ceb3826)`);
355
- }
356
- }
357
- const basePayload = await this.getFilePayloadBuffer({
358
- fileItem: baseItem, space, readCache_graph: ibGibReadCache
359
- });
360
- if (basePayload === undefined) {
361
- if (logalot) {
362
- console.log(`${lc}${mergeDiag} basePayload undefined? (I: 54f05406dca85eb98821b79f7325c826)`);
363
- }
364
- }
365
- const orphanPayload = await this.getFilePayloadBuffer({
366
- fileItem: orphanItem, space, readCache_graph: ibGibReadCache
367
- });
368
- if (orphanPayload === undefined) {
369
- if (logalot) {
370
- console.log(`${lc}${mergeDiag} orphanPayload undefined? (I: cd8b785875b43fc6684c65d818edd826)`);
371
- }
372
- }
277
+ const lcaPayload = await this.getFilePayloadBuffer({ fileItem: lcaItem, space, readCache_graph: ibGibReadCache });
278
+ const basePayload = await this.getFilePayloadBuffer({ fileItem: baseItem, space, readCache_graph: ibGibReadCache });
279
+ const orphanPayload = await this.getFilePayloadBuffer({ fileItem: orphanItem, space, readCache_graph: ibGibReadCache });
373
280
  const isBaseBin = basePayload ? isBinaryBuffer(basePayload.buffer) : false;
374
281
  const isOrphanBin = orphanPayload ? isBinaryBuffer(orphanPayload.buffer) : false;
375
282
  const isLcaBin = lcaPayload ? isBinaryBuffer(lcaPayload.buffer) : false;
376
283
  if (isBaseBin || isOrphanBin || isLcaBin) {
377
284
  if (logalot) {
378
- console.log(`${lc} Non-text binary file detected (${baseItem.data?.name}). Skipping 3-way line diff. (I: 4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b)`);
285
+ console.log(`${lc} Non-text binary file detected (${baseItem.data?.name}). Skipping 3-way line diff and falling through. (I: 4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b)`);
379
286
  }
380
- // even though we've gotten this far into this `graft` method,
381
- // we can still return `undefined` early if we decide we can't
382
- // handle it and we haven't persisted/registered any ibgibs. In
383
- // this particular case of 3-way text merges, we don't graft
384
- // non-text binary divergences, e.g., pics, sound files, etc.
385
- return undefined; /* <<<< returns early */
287
+ return undefined;
386
288
  }
387
289
  if (!lcaPayload) {
388
- throw new Error(`(UNEXPECTED) lcaPayload falsy? By this point in code, we have guaranteed that we are dealing with a text payload. (E: 0b82892204482f5538a430b8915b7826)`);
290
+ throw new Error(`(UNEXPECTED) lcaPayload falsy? (E: 0b82892204482f5538a430b8915b7826)`);
389
291
  }
390
292
  if (!basePayload) {
391
- throw new Error(`(UNEXPECTED) basePayload falsy? By this point in code, we have guaranteed that we are dealing with a text payload. (E: af1f68a020280b3a5d6ed4a812acd426)`);
293
+ throw new Error(`(UNEXPECTED) basePayload falsy? (E: af1f68a020280b3a5d6ed4a812acd426)`);
392
294
  }
393
295
  if (!orphanPayload) {
394
- throw new Error(`(UNEXPECTED) orphanPayload falsy? By this point in code, we have guaranteed that we are dealing with a text payload. (E: 6a521b684763862c3a2e0ca315d62826)`);
296
+ throw new Error(`(UNEXPECTED) orphanPayload falsy? (E: 6a521b684763862c3a2e0ca315d62826)`);
395
297
  }
396
298
  const textLCA = decodeToLines(lcaPayload.buffer).join('\n');
397
299
  const textBase = decodeToLines(basePayload.buffer).join('\n');
398
300
  const textOrphan = decodeToLines(orphanPayload.buffer).join('\n');
399
- console.log(`${lc}${mergeDiag} file: ${baseItem.data.name}`);
400
- console.log(`${lc}${mergeDiag} textLCA:\n${textLCA}`);
401
- console.log(`${lc}${mergeDiag} textBase:\n${textBase}`);
402
- console.log(`${lc}${mergeDiag} textOrphan:\n${textOrphan}`);
301
+ if (logalot) {
302
+ console.log(`${lc}${mergeDiag} file: ${baseItem.data.name}`);
303
+ console.log(`${lc}${mergeDiag} textLCA:\n${textLCA}`);
304
+ console.log(`${lc}${mergeDiag} textBase:\n${textBase}`);
305
+ console.log(`${lc}${mergeDiag} textOrphan:\n${textOrphan}`);
306
+ }
403
307
  const { mergedText } = perform3WayTextLineMerge({ textLCA, textBase, textOrphan });
404
- console.log(`${lc}${mergeDiag} mergedText:\n${mergedText}`);
308
+ if (logalot) {
309
+ console.log(`${lc}${mergeDiag} mergedText:\n${mergedText}`);
310
+ }
405
311
  const dataBuffer = Buffer.from(mergedText, 'utf8');
406
312
  const fileHash = await hash({ s: mergedText });
407
313
  if (baseItem.data.fileExt !== orphanItem.data.fileExt) {
@@ -419,7 +325,6 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
419
325
  };
420
326
  binIbGib.gib = await getGib({ ibGib: binIbGib, hasTjp: false });
421
327
  const binAddr = getIbGibAddr({ ibGib: binIbGib });
422
- // at this point, we are committed to performing the 3-way merge.
423
328
  await putInSpace({ ibGib: binIbGib, space });
424
329
  await registerNewIbGib({ ibGib: binIbGib, space });
425
330
  const fnGetN = (item) => {
@@ -432,25 +337,68 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
432
337
  };
433
338
  const baseItemDataN = fnGetN(baseItem);
434
339
  const orphanItemDataN = fnGetN(orphanItem);
435
- const lowestDataN = baseItemDataN <= orphanItemDataN ?
436
- baseItemDataN :
437
- orphanItemDataN;
340
+ const highestDataN = Math.max(baseItemDataN, orphanItemDataN);
341
+ const lcaCommentAddrs = lcaItem.rel8ns?.comment || [];
342
+ const lcaCommentAddrsSet = new Set(lcaCommentAddrs);
343
+ const mergedCommentAddrsSinceLCA_base = (baseItem.rel8ns?.comment || []).filter(addr => !lcaCommentAddrsSet.has(addr));
344
+ const mergedCommentAddrsSinceLCA_orphan = (orphanItem.rel8ns?.comment || []).filter(addr => !lcaCommentAddrsSet.has(addr));
345
+ const newCommentAddrs = Array.from(new Set([...mergedCommentAddrsSinceLCA_base, ...mergedCommentAddrsSinceLCA_orphan]));
346
+ const allMergedCommentAddrs = Array.from(new Set([...lcaCommentAddrs, ...newCommentAddrs]));
347
+ const commentDepIbGibs = [];
348
+ if (newCommentAddrs.length > 0) {
349
+ for (const cAddr of newCommentAddrs) {
350
+ const cIb = await this.fetchIbGib({ addr: cAddr, space, readCache_graph: ibGibReadCache });
351
+ if (!cIb) {
352
+ throw new Error(`(UNEXPECTED) Comment ibgib for address '${cAddr}' not found in cache or space (E: a1b2c3d4e5f67a8b9c0d1e2f3a4b5c6d)`);
353
+ }
354
+ commentDepIbGibs.push(cIb);
355
+ const cDepGraph = await getDependencyGraph({
356
+ ibGib: cIb,
357
+ space,
358
+ ibGibs: ibGibReadCache ? Object.values(ibGibReadCache) : undefined,
359
+ });
360
+ for (const depNode of Object.values(cDepGraph)) {
361
+ const depAddr = getIbGibAddr({ ibGib: depNode });
362
+ if (!commentDepIbGibs.some(x => getIbGibAddr({ ibGib: x }) === depAddr)) {
363
+ commentDepIbGibs.push(depNode);
364
+ }
365
+ }
366
+ }
367
+ const { mapWithTjp_YesDna, mapWithoutTjps } = splitPerTjpAndOrDna({ ibGibs: commentDepIbGibs });
368
+ // Put DNA and non-timeline stones into space with isDna flag
369
+ for (const dnaOrStone of Object.values(mapWithoutTjps)) {
370
+ if (space) {
371
+ await putInSpace({ ibGib: dnaOrStone, space, isDna: isDna({ ibGib: dnaOrStone }) });
372
+ }
373
+ }
374
+ // Register timeline frames in order
375
+ const timelinesByTjp = getTimelinesGroupedByTjp({ ibGibs: Object.values(mapWithTjp_YesDna) });
376
+ for (const tjpAddr of Object.keys(timelinesByTjp)) {
377
+ const timeline = timelinesByTjp[tjpAddr];
378
+ for (const frame of timeline) {
379
+ if (space) {
380
+ await putInSpace({ ibGib: frame, space });
381
+ await registerNewIbGib({ ibGib: frame, space });
382
+ }
383
+ }
384
+ }
385
+ }
438
386
  const evolveRes = await evolveB2tFSItemIbGib({
439
387
  existingItem: baseItem,
440
388
  dataToUpdate: {
441
389
  fileHash,
442
- n: lowestDataN + 1,
390
+ n: highestDataN + 1,
443
391
  },
444
392
  rel8nsToUpdate: {
445
393
  [BINARY_REL8N_NAME]: [binAddr],
394
+ ...(allMergedCommentAddrs.length > 0 ? { comment: allMergedCommentAddrs } : {}),
446
395
  },
447
396
  });
448
- // sanity checks
449
397
  if (!evolveRes.dnas) {
450
- throw new Error(`(UNEXPECTED) evolveRes.dnas falsy? We should be using dna when working with B2tFS items. (E: e640e892cc76c77f98f3881301035826)`);
398
+ throw new Error(`(UNEXPECTED) evolveRes.dnas falsy? (E: e640e892cc76c77f98f3881301035826)`);
451
399
  }
452
400
  if (!evolveRes.newIbGib) {
453
- throw new Error(`(UNEXPECTED) evolveRes.newIbGib falsy? we just did the merge, so this should be truthy. (E: 9e488d07772827b66a2aff4801905426)`);
401
+ throw new Error(`(UNEXPECTED) evolveRes.newIbGib falsy? (E: 9e488d07772827b66a2aff4801905426)`);
454
402
  }
455
403
  const newItemWithNewBinPayload = evolveRes.newIbGib;
456
404
  const newItemAddr = getIbGibAddr({ ibGib: newItemWithNewBinPayload });
@@ -461,27 +409,17 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
461
409
  const newGraftedIntermediateIbGibs_ordered = [];
462
410
  newGraftDnaIbGibs.push(...evolveRes.dnas);
463
411
  if (evolveRes.intermediateIbGibs) {
464
- // todo: when we have this completed, we should know whether or not there are intermediate ibgibs in all cases, some cases, or no cases (never). we should change this from an `if` block with no else to throw an unexpected error (assertion) if it is indeed unexpected
465
412
  evolveRes.intermediateIbGibs.forEach(x => newGraftedIntermediateIbGibs_ordered.push(x));
466
413
  }
467
414
  await persistTransformResult({ resTransform: evolveRes, space });
468
415
  await registerNewIbGib({ ibGib: evolveRes.newIbGib, space });
469
- const baseItemAddr = getIbGibAddr({ ibGib: baseItem });
470
- const mergedRootAddr = getIbGibAddr({ ibGib: newItemWithNewBinPayload });
471
- const currentRootAddr = baseItem ? getIbGibAddr({ ibGib: baseItem }) : undefined;
472
- /**
473
- * stupid word "details" is plural and I have this set to be an
474
- * array. don't have the ability to refactor right now, so this will
475
- * be mildly confusing unfortunately. Agents should not try to just
476
- * refactor this on the fly.
477
- */
478
416
  const b2tfsAddlGraftDetails = {
479
417
  baseTextB2tFSItemAddr: baseTipAddr,
480
418
  baseTextBinAddr: basePayload.binIbGib ? getIbGibAddr({ ibGib: basePayload.binIbGib }) : undefined,
481
419
  orphanTextB2tFSItemAddr: orphanTipAddr,
482
420
  orphanTextBinAddr: orphanPayload.binIbGib ? getIbGibAddr({ ibGib: orphanPayload.binIbGib }) : undefined,
483
421
  };
484
- // 6. Attach GraftInfo frame
422
+ // 4. Attach GraftInfo frame
485
423
  const graftInfo = await createGraftInfo({
486
424
  conflictStrategy,
487
425
  details: `Merged orphan tip text with the baseTip as a starting point.`,
@@ -520,7 +458,7 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
520
458
  dnasReplayed: [],
521
459
  dnasCreatedInGraft: newGraftDnaIbGibs,
522
460
  intermediateIbGibsCreatedInGraft: newGraftedIntermediateIbGibs_ordered,
523
- ancillaryIbGibsCreated: [binIbGib],
461
+ ancillaryIbGibsCreated: [binIbGib, ...commentDepIbGibs],
524
462
  newGraftTip: finalGraftTip,
525
463
  graftInfoCreated: graftInfo,
526
464
  };
@@ -539,23 +477,20 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
539
477
  if (!addr) {
540
478
  return undefined;
541
479
  }
542
- const cleanAddr = addr.includes('^') ? addr.split('^')[0] : addr;
543
480
  if (readCache_graph) {
544
- if (readCache_graph[cleanAddr]) {
545
- return readCache_graph[cleanAddr];
546
- }
547
481
  if (readCache_graph[addr]) {
548
482
  return readCache_graph[addr];
549
483
  }
550
- const matchingKey = Object.keys(readCache_graph).find(k => k === cleanAddr || k.startsWith(cleanAddr + '^') || (k.includes('^') && k.split('^')[0] === cleanAddr));
484
+ const gib = addr.includes('^') ? addr.substring(addr.lastIndexOf('^') + 1) : addr;
485
+ const matchingKey = Object.keys(readCache_graph).find(k => k === addr || (gib && k.endsWith('^' + gib)));
551
486
  if (matchingKey) {
552
487
  return readCache_graph[matchingKey];
553
488
  }
554
489
  }
555
490
  try {
556
- const res = await getFromSpace({ space, addrs: [addr, cleanAddr] });
557
- if (res && res.success && res.ibGibs && res.ibGibs.length > 0) {
558
- const found = res.ibGibs.find((x) => !!x);
491
+ const res = await getFromSpace({ space, addrs: [addr] });
492
+ if (res) {
493
+ const found = res.ibGibs?.find((x) => !!x) || res.rawResultIbGib?.ibGibs?.find((x) => !!x);
559
494
  if (found) {
560
495
  return found;
561
496
  }
@@ -563,8 +498,6 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
563
498
  }
564
499
  catch {
565
500
  // Suppress fetch error if address not found
566
- // why suppress? any ibgibs available to us here should be in space
567
- // (the temp space of the sync receiver)
568
501
  }
569
502
  return undefined;
570
503
  }
@@ -583,12 +516,10 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
583
516
  throw new Error(`(UNEXPECTED) node falsy? couldn't get node? (E: bd7d1c3b4a3881ff882746281869d826)`);
584
517
  }
585
518
  if (isB2tFSItemIbGib(node)) {
586
- // it's an item ibgib
587
519
  return node;
588
520
  }
589
521
  else {
590
- // not an item ibgib
591
- throw new Error(`(UNEXPECTED) node is not a B2tFSItemIbGib_V1? canGraft should have returned false then and we should never have gotten here. (E: ddabb281ccb2fb1a181109a82046b826)`);
522
+ throw new Error(`(UNEXPECTED) node is not a B2tFSItemIbGib_V1? (E: ddabb281ccb2fb1a181109a82046b826)`);
592
523
  }
593
524
  }
594
525
  async getFilePayloadBuffer({ fileItem, space, readCache_graph, }) {
@@ -606,7 +537,7 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
606
537
  }
607
538
  if (binIbGib.data === undefined) {
608
539
  return undefined;
609
- } // what if it's an empty file. will data be undefined? do we handle this at the b2tfs item level for fsType === 'file'?
540
+ }
610
541
  let fileData;
611
542
  const dataObj = binIbGib.data;
612
543
  if (dataObj && typeof dataObj === 'object' && dataObj._dataType === 'Uint8Array_Base64' && typeof dataObj.value === 'string') {
@@ -635,107 +566,5 @@ export class B2tFS3WayGraftStrategy extends GraftMergeStrategyBase_V1 {
635
566
  }
636
567
  return { buffer: fileData, binIbGib };
637
568
  }
638
- async getChildItemsMap({ folderItem, space, readCache_graph, }) {
639
- const map = new Map();
640
- if (!folderItem || !folderItem.rel8ns) {
641
- return map;
642
- }
643
- const childAddrs = folderItem.rel8ns[B2TFS_CHILD_ITEM_REL8N_NAME] || [];
644
- for (const addr of childAddrs) {
645
- const childNode = await this.fetchIbGib({ addr, space, readCache_graph });
646
- if (childNode && childNode.data?.name) {
647
- map.set(childNode.data.name, childNode);
648
- }
649
- }
650
- return map;
651
- }
652
- async mergeTreeNodes({ lcaItem, baseItem, orphanItem, space, readCache_graph, newGraftDnaIbGibs, newGraftedIntermediateIbGibs_ordered, }) {
653
- const lc = `${lcFile}[${this.mergeTreeNodes.name}]`;
654
- const baseAddr = baseItem ? getIbGibAddr({ ibGib: baseItem }) : undefined;
655
- const orphanAddr = orphanItem ? getIbGibAddr({ ibGib: orphanItem }) : undefined;
656
- const lcaAddr = lcaItem ? getIbGibAddr({ ibGib: lcaItem }) : undefined;
657
- if (baseAddr && orphanAddr && baseAddr === orphanAddr) {
658
- return baseItem;
659
- }
660
- if (lcaAddr && baseAddr && baseAddr === lcaAddr && orphanItem) {
661
- return orphanItem;
662
- }
663
- if (lcaAddr && orphanAddr && orphanAddr === lcaAddr && baseItem) {
664
- return baseItem;
665
- }
666
- if (!baseItem && !orphanItem) {
667
- return undefined;
668
- }
669
- if (baseItem && !orphanItem) {
670
- if (lcaAddr && baseAddr === lcaAddr) {
671
- return undefined;
672
- }
673
- return baseItem;
674
- }
675
- if (orphanItem && !baseItem) {
676
- if (lcaAddr && orphanAddr === lcaAddr) {
677
- return undefined;
678
- }
679
- return orphanItem;
680
- }
681
- if (!baseItem || !orphanItem) {
682
- throw new Error(`(UNEXPECTED) baseItem or orphanItem missing in 3-way merge branch (E: 5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a)`);
683
- }
684
- const fsType = baseItem.data?.fsType || orphanItem.data?.fsType;
685
- if (fsType === 'file') {
686
- }
687
- else if (fsType === 'folder') {
688
- // const lcaChildrenMap = await this.getChildItemsMap({ folderItem: lcaItem, space, readCache_graph });
689
- // const baseChildrenMap = await this.getChildItemsMap({ folderItem: baseItem, space, readCache_graph });
690
- // const orphanChildrenMap = await this.getChildItemsMap({ folderItem: orphanItem, space, readCache_graph });
691
- // const allChildAddrs = new Set([
692
- // ...lcaChildrenMap.keys(),
693
- // ...baseChildrenMap.keys(),
694
- // ...orphanChildrenMap.keys(),
695
- // ]);
696
- // const mergedChildAddrs: string[] = [];
697
- // for (const childItemAddr of allChildAddrs) {
698
- // const childLCA = lcaChildrenMap.get(childItemAddr);
699
- // const childBase = baseChildrenMap.get(childItemAddr);
700
- // const childOrphan = orphanChildrenMap.get(childItemAddr);
701
- // const mergedChild = await this.mergeTreeNodes({
702
- // lcaItem: childLCA,
703
- // baseItem: childBase,
704
- // orphanItem: childOrphan,
705
- // space,
706
- // readCache_graph,
707
- // newGraftDnaIbGibs,
708
- // newGraftedIntermediateIbGibs_ordered,
709
- // });
710
- // if (mergedChild) {
711
- // mergedChildAddrs.push(getIbGibAddr({ ibGib: mergedChild }));
712
- // }
713
- // }
714
- // const currentChildAddrs = baseItem.rel8ns?.[B2TFS_CHILD_ITEM_REL8N_NAME] || [];
715
- // const addrsChanged = mergedChildAddrs.length !== currentChildAddrs.length ||
716
- // mergedChildAddrs.some((addr, idx) => addr !== currentChildAddrs[idx]);
717
- // if (!addrsChanged) {
718
- // return baseItem;
719
- // }
720
- // const evolveRes = await evolveB2tFSItemIbGib({
721
- // existingItem: baseItem,
722
- // rel8nsToUpdate: {
723
- // [B2TFS_CHILD_ITEM_REL8N_NAME]: mergedChildAddrs,
724
- // },
725
- // rel8nsToRemove: {
726
- // [B2TFS_CHILD_ITEM_REL8N_NAME]: baseItem.rel8ns?.[B2TFS_CHILD_ITEM_REL8N_NAME] || [],
727
- // },
728
- // });
729
- // if (evolveRes.dnas) { newGraftDnaIbGibs.push(...evolveRes.dnas); }
730
- // if (evolveRes.newIbGib) { newGraftedIntermediateIbGibs_ordered.push(evolveRes.newIbGib); }
731
- // if (space) {
732
- // await persistTransformResult({ resTransform: evolveRes, space });
733
- // await registerNewIbGib({ ibGib: evolveRes.newIbGib, space });
734
- // }
735
- // return evolveRes.newIbGib as B2tFSItemIbGib_V1;
736
- }
737
- return baseItem;
738
- }
739
569
  }
740
- export const B2tFSItem3WayMergeStrategy = B2tFS3WayGraftStrategy;
741
- //# sourceMappingURL=b2tfs-3way-merge-strategy.mjs.map
570
+ //# sourceMappingURL=b2tfs-3way-graft-strategy.mjs.map