@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
@@ -29,11 +29,9 @@ import {
29
29
  SyncData_V1, SyncIbGib_V1, SyncConflictStrategy, SyncMode, SyncOptions,
30
30
  SyncRel8ns_V1, DomainIbGibAnalysisInfo, NextSagaFrameInfo,
31
31
  SYNC_CONFLICT_STRATEGY_VALID_VALUES, HandleSagaResponseContextResult,
32
- SyncExecutionContext,
33
- SYNC_EXECUTION_CONTEXT_VALID_VALUES,
34
32
  SyncSagaFrameDependencyGraph,
35
33
  } from "./sync-types.mjs";
36
- import { getExecutionContext, getFullSyncSagaHistory, getSyncIb, getTempSpaceName, isPastFrame, putInSpace_dnasThenNonDnas, validateFullSyncSagaHistory } from "./sync-helpers.mjs";
34
+ import { getSyncSagaFrameOrigin, getFullSyncSagaHistory, getSyncIb, getTempSpaceName, isPastFrame, putInSpace_dnasThenNonDnas, validateFullSyncSagaHistory } from "./sync-helpers.mjs";
37
35
  import { getDeltaDependencyGraph, getDependencyGraph, toFlatGraph } from "../common/other/graph-helper.mjs";
38
36
  import {
39
37
  SyncSagaMessageData_V1, SyncSagaMessageInitData_V1,
@@ -58,9 +56,8 @@ import { IbGibSpaceResultData, IbGibSpaceResultIbGib, IbGibSpaceResultRel8ns } f
58
56
  import { FlatIbGibGraph } from "../common/other/graph-types.mjs";
59
57
 
60
58
 
61
- // const logalot = GLOBAL_LOG_A_LOT || true;
62
- const logalot = true;
63
- const logalotControlDomain = true;
59
+ const logalot = GLOBAL_LOG_A_LOT;
60
+ const logalotControlDomain = false;
64
61
  const lcControlDomain = '[ControlDomain]';
65
62
 
66
63
  /**
@@ -505,7 +502,11 @@ export class SyncSagaCoordinator {
505
502
  });
506
503
 
507
504
  if (!contextResult) {
508
- if (logalot) { console.log(`${lc} Handler returned null (Saga End). (I: faae22abc818ba9b28ac6d2881cd7826)`); }
505
+ // should this ever hit?
506
+ console.error(`${lc} NAG ERROR (DOES NOT THROW): does this ever hit now? (E: e04d02efc2a8e72a88b79f1f0f95ca26)`);
507
+ break;
508
+ } else if (contextResult.nextFrameInfo?.sagaComplete) {
509
+ if (logalot) { console.log(`${lc} Handler returned null (Saga End). (I: 123bf9e7dca8886de72553a8d4f29e26)`); }
509
510
  break;
510
511
  }
511
512
 
@@ -514,8 +515,6 @@ export class SyncSagaCoordinator {
514
515
  throw new Error(`Couldn't handle response saga context. errorMsg: ${contextResult.errorMsg} (E: c948e81d513b2a0eb8b8afa878edc626)`);
515
516
  } else if (!contextResult.nextFrameInfo) {
516
517
  throw new Error(`(UNEXPECTED) contextResult.nextFrameInfo falsy? (E: c287a82e823e662a77923278e2418826)`);
517
- } else if (contextResult.nextFrameInfo?.sagaComplete) {
518
- throw new Error(`(UNEXPECTED) contextResult.nextFrameInfo.sagaComplete? logic flow should not have gotten here. (E: 104a32381db816b7183435e805b3d626)`);
519
518
  }
520
519
  // #endregion error conditions throw
521
520
 
@@ -901,15 +900,18 @@ export class SyncSagaCoordinator {
901
900
  sagaContext,
902
901
  sagaIbGib,
903
902
  srcGraph,
904
- metaspace,
905
- mySpace,
906
- myTempSpace,
903
+ metaspace, mySpace, myTempSpace,
907
904
  identity,
908
905
  });
909
906
  break;
910
907
 
911
908
  case SyncStage.commit:
912
- nextFrameInfo = await this.handleCommitFrame({ sagaIbGib, metaspace, mySpace: mySpace, myTempSpace: myTempSpace, identity, });
909
+ if (logalot) { console.log(`${lc}[${getSyncSagaFrameOrigin({ sagaFrame: sagaIbGib })}] mySpace.ib: ${mySpace.ib} (I: 5b270996d848907238d817fffa64a126)`); }
910
+ nextFrameInfo = await this.handleCommitFrame({
911
+ sagaIbGib,
912
+ metaspace, mySpace, myTempSpace,
913
+ identity,
914
+ });
913
915
  break;
914
916
 
915
917
  default:
@@ -973,7 +975,7 @@ export class SyncSagaCoordinator {
973
975
  try {
974
976
  if (logalot) { console.log(`${lc} starting... (I: 9d88dcad0408c029e898a4bcf3b08426)`); }
975
977
 
976
- console.log(`${lc} [TEST DEBUG] Receiver mySpace: ${mySpace.ib}`);
978
+ if (logalot) { console.log(`${lc} [TEST DEBUG] Receiver mySpace: ${mySpace.ib}`); }
977
979
 
978
980
  // Extract Init Data
979
981
  const initData = messageData as SyncSagaMessageInitData_V1; // Using renamed variable for clarity
@@ -1018,7 +1020,7 @@ export class SyncSagaCoordinator {
1018
1020
  const remoteKV = initData.knowledgeVector;
1019
1021
  if (logalot) { console.log(`${lc} remoteKV: ${pretty(remoteKV)} (I: 9f957862356dfeae183c200854e86e26)`); }
1020
1022
  const remoteTjps = Object.keys(remoteKV);
1021
- console.log(`${lc} [TEST DEBUG] remoteTjps: ${JSON.stringify(remoteTjps)}`);
1023
+ if (logalot) { console.log(`${lc} [TEST DEBUG] remoteTjps: ${JSON.stringify(remoteTjps)}`); }
1022
1024
  if (logalot) { console.log(`${lc} remoteTjps: ${pretty(remoteTjps)} (I: 86ea4c53db0dc184c8b253386c402126)`); }
1023
1025
 
1024
1026
  // 1. Get Local Latest Addrs for all TJPs
@@ -1032,7 +1034,7 @@ export class SyncSagaCoordinator {
1032
1034
  if (!resGetLatestAddrs.data) { throw new Error(`(UNEXPECTED) resGetLatestAddrs.data falsy? (E: b180d813c088042b38e1e02e06a16926)`); }
1033
1035
  if (!resGetLatestAddrs.data.latestAddrsMap) { throw new Error(`(UNEXPECTED) resGetLatestAddrs.data.latestAddrsMap falsy? (E: 16bc386dd51d0ff53a49620b1e641826)`); }
1034
1036
  localLatestAddrsMap = resGetLatestAddrs.data.latestAddrsMap;
1035
- console.log(`${lc} [TEST DEBUG] localKV: ${JSON.stringify(localLatestAddrsMap)}`);
1037
+ if (logalot) { console.log(`${lc} [TEST DEBUG] localKV: ${JSON.stringify(localLatestAddrsMap)}`); }
1036
1038
  if (logalot) { console.log(`${lc} localKV: ${pretty(localLatestAddrsMap)} (I: 980975642cbccd8018cf0cd808d30826)`); }
1037
1039
  }
1038
1040
 
@@ -1043,7 +1045,7 @@ export class SyncSagaCoordinator {
1043
1045
 
1044
1046
  if (!localAddr) {
1045
1047
  // We (Receiver) don't have this timeline at all. Request it.
1046
- console.log(`${lc} [TEST DEBUG] Missing local timeline for TJP: ${tjp}. Requesting remoteAddr: ${remoteAddr}`);
1048
+ if (logalot) { console.log(`${lc} [TEST DEBUG] Missing local timeline for TJP: ${tjp}. Requesting remoteAddr: ${remoteAddr}`); }
1047
1049
  deltaRequestAddrInfos.push({
1048
1050
  addr: remoteAddr,
1049
1051
  tjpAddr: tjp,
@@ -1057,10 +1059,10 @@ export class SyncSagaCoordinator {
1057
1059
 
1058
1060
  if (localAddr === remoteAddr) {
1059
1061
  // ...already synced
1060
- console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Synced (localAddr === remoteAddr)`);
1062
+ if (logalot) { console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Synced (localAddr === remoteAddr)`); }
1061
1063
  continue;
1062
1064
  }
1063
- console.log(`${lc} [TEST DEBUG] TJP ${tjp}: localAddr=${localAddr}, remoteAddr=${remoteAddr} - checking for divergence...`);
1065
+ if (logalot) { console.log(`${lc} [TEST DEBUG] TJP ${tjp}: localAddr=${localAddr}, remoteAddr=${remoteAddr} - checking for divergence...`); }
1064
1066
 
1065
1067
  // we have this timeline but it's not synced...
1066
1068
 
@@ -1076,7 +1078,7 @@ export class SyncSagaCoordinator {
1076
1078
  if (remoteIsInPast) {
1077
1079
  // we're ahead, so push the delta of what the sender doesn't
1078
1080
  // have (we have full knowledge)
1079
- console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Remote (sender) is in past - offering push`);
1081
+ if (logalot) { console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Remote (sender) is in past - offering push`); }
1080
1082
  const deltaGraph = await getDeltaDependencyGraph({
1081
1083
  ibGibAddr: localAddr,
1082
1084
  live: false, // always live: false right?
@@ -1110,7 +1112,7 @@ export class SyncSagaCoordinator {
1110
1112
 
1111
1113
  if (localIsInPast) {
1112
1114
  // Fast-Forward: We update to remote's tip.
1113
- console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Local is in past - requesting delta`);
1115
+ if (logalot) { console.log(`${lc} [TEST DEBUG] TJP ${tjp}: Local is in past - requesting delta`); }
1114
1116
  deltaRequestAddrInfos.push({
1115
1117
  addr: remoteAddr,
1116
1118
  tjpAddr: tjp,
@@ -1118,7 +1120,7 @@ export class SyncSagaCoordinator {
1118
1120
  });
1119
1121
  } else {
1120
1122
  // DIVERGENCE: Both have changes the other doesn't know about.
1121
- console.log(`${lc} [TEST DEBUG] TJP ${tjp}: DIVERGENCE DETECTED! conflictStrategy=${conflictStrategy}`);
1123
+ if (logalot) { console.log(`${lc} [TEST DEBUG] TJP ${tjp}: DIVERGENCE DETECTED! conflictStrategy=${conflictStrategy}`); }
1122
1124
 
1123
1125
  if (conflictStrategy === 'abort') {
1124
1126
  // Abort Strategy: We will treat this as terminal.
@@ -1339,14 +1341,14 @@ export class SyncSagaCoordinator {
1339
1341
 
1340
1342
  // 1. Check for Conflicts
1341
1343
  const conflicts = ackData.conflicts || [];
1342
- console.log(`${lc} [CONFLICT DEBUG] Received conflicts from Ack: ${conflicts.length}`);
1343
- if (conflicts.length > 0) {
1344
+ if (logalot) { console.log(`${lc} [CONFLICT DEBUG] Received conflicts from Ack: ${conflicts.length}`); }
1345
+ if (logalot && conflicts.length > 0) {
1344
1346
  console.log(`${lc} [CONFLICT DEBUG] Conflicts detail: ${JSON.stringify(conflicts, null, 2)}`);
1345
1347
  }
1346
1348
 
1347
1349
  const terminalConflicts = conflicts.filter(c => c.terminal);
1348
1350
  if (terminalConflicts.length > 0) {
1349
- console.warn(`${lc} Received terminal conflicts from Ack: ${JSON.stringify(terminalConflicts)}`);
1351
+ if (logalot) { console.warn(`${lc} Received terminal conflicts from Ack: ${JSON.stringify(terminalConflicts)}`); }
1350
1352
  // Terminal failure. Sender should probably Commit(Fail) or just Abort.
1351
1353
  // For now, throw to trigger abort.
1352
1354
  throw new Error(`${lc} Peer reported terminal conflicts. (E: 23a0096ee05a2ccfa89334e8f156b426)`);
@@ -1362,7 +1364,7 @@ export class SyncSagaCoordinator {
1362
1364
  const outgoingDeltaAddrRequestInfos: SyncSagaRequestAddrInfo[] = []; // Additional requests for merging
1363
1365
 
1364
1366
  if (conflicts.length > 0) {
1365
- console.log(`${lc} [CONFLICT DEBUG] Processing ${conflicts.length} non-terminal conflicts`);
1367
+ if (logalot) { console.log(`${lc} [CONFLICT DEBUG] Processing ${conflicts.length} non-terminal conflicts`); }
1366
1368
  // We need to resolve these.
1367
1369
  // Strategy:
1368
1370
  // 1. Analyze Divergence (Sender vs Receiver)
@@ -1495,9 +1497,9 @@ export class SyncSagaCoordinator {
1495
1497
  // }
1496
1498
  }
1497
1499
 
1498
- console.log(`${lc} [CONFLICT DEBUG] Finished processing ${conflicts.length} conflicts. outgoingDeltaAddrRequestInfos: ${outgoingDeltaAddrRequestInfos.length}`);
1500
+ if (logalot) { console.log(`${lc} [CONFLICT DEBUG] Finished processing ${conflicts.length} conflicts. outgoingDeltaAddrRequestInfos: ${outgoingDeltaAddrRequestInfos.length}`); }
1499
1501
  } else {
1500
- console.log(`${lc} [CONFLICT DEBUG] No optimistic conflicts to process`);
1502
+ if (logalot) { console.log(`${lc} [CONFLICT DEBUG] No optimistic conflicts to process`); }
1501
1503
  }
1502
1504
 
1503
1505
  // 2. Prepare Delta Payload (What Receiver Requesting + Our Conflict Logic)
@@ -1608,7 +1610,7 @@ export class SyncSagaCoordinator {
1608
1610
  if (logalot) { console.log(`${lc} deltaData: ${pretty(deltaData)} (I: a76008681df458cfbcdc4848f825a826)`); }
1609
1611
  // #endregion validate/sanity
1610
1612
 
1611
- console.log(`${lc} [CONFLICT DEBUG] deltaData.payloadAddrs count: ${deltaData.payloadAddrs?.length || 0}`);
1613
+ if (logalot) { console.log(`${lc} [CONFLICT DEBUG] deltaData.payloadAddrs count: ${deltaData.payloadAddrs?.length || 0}`); }
1612
1614
 
1613
1615
  const peerProposesCommit = deltaData.proposeCommit || false;
1614
1616
 
@@ -1618,12 +1620,12 @@ export class SyncSagaCoordinator {
1618
1620
  const receivedPayloadIbGibs: IbGib_V1[] = sagaContext.payloadIbGibsDomain ?? [];
1619
1621
 
1620
1622
  // 2. Fulfill Peer Requests (Outgoing Payload with Delta Dependencies)
1621
- console.log(`${lc} [CONFLICT DEBUG] Fulfilling ${(deltaData.deltaRequestAddrInfos || []).length} peer requests`);
1623
+ if (logalot) { console.log(`${lc} [CONFLICT DEBUG] Fulfilling ${(deltaData.deltaRequestAddrInfos || []).length} peer requests`); }
1622
1624
  const outgoingPayload = await this.getPayloadsForRequestedInfos({
1623
1625
  deltaRequestAddrInfos: deltaData.deltaRequestAddrInfos || [],
1624
1626
  mySpace,
1625
1627
  });
1626
- console.log(`${lc} [CONFLICT DEBUG] Outgoing payload size (with deps): ${outgoingPayload.length}`);
1628
+ if (logalot) { console.log(`${lc} [CONFLICT DEBUG] Outgoing payload size (with deps): ${outgoingPayload.length}`); }
1627
1629
 
1628
1630
  // 3. Execute Merges (If applicable)
1629
1631
  // Check if we have pending conflicts that we CAN resolve now that we have data.
@@ -1631,15 +1633,15 @@ export class SyncSagaCoordinator {
1631
1633
  // Optimization: Do this only if we received payloads.
1632
1634
  const mergeResultIbGibs: IbGib_V1[] = [];
1633
1635
 
1634
- console.log(`${lc} [CONFLICT DEBUG] Checking for merge. receivedPayloadIbGibs.length: ${receivedPayloadIbGibs.length}`);
1636
+ if (logalot) { console.log(`${lc} [CONFLICT DEBUG] Checking for merge. receivedPayloadIbGibs.length: ${receivedPayloadIbGibs.length}`); }
1635
1637
 
1636
1638
  if (receivedPayloadIbGibs.length > 0) {
1637
- console.log(`${lc} [TEST DEBUG] Received Payloads (${receivedPayloadIbGibs.length}). Checking for conflicts/merges...`);
1639
+ if (logalot) { console.log(`${lc} [TEST DEBUG] Received Payloads (${receivedPayloadIbGibs.length}). Checking for conflicts/merges...`); }
1638
1640
  // Find the Ack frame in history to get conflicts
1639
1641
  // Optimization: Batch fetch history from `sagaIbGib.rel8ns.past`
1640
1642
  // V1 timelines carry full history in `past`.
1641
1643
  const pastAddrs = sagaIbGib.rel8ns?.past || [];
1642
- console.log(`${lc} [TEST DEBUG] pastAddrs count: ${pastAddrs.length}`);
1644
+ if (logalot) { console.log(`${lc} [TEST DEBUG] pastAddrs count: ${pastAddrs.length}`); }
1643
1645
 
1644
1646
  const sagaHistory = await getFullSyncSagaHistory({
1645
1647
  sagaIbGib,
@@ -1679,9 +1681,9 @@ export class SyncSagaCoordinator {
1679
1681
  // We need `receiverTip` (localAddr in Ack) and `senderTip` (remoteAddr).
1680
1682
 
1681
1683
  // Check if we have receiverTip in space
1682
- console.log(`${lc} [CONFLICT DEBUG] Attempting merge for conflict. ReceiverTip: ${receiverTip}, SenderTip: ${senderTip}`);
1684
+ if (logalot) { console.log(`${lc} [CONFLICT DEBUG] Attempting merge for conflict. ReceiverTip: ${receiverTip}, SenderTip: ${senderTip}`); }
1683
1685
  const resRecTip = await getFromSpace({ addr: receiverTip, space: myTempSpace }); // Check myTempSpace for incoming data
1684
- console.log(`${lc} [CONFLICT DEBUG] ReceiverTip found in myTempSpace: ${!!resRecTip.ibGibs?.[0]}`);
1686
+ if (logalot) { console.log(`${lc} [CONFLICT DEBUG] ReceiverTip found in myTempSpace: ${!!resRecTip.ibGibs?.[0]}`); }
1685
1687
  if (resRecTip.success && resRecTip.ibGibs?.[0]) {
1686
1688
  // We have the tip!
1687
1689
  // Do we have the full history?
@@ -1697,13 +1699,13 @@ export class SyncSagaCoordinator {
1697
1699
  metaspace,
1698
1700
  });
1699
1701
  if (mergeResult) {
1700
- console.log(`${lc} [TEST DEBUG] Merge success! New Tip: ${getIbGibAddr({ ibGib: mergeResult })}`);
1702
+ if (logalot) { console.log(`${lc} [TEST DEBUG] Merge success! New Tip: ${getIbGibAddr({ ibGib: mergeResult })}`); }
1701
1703
  if (logalot) { console.log(`${lc} Merge success! New Tip: ${getIbGibAddr({ ibGib: mergeResult })}`); }
1702
1704
  mergeResultIbGibs.push(mergeResult);
1703
1705
  outgoingPayload.push(mergeResult); // Send result to peer
1704
1706
  }
1705
1707
  } catch (e) {
1706
- console.error(`${lc} Merge failed: ${e}`);
1708
+ console.error(`${lc} (NOT THROWN) Merge failed: ${e} (E: 491b464fc6f4857f52ff3df213105826)`);
1707
1709
  // If merge fails, we might Abort or just continue?
1708
1710
  }
1709
1711
  }
@@ -1864,11 +1866,13 @@ export class SyncSagaCoordinator {
1864
1866
  */
1865
1867
  private async executeLocalCommit({
1866
1868
  deltaFrame,
1869
+ commitFrame,
1867
1870
  sagaHistory,
1868
1871
  metaspace, localSpace, localTempSpace,
1869
1872
  identity,
1870
1873
  }: {
1871
- deltaFrame: SyncIbGib_V1;
1874
+ deltaFrame?: SyncIbGib_V1;
1875
+ commitFrame?: SyncIbGib_V1;
1872
1876
  sagaHistory: SyncSagaFrameDependencyGraph[];
1873
1877
  metaspace: MetaspaceService;
1874
1878
  localSpace: IbGibSpaceAny;
@@ -1878,9 +1882,39 @@ export class SyncSagaCoordinator {
1878
1882
  const lc = `${this.lc}[${this.executeLocalCommit.name}]`;
1879
1883
  try {
1880
1884
  if (logalot) { console.log(`${lc} starting... (I: 6734980446b86a63c1af6e2e206de826)`); }
1885
+ if (!deltaFrame && !commitFrame) {
1886
+ 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)`);
1887
+ } else if (deltaFrame && commitFrame) {
1888
+ 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)`);
1889
+ }
1890
+
1891
+ /**
1892
+ * Sync has a two-stage commit. The first is from a delta frame with
1893
+ * `proposeCommit: true`. That produces a commit frame, which on the
1894
+ * other end triggers the second leg.
1895
+ */
1896
+ const isFirstCommitLeg = !!deltaFrame;
1897
+ const currentFrame = isFirstCommitLeg ? deltaFrame : commitFrame;
1898
+ if (!currentFrame) { throw new Error(`(UNEXPECTED) !currentFrame? something wrong with my logic. (E: 4ec0ce6625cc1d677bc902c839ca1a26)`); }
1899
+
1900
+ /**
1901
+ * we only want to register new ibgibs from the other end, so we
1902
+ * will compare the history payloads/push offers with the context
1903
+ * that provided those payloads.
1904
+ *
1905
+ * So we will filter out the history that we produced, which should
1906
+ * leave us only with externally created payload addrs.
1907
+ *
1908
+ * NOTE: I have this at the beginning of the function PURELY to get
1909
+ * a log value in to understand the context of this function's
1910
+ * output.
1911
+ */
1912
+ const currentFrameOrigin = getSyncSagaFrameOrigin({ sagaFrame: currentFrame });
1913
+
1914
+ if (logalot) { console.log(`${lc} currentFrameOrigin: ${currentFrameOrigin} (I: 3add8f8390c89743ae554bd3cc60b826)`); }
1881
1915
 
1882
1916
  // #region validate/sanity
1883
- if (!deltaFrame.data) { throw new Error(`(UNEXPECTED) deltaFrame.data falsy? (E: a8be68d48668d93d992d793834823826)`); }
1917
+ if (!currentFrame.data) { throw new Error(`(UNEXPECTED) currentFrame.data falsy? (E: a8be68d48668d93d992d793834823826)`); }
1884
1918
  // #endregion validate/sanity
1885
1919
 
1886
1920
  // * move all payload addrs from temp space to local space
@@ -1894,8 +1928,12 @@ export class SyncSagaCoordinator {
1894
1928
  }
1895
1929
  }
1896
1930
 
1897
- sagaHistory.forEach(x => {
1931
+ sagaHistory.filter(x => {
1932
+ const frameExecutionContext = getSyncSagaFrameOrigin({ sagaFrame: x.sagaIbGib });
1933
+ return currentFrameOrigin === frameExecutionContext;
1934
+ }).forEach(x => {
1898
1935
  if (!x.sagaIbGib.data) { throw new Error(`(UNEXPECTED) sagaIbGib.data falsy? (E: 34d7f8cdee14717ce828878d98f89826)`); }
1936
+ if (logalot) { console.log(`${lc}[${currentFrameOrigin}] history slice: ${pretty(x)} (I: e5a9436fb66b0df3183bd6d81be2ca26)`); }
1899
1937
  x.msgStones.forEach(msgStone => {
1900
1938
  if (!msgStone.data) { throw new Error(`(UNEXPECTED) msgStone.data falsy? (E: 21406101f91847514cc759c8a7382f26)`); }
1901
1939
  if (msgStone.data.stage === SyncStage.ack) {
@@ -1914,70 +1952,90 @@ export class SyncSagaCoordinator {
1914
1952
  })
1915
1953
  });
1916
1954
 
1955
+ if (logalot) { console.log(`${lc}[${currentFrameOrigin}] allPayloadAddrsDomainTransferred: ${allPayloadAddrsDomainTransferred.length > 0 ? allPayloadAddrsDomainTransferred.join(', ') : 'none'} (I: a1950eb3ca95bdc9ec18a4b8823e9826)`); }
1956
+
1917
1957
  // at this point, we have a list of ALL payload addrs retrieved.
1918
1958
  let allPayloadIbGibsDomainTransferred: IbGib_V1[] = [];
1919
- const resGetAllTransferred =
1920
- await getFromSpace({ addrs: allPayloadAddrsDomainTransferred, space: localTempSpace });
1921
- if (resGetAllTransferred.success && resGetAllTransferred.ibGibs && resGetAllTransferred.ibGibs.length === allPayloadAddrsDomainTransferred.length) {
1922
- allPayloadIbGibsDomainTransferred = resGetAllTransferred.ibGibs.concat();
1923
- } else {
1924
- // errored out, gather info
1925
- if (!resGetAllTransferred.rawResultIbGib) { throw new Error(`(UNEXPECTED) !resGetAllTransferred.rawResultIbGib falsy? (E: dc6cf8729668f4fbe8c024f887d97a26)`); }
1926
- const { addrsNotFound, addrsErrored, errors } = resGetAllTransferred.rawResultIbGib.data as IbGibSpaceResultData;
1927
- 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)`);
1959
+ if (allPayloadAddrsDomainTransferred.length > 0) {
1960
+ const resGetAllTransferred =
1961
+ await getFromSpace({ addrs: allPayloadAddrsDomainTransferred, space: localTempSpace });
1962
+ if (resGetAllTransferred.success && resGetAllTransferred.ibGibs && resGetAllTransferred.ibGibs.length === allPayloadAddrsDomainTransferred.length) {
1963
+ allPayloadIbGibsDomainTransferred = resGetAllTransferred.ibGibs.concat();
1964
+ } else {
1965
+ // errored out, gather info
1966
+ if (!resGetAllTransferred.rawResultIbGib) { throw new Error(`(UNEXPECTED) !resGetAllTransferred.rawResultIbGib falsy? (E: dc6cf8729668f4fbe8c024f887d97a26)`); }
1967
+ const { addrsNotFound, addrsErrored, errors } = resGetAllTransferred.rawResultIbGib.data as IbGibSpaceResultData;
1968
+ 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)`);
1969
+ }
1928
1970
  }
1929
1971
 
1930
1972
  // now we have all ibgibs transferred, first put them all the local space
1973
+ if (allPayloadIbGibsDomainTransferred.length === 0) {
1974
+ // nothing was synced
1975
+ if (logalot) { console.log(`${lc}[${currentFrameOrigin}] no changes on this end (I: fa30d18e83a87ee9e8487fbb5d632b26)`); }
1976
+ } else {
1977
+ if (logalot) { console.log(`${lc}[${currentFrameOrigin}] ${allPayloadIbGibsDomainTransferred.length} changes detected (I: fa30d18e83a87ee9e8487fbb5d632b26)`); }
1931
1978
 
1932
- const { payload_Dnas, payload_NonDnas } =
1933
- await putInSpace_dnasThenNonDnas({
1934
- ibGibs: allPayloadIbGibsDomainTransferred,
1935
- space: localSpace
1936
- });
1937
-
1938
- const { mapWithTjp_NoDna, mapWithTjp_YesDna, mapWithoutTjps } =
1939
- splitPerTjpAndOrDna({ ibGibs: payload_NonDnas, filterPrimitives: true });
1940
-
1941
- // first register all non-tjp stones
1942
- const nontjps = Object.values(mapWithoutTjps);
1943
- for (const nontjp of nontjps) {
1944
- await metaspace.registerNewIbGib({
1945
- ibGib: nontjp,
1946
- space: localSpace,
1947
- });
1948
- }
1979
+ if (logalot) { console.log(`${lc} put all into localSpace (${localSpace.ib}) starting... (I: d5e0d9870e380b61e80c729660058826)`); }
1980
+ const { payload_Dnas, payload_NonDnas } =
1981
+ await putInSpace_dnasThenNonDnas({
1982
+ ibGibs: allPayloadIbGibsDomainTransferred,
1983
+ space: localSpace
1984
+ });
1985
+ if (logalot) { console.log(`${lc} put all into localSpace (${localSpace.ib}) complete. (I: d5e0d9870e380b61e80c729660058826)`); }
1949
1986
 
1950
- // next register each timeline in order...
1987
+ const { mapWithTjp_NoDna, mapWithTjp_YesDna, mapWithoutTjps } =
1988
+ splitPerTjpAndOrDna({ ibGibs: payload_NonDnas, filterPrimitives: true });
1951
1989
 
1952
- // ...first the ones without dna...
1953
- const timelinesByTjpAddr_NoDna =
1954
- getTimelinesGroupedByTjp({ ibGibs: Object.values(mapWithTjp_NoDna) });
1955
- const tjpAddrs_NoDna = Object.keys(timelinesByTjpAddr_NoDna);
1956
- for (const tjpAddr_NoDna of tjpAddrs_NoDna) {
1957
- const timelineIbGibs = timelinesByTjpAddr_NoDna[tjpAddr_NoDna];
1958
- for (const ibGib of timelineIbGibs) {
1990
+ // first register all non-tjp stones
1991
+ if (logalot) { console.log(`${lc} register mapWithoutTjps starting... (I: 2b84d8f8dda85adde88696d8419bf726)`); }
1992
+ const nontjps = Object.values(mapWithoutTjps);
1993
+ for (const nontjp of nontjps) {
1994
+ if (logalot) { console.log(`${lc} registering ${getIbGibAddr({ ibGib: nontjp })} (I: 4647b4f42d27cffe0fbfce8846755826)`); }
1959
1995
  await metaspace.registerNewIbGib({
1960
- ibGib,
1996
+ ibGib: nontjp,
1961
1997
  space: localSpace,
1962
1998
  });
1963
1999
  }
1964
- }
1965
-
1966
- // ...then the ones WITH dna.
1967
- const timelinesByTjpAddr_YesDna =
1968
- getTimelinesGroupedByTjp({ ibGibs: Object.values(mapWithTjp_YesDna) });
1969
- const tjpAddrs_YesDna = Object.keys(timelinesByTjpAddr_YesDna);
1970
- for (const tjpAddr_YesDna of tjpAddrs_YesDna) {
1971
- const timelineIbGibs = timelinesByTjpAddr_YesDna[tjpAddr_YesDna];
1972
- for (const ibGib of timelineIbGibs) {
1973
- await metaspace.registerNewIbGib({
1974
- ibGib,
1975
- space: localSpace,
1976
- });
2000
+ if (logalot) { console.log(`${lc} mapWithoutTjps complete. (I: 2b84d8f8dda85adde88696d8419bf726)`); }
2001
+
2002
+ // next register each timeline in order...
2003
+
2004
+ // ...first the ones without dna...
2005
+ if (logalot) { console.log(`${lc} register mapWithTjp_NoDna starting... (I: 96e648e4db382499b8bfaa1b37c24826)`); }
2006
+ const timelinesByTjpAddr_NoDna =
2007
+ getTimelinesGroupedByTjp({ ibGibs: Object.values(mapWithTjp_NoDna) });
2008
+ const tjpAddrs_NoDna = Object.keys(timelinesByTjpAddr_NoDna);
2009
+ for (const tjpAddr_NoDna of tjpAddrs_NoDna) {
2010
+ const timelineIbGibs = timelinesByTjpAddr_NoDna[tjpAddr_NoDna];
2011
+ for (const ibGib of timelineIbGibs) {
2012
+ await metaspace.registerNewIbGib({
2013
+ ibGib,
2014
+ space: localSpace,
2015
+ });
2016
+ }
1977
2017
  }
2018
+ if (logalot) { console.log(`${lc} register mapWithTjp_NoDna complete. (I: 96e648e4db382499b8bfaa1b37c24826)`); }
2019
+
2020
+ // ...then the ones WITH dna.
2021
+ if (logalot) { console.log(`${lc} register mapWithTjp_YesDna starting... (I: d54a820e9442dee4681f6228a6795926)`); }
2022
+ const timelinesByTjpAddr_YesDna =
2023
+ getTimelinesGroupedByTjp({ ibGibs: Object.values(mapWithTjp_YesDna) });
2024
+ const tjpAddrs_YesDna = Object.keys(timelinesByTjpAddr_YesDna);
2025
+ for (const tjpAddr_YesDna of tjpAddrs_YesDna) {
2026
+ const timelineIbGibs = timelinesByTjpAddr_YesDna[tjpAddr_YesDna];
2027
+ for (const ibGib of timelineIbGibs) {
2028
+ await metaspace.registerNewIbGib({
2029
+ ibGib,
2030
+ space: localSpace,
2031
+ });
2032
+ }
2033
+ }
2034
+ if (logalot) { console.log(`${lc} register mapWithTjp_YesDna complete. (I: d54a820e9442dee4681f6228a6795926)`); }
1978
2035
  }
1979
2036
 
1980
2037
 
2038
+
1981
2039
  } catch (error) {
1982
2040
  console.error(`${lc} ${extractErrorMsg(error)}`);
1983
2041
  throw error;
@@ -2059,49 +2117,55 @@ export class SyncSagaCoordinator {
2059
2117
  try {
2060
2118
  if (logalot) { console.log(`${lc} starting... (I: e179573bdd881202f8ba3168da1c3826)`); }
2061
2119
 
2062
- let resNextSagaFrameInfo: NextSagaFrameInfo;
2120
+ if (!sagaIbGib.data) { throw new Error(`(UNEXPECTED) sagaIbGib.data falsy? (E: cbc31dbb7d28b5b8c8cddb510d7d2826)`); }
2063
2121
 
2064
- // Sender Logic (Finalizing):
2065
- // If we are here, we received a Commit frame from the Peer.
2066
- // This implies the Peer has successfully committed.
2067
- // We should now:
2068
- // 1. Validate (implicitly done by receiving valid frame)
2069
- // 2. Perform our own cleanup (Temp -> Dest, if applicable)
2070
- // 3. Return saga completion.
2071
-
2072
- // one last validate entire history?
2073
- const history = await getFullSyncSagaHistory({
2074
- sagaIbGib,
2075
- space: mySpace,
2076
- });
2077
- const validationErrors = await validateFullSyncSagaHistory({
2078
- history,
2079
- });
2080
- if (validationErrors.length > 0) {
2081
- const errorCommitFrame = await this.createCommitFrame({
2122
+ if (sagaIbGib.data.errors && sagaIbGib.data.errors.length > 0) {
2123
+ // our saga errored out but we already committed the darn
2124
+ // changes previously
2125
+ 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)`);
2126
+ } else {
2127
+ // Sender Logic (Finalizing):
2128
+ // If we are here, we received a Commit frame from the Peer.
2129
+ // This implies the Peer has successfully committed.
2130
+ // We should now:
2131
+ // 1. Validate (implicitly done by receiving valid frame)
2132
+ // 2. Perform our own cleanup (Temp -> Dest, if applicable)
2133
+ // 3. Return saga completion.
2134
+
2135
+ // one last validate entire history ?
2136
+ const history = await getFullSyncSagaHistory({
2082
2137
  sagaIbGib,
2083
- metaspace,
2084
- mySpace,
2085
- identity,
2086
- errors: validationErrors,
2138
+ space: mySpace,
2087
2139
  });
2088
- return { frame: errorCommitFrame, }; /* <<<< returns early */
2089
- }
2140
+ const validationErrors = await validateFullSyncSagaHistory({
2141
+ history,
2142
+ });
2143
+ if (validationErrors.length > 0) {
2144
+ const errorCommitFrame = await this.createCommitFrame({
2145
+ sagaIbGib,
2146
+ metaspace,
2147
+ mySpace,
2148
+ identity,
2149
+ errors: validationErrors,
2150
+ });
2151
+ return { frame: errorCommitFrame, }; /* <<<< returns early */
2152
+ }
2090
2153
 
2091
- await this.executeLocalCommit({
2092
- deltaFrame: sagaIbGib,
2093
- sagaHistory: history,
2094
- localSpace: mySpace,
2095
- localTempSpace: myTempSpace,
2096
- metaspace,
2097
- });
2154
+ await this.executeLocalCommit({
2155
+ commitFrame: sagaIbGib,
2156
+ sagaHistory: history,
2157
+ localSpace: mySpace,
2158
+ localTempSpace: myTempSpace,
2159
+ metaspace,
2160
+ });
2098
2161
 
2099
- // todo: implement explicit cleanup logic here and in peer
2100
- console.error(`${lc} NAG ERROR (NOT THROWN): implement cleanup logic, including add a cleanup method to the peer (E: 3a9a24befb98a981a88fbdbf52920e26)`);
2101
- if (logalot) { console.log(`${lc} Peer committed. Finalizing saga locally. Saga Complete.`); }
2162
+ // todo: implement explicit cleanup logic here and in peer
2163
+ console.error(`${lc} NAG ERROR (NOT THROWN): implement cleanup logic, including add a cleanup method to the peer (E: 3a9a24befb98a981a88fbdbf52920e26)`);
2164
+ if (logalot) { console.log(`${lc} Peer committed. Finalizing saga locally. Saga Complete.`); }
2102
2165
 
2103
- // the holy grail!
2104
- return { sagaComplete: true };
2166
+ // the holy grail!
2167
+ return { sagaComplete: true };
2168
+ }
2105
2169
  } catch (error) {
2106
2170
  const emsg = `${lc} ${extractErrorMsg(error)}`;
2107
2171
  console.error(emsg);
@@ -54,40 +54,34 @@ export function isValidSyncConflictStrategy(strategy: string): strategy is SyncC
54
54
  }
55
55
  // #endregion SyncConflictStrategy
56
56
 
57
- // #region SyncExecutionContext
58
- export const SYNC_EXECUTION_CONTEXT_SENDER = 'sender';
59
- export const SYNC_EXECUTION_CONTEXT_RECEIVER = 'receiver';
60
- export type SyncExecutionContext =
61
- | typeof SYNC_EXECUTION_CONTEXT_SENDER
62
- | typeof SYNC_EXECUTION_CONTEXT_RECEIVER
57
+ // #region SyncSagaFrameOrigin
58
+ export const SYNC_SAGA_FRAME_ORIGIN_SENDER = 'sender';
59
+ export const SYNC_SAGA_FRAME_ORIGIN_RECEIVER = 'receiver';
60
+ export type SyncSagaFrameOrigin =
61
+ | typeof SYNC_SAGA_FRAME_ORIGIN_SENDER
62
+ | typeof SYNC_SAGA_FRAME_ORIGIN_RECEIVER
63
63
  ;
64
64
  /**
65
- * if the current code execution is executing on the original sender (the
66
- * initiator of the sync saga operation) or the other party, the "receiver" (the
67
- * one responding).
65
+ * if the frame was created by the original sender (the initiator of the sync
66
+ * saga operation) or the other party, the "receiver" (the one responding).
68
67
  *
69
68
  * This is driven by looking at the latest value of `sagaFrame.data.n` value.
70
- *
71
- * NOTE: This is not to be confused with the sync saga context ibgib, which is
72
- * something else entirely. That is the transport wrapper ibgib around the saga.
73
- * this is strictly the enum for where the code is executing.
74
69
  */
75
- export const SyncExecutionContext = {
70
+ export const SyncSagaFrameOrigin = {
76
71
  /**
77
- * The current code is executing on the initial location that started the
78
- * sync.
72
+ * The frame was created on the initial location that started the sync.
79
73
  */
80
- sender: SYNC_EXECUTION_CONTEXT_SENDER,
74
+ sender: SYNC_SAGA_FRAME_ORIGIN_SENDER,
81
75
  /**
82
- * The current code is executing on the receiving end, which is either a
83
- * physically different location or is the logical "receiver" of an
84
- * in-memory sync execution.
76
+ * The frame was created on the receiving end, which is either a physically
77
+ * different location or is the logical "receiver" of an in-memory sync
78
+ * execution.
85
79
  */
86
- receiver: SYNC_EXECUTION_CONTEXT_RECEIVER,
87
- } satisfies { [key in SyncExecutionContext]: SyncExecutionContext };
88
- export const SYNC_EXECUTION_CONTEXT_VALID_VALUES = Object.values(SyncExecutionContext);
89
- export function isValidSyncExecutionContext(executionContext: string): executionContext is SyncExecutionContext {
90
- return SYNC_EXECUTION_CONTEXT_VALID_VALUES.includes(executionContext as SyncExecutionContext);
80
+ receiver: SYNC_SAGA_FRAME_ORIGIN_RECEIVER,
81
+ } satisfies { [key in SyncSagaFrameOrigin]: SyncSagaFrameOrigin };
82
+ export const SYNC_SAGA_FRAME_ORIGIN_VALID_VALUES = Object.values(SyncSagaFrameOrigin);
83
+ export function isValidSyncSagaFrameOrigin(sagaFrameOrigin: string): sagaFrameOrigin is SyncSagaFrameOrigin {
84
+ return SYNC_SAGA_FRAME_ORIGIN_VALID_VALUES.includes(sagaFrameOrigin as SyncSagaFrameOrigin);
91
85
  }
92
86
  // #endregion SyncConflictStrategy
93
87
 
@@ -113,7 +107,6 @@ export interface NextSagaFrameInfo_SagaComplete {
113
107
  export type NextSagaFrameInfo =
114
108
  NextSagaFrameInfo_Frame | NextSagaFrameInfo_SagaComplete;
115
109
 
116
-
117
110
  export interface HandleSagaResponseContextResult_Base {
118
111
  /**
119
112
  * if truthy, handling saga context failed, else it succeeded.
package/test_output.log CHANGED
Binary file