@ibgib/core-gib 0.1.21 → 0.1.22
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.
- package/dist/sync/sync-conflict.respec.mjs +24 -22
- package/dist/sync/sync-conflict.respec.mjs.map +1 -1
- package/dist/sync/sync-constants.d.mts +8 -8
- package/dist/sync/sync-constants.d.mts.map +1 -1
- package/dist/sync/sync-constants.mjs +3 -3
- package/dist/sync/sync-constants.mjs.map +1 -1
- package/dist/sync/sync-helpers.d.mts +2 -0
- package/dist/sync/sync-helpers.d.mts.map +1 -1
- package/dist/sync/sync-helpers.mjs +11 -9
- package/dist/sync/sync-helpers.mjs.map +1 -1
- package/dist/sync/sync-innerspace-constants.respec.mjs +5 -1
- package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs +5 -1
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs +8 -4
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs +5 -1
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-partial-update.respec.mjs +5 -1
- package/dist/sync/sync-innerspace-partial-update.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace.respec.mjs +5 -1
- package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-constants.d.mts +2 -0
- package/dist/sync/sync-peer/sync-peer-constants.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-constants.mjs +2 -0
- package/dist/sync/sync-peer/sync-peer-constants.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-helpers.d.mts +2 -0
- package/dist/sync/sync-peer/sync-peer-helpers.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-helpers.mjs +2 -0
- package/dist/sync/sync-peer/sync-peer-helpers.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.d.mts +8 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs +8 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-helpers.d.mts +18 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-helpers.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-helpers.mjs +54 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-helpers.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.d.mts +80 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.mjs +5 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts +43 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +229 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-types.d.mts +12 -0
- package/dist/sync/sync-peer/sync-peer-types.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.d.mts +15 -7
- package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.mjs +105 -24
- package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +5 -8
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +34 -18
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +26 -22
- package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-types.mjs +1 -9
- package/dist/sync/sync-saga-context/sync-saga-context-types.mjs.map +1 -1
- package/dist/sync/sync-saga-coordinator.d.mts +23 -33
- package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.mjs +271 -163
- package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
- package/dist/sync/sync-types.d.mts +15 -3
- package/dist/sync/sync-types.d.mts.map +1 -1
- package/dist/witness/light-witness-base-v1.d.mts.map +1 -1
- package/dist/witness/light-witness-base-v1.mjs +2 -0
- package/dist/witness/light-witness-base-v1.mjs.map +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.mjs +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.mjs.map +1 -1
- package/package.json +1 -1
- package/src/sync/README.md +31 -22
- package/src/sync/sync-conflict.respec.mts +23 -19
- package/src/sync/sync-constants.mts +4 -5
- package/src/sync/sync-helpers.mts +11 -7
- package/src/sync/sync-innerspace-constants.respec.mts +5 -1
- package/src/sync/sync-innerspace-deep-updates.respec.mts +5 -1
- package/src/sync/sync-innerspace-dest-ahead.respec.mts +7 -3
- package/src/sync/sync-innerspace-multiple-timelines.respec.mts +5 -1
- package/src/sync/sync-innerspace-partial-update.respec.mts +8 -2
- package/src/sync/sync-innerspace.respec.mts +5 -1
- package/src/sync/sync-peer/sync-peer-constants.mts +0 -0
- package/src/sync/sync-peer/sync-peer-helpers.mts +0 -0
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mts +8 -0
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-helpers.mts +72 -0
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.mts +87 -0
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +242 -0
- package/src/sync/sync-peer/sync-peer-types.mts +13 -1
- package/src/sync/sync-peer/sync-peer-v1.mts +93 -27
- package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +47 -29
- package/src/sync/sync-saga-context/sync-saga-context-types.mts +29 -30
- package/src/sync/sync-saga-coordinator.mts +280 -170
- package/src/sync/sync-types.mts +17 -3
- package/src/witness/light-witness-base-v1.mts +2 -1
- package/src/witness/space/inner-space/inner-space-v1.mts +1 -1
- package/test_output.log +0 -0
- package/tmp.md +62 -44
- package/dist/sync/sync-local-spaces.respec.d.mts +0 -2
- package/dist/sync/sync-local-spaces.respec.d.mts.map +0 -1
- package/dist/sync/sync-local-spaces.respec.mjs +0 -159
- package/dist/sync/sync-local-spaces.respec.mjs.map +0 -1
- package/dist/sync/sync-peer/sync-peer-innerspace-v1.d.mts +0 -42
- package/dist/sync/sync-peer/sync-peer-innerspace-v1.d.mts.map +0 -1
- package/dist/sync/sync-peer/sync-peer-innerspace-v1.mjs +0 -194
- package/dist/sync/sync-peer/sync-peer-innerspace-v1.mjs.map +0 -1
- package/dist/sync/sync-saga-coordinator.respec.d.mts +0 -2
- package/dist/sync/sync-saga-coordinator.respec.d.mts.map +0 -1
- package/dist/sync/sync-saga-coordinator.respec.mjs +0 -40
- package/dist/sync/sync-saga-coordinator.respec.mjs.map +0 -1
- package/src/sync/sync-local-spaces.respec.mts +0 -200
- package/src/sync/sync-peer/sync-peer-innerspace-v1.mts +0 -240
- package/src/sync/sync-saga-coordinator.respec.mts +0 -52
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
import { extractErrorMsg, getUUID, // so our timestamp in ticks as a string are uniform
|
|
2
|
-
pretty } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
2
|
+
pretty, } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
3
3
|
import { getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
|
|
4
|
-
import { splitPerTjpAndOrDna, getTimelinesGroupedByTjp } from "../common/other/ibgib-helper.mjs";
|
|
4
|
+
import { splitPerTjpAndOrDna, getTimelinesGroupedByTjp, isIbGib } from "../common/other/ibgib-helper.mjs";
|
|
5
5
|
import { Factory_V1 } from "@ibgib/ts-gib/dist/V1/factory.mjs";
|
|
6
|
-
import { GLOBAL_LOG_A_LOT } from "../core-constants.mjs";
|
|
7
6
|
import { putInSpace, getLatestAddrs, getFromSpace } from "../witness/space/space-helper.mjs";
|
|
8
|
-
import { SyncStage, SYNC_ATOM, SYNC_MSG_REL8N_NAME } from "./sync-constants.mjs";
|
|
7
|
+
import { SyncStage, SYNC_ATOM, SYNC_MSG_REL8N_NAME, SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN } from "./sync-constants.mjs";
|
|
9
8
|
import { appendToTimeline, createTimeline } from "../timeline/timeline-api.mjs";
|
|
10
9
|
import { SyncMode, } from "./sync-types.mjs";
|
|
11
10
|
import { getSyncIb, isPastFrame } from "./sync-helpers.mjs";
|
|
12
|
-
import { getSyncSagaDependencyGraph } from "./sync-helpers.mjs";
|
|
11
|
+
import { getSyncSagaDependencyGraph as getSyncSagaDependencyGraphForThisFrameOnly } from "./sync-helpers.mjs";
|
|
13
12
|
import { getDependencyGraph } from "../common/other/graph-helper.mjs";
|
|
14
13
|
import { getSyncSagaMessageIb } from "./sync-saga-message/sync-saga-message-helpers.mjs";
|
|
15
14
|
import { SYNC_SAGA_MSG_ATOM } from "./sync-saga-message/sync-saga-message-constants.mjs";
|
|
16
|
-
import { SyncSagaContextCmd } from "./sync-saga-context/sync-saga-context-types.mjs";
|
|
17
15
|
import { createSyncSagaContext } from "./sync-saga-context/sync-saga-context-helpers.mjs";
|
|
18
|
-
import { newupSubject } from "../common/pubsub/subject/subject-helper.mjs";
|
|
16
|
+
import { newupSubject, } from "../common/pubsub/subject/subject-helper.mjs";
|
|
19
17
|
import { mergeDivergentTimelines } from "./strategies/conflict-optimistic.mjs";
|
|
20
18
|
import { getSyncSagaMessageFromFrame } from "./sync-saga-message/sync-saga-message-helpers.mjs";
|
|
21
|
-
|
|
19
|
+
import { fnObs } from "../common/pubsub/observer/observer-helper.mjs";
|
|
20
|
+
import { SyncPeerInnerspace_V1 } from "./sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs";
|
|
21
|
+
// const logalot = GLOBAL_LOG_A_LOT || true;
|
|
22
|
+
const logalot = false;
|
|
23
|
+
const logalotControlDomain = true;
|
|
24
|
+
const lcControlDomain = '[ControlDomain]';
|
|
22
25
|
/**
|
|
23
26
|
* Orchestrates the synchronization process between two spaces (Source and Destination).
|
|
24
27
|
*
|
|
@@ -115,6 +118,14 @@ export class SyncSagaCoordinator {
|
|
|
115
118
|
conflictStrategy
|
|
116
119
|
});
|
|
117
120
|
// 4. EXECUTE SAGA LOOP (FSM)
|
|
121
|
+
// Inject tempSpace into peer so it can pull control payloads to the right place
|
|
122
|
+
// if ('opts' in peer && peer.opts) {
|
|
123
|
+
if (!peer.data) {
|
|
124
|
+
throw new Error(`(UNEXPECTED) peer.data falsy? (E: 8546a884c82ffb1999e95d9867da2826)`);
|
|
125
|
+
}
|
|
126
|
+
if (peer.data.classname === SyncPeerInnerspace_V1.name) {
|
|
127
|
+
// (peer as SyncPeerInnerspace_V1).senderTempSpace = tempSpace;
|
|
128
|
+
}
|
|
118
129
|
const syncedIbGibs = await this.executeSagaLoop({
|
|
119
130
|
initialFrame: initFrame,
|
|
120
131
|
srcGraph,
|
|
@@ -207,74 +218,123 @@ export class SyncSagaCoordinator {
|
|
|
207
218
|
// The current frame we just generated (e.g., Init or Delta Request)
|
|
208
219
|
let currentFrame = initialFrame;
|
|
209
220
|
// The payload we need to attach to the message (data we are sending)
|
|
210
|
-
let
|
|
221
|
+
let nextDomainIbGibs = [];
|
|
211
222
|
// Accumulator for all data we've successfully pulled from the remote
|
|
212
223
|
const allReceivedIbGibs = [];
|
|
213
224
|
while (currentFrame) {
|
|
214
225
|
// A. Create Context (Request)
|
|
215
226
|
// 1. Calculate Full Dependency Graph (including Ancestors/DNA)
|
|
216
|
-
//
|
|
217
|
-
|
|
227
|
+
// TODO: adjust this algorithm to only do the dependencies that the other end doesn't need (diff between tip and LCA)
|
|
228
|
+
// We must do this BEFORE creating the Context so we can list them
|
|
229
|
+
// all in payloadAddrsDomain and payloadAddrsControl.
|
|
230
|
+
// const depsDomainIbGibs: IbGib_V1[] = [];
|
|
231
|
+
// const depsControlIbGibs: IbGib_V1[] = [];
|
|
232
|
+
const payloadIbGibsControl = [];
|
|
233
|
+
const payloadIbGibsDomain = [];
|
|
218
234
|
// A. Payload (Standard Deep Deps)
|
|
219
|
-
for (const
|
|
220
|
-
let
|
|
221
|
-
if (!
|
|
222
|
-
|
|
235
|
+
for (const nextDomainIbGib of nextDomainIbGibs) {
|
|
236
|
+
let nextDomainIbGibGraph = await getDependencyGraph({ ibGib: nextDomainIbGib, space: localSpace });
|
|
237
|
+
if (!nextDomainIbGibGraph) {
|
|
238
|
+
nextDomainIbGibGraph = await getDependencyGraph({ ibGib: nextDomainIbGib, space: tempSpace });
|
|
223
239
|
}
|
|
224
|
-
if (
|
|
225
|
-
|
|
240
|
+
if (nextDomainIbGibGraph) {
|
|
241
|
+
payloadIbGibsDomain.push(...Object.values(nextDomainIbGibGraph));
|
|
226
242
|
}
|
|
227
243
|
else {
|
|
228
|
-
|
|
244
|
+
throw new Error(`(UNEXPECTED) we couldn't get the graph for a known domain ibgib? nextDomainIbGib addr: ${getIbGibAddr({ ibGib: nextDomainIbGib })} (E: 01b3e4db8768b5b77db72e486f4f7826)`);
|
|
229
245
|
}
|
|
230
246
|
}
|
|
231
247
|
if (logalot) {
|
|
232
|
-
|
|
248
|
+
console.log(`${lc} payloadIbGibsDomain count: ${payloadIbGibsDomain.length} (I: 2beda8ca7dc5ac0f48ed9e25e704b826)`);
|
|
233
249
|
}
|
|
234
250
|
// B. Frames (Shallow Sync Deps)
|
|
235
251
|
if (currentFrame) {
|
|
236
|
-
const
|
|
237
|
-
if (
|
|
238
|
-
|
|
252
|
+
const depsCurrentFrame = await getSyncSagaDependencyGraphForThisFrameOnly({ ibGib: currentFrame, space: tempSpace });
|
|
253
|
+
if (depsCurrentFrame.length > 0) {
|
|
254
|
+
depsCurrentFrame.forEach(x => payloadIbGibsControl.push(x));
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
throw new Error(`(UNEXPECTED) couldn't get deps for currentFrame? currentFrame: ${JSON.stringify(currentFrame)} (E: 06344d07adc80d80b809211171444d26)`);
|
|
258
|
+
}
|
|
239
259
|
}
|
|
240
260
|
// 2. Create Context (Envelope)
|
|
241
|
-
|
|
242
|
-
const
|
|
261
|
+
const domainPayloadsMap = new Map();
|
|
262
|
+
const sublc = `${lc}[peer.payloadIbGibsDomainReceived$]`;
|
|
263
|
+
let subscription;
|
|
264
|
+
if (peer && peer.payloadIbGibsDomainReceived$) {
|
|
265
|
+
// Subscribe to stream
|
|
266
|
+
subscription = await peer.payloadIbGibsDomainReceived$.subscribe(fnObs({
|
|
267
|
+
next: async (ibgib) => {
|
|
268
|
+
if (logalot) {
|
|
269
|
+
console.log(`${sublc} next fired. (I: 2b4bdf502a38a90ba33d9711e7cb7826)`);
|
|
270
|
+
}
|
|
271
|
+
const addr = getIbGibAddr({ ibGib: ibgib });
|
|
272
|
+
if (logalotControlDomain) {
|
|
273
|
+
console.log(`${lc}${lcControlDomain} DOMAIN STREAM RECEIVED <- observable: ${addr} (I: d69ee80fcaece272483ec33b2d289826)`);
|
|
274
|
+
}
|
|
275
|
+
domainPayloadsMap.set(addr, ibgib);
|
|
276
|
+
},
|
|
277
|
+
error: async (e) => {
|
|
278
|
+
if (isIbGib(e)) {
|
|
279
|
+
console.error(`${sublc} error fired. error: ${JSON.stringify(e.data)} (E: 01cc08ba05ad99682831174fd7c31a26)`);
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
console.dir(e);
|
|
283
|
+
console.error(`${sublc} error fired. error: ${extractErrorMsg(e)} (E: 73d3d61464e8e4ce4cd6efd8b9675826)`);
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
complete: async () => {
|
|
287
|
+
if (logalot) {
|
|
288
|
+
console.log(`${sublc} complete fired. (I: a47218aa9e4433fdb97c068880a45826)`);
|
|
289
|
+
}
|
|
290
|
+
await subscription.unsubscribe();
|
|
291
|
+
},
|
|
292
|
+
}));
|
|
293
|
+
}
|
|
294
|
+
// 2b. Request Context
|
|
243
295
|
const requestCtx = await createSyncSagaContext({
|
|
244
|
-
cmd: SyncSagaContextCmd.process,
|
|
245
296
|
sagaFrame: currentFrame,
|
|
246
297
|
sessionKeystones: sessionIdentity ? [sessionIdentity] : undefined,
|
|
247
|
-
|
|
298
|
+
payloadIbGibsDomain,
|
|
248
299
|
});
|
|
249
|
-
//
|
|
250
|
-
if (
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
300
|
+
// Log what we're sending
|
|
301
|
+
if (logalotControlDomain) {
|
|
302
|
+
const controlAddrs = payloadIbGibsControl.map(p => getIbGibAddr({ ibGib: p }));
|
|
303
|
+
const domainAddrs = payloadIbGibsDomain.map(p => getIbGibAddr({ ibGib: p }));
|
|
304
|
+
console.log(`${lc}${lcControlDomain} SENDER TRANSMIT -> peer.witness (I: b3c4d5e6f7a8b9c0)`);
|
|
305
|
+
console.log(`${lc}${lcControlDomain} Context: ${getIbGibAddr({ ibGib: requestCtx })}`);
|
|
306
|
+
console.log(`${lc}${lcControlDomain} Frame: ${getIbGibAddr({ ibGib: currentFrame })}`);
|
|
307
|
+
console.log(`${lc}${lcControlDomain} CONTROL Payloads (${controlAddrs.length}): ${controlAddrs.join(', ') || '(none)'}`);
|
|
308
|
+
console.log(`${lc}${lcControlDomain} DOMAIN Payloads (${domainAddrs.length}): ${domainAddrs.join(', ') || '(none)'}`);
|
|
254
309
|
}
|
|
310
|
+
// Add Context Deps
|
|
311
|
+
// do we need to add requestCtx to the payload ibgibs?
|
|
312
|
+
// if (requestCtx) {
|
|
313
|
+
// const deps = await getSyncSagaDependencyGraphForThisFrameOnly({ ibGib: requestCtx, space: tempSpace });
|
|
314
|
+
// if (deps) { deps.forEach(x => payloadIbGibsControl.push(x)); }
|
|
315
|
+
// }
|
|
255
316
|
// 3. Identity (if exists)
|
|
256
317
|
// Identity might be deep? Keystone? Usually self-contained or shallow references.
|
|
257
318
|
if (sessionIdentity) {
|
|
258
|
-
|
|
319
|
+
payloadIbGibsControl.push(sessionIdentity);
|
|
259
320
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
321
|
+
// we only put the **CONTROL** payload ibgibs in localSpace. we
|
|
322
|
+
// don't put any domain ibgibs into this durable space until the
|
|
323
|
+
// final commit phase.
|
|
324
|
+
// The requestCtx envelope itself also goes to localSpace so transfer can find it.
|
|
325
|
+
await putInSpace({ space: localSpace, ibGib: requestCtx });
|
|
326
|
+
if (payloadIbGibsControl.length > 0) {
|
|
327
|
+
await putInSpace({ space: localSpace, ibGibs: payloadIbGibsControl });
|
|
265
328
|
}
|
|
266
329
|
// B. Transmit
|
|
267
330
|
// if (logalot) { console.log(`${lc} transmitting... requestCtx: ${pretty(requestCtx)} (I: 8cf20817c66899abdb1e76df50356826)`); }
|
|
268
|
-
updates$.next(requestCtx);
|
|
331
|
+
updates$.next(requestCtx); // spins off (don't remove this comment!)
|
|
269
332
|
const responseCtx = await peer.witness(requestCtx);
|
|
270
333
|
// C. Handle Response
|
|
271
334
|
if (!responseCtx) {
|
|
272
|
-
// Check if we just sent a Commit frame. If so, peer's silence is success/expected.
|
|
273
335
|
if (currentFrame) {
|
|
336
|
+
// Check for Commit (Peer silence expected)
|
|
274
337
|
const msg = await getSyncSagaMessageFromFrame({ frameIbGib: currentFrame, space: localSpace });
|
|
275
|
-
if (logalot) {
|
|
276
|
-
console.log(`${lc} Checking currentFrame stage: ${msg?.data?.stage} (Expected: ${SyncStage.commit})`);
|
|
277
|
-
}
|
|
278
338
|
if (msg?.data?.stage === SyncStage.commit) {
|
|
279
339
|
if (logalot) {
|
|
280
340
|
console.log(`${lc} Sender sent Commit. Peer returned no response. Saga Complete.`);
|
|
@@ -282,57 +342,85 @@ export class SyncSagaCoordinator {
|
|
|
282
342
|
currentFrame = null;
|
|
283
343
|
break;
|
|
284
344
|
}
|
|
345
|
+
else {
|
|
346
|
+
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)`);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
throw new Error(`(UNEXPECTED) no response and currentFrame falsy? (E: 8d1085ea2f28cfc3f9c922649864a826)`);
|
|
285
351
|
}
|
|
286
|
-
throw new Error(`responseCtx falsy. Peer returned no response context (E: c099d8073b48d85e881f917835158f26)`);
|
|
287
|
-
// console.warn(`${lc} Peer returned no response context. Ending loop.`);
|
|
288
|
-
// currentFrame = null;
|
|
289
|
-
// break;
|
|
290
352
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
//
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if (!remoteFrame) {
|
|
309
|
-
throw new Error(`Could not resolve remote frame: ${remoteFrameAddr}`);
|
|
310
|
-
}
|
|
311
|
-
// if (logalot) { console.log(`${lc} remoteFrame: ${pretty(remoteFrame)}`); } // leave this in for later use if needed
|
|
312
|
-
// Ensure remote frame and its dependencies are in tempSpace
|
|
313
|
-
// The Peer delivered them to localSpace, but handleSagaFrame works in tempSpace.
|
|
314
|
-
const remoteDeps = await getSyncSagaDependencyGraph({ ibGib: remoteFrame, space: localSpace });
|
|
315
|
-
if (remoteDeps && remoteDeps.length > 0) {
|
|
316
|
-
await putInSpace({ space: tempSpace, ibGibs: remoteDeps });
|
|
317
|
-
}
|
|
318
|
-
// React (Reducer)
|
|
319
|
-
// This processes the FRAME we just got from the peer.
|
|
320
|
-
// i.e., We Sent Init -> Got Ack. This calls handleAckFrame.
|
|
321
|
-
// i.e., We Sent Delta -> Got Delta. This calls handleDeltaFrame.
|
|
322
|
-
const result = await this.handleSagaFrame({
|
|
323
|
-
sagaIbGib: remoteFrame,
|
|
324
|
-
srcGraph,
|
|
325
|
-
destSpace: localSpace, // Query existing data from localSpace (Source)
|
|
326
|
-
tempSpace: tempSpace, // Transaction space for saga frames
|
|
327
|
-
identity: sessionIdentity,
|
|
328
|
-
metaspace
|
|
329
|
-
});
|
|
330
|
-
currentFrame = result?.frame || null;
|
|
331
|
-
nextPayloadIbGibs = result?.payloadIbGibs || []; // Payload to send in NEXT Ping
|
|
332
|
-
if (result?.receivedPayloadIbGibs) {
|
|
333
|
-
// Keep track of what we received for final merge
|
|
334
|
-
allReceivedIbGibs.push(...result.receivedPayloadIbGibs);
|
|
353
|
+
// ---------------------------------------------------------------------
|
|
354
|
+
// 2d. HANDLE RESPONSE
|
|
355
|
+
// ---------------------------------------------------------------------
|
|
356
|
+
if (!responseCtx.data) {
|
|
357
|
+
throw new Error(`(UNEXPECTED) responseCtx.data falsy? (E: a969992bae53ab18a827ec58aec15826)`);
|
|
358
|
+
}
|
|
359
|
+
updates$.next(responseCtx); // spins off -- don't remove this comment!
|
|
360
|
+
// Extract expected domain addresses from response context
|
|
361
|
+
const responsePayloadAddrsDomain = responseCtx.data[SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN] || [];
|
|
362
|
+
// TODO: check if we are validating the responseCtx in sync peer. I'm thinking that we must, because we can't start the domain ibgibs until we know the response's control ibgibs are valid.
|
|
363
|
+
// Poll for them if needed
|
|
364
|
+
if (responsePayloadAddrsDomain.length > 0) {
|
|
365
|
+
await this.pollForDomainPayloads({
|
|
366
|
+
expectedAddrs: responsePayloadAddrsDomain,
|
|
367
|
+
domainPayloadsMap,
|
|
368
|
+
tempSpace,
|
|
369
|
+
});
|
|
335
370
|
}
|
|
371
|
+
// Extract Response Frame
|
|
372
|
+
const responseFrameAddr = responseCtx.rel8ns?.sagaFrame?.[0];
|
|
373
|
+
if (!responseFrameAddr) {
|
|
374
|
+
throw new Error(`${lc} Peer response missing sagaFrame (E: 83a0)`);
|
|
375
|
+
}
|
|
376
|
+
// Log what we received back
|
|
377
|
+
if (logalotControlDomain) {
|
|
378
|
+
const responseControlAddrs = responseCtx.data?.['@payloadAddrsControl'] || [];
|
|
379
|
+
console.log(`${lc}${lcControlDomain} SENDER RECEIVED <- peer.witness (I: c4d5e6f7a8b9c0d1)`);
|
|
380
|
+
console.log(`${lc}${lcControlDomain} Response Context: ${getIbGibAddr({ ibGib: responseCtx })}`);
|
|
381
|
+
console.log(`${lc}${lcControlDomain} Response Frame: ${responseFrameAddr}`);
|
|
382
|
+
console.log(`${lc}${lcControlDomain} CONTROL Payloads (${responseControlAddrs.length}): ${responseControlAddrs.join(', ') || '(none)'}`);
|
|
383
|
+
console.log(`${lc}${lcControlDomain} DOMAIN Payloads (${responsePayloadAddrsDomain.length}): ${responsePayloadAddrsDomain.join(', ') || '(none)'}`);
|
|
384
|
+
}
|
|
385
|
+
// Get response frame from localSpace (SyncPeer puts it there)
|
|
386
|
+
let resResponseFrame = await getFromSpace({ space: localSpace, addr: responseFrameAddr });
|
|
387
|
+
if (!resResponseFrame.success || !resResponseFrame.ibGibs?.length) {
|
|
388
|
+
// Fallback to tempSpace
|
|
389
|
+
resResponseFrame = await getFromSpace({ space: tempSpace, addr: responseFrameAddr });
|
|
390
|
+
}
|
|
391
|
+
const responseFrame = resResponseFrame.ibGibs?.[0];
|
|
392
|
+
if (!responseFrame)
|
|
393
|
+
throw new Error(`${lc} Response frame not found (E: 7c2a)`);
|
|
394
|
+
// Handle Response Frame
|
|
395
|
+
const handleResult = await this.handleSagaFrame({
|
|
396
|
+
sagaIbGib: responseFrame,
|
|
397
|
+
srcGraph: {},
|
|
398
|
+
destSpace: localSpace,
|
|
399
|
+
tempSpace,
|
|
400
|
+
metaspace,
|
|
401
|
+
domainPayloadsMap,
|
|
402
|
+
expectedDomainAddrs: responsePayloadAddrsDomain,
|
|
403
|
+
});
|
|
404
|
+
if (!handleResult) {
|
|
405
|
+
if (logalot) {
|
|
406
|
+
console.log(`${lc} Handler returned null (Saga End).`);
|
|
407
|
+
}
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
currentFrame = handleResult.frame;
|
|
411
|
+
// Collect next DOMAIN payloads for the NEXT request
|
|
412
|
+
// Control payloads are handled separately by ensureSagaFrameInBothSpaces
|
|
413
|
+
nextDomainIbGibs = [...(handleResult.payloadIbGibsDomain || [])];
|
|
414
|
+
// Log handler output for next iteration
|
|
415
|
+
if (logalotControlDomain) {
|
|
416
|
+
const handlerControlAddrs = (handleResult.payloadIbGibsControl || []).map(p => getIbGibAddr({ ibGib: p }));
|
|
417
|
+
const handlerDomainAddrs = nextDomainIbGibs.map(p => getIbGibAddr({ ibGib: p }));
|
|
418
|
+
console.log(`${lc}${lcControlDomain} HANDLER RESULT -> next iteration (I: d5e6f7a8b9c0d1e2)`);
|
|
419
|
+
console.log(`${lc}${lcControlDomain} Next Frame: ${getIbGibAddr({ ibGib: currentFrame })}`);
|
|
420
|
+
console.log(`${lc}${lcControlDomain} CONTROL for next (${handlerControlAddrs.length}): ${handlerControlAddrs.join(', ') || '(none)'} (saved via ensureSagaFrameInBothSpaces)`);
|
|
421
|
+
console.log(`${lc}${lcControlDomain} DOMAIN for next (${handlerDomainAddrs.length}): ${handlerDomainAddrs.join(', ') || '(none)'}`);
|
|
422
|
+
}
|
|
423
|
+
// Note: currentFrame is automatically added to dependencies at start of next loop via B. Frames logic.
|
|
336
424
|
}
|
|
337
425
|
return allReceivedIbGibs;
|
|
338
426
|
}
|
|
@@ -346,7 +434,7 @@ export class SyncSagaCoordinator {
|
|
|
346
434
|
if (logalot) {
|
|
347
435
|
console.log(`${lc} starting... (I: e184f8a7818666febfbbd2d841ed3826)`);
|
|
348
436
|
}
|
|
349
|
-
console.dir(space);
|
|
437
|
+
// console.dir(space);
|
|
350
438
|
if (!(domainIbGibs && domainIbGibs.length > 0) &&
|
|
351
439
|
!(tjpAddrs && tjpAddrs.length > 0)) {
|
|
352
440
|
throw new Error(`(UNEXPECTED) domainIbGibs and tjpAddrs falsy/empty? we need one or the other (E: f674285111c8648398cd79d8c08ec826)`);
|
|
@@ -361,23 +449,21 @@ export class SyncSagaCoordinator {
|
|
|
361
449
|
}
|
|
362
450
|
else if (domainIbGibs && domainIbGibs.length > 0) {
|
|
363
451
|
// Extract TJPs from domain Ibgibs
|
|
364
|
-
if (
|
|
365
|
-
console.log(`${lc} domainIbGibs (${domainIbGibs.length}) provided. (I: a378995a0658af1f086ac1f297486c26)`);
|
|
366
|
-
}
|
|
452
|
+
// if (false) { console.log(`${lc} domainIbGibs (${domainIbGibs.length}) provided. (I: a378995a0658af1f086ac1f297486c26)`); }
|
|
367
453
|
const { mapWithTjp_YesDna, mapWithTjp_NoDna } = splitPerTjpAndOrDna({ ibGibs: domainIbGibs });
|
|
368
|
-
if (
|
|
454
|
+
if (false) {
|
|
369
455
|
console.log(`${lc}[TEST DEBUG] mapWithTjp_YesDna: ${JSON.stringify(mapWithTjp_YesDna)} (I: 287e22897148298e185712c8d50cfb26)`);
|
|
370
456
|
}
|
|
371
|
-
if (
|
|
457
|
+
if (false) {
|
|
372
458
|
console.log(`${lc}[TEST DEBUG] mapWithTjp_NoDna: ${JSON.stringify(mapWithTjp_NoDna)} (I: 1bdc62656294aed0f9df334647dc7326)`);
|
|
373
459
|
}
|
|
374
460
|
const allWithTjp = [...Object.values(mapWithTjp_YesDna), ...Object.values(mapWithTjp_NoDna)];
|
|
375
461
|
const timelineMap = getTimelinesGroupedByTjp({ ibGibs: allWithTjp });
|
|
376
|
-
if (
|
|
462
|
+
if (false) {
|
|
377
463
|
console.log(`${lc}[TEST DEBUG] timelineMap: ${JSON.stringify(timelineMap)} (I: 2cc04898e5f85179fb1ac7f827abc426)`);
|
|
378
464
|
}
|
|
379
465
|
tjps = Object.keys(timelineMap);
|
|
380
|
-
if (
|
|
466
|
+
if (false) {
|
|
381
467
|
console.log(`${lc}[TEST DEBUG] tjps: ${tjps} (I: 3dd548667cbd967c68e57c88dc570826)`);
|
|
382
468
|
}
|
|
383
469
|
}
|
|
@@ -390,16 +476,14 @@ export class SyncSagaCoordinator {
|
|
|
390
476
|
if (tjps.length === 0) {
|
|
391
477
|
return {};
|
|
392
478
|
}
|
|
393
|
-
if (
|
|
479
|
+
if (false) {
|
|
394
480
|
console.log(`${lc} getting latest addrs for tjps: ${tjps} (I: d4e7080b8ba8187c583b82fd91ac0626)`);
|
|
395
481
|
}
|
|
396
482
|
const res = await getLatestAddrs({ space, tjpAddrs: tjps });
|
|
397
483
|
if (!res.data || !res.data.latestAddrsMap) {
|
|
398
484
|
throw new Error(`${lc} Failed to get latest addrs. (E: 7a8b9c0d)`);
|
|
399
485
|
}
|
|
400
|
-
if (
|
|
401
|
-
console.log(`${lc}[TEST DEBUG] res.data.latestAddrsMap: ${JSON.stringify(res.data.latestAddrsMap)} (I: a8e128bdf80898ac2e6d8021a5bff726)`);
|
|
402
|
-
}
|
|
486
|
+
// if (false) { console.log(`${lc}[TEST DEBUG] res.data.latestAddrsMap: ${JSON.stringify(res.data.latestAddrsMap)} (I: a8e128bdf80898ac2e6d8021a5bff726)`); }
|
|
403
487
|
return res.data.latestAddrsMap;
|
|
404
488
|
}
|
|
405
489
|
catch (error) {
|
|
@@ -503,18 +587,55 @@ export class SyncSagaCoordinator {
|
|
|
503
587
|
}
|
|
504
588
|
}
|
|
505
589
|
/**
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
* @remarks
|
|
509
|
-
* **Execution Context**: **Universal (Both Sender and Receiver)**.
|
|
510
|
-
*
|
|
511
|
-
* This method acts as the "Reducer" for the Sync FSM. It determines the current stage
|
|
512
|
-
* based on the incoming frame and delegates to the appropriate handler.
|
|
513
|
-
*
|
|
514
|
-
* * If running on **Receiver**: Handles `Init` (via `handleInitFrame`).
|
|
515
|
-
* * If running on **Sender**: Handles `Ack` (via `handleAckFrame`).
|
|
516
|
-
* * If running on **Either**: Handles `Delta` (via `handleDeltaFrame`) or `Commit`.
|
|
590
|
+
* Helper to poll for streaming domain payloads and put them in the
|
|
591
|
+
* local {@link tempSpace}.
|
|
517
592
|
*/
|
|
593
|
+
async pollForDomainPayloads({ expectedAddrs, domainPayloadsMap, tempSpace, }) {
|
|
594
|
+
const lc = `${this.lc}[${this.pollForDomainPayloads.name}]`;
|
|
595
|
+
try {
|
|
596
|
+
if (logalot) {
|
|
597
|
+
console.log(`${lc} starting... (I: 26dce86bfca572939885798802d6e926)`);
|
|
598
|
+
}
|
|
599
|
+
let pending = [...expectedAddrs];
|
|
600
|
+
const start = Date.now();
|
|
601
|
+
/**
|
|
602
|
+
* This needs
|
|
603
|
+
*/
|
|
604
|
+
const timeoutMs = 5 * 60 * 1000; // 5 minutes...arbitrary at this point. This needs to be pulled out and improved eesh.
|
|
605
|
+
while (pending.length > 0) {
|
|
606
|
+
if (Date.now() - start > timeoutMs) {
|
|
607
|
+
throw new Error(`Timeout waiting for payloads: ${pending.join(', ')} (E: 46e1683c9578095261aaf798bd5e1826)`);
|
|
608
|
+
}
|
|
609
|
+
const stillPending = [];
|
|
610
|
+
const found = [];
|
|
611
|
+
for (const addr of pending) {
|
|
612
|
+
if (domainPayloadsMap.has(addr)) {
|
|
613
|
+
found.push(domainPayloadsMap.get(addr));
|
|
614
|
+
domainPayloadsMap.delete(addr);
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
stillPending.push(addr);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
if (found.length > 0) {
|
|
621
|
+
await putInSpace({ space: tempSpace, ibGibs: found });
|
|
622
|
+
}
|
|
623
|
+
pending = stillPending;
|
|
624
|
+
if (pending.length > 0) {
|
|
625
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
catch (error) {
|
|
630
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
631
|
+
throw error;
|
|
632
|
+
}
|
|
633
|
+
finally {
|
|
634
|
+
if (logalot) {
|
|
635
|
+
console.log(`${lc} complete.`);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
518
639
|
async handleSagaFrame({ sagaIbGib, srcGraph, destSpace, tempSpace, identity, identitySecret, metaspace, }) {
|
|
519
640
|
const lc = `${this.lc}[${this.handleSagaFrame.name}]`;
|
|
520
641
|
try {
|
|
@@ -838,7 +959,12 @@ export class SyncSagaCoordinator {
|
|
|
838
959
|
// IMMEDIATELY persist to both spaces for audit trail (before any errors can occur)
|
|
839
960
|
await this.ensureSagaFrameInBothSpaces({ frame: ackFrame, destSpace, tempSpace, metaspace });
|
|
840
961
|
// if (logalot) { console.log(`${lc} ackFrame created: ${pretty(ackFrame)} (I: be24480592eec478086bb3da49286826)`); }
|
|
841
|
-
|
|
962
|
+
// Build control payloads: frame + its dependencies (msg stone, identity)
|
|
963
|
+
const payloadIbGibsControl = [ackFrame, ackStone];
|
|
964
|
+
if (identity) {
|
|
965
|
+
payloadIbGibsControl.push(identity);
|
|
966
|
+
}
|
|
967
|
+
return { frame: ackFrame, payloadIbGibsControl };
|
|
842
968
|
}
|
|
843
969
|
/**
|
|
844
970
|
* Handles the `Ack` frame.
|
|
@@ -938,50 +1064,7 @@ export class SyncSagaCoordinator {
|
|
|
938
1064
|
// PULL these frames from Peer into Local Space
|
|
939
1065
|
// (Validation: We trust peer for now / verification happens on put)
|
|
940
1066
|
for (const addr of receiverOnlyAddrs) {
|
|
941
|
-
|
|
942
|
-
// The Coordinator 'peer' passed in 'sync()' might be needed here?
|
|
943
|
-
// Wait, `handleAckFrame` doesn't have reference to `peer`?
|
|
944
|
-
// It only has `space`, `metaspace`.
|
|
945
|
-
// The `peer` is held by the `executeSagaLoop`.
|
|
946
|
-
// PROBLEM: `handleAckFrame` is pure logic on the Space/Data?
|
|
947
|
-
// No, it's a method on Coordinator.
|
|
948
|
-
// But `executeSagaLoop` calls it.
|
|
949
|
-
// We might need to return "Requirements" to the loop?
|
|
950
|
-
// Checking return type: `{ frame: SyncIbGib_V1, payloadIbGibs?: ... }`
|
|
951
|
-
// It returns the NEXT frame (Delta).
|
|
952
|
-
// If we need to fetch data, we are blocked.
|
|
953
|
-
// We can't easily "Pull" here without the Peer reference.
|
|
954
|
-
// OPTION A: Pass `peer` to `handleAckFrame`.
|
|
955
|
-
// OPTION B: Return a strict list of "MissingDeps" and let Loop handle it.
|
|
956
|
-
// Let's assume we can resolve this by adding `peer` to signature or using `metaspace` if it's a peer-witness?
|
|
957
|
-
// No, Peer is ephemeral connection.
|
|
958
|
-
// Let's add `peer` to `handleAckFrame` signature?
|
|
959
|
-
// It breaks the pattern of just handling frame + space.
|
|
960
|
-
// ALTERNATIVE: Use the `Delta` frame to request data?
|
|
961
|
-
// `SyncSagaMessageDeltaData` has `requests?: string[]`.
|
|
962
|
-
// Sender sends Delta Frame.
|
|
963
|
-
// Does Receiver handle Delta Requests?
|
|
964
|
-
// `handleDeltaFrame` (Receiver) -> checks `requests`.
|
|
965
|
-
// YES.
|
|
966
|
-
// So Sender puts `receiverOnlyAddrs` into `deltaFrame.requests`.
|
|
967
|
-
// Receiver sees them, fetches them, and includes them in the Response (Commit?).
|
|
968
|
-
// Wait, Init->Ack->Delta->Commit.
|
|
969
|
-
// If Receiver sends data in Commit, that's "too late" for Sender to Merge in THIS saga round?
|
|
970
|
-
// Unless Commit is not the end?
|
|
971
|
-
// Or we do a "Delta 2" loop?
|
|
972
|
-
// "Iterative Resolution Loop" from plan.
|
|
973
|
-
// If we request data in Delta, Receiver sends it in Commit (or Delta-Response).
|
|
974
|
-
// Sender gets Commit. Sees data. Merges.
|
|
975
|
-
// Then Sender needs to Send the MERGE result.
|
|
976
|
-
// Needs another Push/Delta.
|
|
977
|
-
// REFINED FLOW:
|
|
978
|
-
// 1. Sender sends Delta Frame with `requests: [receiverOnlyAddrs]`.
|
|
979
|
-
// 2. Receiver responds (Commit? or Ack 2?) with Payload (Divergent Frames).
|
|
980
|
-
// 3. Sender handles response -> Merges.
|
|
981
|
-
// 4. Sender sends Commit (containing Merge Frame).
|
|
982
|
-
// Issue: Current state machine is Init->Ack->Delta->Commit.
|
|
983
|
-
// We need to keep Saga open.
|
|
984
|
-
// If Sender sends Delta with requests, does it transition to Commit?
|
|
1067
|
+
console.error(`${lc} [CONFLICT DEBUG] NOT IMPLEMENTED (E: e6bf1a9d2758c469bb2f97514062d826)`);
|
|
985
1068
|
}
|
|
986
1069
|
// Compute DELTA dependencies for each receiver-only frame
|
|
987
1070
|
// Find LCA to determine what dependencies we already have
|
|
@@ -1153,7 +1236,12 @@ export class SyncSagaCoordinator {
|
|
|
1153
1236
|
if (logalot) {
|
|
1154
1237
|
console.log(`${lc} Delta Frame created. Rel8ns: ${JSON.stringify(deltaFrame.rel8ns)}`);
|
|
1155
1238
|
}
|
|
1156
|
-
|
|
1239
|
+
// Build control payloads: frame + its dependencies (msg stone, identity)
|
|
1240
|
+
const payloadIbGibsControl = [deltaFrame, deltaStone];
|
|
1241
|
+
if (identity) {
|
|
1242
|
+
payloadIbGibsControl.push(identity);
|
|
1243
|
+
}
|
|
1244
|
+
return { frame: deltaFrame, payloadIbGibsControl, payloadIbGibsDomain: payloadIbGibs };
|
|
1157
1245
|
}
|
|
1158
1246
|
catch (error) {
|
|
1159
1247
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
@@ -1378,7 +1466,12 @@ export class SyncSagaCoordinator {
|
|
|
1378
1466
|
});
|
|
1379
1467
|
// IMMEDIATELY persist to both spaces for audit trail
|
|
1380
1468
|
await this.ensureSagaFrameInBothSpaces({ frame: deltaFrame, destSpace, tempSpace, metaspace });
|
|
1381
|
-
|
|
1469
|
+
// Build control payloads: frame + its dependencies (msg stone, identity)
|
|
1470
|
+
const payloadIbGibsControl = [deltaFrame, deltaStone];
|
|
1471
|
+
if (identity) {
|
|
1472
|
+
payloadIbGibsControl.push(identity);
|
|
1473
|
+
}
|
|
1474
|
+
return { frame: deltaFrame, payloadIbGibsControl, payloadIbGibsDomain: outgoingPayload };
|
|
1382
1475
|
}
|
|
1383
1476
|
else {
|
|
1384
1477
|
// We have nothing to send.
|
|
@@ -1403,7 +1496,12 @@ export class SyncSagaCoordinator {
|
|
|
1403
1496
|
});
|
|
1404
1497
|
// IMMEDIATELY persist to both spaces for audit trail
|
|
1405
1498
|
await this.ensureSagaFrameInBothSpaces({ frame: commitFrame, destSpace, tempSpace, metaspace });
|
|
1406
|
-
|
|
1499
|
+
// Build control payloads for commit
|
|
1500
|
+
const commitCtrlPayloads = [commitFrame, commitStone];
|
|
1501
|
+
if (identity) {
|
|
1502
|
+
commitCtrlPayloads.push(identity);
|
|
1503
|
+
}
|
|
1504
|
+
return { frame: commitFrame, payloadIbGibsControl: commitCtrlPayloads };
|
|
1407
1505
|
}
|
|
1408
1506
|
else {
|
|
1409
1507
|
// peer did NOT propose commit (maybe they just sent data/requests and didn't ready flag).
|
|
@@ -1455,9 +1553,19 @@ export class SyncSagaCoordinator {
|
|
|
1455
1553
|
});
|
|
1456
1554
|
// IMMEDIATELY persist to both spaces for audit trail
|
|
1457
1555
|
await this.ensureSagaFrameInBothSpaces({ frame: commitFrame, destSpace, tempSpace, metaspace });
|
|
1458
|
-
|
|
1556
|
+
// Build control payloads for commit
|
|
1557
|
+
const commitCtrlPayloads2 = [commitFrame, commitStone];
|
|
1558
|
+
if (identity) {
|
|
1559
|
+
commitCtrlPayloads2.push(identity);
|
|
1560
|
+
}
|
|
1561
|
+
return { frame: commitFrame, payloadIbGibsControl: commitCtrlPayloads2 };
|
|
1562
|
+
}
|
|
1563
|
+
// Build control payloads for delta propose
|
|
1564
|
+
const deltaCtrlPayloads = [deltaFrame, deltaStone];
|
|
1565
|
+
if (identity) {
|
|
1566
|
+
deltaCtrlPayloads.push(identity);
|
|
1459
1567
|
}
|
|
1460
|
-
return { frame: deltaFrame,
|
|
1568
|
+
return { frame: deltaFrame, payloadIbGibsControl: deltaCtrlPayloads };
|
|
1461
1569
|
}
|
|
1462
1570
|
}
|
|
1463
1571
|
}
|