@ibgib/core-gib 0.1.28 → 0.1.29

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 (44) hide show
  1. package/dist/common/meta-stone/meta-stone-helper.d.mts.map +1 -1
  2. package/dist/common/meta-stone/meta-stone-helper.mjs +19 -7
  3. package/dist/common/meta-stone/meta-stone-helper.mjs.map +1 -1
  4. package/dist/sync/sync-helpers.d.mts +4 -4
  5. package/dist/sync/sync-helpers.d.mts.map +1 -1
  6. package/dist/sync/sync-helpers.mjs +12 -8
  7. package/dist/sync/sync-helpers.mjs.map +1 -1
  8. package/dist/sync/sync-innerspace-constants.respec.mjs +36 -36
  9. package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
  10. package/dist/sync/sync-innerspace-deep-updates.respec.mjs +5 -3
  11. package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
  12. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs +2 -2
  13. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
  14. package/dist/sync/sync-innerspace-partial-update.respec.mjs +3 -3
  15. package/dist/sync/sync-innerspace-partial-update.respec.mjs.map +1 -1
  16. package/dist/sync/sync-innerspace.respec.mjs +49 -20
  17. package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
  18. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts +0 -9
  19. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
  20. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +13 -42
  21. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
  22. package/dist/sync/sync-peer/sync-peer-v1.mjs +2 -2
  23. package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
  24. package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
  25. package/dist/sync/sync-saga-coordinator.mjs +261 -118
  26. package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
  27. package/dist/sync/sync-types.d.mts +12 -18
  28. package/dist/sync/sync-types.d.mts.map +1 -1
  29. package/dist/sync/sync-types.mjs +15 -21
  30. package/dist/sync/sync-types.mjs.map +1 -1
  31. package/package.json +1 -1
  32. package/src/common/meta-stone/meta-stone-helper.mts +17 -7
  33. package/src/sync/sync-helpers.mts +13 -9
  34. package/src/sync/sync-innerspace-constants.respec.mts +39 -39
  35. package/src/sync/sync-innerspace-deep-updates.respec.mts +6 -6
  36. package/src/sync/sync-innerspace-multiple-timelines.respec.mts +1 -1
  37. package/src/sync/sync-innerspace-partial-update.respec.mts +2 -2
  38. package/src/sync/sync-innerspace.respec.mts +20 -19
  39. package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +11 -58
  40. package/src/sync/sync-peer/sync-peer-v1.mts +2 -2
  41. package/src/sync/sync-saga-coordinator.mts +190 -126
  42. package/src/sync/sync-types.mts +19 -26
  43. package/test_output.log +0 -0
  44. package/tmp.md +170 -62
@@ -2,11 +2,12 @@ import { extractErrorMsg, getUUID, // so our timestamp in ticks as a string are
2
2
  pretty, delay, } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
3
3
  import { getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
4
4
  import { Factory_V1 } from "@ibgib/ts-gib/dist/V1/factory.mjs";
5
+ import { GLOBAL_LOG_A_LOT } from "../core-constants.mjs";
5
6
  import { putInSpace, getLatestAddrs, getFromSpace } from "../witness/space/space-helper.mjs";
6
7
  import { SyncStage, SYNC_ATOM, SYNC_MSG_REL8N_NAME, SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN, } from "./sync-constants.mjs";
7
8
  import { appendToTimeline, createTimeline } from "../timeline/timeline-api.mjs";
8
9
  import { SyncConflictStrategy, SyncMode, SYNC_CONFLICT_STRATEGY_VALID_VALUES, } from "./sync-types.mjs";
9
- import { getFullSyncSagaHistory, getSyncIb, getTempSpaceName, isPastFrame, putInSpace_dnasThenNonDnas, validateFullSyncSagaHistory } from "./sync-helpers.mjs";
10
+ import { getSyncSagaFrameOrigin, getFullSyncSagaHistory, getSyncIb, getTempSpaceName, isPastFrame, putInSpace_dnasThenNonDnas, validateFullSyncSagaHistory } from "./sync-helpers.mjs";
10
11
  import { getDeltaDependencyGraph, getDependencyGraph, toFlatGraph } from "../common/other/graph-helper.mjs";
11
12
  import { getSyncSagaMessageIb } from "./sync-saga-message/sync-saga-message-helpers.mjs";
12
13
  import { SYNC_SAGA_MSG_ATOM } from "./sync-saga-message/sync-saga-message-constants.mjs";
@@ -16,9 +17,8 @@ import { newupSubject, } from "../common/pubsub/subject/subject-helper.mjs";
16
17
  import { mergeDivergentTimelines } from "./strategies/conflict-optimistic.mjs";
17
18
  import { getSyncSagaMessageFromFrame } from "./sync-saga-message/sync-saga-message-helpers.mjs";
18
19
  import { fnObs } from "../common/pubsub/observer/observer-helper.mjs";
19
- // const logalot = GLOBAL_LOG_A_LOT || true;
20
- const logalot = true;
21
- const logalotControlDomain = true;
20
+ const logalot = GLOBAL_LOG_A_LOT;
21
+ const logalotControlDomain = false;
22
22
  const lcControlDomain = '[ControlDomain]';
23
23
  /**
24
24
  * Orchestrates the synchronization process between two spaces (Source and Destination).
@@ -407,8 +407,13 @@ export class SyncSagaCoordinator {
407
407
  metaspace,
408
408
  });
409
409
  if (!contextResult) {
410
+ // should this ever hit?
411
+ console.error(`${lc} NAG ERROR (DOES NOT THROW): does this ever hit now? (E: e04d02efc2a8e72a88b79f1f0f95ca26)`);
412
+ break;
413
+ }
414
+ else if (contextResult.nextFrameInfo?.sagaComplete) {
410
415
  if (logalot) {
411
- console.log(`${lc} Handler returned null (Saga End). (I: faae22abc818ba9b28ac6d2881cd7826)`);
416
+ console.log(`${lc} Handler returned null (Saga End). (I: 123bf9e7dca8886de72553a8d4f29e26)`);
412
417
  }
413
418
  break;
414
419
  }
@@ -419,9 +424,6 @@ export class SyncSagaCoordinator {
419
424
  else if (!contextResult.nextFrameInfo) {
420
425
  throw new Error(`(UNEXPECTED) contextResult.nextFrameInfo falsy? (E: c287a82e823e662a77923278e2418826)`);
421
426
  }
422
- else if (contextResult.nextFrameInfo?.sagaComplete) {
423
- throw new Error(`(UNEXPECTED) contextResult.nextFrameInfo.sagaComplete? logic flow should not have gotten here. (E: 104a32381db816b7183435e805b3d626)`);
424
- }
425
427
  // #endregion error conditions throw
426
428
  // we have another frame to process and send out, with possibly
427
429
  // payload domain ibgibs as well
@@ -730,14 +732,19 @@ export class SyncSagaCoordinator {
730
732
  sagaContext,
731
733
  sagaIbGib,
732
734
  srcGraph,
733
- metaspace,
734
- mySpace,
735
- myTempSpace,
735
+ metaspace, mySpace, myTempSpace,
736
736
  identity,
737
737
  });
738
738
  break;
739
739
  case SyncStage.commit:
740
- nextFrameInfo = await this.handleCommitFrame({ sagaIbGib, metaspace, mySpace: mySpace, myTempSpace: myTempSpace, identity, });
740
+ if (logalot) {
741
+ console.log(`${lc}[${getSyncSagaFrameOrigin({ sagaFrame: sagaIbGib })}] mySpace.ib: ${mySpace.ib} (I: 5b270996d848907238d817fffa64a126)`);
742
+ }
743
+ nextFrameInfo = await this.handleCommitFrame({
744
+ sagaIbGib,
745
+ metaspace, mySpace, myTempSpace,
746
+ identity,
747
+ });
741
748
  break;
742
749
  default:
743
750
  throw new Error(`${lc} (UNEXPECTED) Unknown sync stage: ${stage} (E: 9c2b4c8a6d34469f8263544710183355)`);
@@ -779,7 +786,9 @@ export class SyncSagaCoordinator {
779
786
  if (logalot) {
780
787
  console.log(`${lc} starting... (I: 9d88dcad0408c029e898a4bcf3b08426)`);
781
788
  }
782
- console.log(`${lc} [TEST DEBUG] Receiver mySpace: ${mySpace.ib}`);
789
+ if (logalot) {
790
+ console.log(`${lc} [TEST DEBUG] Receiver mySpace: ${mySpace.ib}`);
791
+ }
783
792
  // Extract Init Data
784
793
  const initData = messageData; // Using renamed variable for clarity
785
794
  if (initData.stage !== SyncStage.init) {
@@ -827,7 +836,9 @@ export class SyncSagaCoordinator {
827
836
  console.log(`${lc} remoteKV: ${pretty(remoteKV)} (I: 9f957862356dfeae183c200854e86e26)`);
828
837
  }
829
838
  const remoteTjps = Object.keys(remoteKV);
830
- console.log(`${lc} [TEST DEBUG] remoteTjps: ${JSON.stringify(remoteTjps)}`);
839
+ if (logalot) {
840
+ console.log(`${lc} [TEST DEBUG] remoteTjps: ${JSON.stringify(remoteTjps)}`);
841
+ }
831
842
  if (logalot) {
832
843
  console.log(`${lc} remoteTjps: ${pretty(remoteTjps)} (I: 86ea4c53db0dc184c8b253386c402126)`);
833
844
  }
@@ -846,7 +857,9 @@ export class SyncSagaCoordinator {
846
857
  throw new Error(`(UNEXPECTED) resGetLatestAddrs.data.latestAddrsMap falsy? (E: 16bc386dd51d0ff53a49620b1e641826)`);
847
858
  }
848
859
  localLatestAddrsMap = resGetLatestAddrs.data.latestAddrsMap;
849
- console.log(`${lc} [TEST DEBUG] localKV: ${JSON.stringify(localLatestAddrsMap)}`);
860
+ if (logalot) {
861
+ console.log(`${lc} [TEST DEBUG] localKV: ${JSON.stringify(localLatestAddrsMap)}`);
862
+ }
850
863
  if (logalot) {
851
864
  console.log(`${lc} localKV: ${pretty(localLatestAddrsMap)} (I: 980975642cbccd8018cf0cd808d30826)`);
852
865
  }
@@ -857,7 +870,9 @@ export class SyncSagaCoordinator {
857
870
  const localAddr = localLatestAddrsMap[tjp];
858
871
  if (!localAddr) {
859
872
  // We (Receiver) don't have this timeline at all. Request it.
860
- console.log(`${lc} [TEST DEBUG] Missing local timeline for TJP: ${tjp}. Requesting remoteAddr: ${remoteAddr}`);
873
+ if (logalot) {
874
+ console.log(`${lc} [TEST DEBUG] Missing local timeline for TJP: ${tjp}. Requesting remoteAddr: ${remoteAddr}`);
875
+ }
861
876
  deltaRequestAddrInfos.push({
862
877
  addr: remoteAddr,
863
878
  tjpAddr: tjp,
@@ -869,10 +884,14 @@ export class SyncSagaCoordinator {
869
884
  // we do have this timeline...
870
885
  if (localAddr === remoteAddr) {
871
886
  // ...already synced
872
- console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Synced (localAddr === remoteAddr)`);
887
+ if (logalot) {
888
+ console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Synced (localAddr === remoteAddr)`);
889
+ }
873
890
  continue;
874
891
  }
875
- console.log(`${lc} [TEST DEBUG] TJP ${tjp}: localAddr=${localAddr}, remoteAddr=${remoteAddr} - checking for divergence...`);
892
+ if (logalot) {
893
+ console.log(`${lc} [TEST DEBUG] TJP ${tjp}: localAddr=${localAddr}, remoteAddr=${remoteAddr} - checking for divergence...`);
894
+ }
876
895
  // we have this timeline but it's not synced...
877
896
  // We're executing on receiver. Check if Remote (Sender) is in
878
897
  // our past, and if so, we are ahead and need to push the delta
@@ -885,7 +904,9 @@ export class SyncSagaCoordinator {
885
904
  if (remoteIsInPast) {
886
905
  // we're ahead, so push the delta of what the sender doesn't
887
906
  // have (we have full knowledge)
888
- console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Remote (sender) is in past - offering push`);
907
+ if (logalot) {
908
+ console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Remote (sender) is in past - offering push`);
909
+ }
889
910
  const deltaGraph = await getDeltaDependencyGraph({
890
911
  ibGibAddr: localAddr,
891
912
  live: false, // always live: false right?
@@ -921,7 +942,9 @@ export class SyncSagaCoordinator {
921
942
  }
922
943
  if (localIsInPast) {
923
944
  // Fast-Forward: We update to remote's tip.
924
- console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Local is in past - requesting delta`);
945
+ if (logalot) {
946
+ console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Local is in past - requesting delta`);
947
+ }
925
948
  deltaRequestAddrInfos.push({
926
949
  addr: remoteAddr,
927
950
  tjpAddr: tjp,
@@ -930,7 +953,9 @@ export class SyncSagaCoordinator {
930
953
  }
931
954
  else {
932
955
  // DIVERGENCE: Both have changes the other doesn't know about.
933
- console.log(`${lc} [TEST DEBUG] TJP ${tjp}: DIVERGENCE DETECTED! conflictStrategy=${conflictStrategy}`);
956
+ if (logalot) {
957
+ console.log(`${lc} [TEST DEBUG] TJP ${tjp}: DIVERGENCE DETECTED! conflictStrategy=${conflictStrategy}`);
958
+ }
934
959
  if (conflictStrategy === 'abort') {
935
960
  // Abort Strategy: We will treat this as terminal.
936
961
  // But for Unified Ack, we just mark it terminal in the list?
@@ -1134,13 +1159,17 @@ export class SyncSagaCoordinator {
1134
1159
  // #region sanity/validation
1135
1160
  // 1. Check for Conflicts
1136
1161
  const conflicts = ackData.conflicts || [];
1137
- console.log(`${lc} [CONFLICT DEBUG] Received conflicts from Ack: ${conflicts.length}`);
1138
- if (conflicts.length > 0) {
1162
+ if (logalot) {
1163
+ console.log(`${lc} [CONFLICT DEBUG] Received conflicts from Ack: ${conflicts.length}`);
1164
+ }
1165
+ if (logalot && conflicts.length > 0) {
1139
1166
  console.log(`${lc} [CONFLICT DEBUG] Conflicts detail: ${JSON.stringify(conflicts, null, 2)}`);
1140
1167
  }
1141
1168
  const terminalConflicts = conflicts.filter(c => c.terminal);
1142
1169
  if (terminalConflicts.length > 0) {
1143
- console.warn(`${lc} Received terminal conflicts from Ack: ${JSON.stringify(terminalConflicts)}`);
1170
+ if (logalot) {
1171
+ console.warn(`${lc} Received terminal conflicts from Ack: ${JSON.stringify(terminalConflicts)}`);
1172
+ }
1144
1173
  // Terminal failure. Sender should probably Commit(Fail) or just Abort.
1145
1174
  // For now, throw to trigger abort.
1146
1175
  throw new Error(`${lc} Peer reported terminal conflicts. (E: 23a0096ee05a2ccfa89334e8f156b426)`);
@@ -1153,7 +1182,9 @@ export class SyncSagaCoordinator {
1153
1182
  */
1154
1183
  const outgoingDeltaAddrRequestInfos = []; // Additional requests for merging
1155
1184
  if (conflicts.length > 0) {
1156
- console.log(`${lc} [CONFLICT DEBUG] Processing ${conflicts.length} non-terminal conflicts`);
1185
+ if (logalot) {
1186
+ console.log(`${lc} [CONFLICT DEBUG] Processing ${conflicts.length} non-terminal conflicts`);
1187
+ }
1157
1188
  // We need to resolve these.
1158
1189
  // Strategy:
1159
1190
  // 1. Analyze Divergence (Sender vs Receiver)
@@ -1261,10 +1292,14 @@ export class SyncSagaCoordinator {
1261
1292
  // console.log(`${lc} [CONFLICT DEBUG] No receiver-only frames found for this conflict`);
1262
1293
  // }
1263
1294
  }
1264
- console.log(`${lc} [CONFLICT DEBUG] Finished processing ${conflicts.length} conflicts. outgoingDeltaAddrRequestInfos: ${outgoingDeltaAddrRequestInfos.length}`);
1295
+ if (logalot) {
1296
+ console.log(`${lc} [CONFLICT DEBUG] Finished processing ${conflicts.length} conflicts. outgoingDeltaAddrRequestInfos: ${outgoingDeltaAddrRequestInfos.length}`);
1297
+ }
1265
1298
  }
1266
1299
  else {
1267
- console.log(`${lc} [CONFLICT DEBUG] No optimistic conflicts to process`);
1300
+ if (logalot) {
1301
+ console.log(`${lc} [CONFLICT DEBUG] No optimistic conflicts to process`);
1302
+ }
1268
1303
  }
1269
1304
  // 2. Prepare Delta Payload (What Receiver Requesting + Our Conflict Logic)
1270
1305
  /**
@@ -1364,32 +1399,44 @@ export class SyncSagaCoordinator {
1364
1399
  console.log(`${lc} deltaData: ${pretty(deltaData)} (I: a76008681df458cfbcdc4848f825a826)`);
1365
1400
  }
1366
1401
  // #endregion validate/sanity
1367
- console.log(`${lc} [CONFLICT DEBUG] deltaData.payloadAddrs count: ${deltaData.payloadAddrs?.length || 0}`);
1402
+ if (logalot) {
1403
+ console.log(`${lc} [CONFLICT DEBUG] deltaData.payloadAddrs count: ${deltaData.payloadAddrs?.length || 0}`);
1404
+ }
1368
1405
  const peerProposesCommit = deltaData.proposeCommit || false;
1369
1406
  /**
1370
1407
  * these are already in the local temp space
1371
1408
  */
1372
1409
  const receivedPayloadIbGibs = sagaContext.payloadIbGibsDomain ?? [];
1373
1410
  // 2. Fulfill Peer Requests (Outgoing Payload with Delta Dependencies)
1374
- console.log(`${lc} [CONFLICT DEBUG] Fulfilling ${(deltaData.deltaRequestAddrInfos || []).length} peer requests`);
1411
+ if (logalot) {
1412
+ console.log(`${lc} [CONFLICT DEBUG] Fulfilling ${(deltaData.deltaRequestAddrInfos || []).length} peer requests`);
1413
+ }
1375
1414
  const outgoingPayload = await this.getPayloadsForRequestedInfos({
1376
1415
  deltaRequestAddrInfos: deltaData.deltaRequestAddrInfos || [],
1377
1416
  mySpace,
1378
1417
  });
1379
- console.log(`${lc} [CONFLICT DEBUG] Outgoing payload size (with deps): ${outgoingPayload.length}`);
1418
+ if (logalot) {
1419
+ console.log(`${lc} [CONFLICT DEBUG] Outgoing payload size (with deps): ${outgoingPayload.length}`);
1420
+ }
1380
1421
  // 3. Execute Merges (If applicable)
1381
1422
  // Check if we have pending conflicts that we CAN resolve now that we have data.
1382
1423
  // We look at the Saga History (Ack Frame) to find conflicts.
1383
1424
  // Optimization: Do this only if we received payloads.
1384
1425
  const mergeResultIbGibs = [];
1385
- console.log(`${lc} [CONFLICT DEBUG] Checking for merge. receivedPayloadIbGibs.length: ${receivedPayloadIbGibs.length}`);
1426
+ if (logalot) {
1427
+ console.log(`${lc} [CONFLICT DEBUG] Checking for merge. receivedPayloadIbGibs.length: ${receivedPayloadIbGibs.length}`);
1428
+ }
1386
1429
  if (receivedPayloadIbGibs.length > 0) {
1387
- console.log(`${lc} [TEST DEBUG] Received Payloads (${receivedPayloadIbGibs.length}). Checking for conflicts/merges...`);
1430
+ if (logalot) {
1431
+ console.log(`${lc} [TEST DEBUG] Received Payloads (${receivedPayloadIbGibs.length}). Checking for conflicts/merges...`);
1432
+ }
1388
1433
  // Find the Ack frame in history to get conflicts
1389
1434
  // Optimization: Batch fetch history from `sagaIbGib.rel8ns.past`
1390
1435
  // V1 timelines carry full history in `past`.
1391
1436
  const pastAddrs = sagaIbGib.rel8ns?.past || [];
1392
- console.log(`${lc} [TEST DEBUG] pastAddrs count: ${pastAddrs.length}`);
1437
+ if (logalot) {
1438
+ console.log(`${lc} [TEST DEBUG] pastAddrs count: ${pastAddrs.length}`);
1439
+ }
1393
1440
  const sagaHistory = await getFullSyncSagaHistory({
1394
1441
  sagaIbGib,
1395
1442
  space: mySpace,
@@ -1428,9 +1475,13 @@ export class SyncSagaCoordinator {
1428
1475
  // We blindly attempt merge if we have both tips accessible?
1429
1476
  // We need `receiverTip` (localAddr in Ack) and `senderTip` (remoteAddr).
1430
1477
  // Check if we have receiverTip in space
1431
- console.log(`${lc} [CONFLICT DEBUG] Attempting merge for conflict. ReceiverTip: ${receiverTip}, SenderTip: ${senderTip}`);
1478
+ if (logalot) {
1479
+ console.log(`${lc} [CONFLICT DEBUG] Attempting merge for conflict. ReceiverTip: ${receiverTip}, SenderTip: ${senderTip}`);
1480
+ }
1432
1481
  const resRecTip = await getFromSpace({ addr: receiverTip, space: myTempSpace }); // Check myTempSpace for incoming data
1433
- console.log(`${lc} [CONFLICT DEBUG] ReceiverTip found in myTempSpace: ${!!resRecTip.ibGibs?.[0]}`);
1482
+ if (logalot) {
1483
+ console.log(`${lc} [CONFLICT DEBUG] ReceiverTip found in myTempSpace: ${!!resRecTip.ibGibs?.[0]}`);
1484
+ }
1434
1485
  if (resRecTip.success && resRecTip.ibGibs?.[0]) {
1435
1486
  // We have the tip!
1436
1487
  // Do we have the full history?
@@ -1445,7 +1496,9 @@ export class SyncSagaCoordinator {
1445
1496
  metaspace,
1446
1497
  });
1447
1498
  if (mergeResult) {
1448
- console.log(`${lc} [TEST DEBUG] Merge success! New Tip: ${getIbGibAddr({ ibGib: mergeResult })}`);
1499
+ if (logalot) {
1500
+ console.log(`${lc} [TEST DEBUG] Merge success! New Tip: ${getIbGibAddr({ ibGib: mergeResult })}`);
1501
+ }
1449
1502
  if (logalot) {
1450
1503
  console.log(`${lc} Merge success! New Tip: ${getIbGibAddr({ ibGib: mergeResult })}`);
1451
1504
  }
@@ -1454,7 +1507,7 @@ export class SyncSagaCoordinator {
1454
1507
  }
1455
1508
  }
1456
1509
  catch (e) {
1457
- console.error(`${lc} Merge failed: ${e}`);
1510
+ console.error(`${lc} (NOT THROWN) Merge failed: ${e} (E: 491b464fc6f4857f52ff3df213105826)`);
1458
1511
  // If merge fails, we might Abort or just continue?
1459
1512
  }
1460
1513
  }
@@ -1602,15 +1655,47 @@ export class SyncSagaCoordinator {
1602
1655
  /**
1603
1656
  * should throw if fails
1604
1657
  */
1605
- async executeLocalCommit({ deltaFrame, sagaHistory, metaspace, localSpace, localTempSpace, identity, }) {
1658
+ async executeLocalCommit({ deltaFrame, commitFrame, sagaHistory, metaspace, localSpace, localTempSpace, identity, }) {
1606
1659
  const lc = `${this.lc}[${this.executeLocalCommit.name}]`;
1607
1660
  try {
1608
1661
  if (logalot) {
1609
1662
  console.log(`${lc} starting... (I: 6734980446b86a63c1af6e2e206de826)`);
1610
1663
  }
1664
+ if (!deltaFrame && !commitFrame) {
1665
+ throw new Error(`(UNEXPECTED) !deltaFrame && !commitFrame? we're expecting to execute the commit based off of EITHER a delta OR a commit frame. (E: 10cae319a2685a672866f5583514e326)`);
1666
+ }
1667
+ else if (deltaFrame && commitFrame) {
1668
+ throw new Error(`(UNEXPECTED) deltaFrame && commitFrame? we're expecting to execute the commit based off of EITHER a delta OR a commit frame. (E: b9037b1ed6d8684ac8a5d01328bad826)`);
1669
+ }
1670
+ /**
1671
+ * Sync has a two-stage commit. The first is from a delta frame with
1672
+ * `proposeCommit: true`. That produces a commit frame, which on the
1673
+ * other end triggers the second leg.
1674
+ */
1675
+ const isFirstCommitLeg = !!deltaFrame;
1676
+ const currentFrame = isFirstCommitLeg ? deltaFrame : commitFrame;
1677
+ if (!currentFrame) {
1678
+ throw new Error(`(UNEXPECTED) !currentFrame? something wrong with my logic. (E: 4ec0ce6625cc1d677bc902c839ca1a26)`);
1679
+ }
1680
+ /**
1681
+ * we only want to register new ibgibs from the other end, so we
1682
+ * will compare the history payloads/push offers with the context
1683
+ * that provided those payloads.
1684
+ *
1685
+ * So we will filter out the history that we produced, which should
1686
+ * leave us only with externally created payload addrs.
1687
+ *
1688
+ * NOTE: I have this at the beginning of the function PURELY to get
1689
+ * a log value in to understand the context of this function's
1690
+ * output.
1691
+ */
1692
+ const currentFrameOrigin = getSyncSagaFrameOrigin({ sagaFrame: currentFrame });
1693
+ if (logalot) {
1694
+ console.log(`${lc} currentFrameOrigin: ${currentFrameOrigin} (I: 3add8f8390c89743ae554bd3cc60b826)`);
1695
+ }
1611
1696
  // #region validate/sanity
1612
- if (!deltaFrame.data) {
1613
- throw new Error(`(UNEXPECTED) deltaFrame.data falsy? (E: a8be68d48668d93d992d793834823826)`);
1697
+ if (!currentFrame.data) {
1698
+ throw new Error(`(UNEXPECTED) currentFrame.data falsy? (E: a8be68d48668d93d992d793834823826)`);
1614
1699
  }
1615
1700
  // #endregion validate/sanity
1616
1701
  // * move all payload addrs from temp space to local space
@@ -1622,10 +1707,16 @@ export class SyncSagaCoordinator {
1622
1707
  allPayloadAddrsDomainTransferred.push(addr);
1623
1708
  }
1624
1709
  };
1625
- sagaHistory.forEach(x => {
1710
+ sagaHistory.filter(x => {
1711
+ const frameExecutionContext = getSyncSagaFrameOrigin({ sagaFrame: x.sagaIbGib });
1712
+ return currentFrameOrigin === frameExecutionContext;
1713
+ }).forEach(x => {
1626
1714
  if (!x.sagaIbGib.data) {
1627
1715
  throw new Error(`(UNEXPECTED) sagaIbGib.data falsy? (E: 34d7f8cdee14717ce828878d98f89826)`);
1628
1716
  }
1717
+ if (logalot) {
1718
+ console.log(`${lc}[${currentFrameOrigin}] history slice: ${pretty(x)} (I: e5a9436fb66b0df3183bd6d81be2ca26)`);
1719
+ }
1629
1720
  x.msgStones.forEach(msgStone => {
1630
1721
  if (!msgStone.data) {
1631
1722
  throw new Error(`(UNEXPECTED) msgStone.data falsy? (E: 21406101f91847514cc759c8a7382f26)`);
@@ -1646,58 +1737,101 @@ export class SyncSagaCoordinator {
1646
1737
  }
1647
1738
  });
1648
1739
  });
1740
+ if (logalot) {
1741
+ console.log(`${lc}[${currentFrameOrigin}] allPayloadAddrsDomainTransferred: ${allPayloadAddrsDomainTransferred.length > 0 ? allPayloadAddrsDomainTransferred.join(', ') : 'none'} (I: a1950eb3ca95bdc9ec18a4b8823e9826)`);
1742
+ }
1649
1743
  // at this point, we have a list of ALL payload addrs retrieved.
1650
1744
  let allPayloadIbGibsDomainTransferred = [];
1651
- const resGetAllTransferred = await getFromSpace({ addrs: allPayloadAddrsDomainTransferred, space: localTempSpace });
1652
- if (resGetAllTransferred.success && resGetAllTransferred.ibGibs && resGetAllTransferred.ibGibs.length === allPayloadAddrsDomainTransferred.length) {
1653
- allPayloadIbGibsDomainTransferred = resGetAllTransferred.ibGibs.concat();
1654
- }
1655
- else {
1656
- // errored out, gather info
1657
- if (!resGetAllTransferred.rawResultIbGib) {
1658
- throw new Error(`(UNEXPECTED) !resGetAllTransferred.rawResultIbGib falsy? (E: dc6cf8729668f4fbe8c024f887d97a26)`);
1745
+ if (allPayloadAddrsDomainTransferred.length > 0) {
1746
+ const resGetAllTransferred = await getFromSpace({ addrs: allPayloadAddrsDomainTransferred, space: localTempSpace });
1747
+ if (resGetAllTransferred.success && resGetAllTransferred.ibGibs && resGetAllTransferred.ibGibs.length === allPayloadAddrsDomainTransferred.length) {
1748
+ allPayloadIbGibsDomainTransferred = resGetAllTransferred.ibGibs.concat();
1749
+ }
1750
+ else {
1751
+ // errored out, gather info
1752
+ if (!resGetAllTransferred.rawResultIbGib) {
1753
+ throw new Error(`(UNEXPECTED) !resGetAllTransferred.rawResultIbGib falsy? (E: dc6cf8729668f4fbe8c024f887d97a26)`);
1754
+ }
1755
+ const { addrsNotFound, addrsErrored, errors } = resGetAllTransferred.rawResultIbGib.data;
1756
+ throw new Error(`(UNEXPECTED) we couldn't get all addrs transferred throughout the saga from the tempspace (${localTempSpace.ib})? addrsNotFound: ${addrsNotFound ?? []}. addrsErrored: ${addrsErrored ?? []}. errors: ${errors ?? []}(E: 222e341e634862b4d88ae7282584d826)`);
1659
1757
  }
1660
- const { addrsNotFound, addrsErrored, errors } = resGetAllTransferred.rawResultIbGib.data;
1661
- throw new Error(`(UNEXPECTED) we couldn't get all addrs transferred throughout the saga from the tempspace (${localTempSpace.ib})? addrsNotFound: ${addrsNotFound ?? []}. addrsErrored: ${addrsErrored ?? []}. errors: ${errors ?? []}(E: 222e341e634862b4d88ae7282584d826)`);
1662
1758
  }
1663
1759
  // now we have all ibgibs transferred, first put them all the local space
1664
- const { payload_Dnas, payload_NonDnas } = await putInSpace_dnasThenNonDnas({
1665
- ibGibs: allPayloadIbGibsDomainTransferred,
1666
- space: localSpace
1667
- });
1668
- const { mapWithTjp_NoDna, mapWithTjp_YesDna, mapWithoutTjps } = splitPerTjpAndOrDna({ ibGibs: payload_NonDnas, filterPrimitives: true });
1669
- // first register all non-tjp stones
1670
- const nontjps = Object.values(mapWithoutTjps);
1671
- for (const nontjp of nontjps) {
1672
- await metaspace.registerNewIbGib({
1673
- ibGib: nontjp,
1674
- space: localSpace,
1675
- });
1676
- }
1677
- // next register each timeline in order...
1678
- // ...first the ones without dna...
1679
- const timelinesByTjpAddr_NoDna = getTimelinesGroupedByTjp({ ibGibs: Object.values(mapWithTjp_NoDna) });
1680
- const tjpAddrs_NoDna = Object.keys(timelinesByTjpAddr_NoDna);
1681
- for (const tjpAddr_NoDna of tjpAddrs_NoDna) {
1682
- const timelineIbGibs = timelinesByTjpAddr_NoDna[tjpAddr_NoDna];
1683
- for (const ibGib of timelineIbGibs) {
1684
- await metaspace.registerNewIbGib({
1685
- ibGib,
1686
- space: localSpace,
1687
- });
1760
+ if (allPayloadIbGibsDomainTransferred.length === 0) {
1761
+ // nothing was synced
1762
+ if (logalot) {
1763
+ console.log(`${lc}[${currentFrameOrigin}] no changes on this end (I: fa30d18e83a87ee9e8487fbb5d632b26)`);
1688
1764
  }
1689
1765
  }
1690
- // ...then the ones WITH dna.
1691
- const timelinesByTjpAddr_YesDna = getTimelinesGroupedByTjp({ ibGibs: Object.values(mapWithTjp_YesDna) });
1692
- const tjpAddrs_YesDna = Object.keys(timelinesByTjpAddr_YesDna);
1693
- for (const tjpAddr_YesDna of tjpAddrs_YesDna) {
1694
- const timelineIbGibs = timelinesByTjpAddr_YesDna[tjpAddr_YesDna];
1695
- for (const ibGib of timelineIbGibs) {
1766
+ else {
1767
+ if (logalot) {
1768
+ console.log(`${lc}[${currentFrameOrigin}] ${allPayloadIbGibsDomainTransferred.length} changes detected (I: fa30d18e83a87ee9e8487fbb5d632b26)`);
1769
+ }
1770
+ if (logalot) {
1771
+ console.log(`${lc} put all into localSpace (${localSpace.ib}) starting... (I: d5e0d9870e380b61e80c729660058826)`);
1772
+ }
1773
+ const { payload_Dnas, payload_NonDnas } = await putInSpace_dnasThenNonDnas({
1774
+ ibGibs: allPayloadIbGibsDomainTransferred,
1775
+ space: localSpace
1776
+ });
1777
+ if (logalot) {
1778
+ console.log(`${lc} put all into localSpace (${localSpace.ib}) complete. (I: d5e0d9870e380b61e80c729660058826)`);
1779
+ }
1780
+ const { mapWithTjp_NoDna, mapWithTjp_YesDna, mapWithoutTjps } = splitPerTjpAndOrDna({ ibGibs: payload_NonDnas, filterPrimitives: true });
1781
+ // first register all non-tjp stones
1782
+ if (logalot) {
1783
+ console.log(`${lc} register mapWithoutTjps starting... (I: 2b84d8f8dda85adde88696d8419bf726)`);
1784
+ }
1785
+ const nontjps = Object.values(mapWithoutTjps);
1786
+ for (const nontjp of nontjps) {
1787
+ if (logalot) {
1788
+ console.log(`${lc} registering ${getIbGibAddr({ ibGib: nontjp })} (I: 4647b4f42d27cffe0fbfce8846755826)`);
1789
+ }
1696
1790
  await metaspace.registerNewIbGib({
1697
- ibGib,
1791
+ ibGib: nontjp,
1698
1792
  space: localSpace,
1699
1793
  });
1700
1794
  }
1795
+ if (logalot) {
1796
+ console.log(`${lc} mapWithoutTjps complete. (I: 2b84d8f8dda85adde88696d8419bf726)`);
1797
+ }
1798
+ // next register each timeline in order...
1799
+ // ...first the ones without dna...
1800
+ if (logalot) {
1801
+ console.log(`${lc} register mapWithTjp_NoDna starting... (I: 96e648e4db382499b8bfaa1b37c24826)`);
1802
+ }
1803
+ const timelinesByTjpAddr_NoDna = getTimelinesGroupedByTjp({ ibGibs: Object.values(mapWithTjp_NoDna) });
1804
+ const tjpAddrs_NoDna = Object.keys(timelinesByTjpAddr_NoDna);
1805
+ for (const tjpAddr_NoDna of tjpAddrs_NoDna) {
1806
+ const timelineIbGibs = timelinesByTjpAddr_NoDna[tjpAddr_NoDna];
1807
+ for (const ibGib of timelineIbGibs) {
1808
+ await metaspace.registerNewIbGib({
1809
+ ibGib,
1810
+ space: localSpace,
1811
+ });
1812
+ }
1813
+ }
1814
+ if (logalot) {
1815
+ console.log(`${lc} register mapWithTjp_NoDna complete. (I: 96e648e4db382499b8bfaa1b37c24826)`);
1816
+ }
1817
+ // ...then the ones WITH dna.
1818
+ if (logalot) {
1819
+ console.log(`${lc} register mapWithTjp_YesDna starting... (I: d54a820e9442dee4681f6228a6795926)`);
1820
+ }
1821
+ const timelinesByTjpAddr_YesDna = getTimelinesGroupedByTjp({ ibGibs: Object.values(mapWithTjp_YesDna) });
1822
+ const tjpAddrs_YesDna = Object.keys(timelinesByTjpAddr_YesDna);
1823
+ for (const tjpAddr_YesDna of tjpAddrs_YesDna) {
1824
+ const timelineIbGibs = timelinesByTjpAddr_YesDna[tjpAddr_YesDna];
1825
+ for (const ibGib of timelineIbGibs) {
1826
+ await metaspace.registerNewIbGib({
1827
+ ibGib,
1828
+ space: localSpace,
1829
+ });
1830
+ }
1831
+ }
1832
+ if (logalot) {
1833
+ console.log(`${lc} register mapWithTjp_YesDna complete. (I: d54a820e9442dee4681f6228a6795926)`);
1834
+ }
1701
1835
  }
1702
1836
  }
1703
1837
  catch (error) {
@@ -1760,46 +1894,55 @@ export class SyncSagaCoordinator {
1760
1894
  if (logalot) {
1761
1895
  console.log(`${lc} starting... (I: e179573bdd881202f8ba3168da1c3826)`);
1762
1896
  }
1763
- let resNextSagaFrameInfo;
1764
- // Sender Logic (Finalizing):
1765
- // If we are here, we received a Commit frame from the Peer.
1766
- // This implies the Peer has successfully committed.
1767
- // We should now:
1768
- // 1. Validate (implicitly done by receiving valid frame)
1769
- // 2. Perform our own cleanup (Temp -> Dest, if applicable)
1770
- // 3. Return saga completion.
1771
- // one last validate entire history?
1772
- const history = await getFullSyncSagaHistory({
1773
- sagaIbGib,
1774
- space: mySpace,
1775
- });
1776
- const validationErrors = await validateFullSyncSagaHistory({
1777
- history,
1778
- });
1779
- if (validationErrors.length > 0) {
1780
- const errorCommitFrame = await this.createCommitFrame({
1897
+ if (!sagaIbGib.data) {
1898
+ throw new Error(`(UNEXPECTED) sagaIbGib.data falsy? (E: cbc31dbb7d28b5b8c8cddb510d7d2826)`);
1899
+ }
1900
+ if (sagaIbGib.data.errors && sagaIbGib.data.errors.length > 0) {
1901
+ // our saga errored out but we already committed the darn
1902
+ // changes previously
1903
+ throw new Error(`not implemented...saga errored out on other end but we've already committed our changes. we need to implement undoing our changes, i.e., rollback commit, which basically is deleting all the payloads that we already put in in our previous commit. (E: e8eb789e0c08f0b3cf93607cb73e9f26)`);
1904
+ }
1905
+ else {
1906
+ // Sender Logic (Finalizing):
1907
+ // If we are here, we received a Commit frame from the Peer.
1908
+ // This implies the Peer has successfully committed.
1909
+ // We should now:
1910
+ // 1. Validate (implicitly done by receiving valid frame)
1911
+ // 2. Perform our own cleanup (Temp -> Dest, if applicable)
1912
+ // 3. Return saga completion.
1913
+ // one last validate entire history ?
1914
+ const history = await getFullSyncSagaHistory({
1781
1915
  sagaIbGib,
1916
+ space: mySpace,
1917
+ });
1918
+ const validationErrors = await validateFullSyncSagaHistory({
1919
+ history,
1920
+ });
1921
+ if (validationErrors.length > 0) {
1922
+ const errorCommitFrame = await this.createCommitFrame({
1923
+ sagaIbGib,
1924
+ metaspace,
1925
+ mySpace,
1926
+ identity,
1927
+ errors: validationErrors,
1928
+ });
1929
+ return { frame: errorCommitFrame, }; /* <<<< returns early */
1930
+ }
1931
+ await this.executeLocalCommit({
1932
+ commitFrame: sagaIbGib,
1933
+ sagaHistory: history,
1934
+ localSpace: mySpace,
1935
+ localTempSpace: myTempSpace,
1782
1936
  metaspace,
1783
- mySpace,
1784
- identity,
1785
- errors: validationErrors,
1786
1937
  });
1787
- return { frame: errorCommitFrame, }; /* <<<< returns early */
1788
- }
1789
- await this.executeLocalCommit({
1790
- deltaFrame: sagaIbGib,
1791
- sagaHistory: history,
1792
- localSpace: mySpace,
1793
- localTempSpace: myTempSpace,
1794
- metaspace,
1795
- });
1796
- // todo: implement explicit cleanup logic here and in peer
1797
- console.error(`${lc} NAG ERROR (NOT THROWN): implement cleanup logic, including add a cleanup method to the peer (E: 3a9a24befb98a981a88fbdbf52920e26)`);
1798
- if (logalot) {
1799
- console.log(`${lc} Peer committed. Finalizing saga locally. Saga Complete.`);
1938
+ // todo: implement explicit cleanup logic here and in peer
1939
+ console.error(`${lc} NAG ERROR (NOT THROWN): implement cleanup logic, including add a cleanup method to the peer (E: 3a9a24befb98a981a88fbdbf52920e26)`);
1940
+ if (logalot) {
1941
+ console.log(`${lc} Peer committed. Finalizing saga locally. Saga Complete.`);
1942
+ }
1943
+ // the holy grail!
1944
+ return { sagaComplete: true };
1800
1945
  }
1801
- // the holy grail!
1802
- return { sagaComplete: true };
1803
1946
  }
1804
1947
  catch (error) {
1805
1948
  const emsg = `${lc} ${extractErrorMsg(error)}`;