@ibgib/core-gib 0.1.60 → 0.1.61

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 (179) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/dist/common/other/graph-helper.d.mts.map +1 -1
  3. package/dist/common/other/graph-helper.mjs +7 -6
  4. package/dist/common/other/graph-helper.mjs.map +1 -1
  5. package/dist/keystone/keystone-config-builder.d.mts +1 -2
  6. package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
  7. package/dist/keystone/keystone-config-builder.mjs +4 -19
  8. package/dist/keystone/keystone-config-builder.mjs.map +1 -1
  9. package/dist/keystone/keystone-constants.d.mts +2 -0
  10. package/dist/keystone/keystone-constants.d.mts.map +1 -1
  11. package/dist/keystone/keystone-constants.mjs +2 -0
  12. package/dist/keystone/keystone-constants.mjs.map +1 -1
  13. package/dist/keystone/keystone-helpers.d.mts +5 -15
  14. package/dist/keystone/keystone-helpers.d.mts.map +1 -1
  15. package/dist/keystone/keystone-helpers.mjs +59 -73
  16. package/dist/keystone/keystone-helpers.mjs.map +1 -1
  17. package/dist/keystone/keystone-policy-types.d.mts +6 -4
  18. package/dist/keystone/keystone-policy-types.d.mts.map +1 -1
  19. package/dist/keystone/keystone-service-v1.d.mts.map +1 -1
  20. package/dist/keystone/keystone-service-v1.mjs +4 -8
  21. package/dist/keystone/keystone-service-v1.mjs.map +1 -1
  22. package/dist/keystone/keystone-service-v1.respec.mjs +182 -33
  23. package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -1
  24. package/dist/keystone/keystone-types.d.mts +4 -11
  25. package/dist/keystone/keystone-types.d.mts.map +1 -1
  26. package/dist/keystone/policy/keystone-profile-builder.d.mts +25 -0
  27. package/dist/keystone/policy/keystone-profile-builder.d.mts.map +1 -0
  28. package/dist/keystone/policy/keystone-profile-builder.mjs +117 -0
  29. package/dist/keystone/policy/keystone-profile-builder.mjs.map +1 -0
  30. package/dist/keystone/policy/profiles/profile-high.json +84 -0
  31. package/dist/keystone/policy/profiles/profile-low.json +84 -0
  32. package/dist/keystone/policy/profiles/profile-medium.json +84 -0
  33. package/dist/keystone/policy/profiles/profile-session.json +84 -0
  34. package/dist/keystone/policy/profiles/profile-test.json +84 -0
  35. package/dist/keystone/policy/schemas/connect-pool.high.schema.json +23 -0
  36. package/dist/keystone/policy/schemas/connect-pool.low.schema.json +23 -0
  37. package/dist/keystone/policy/schemas/connect-pool.medium.schema.json +23 -0
  38. package/dist/keystone/policy/schemas/keystone.high.schema.json +26 -0
  39. package/dist/keystone/policy/schemas/keystone.low.schema.json +26 -0
  40. package/dist/keystone/policy/schemas/keystone.medium.schema.json +26 -0
  41. package/dist/keystone/policy/schemas/manage-pool.high.schema.json +23 -0
  42. package/dist/keystone/policy/schemas/manage-pool.low.schema.json +23 -0
  43. package/dist/keystone/policy/schemas/manage-pool.medium.schema.json +23 -0
  44. package/dist/keystone/policy/schemas/revoke-pool.high.schema.json +23 -0
  45. package/dist/keystone/policy/schemas/revoke-pool.low.schema.json +23 -0
  46. package/dist/keystone/policy/schemas/revoke-pool.medium.schema.json +23 -0
  47. package/dist/keystone/policy/schemas/sign-pool.high.schema.json +23 -0
  48. package/dist/keystone/policy/schemas/sign-pool.low.schema.json +23 -0
  49. package/dist/keystone/policy/schemas/sign-pool.medium.schema.json +23 -0
  50. package/dist/keystone/policy/schemas/sync-pool.high.schema.json +23 -0
  51. package/dist/keystone/policy/schemas/sync-pool.low.schema.json +23 -0
  52. package/dist/keystone/policy/schemas/sync-pool.medium.schema.json +23 -0
  53. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.d.mts +8 -0
  54. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.d.mts.map +1 -0
  55. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.mjs +582 -0
  56. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.mjs.map +1 -0
  57. package/dist/sync/sync-conflict-basic-divergence.withid.respec.d.mts +7 -0
  58. package/dist/sync/sync-conflict-basic-divergence.withid.respec.d.mts.map +1 -0
  59. package/dist/sync/sync-conflict-basic-divergence.withid.respec.mjs +274 -0
  60. package/dist/sync/sync-conflict-basic-divergence.withid.respec.mjs.map +1 -0
  61. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.d.mts +8 -0
  62. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.d.mts.map +1 -0
  63. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.mjs +322 -0
  64. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.mjs.map +1 -0
  65. package/dist/sync/sync-conflict-text-merge.withid.respec.d.mts +7 -0
  66. package/dist/sync/sync-conflict-text-merge.withid.respec.d.mts.map +1 -0
  67. package/dist/sync/sync-conflict-text-merge.withid.respec.mjs +307 -0
  68. package/dist/sync/sync-conflict-text-merge.withid.respec.mjs.map +1 -0
  69. package/dist/sync/sync-innerspace-constants.withid.respec.d.mts +8 -0
  70. package/dist/sync/sync-innerspace-constants.withid.respec.d.mts.map +1 -0
  71. package/dist/sync/sync-innerspace-constants.withid.respec.mjs +233 -0
  72. package/dist/sync/sync-innerspace-constants.withid.respec.mjs.map +1 -0
  73. package/dist/sync/sync-innerspace-deep-updates.withid.respec.d.mts +7 -0
  74. package/dist/sync/sync-innerspace-deep-updates.withid.respec.d.mts.map +1 -0
  75. package/dist/sync/sync-innerspace-deep-updates.withid.respec.mjs +233 -0
  76. package/dist/sync/sync-innerspace-deep-updates.withid.respec.mjs.map +1 -0
  77. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.d.mts +7 -0
  78. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.d.mts.map +1 -0
  79. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.mjs +225 -0
  80. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.mjs.map +1 -0
  81. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
  82. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.d.mts +7 -0
  83. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.d.mts.map +1 -0
  84. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.mjs +235 -0
  85. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.mjs.map +1 -0
  86. package/dist/sync/sync-innerspace-partial-update.withid.respec.d.mts +7 -0
  87. package/dist/sync/sync-innerspace-partial-update.withid.respec.d.mts.map +1 -0
  88. package/dist/sync/sync-innerspace-partial-update.withid.respec.mjs +211 -0
  89. package/dist/sync/sync-innerspace-partial-update.withid.respec.mjs.map +1 -0
  90. package/dist/sync/sync-innerspace.withid.respec.d.mts +8 -0
  91. package/dist/sync/sync-innerspace.withid.respec.d.mts.map +1 -0
  92. package/dist/sync/sync-innerspace.withid.respec.mjs +260 -0
  93. package/dist/sync/sync-innerspace.withid.respec.mjs.map +1 -0
  94. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts +1 -0
  95. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts.map +1 -1
  96. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs +13 -4
  97. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs.map +1 -1
  98. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts +1 -1
  99. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts.map +1 -1
  100. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs +5 -3
  101. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs.map +1 -1
  102. package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
  103. package/dist/sync/sync-saga-coordinator.mjs +165 -145
  104. package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
  105. package/dist/sync/sync-withid.pingpong.respec.mjs +8 -8
  106. package/dist/sync/sync-withid.pingpong.respec.mjs.map +1 -1
  107. package/dist/timeline/timeline-api.d.mts.map +1 -1
  108. package/dist/timeline/timeline-api.mjs +1 -14
  109. package/dist/timeline/timeline-api.mjs.map +1 -1
  110. package/dist/witness/space/reconciliation-space/reconciliation-space-base.d.mts.map +1 -1
  111. package/dist/witness/space/reconciliation-space/reconciliation-space-base.mjs +0 -40
  112. package/dist/witness/space/reconciliation-space/reconciliation-space-base.mjs.map +1 -1
  113. package/dist/witness/space/reconciliation-space/reconciliation-space-helper.d.mts.map +1 -1
  114. package/dist/witness/space/reconciliation-space/reconciliation-space-helper.mjs +6 -6
  115. package/dist/witness/space/reconciliation-space/reconciliation-space-helper.mjs.map +1 -1
  116. package/ibgib-foundations.md +2 -1
  117. package/package.json +1 -1
  118. package/src/common/other/graph-helper.mts +7 -6
  119. package/src/keystone/README.md +19 -15
  120. package/src/keystone/docs/CRYPTANALYSIS.md +185 -0
  121. package/src/keystone/docs/architecture.md +24 -1
  122. package/src/keystone/docs/profiles.md +124 -0
  123. package/src/keystone/keystone-config-builder.mts +3 -21
  124. package/src/keystone/keystone-constants.mts +2 -0
  125. package/src/keystone/keystone-helpers.mts +74 -77
  126. package/src/keystone/keystone-policy-types.mts +6 -4
  127. package/src/keystone/keystone-service-v1.mts +4 -9
  128. package/src/keystone/keystone-service-v1.respec.mts +214 -32
  129. package/src/keystone/keystone-types.mts +5 -9
  130. package/src/keystone/policy/IMPLEMENTATION.md +60 -0
  131. package/src/keystone/policy/README.md +94 -0
  132. package/src/keystone/policy/keystone-profile-builder.mts +131 -0
  133. package/src/keystone/policy/profiles/profile-high.json +84 -0
  134. package/src/keystone/policy/profiles/profile-low.json +84 -0
  135. package/src/keystone/policy/profiles/profile-medium.json +84 -0
  136. package/src/keystone/policy/profiles/profile-session.json +84 -0
  137. package/src/keystone/policy/profiles/profile-test.json +84 -0
  138. package/src/keystone/policy/schemas/connect-pool.high.schema.json +23 -0
  139. package/src/keystone/policy/schemas/connect-pool.low.schema.json +23 -0
  140. package/src/keystone/policy/schemas/connect-pool.medium.schema.json +23 -0
  141. package/src/keystone/policy/schemas/keystone.high.schema.json +26 -0
  142. package/src/keystone/policy/schemas/keystone.low.schema.json +26 -0
  143. package/src/keystone/policy/schemas/keystone.medium.schema.json +26 -0
  144. package/src/keystone/policy/schemas/manage-pool.high.schema.json +23 -0
  145. package/src/keystone/policy/schemas/manage-pool.low.schema.json +23 -0
  146. package/src/keystone/policy/schemas/manage-pool.medium.schema.json +23 -0
  147. package/src/keystone/policy/schemas/revoke-pool.high.schema.json +23 -0
  148. package/src/keystone/policy/schemas/revoke-pool.low.schema.json +23 -0
  149. package/src/keystone/policy/schemas/revoke-pool.medium.schema.json +23 -0
  150. package/src/keystone/policy/schemas/sign-pool.high.schema.json +23 -0
  151. package/src/keystone/policy/schemas/sign-pool.low.schema.json +23 -0
  152. package/src/keystone/policy/schemas/sign-pool.medium.schema.json +23 -0
  153. package/src/keystone/policy/schemas/sync-pool.high.schema.json +23 -0
  154. package/src/keystone/policy/schemas/sync-pool.low.schema.json +23 -0
  155. package/src/keystone/policy/schemas/sync-pool.medium.schema.json +23 -0
  156. package/src/sync/docs/security.md +54 -21
  157. package/src/sync/sync-conflict-adv-multitimelines.withid.respec.mts +706 -0
  158. package/src/sync/sync-conflict-basic-divergence.withid.respec.mts +321 -0
  159. package/src/sync/sync-conflict-basic-multitimelines.withid.respec.mts +374 -0
  160. package/src/sync/sync-conflict-text-merge.withid.respec.mts +347 -0
  161. package/src/sync/sync-innerspace-constants.withid.respec.mts +264 -0
  162. package/src/sync/sync-innerspace-deep-updates.withid.respec.mts +272 -0
  163. package/src/sync/sync-innerspace-dest-ahead.withid.respec.mts +266 -0
  164. package/src/sync/sync-innerspace-multiple-timelines.respec.mts +0 -1
  165. package/src/sync/sync-innerspace-multiple-timelines.withid.respec.mts +273 -0
  166. package/src/sync/sync-innerspace-partial-update.withid.respec.mts +249 -0
  167. package/src/sync/sync-innerspace.withid.respec.mts +265 -0
  168. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mts +12 -4
  169. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mts +5 -3
  170. package/src/sync/sync-saga-coordinator.mts +159 -143
  171. package/src/sync/sync-withid.pingpong.respec.mts +8 -8
  172. package/src/timeline/timeline-api.mts +1 -15
  173. package/src/timeline/timeline-api.respec.mts +3 -3
  174. package/src/witness/space/reconciliation-space/reconciliation-space-base.mts +0 -46
  175. package/src/witness/space/reconciliation-space/reconciliation-space-helper.mts +6 -5
  176. package/tsconfig.json +6 -1
  177. package/src/keystone/keystone-policy.schema.json +0 -51
  178. package/src/witness/space/reconciliation-space/reconciliation-space-base.mts.OLD.md +0 -884
  179. package/src/witness/space/reconciliation-space/reconciliation-space-helper.mts.OLD.md +0 -125
@@ -324,150 +324,155 @@ export class SyncSagaCoordinator {
324
324
  },
325
325
  }));
326
326
  // #endregion set up peer observable for any domainPayloadsMap
327
- // ...create/compose the Request Context itself...
328
- const requestCtx = await this.createSyncSagaContext({
329
- sagaFrame: currentFrame,
330
- /**
331
- * init frame: empty
332
- * ack frame: possible push offers
333
- * delta frame: requested ibgibs or commit offer
334
- * commit frame: empty
335
- */
336
- payloadIbGibsDomain: nextDomainIbGibs,
337
- localSpace,
338
- metaspace,
339
- sessionIdentityAddr: peer.currentSessionIdentityAddr,
340
- peer,
341
- });
342
- // #region Log what we're sending
343
- if (logalotControlDomain) {
344
- const domainAddrs = nextDomainIbGibs.map(p => getIbGibAddr({ ibGib: p }));
345
- console.log(`${lc}${lcControlDomain} SENDER TRANSMIT -> peer.witness (I: 5b0081803698770f0bf64992220b312)`);
346
- console.log(`${lc}${lcControlDomain} Context: ${getIbGibAddr({ ibGib: requestCtx })}`);
347
- console.log(`${lc}${lcControlDomain} Frame: ${getIbGibAddr({ ibGib: currentFrame })}`);
348
- console.log(`${lc}${lcControlDomain} DOMAIN Payloads (${domainAddrs.length}): ${domainAddrs.join(', ') || '(none)'}`);
349
- }
350
- // #endregion Log what we're sending
351
- // update our saga listeners...
352
- // if (logalot) { console.log(`${lc} transmitting... requestCtx: ${pretty(requestCtx)} (I: 8cf20817c66899abdb1e76df50356826)`); }
353
- updates$.next(requestCtx); // spins off for saga UI updates
354
- // ...And send the context.
355
- peer.setOptionalOpts({ localSpace, localTempSpace: tempSpace, });
356
- const responseCtx = await peer.witness(requestCtx);
357
- // the send returned, but a peer can return a falsy responseCtx, if
358
- // we just sent a commit to them and they're done. If so, there will
359
- // necessarily be no payload to wait to receive
360
- if (!responseCtx) {
361
- if (currentFrame) {
362
- // Check for Commit (Peer silence expected)
363
- const msg = await getSyncSagaMessageFromFrame({ frameIbGib: currentFrame, space: localSpace });
364
- if (msg?.data?.stage === SyncStage.commit) {
365
- if (logalot) {
366
- console.log(`${lc} Sender sent Commit. Peer returned no response. Saga Complete. (I: 26f9ee073858ca78b8284753368b5226)`);
327
+ try {
328
+ // ...create/compose the Request Context itself...
329
+ const requestCtx = await this.createSyncSagaContext({
330
+ sagaFrame: currentFrame,
331
+ /**
332
+ * init frame: empty
333
+ * ack frame: possible push offers
334
+ * delta frame: requested ibgibs or commit offer
335
+ * commit frame: empty
336
+ */
337
+ payloadIbGibsDomain: nextDomainIbGibs,
338
+ localSpace,
339
+ metaspace,
340
+ sessionIdentityAddr: peer.currentSessionIdentityAddr,
341
+ peer,
342
+ });
343
+ // #region Log what we're sending
344
+ if (logalotControlDomain) {
345
+ const domainAddrs = nextDomainIbGibs.map(p => getIbGibAddr({ ibGib: p }));
346
+ console.log(`${lc}${lcControlDomain} SENDER TRANSMIT -> peer.witness (I: 5b0081803698770f0bf64992220b312)`);
347
+ console.log(`${lc}${lcControlDomain} Context: ${getIbGibAddr({ ibGib: requestCtx })}`);
348
+ console.log(`${lc}${lcControlDomain} Frame: ${getIbGibAddr({ ibGib: currentFrame })}`);
349
+ console.log(`${lc}${lcControlDomain} DOMAIN Payloads (${domainAddrs.length}): ${domainAddrs.join(', ') || '(none)'}`);
350
+ }
351
+ // #endregion Log what we're sending
352
+ // update our saga listeners...
353
+ // if (logalot) { console.log(`${lc} transmitting... requestCtx: ${pretty(requestCtx)} (I: 8cf20817c66899abdb1e76df50356826)`); }
354
+ updates$.next(requestCtx); // spins off for saga UI updates
355
+ // ...And send the context.
356
+ peer.setOptionalOpts({ localSpace, localTempSpace: tempSpace, });
357
+ const responseCtx = await peer.witness(requestCtx);
358
+ // the send returned, but a peer can return a falsy responseCtx, if
359
+ // we just sent a commit to them and they're done. If so, there will
360
+ // necessarily be no payload to wait to receive
361
+ if (!responseCtx) {
362
+ if (currentFrame) {
363
+ // Check for Commit (Peer silence expected)
364
+ const msg = await getSyncSagaMessageFromFrame({ frameIbGib: currentFrame, space: localSpace });
365
+ if (msg?.data?.stage === SyncStage.commit) {
366
+ if (logalot) {
367
+ console.log(`${lc} Sender sent Commit. Peer returned no response. Saga Complete. (I: 26f9ee073858ca78b8284753368b5226)`);
368
+ }
369
+ currentFrame = null;
370
+ break;
371
+ }
372
+ else {
373
+ throw new Error(`(UNEXPECTED) responseCtx falsy and currentFrame truthy, but we're not in the commit stage? This may be expected ultimately, but atow I am not seeing this as being expected. (E: cc34498962bd370deeff351fac939f26)`);
367
374
  }
368
- currentFrame = null;
369
- break;
370
375
  }
371
376
  else {
372
- throw new Error(`(UNEXPECTED) responseCtx falsy and currentFrame truthy, but we're not in the commit stage? This may be expected ultimately, but atow I am not seeing this as being expected. (E: cc34498962bd370deeff351fac939f26)`);
377
+ throw new Error(`(UNEXPECTED) no response and currentFrame falsy? (E: 8d1085ea2f28cfc3f9c922649864a826)`);
373
378
  }
374
379
  }
375
- else {
376
- throw new Error(`(UNEXPECTED) no response and currentFrame falsy? (E: 8d1085ea2f28cfc3f9c922649864a826)`);
377
- }
378
- }
379
- // at this point, we did indeed receive a response to analyze. BUT!
380
- // we have only necessarily received the response context ibgib.
381
- // if there were payloads expected to be transferred, they may not
382
- // be done yet.
383
- if (!responseCtx.data) {
384
- throw new Error(`(UNEXPECTED) responseCtx.data falsy? (E: a969992bae53ab18a827ec58aec15826)`);
385
- }
386
- updates$.next(responseCtx); // spins off for saga UI updating
387
- // immediately validate context/saga frame (but not payloads because
388
- // we may not have those yet)
389
- const contextAndSagaFrameValidationErrors = await validateContextAndSagaFrame({ context: responseCtx });
390
- if (contextAndSagaFrameValidationErrors.length > 0) {
391
- throw new Error(`contextAndSagaFrameValidationErrors: ${contextAndSagaFrameValidationErrors} (E: 6eebe8e7fa437c00a8cde3ada3c66826)`);
392
- }
393
- // Turn-by-turn continuation & identity checks
394
- const returnContextErrors = await this.validateReturnContext({
395
- requestCtx,
396
- responseCtx,
397
- localSpace,
398
- });
399
- if (returnContextErrors.length > 0) {
400
- throw new Error(`validateReturnContext errors: ${returnContextErrors.join(', ')} (E: cb8a023b9d0728cceb09fa3da0bb8226)`);
401
- }
402
- // Extract expected domain addresses from response context
403
- const responsePayloadAddrsDomain = responseCtx.data[SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN] || [];
404
- // Poll for them if needed. see above jsdocs for domainPayloadsMap
405
- if (responsePayloadAddrsDomain.length > 0) {
406
- responseCtx.payloadIbGibsDomain = await this.pollForDomainPayloads({
407
- expectedAddrs: responsePayloadAddrsDomain,
408
- pollIntervalMs: 20, // relatively arbitrary right now
409
- domainPayloadsMap,
410
- tempSpace,
380
+ // at this point, we did indeed receive a response to analyze. BUT!
381
+ // we have only necessarily received the response context ibgib.
382
+ // if there were payloads expected to be transferred, they may not
383
+ // be done yet.
384
+ if (!responseCtx.data) {
385
+ throw new Error(`(UNEXPECTED) responseCtx.data falsy? (E: a969992bae53ab18a827ec58aec15826)`);
386
+ }
387
+ updates$.next(responseCtx); // spins off for saga UI updating
388
+ // immediately validate context/saga frame (but not payloads because
389
+ // we may not have those yet)
390
+ const contextAndSagaFrameValidationErrors = await validateContextAndSagaFrame({ context: responseCtx });
391
+ if (contextAndSagaFrameValidationErrors.length > 0) {
392
+ throw new Error(`contextAndSagaFrameValidationErrors: ${contextAndSagaFrameValidationErrors} (E: 6eebe8e7fa437c00a8cde3ada3c66826)`);
393
+ }
394
+ // Turn-by-turn continuation & identity checks
395
+ const returnContextErrors = await this.validateReturnContext({
396
+ requestCtx,
397
+ responseCtx,
398
+ localSpace,
411
399
  });
412
- }
413
- // #region Log what we received back
414
- if (!responseCtx.sagaFrame) {
415
- throw new Error(`(UNEXPECTED) responseCtx.sagaFrame falsy? the Peer should have set this when it got the response back from the remote. (E: e650adadf9a2063ec6764a1e31d3d826)`);
416
- }
417
- if (logalotControlDomain) {
418
- const responseControlAddrs = responseCtx.data?.['@payloadAddrsControl'] || [];
419
- console.log(`${lc}${lcControlDomain} SENDER RECEIVED <- peer.witness (I: 3dc76a9744d89a4fc3e2f076c2be4826)`);
420
- console.log(`${lc}${lcControlDomain} Response Context: ${getIbGibAddr({ ibGib: responseCtx })}`);
421
- console.log(`${lc}${lcControlDomain} Response Saga Frame: ${getIbGibAddr({ ibGib: responseCtx.sagaFrame })}`);
422
- console.log(`${lc}${lcControlDomain} CONTROL Payloads (${responseControlAddrs.length}): ${responseControlAddrs.join(', ') || '(none)'}`);
423
- console.log(`${lc}${lcControlDomain} DOMAIN Payloads (${responsePayloadAddrsDomain.length}): ${responsePayloadAddrsDomain.join(', ') || '(none)'}`);
424
- }
425
- // #endregion Log what we received back
426
- // at this point, we have received the context AND **all** of the
427
- // domain payloads (if applicable), so we are ready to do the next
428
- // iteration in the saga loop
429
- // this is the part that drives the FSM forward, i.e., when we
430
- // evolve the sync saga ibgib itself to the next frame if we aren't
431
- // finished/errored out.
432
- const contextResult = await this.handleResponseSagaContext({
433
- sagaContext: responseCtx,
434
- initDomainGraph,
435
- mySpace: localSpace,
436
- myTempSpace: tempSpace,
437
- metaspace,
438
- });
439
- if (!contextResult) {
440
- // should this ever hit?
441
- console.error(`${lc} NAG ERROR (DOES NOT THROW): does this ever hit now? (E: e04d02efc2a8e72a88b79f1f0f95ca26)`);
442
- break;
443
- }
444
- else if (contextResult.nextFrameInfo?.sagaComplete) {
445
- if (logalot) {
446
- console.log(`${lc} Handler returned null (Saga End). (I: 123bf9e7dca8886de72553a8d4f29e26)`);
400
+ if (returnContextErrors.length > 0) {
401
+ throw new Error(`validateReturnContext errors: ${returnContextErrors.join(', ')} (E: cb8a023b9d0728cceb09fa3da0bb8226)`);
402
+ }
403
+ // Extract expected domain addresses from response context
404
+ const responsePayloadAddrsDomain = responseCtx.data[SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN] || [];
405
+ // Poll for them if needed. see above jsdocs for domainPayloadsMap
406
+ if (responsePayloadAddrsDomain.length > 0) {
407
+ responseCtx.payloadIbGibsDomain = await this.pollForDomainPayloads({
408
+ expectedAddrs: responsePayloadAddrsDomain,
409
+ pollIntervalMs: 20, // relatively arbitrary right now
410
+ domainPayloadsMap,
411
+ tempSpace,
412
+ });
447
413
  }
448
- break;
449
- }
450
- // #region error conditions throw
451
- if (contextResult.errorMsg) {
452
- throw new Error(`Couldn't handle response saga context. errorMsg: ${contextResult.errorMsg} (E: c948e81d513b2a0eb8b8afa878edc626)`);
414
+ // #region Log what we received back
415
+ if (!responseCtx.sagaFrame) {
416
+ throw new Error(`(UNEXPECTED) responseCtx.sagaFrame falsy? the Peer should have set this when it got the response back from the remote. (E: e650adadf9a2063ec6764a1e31d3d826)`);
417
+ }
418
+ if (logalotControlDomain) {
419
+ const responseControlAddrs = responseCtx.data?.['@payloadAddrsControl'] || [];
420
+ console.log(`${lc}${lcControlDomain} SENDER RECEIVED <- peer.witness (I: 3dc76a9744d89a4fc3e2f076c2be4826)`);
421
+ console.log(`${lc}${lcControlDomain} Response Context: ${getIbGibAddr({ ibGib: responseCtx })}`);
422
+ console.log(`${lc}${lcControlDomain} Response Saga Frame: ${getIbGibAddr({ ibGib: responseCtx.sagaFrame })}`);
423
+ console.log(`${lc}${lcControlDomain} CONTROL Payloads (${responseControlAddrs.length}): ${responseControlAddrs.join(', ') || '(none)'}`);
424
+ console.log(`${lc}${lcControlDomain} DOMAIN Payloads (${responsePayloadAddrsDomain.length}): ${responsePayloadAddrsDomain.join(', ') || '(none)'}`);
425
+ }
426
+ // #endregion Log what we received back
427
+ // at this point, we have received the context AND **all** of the
428
+ // domain payloads (if applicable), so we are ready to do the next
429
+ // iteration in the saga loop
430
+ // this is the part that drives the FSM forward, i.e., when we
431
+ // evolve the sync saga ibgib itself to the next frame if we aren't
432
+ // finished/errored out.
433
+ const contextResult = await this.handleResponseSagaContext({
434
+ sagaContext: responseCtx,
435
+ initDomainGraph,
436
+ mySpace: localSpace,
437
+ myTempSpace: tempSpace,
438
+ metaspace,
439
+ });
440
+ if (!contextResult) {
441
+ // should this ever hit?
442
+ console.error(`${lc} NAG ERROR (DOES NOT THROW): does this ever hit now? (E: e04d02efc2a8e72a88b79f1f0f95ca26)`);
443
+ break;
444
+ }
445
+ else if (contextResult.nextFrameInfo?.sagaComplete) {
446
+ if (logalot) {
447
+ console.log(`${lc} Handler returned null (Saga End). (I: 123bf9e7dca8886de72553a8d4f29e26)`);
448
+ }
449
+ break;
450
+ }
451
+ // #region error conditions throw
452
+ if (contextResult.errorMsg) {
453
+ throw new Error(`Couldn't handle response saga context. errorMsg: ${contextResult.errorMsg} (E: c948e81d513b2a0eb8b8afa878edc626)`);
454
+ }
455
+ else if (!contextResult.nextFrameInfo) {
456
+ throw new Error(`(UNEXPECTED) contextResult.nextFrameInfo falsy? (E: c287a82e823e662a77923278e2418826)`);
457
+ }
458
+ // #endregion error conditions throw
459
+ // we have another frame to process and send out, with possibly
460
+ // payload domain ibgibs as well
461
+ const { frame, payloadIbGibsDomain, } = contextResult.nextFrameInfo;
462
+ currentFrame = frame;
463
+ nextDomainIbGibs = [...(payloadIbGibsDomain || [])];
464
+ // #region Log handler output for next iteration
465
+ if (logalotControlDomain) {
466
+ const handlerDomainAddrs = nextDomainIbGibs.map(p => getIbGibAddr({ ibGib: p }));
467
+ console.log(`${lc}${lcControlDomain} HANDLER RESULT -> next iteration (I: 6b0d88c4c28857ccd812381515bd7826)`);
468
+ console.log(`${lc}${lcControlDomain} Next Frame: ${getIbGibAddr({ ibGib: currentFrame })}`);
469
+ console.log(`${lc}${lcControlDomain} DOMAIN for next (${handlerDomainAddrs.length}): ${handlerDomainAddrs.join(', ') || '(none)'}`);
470
+ }
471
+ // #endregion Log handler output for next iteration
453
472
  }
454
- else if (!contextResult.nextFrameInfo) {
455
- throw new Error(`(UNEXPECTED) contextResult.nextFrameInfo falsy? (E: c287a82e823e662a77923278e2418826)`);
473
+ finally {
474
+ await subscription.unsubscribe();
456
475
  }
457
- // #endregion error conditions throw
458
- // we have another frame to process and send out, with possibly
459
- // payload domain ibgibs as well
460
- const { frame, payloadIbGibsDomain, } = contextResult.nextFrameInfo;
461
- currentFrame = frame;
462
- nextDomainIbGibs = [...(payloadIbGibsDomain || [])];
463
- // #region Log handler output for next iteration
464
- if (logalotControlDomain) {
465
- const handlerDomainAddrs = nextDomainIbGibs.map(p => getIbGibAddr({ ibGib: p }));
466
- console.log(`${lc}${lcControlDomain} HANDLER RESULT -> next iteration (I: 6b0d88c4c28857ccd812381515bd7826)`);
467
- console.log(`${lc}${lcControlDomain} Next Frame: ${getIbGibAddr({ ibGib: currentFrame })}`);
468
- console.log(`${lc}${lcControlDomain} DOMAIN for next (${handlerDomainAddrs.length}): ${handlerDomainAddrs.join(', ') || '(none)'}`);
469
- }
470
- // #endregion Log handler output for next iteration
471
476
  }
472
477
  }
473
478
  /**
@@ -776,7 +781,8 @@ export class SyncSagaCoordinator {
776
781
  console.log(`${lc} starting... (I: 26dce86bfca572939885798802d6e926)`);
777
782
  }
778
783
  let resultDomainPayloads = [];
779
- let pending = [...expectedAddrs];
784
+ const uniqueExpectedAddrs = [...new Set(expectedAddrs)];
785
+ let pending = [...uniqueExpectedAddrs];
780
786
  const start = Date.now();
781
787
  /**
782
788
  * This needs
@@ -806,8 +812,8 @@ export class SyncSagaCoordinator {
806
812
  await delay(pollIntervalMs);
807
813
  }
808
814
  }
809
- if (expectedAddrs.length !== resultDomainPayloads.length) {
810
- throw new Error(`(UNEXPECTED) expectedAddrs.length !== resultDomainPayloads.length? at this point, we expect all of the payload ibgibs to have been received. (E: 03749a7478c4b8b28bfc86951887a826)`);
815
+ if (uniqueExpectedAddrs.length !== resultDomainPayloads.length) {
816
+ throw new Error(`(UNEXPECTED) uniqueExpectedAddrs.length !== resultDomainPayloads.length? at this point, we expect all of the payload ibgibs to have been received. (E: 03749a7478c4b8b28bfc86951887a826)`);
811
817
  }
812
818
  return resultDomainPayloads;
813
819
  }
@@ -1378,12 +1384,11 @@ export class SyncSagaCoordinator {
1378
1384
  * end will have to do the actual merging (assuming feasability).
1379
1385
  */
1380
1386
  const outgoingPayloadIbGibsDomain_conflicts = [];
1387
+ const activeConflicts = [];
1381
1388
  if (conflicts.length > 0) {
1382
1389
  if (logalot) {
1383
1390
  console.log(`${lc} [CONFLICT DEBUG] Processing ${conflicts.length} non-terminal conflicts`);
1384
1391
  }
1385
- // we will need to resolve conflicts, so no commit yet
1386
- proposeCommit = false;
1387
1392
  for (const conflict of conflicts) {
1388
1393
  const { receiverTipAddr, reason, senderTipAddr,
1389
1394
  // latestCommonFrameAddr, // to be determined in this handler
@@ -1445,13 +1450,28 @@ export class SyncSagaCoordinator {
1445
1450
  const deltaPayloadIbGib = deltaGraph[deltaPayloadAddr];
1446
1451
  outgoingPayloadIbGibsDomain_conflicts.push(deltaPayloadIbGib);
1447
1452
  });
1448
- if (conflict.accretivePayloadAddrs) {
1449
- throw new Error(`(UNEXPECTED) conflict.accretivePayloadAddrs already truthy? This is expected to be falsy at this point in the sync. (E: 6b6b1846779867849cbde208f4374326)`);
1453
+ const isFastForward = latestCommonFrameAddr === receiverTipAddr;
1454
+ if (isFastForward) {
1455
+ if (logalot) {
1456
+ console.log(`${lc} [CONFLICT DEBUG] TJP ${tjpAddr}: Fast-forward detected (receiver behind sender). Excluding from active conflicts and sending delta payload.`);
1457
+ }
1458
+ }
1459
+ else {
1460
+ if (conflict.accretivePayloadAddrs) {
1461
+ throw new Error(`(UNEXPECTED) conflict.accretivePayloadAddrs already truthy? This is expected to be falsy at this point in the sync. (E: 6b6b1846779867849cbde208f4374326)`);
1462
+ }
1463
+ conflict.accretivePayloadAddrs = accretivePayloadAddrs;
1464
+ activeConflicts.push(conflict);
1450
1465
  }
1451
- conflict.accretivePayloadAddrs = accretivePayloadAddrs;
1466
+ }
1467
+ if (activeConflicts.length > 0) {
1468
+ proposeCommit = false;
1469
+ }
1470
+ else {
1471
+ proposeCommit = true;
1452
1472
  }
1453
1473
  if (logalot) {
1454
- console.log(`${lc} [CONFLICT DEBUG] Finished processing ${conflicts.length} conflicts. outgoingPayloadIbGibsDomain_conflicts.length (total outgoing payload ibgibs for ALL conflicts): ${outgoingPayloadIbGibsDomain_conflicts.length}`);
1474
+ console.log(`${lc} [CONFLICT DEBUG] Finished processing ${conflicts.length} conflicts. Active (divergent) conflicts: ${activeConflicts.length}. outgoingPayloadIbGibsDomain_conflicts.length (total outgoing payload ibgibs for ALL conflicts): ${outgoingPayloadIbGibsDomain_conflicts.length}`);
1455
1475
  }
1456
1476
  }
1457
1477
  else {
@@ -1490,7 +1510,7 @@ export class SyncSagaCoordinator {
1490
1510
  /**
1491
1511
  * these are the modified conflicts with additional information.
1492
1512
  */
1493
- conflicts,
1513
+ conflicts: activeConflicts,
1494
1514
  /**
1495
1515
  * we're sending these domain ibgibs as payload (they were
1496
1516
  * requested by receiver and/or they are being sent as delta