@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
|
@@ -4,10 +4,11 @@ import {
|
|
|
4
4
|
getTimestamp, // so our timestamp strings are uniform
|
|
5
5
|
getTimestampInTicks, // so our timestamp in ticks as a string are uniform
|
|
6
6
|
pretty,
|
|
7
|
-
clone
|
|
7
|
+
clone,
|
|
8
|
+
unique,
|
|
8
9
|
} from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
9
10
|
import { getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
|
|
10
|
-
import { splitPerTjpAndOrDna, getTimelinesGroupedByTjp } from "../common/other/ibgib-helper.mjs";
|
|
11
|
+
import { splitPerTjpAndOrDna, getTimelinesGroupedByTjp, isIbGib } from "../common/other/ibgib-helper.mjs";
|
|
11
12
|
import { Factory_V1 } from "@ibgib/ts-gib/dist/V1/factory.mjs";
|
|
12
13
|
import { IbGib_V1, IbGibRel8ns_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
13
14
|
import { isPrimitive } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
|
|
@@ -18,7 +19,7 @@ import { putInSpace, getLatestAddrs, getFromSpace } from "../witness/space/space
|
|
|
18
19
|
import { KeystoneIbGib_V1 } from "../keystone/keystone-types.mjs";
|
|
19
20
|
import { KeystoneService_V1 } from "../keystone/keystone-service-v1.mjs";
|
|
20
21
|
import { MetaspaceService } from "../witness/space/metaspace/metaspace-types.mjs";
|
|
21
|
-
import { SyncStage, SYNC_ATOM, SYNC_MSG_REL8N_NAME } from "./sync-constants.mjs";
|
|
22
|
+
import { SyncStage, SYNC_ATOM, SYNC_MSG_REL8N_NAME, SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN } from "./sync-constants.mjs";
|
|
22
23
|
import { appendToTimeline, createTimeline, Rel8nInfo, Rel8nRemovalInfo } from "../timeline/timeline-api.mjs";
|
|
23
24
|
import {
|
|
24
25
|
SyncData_V1, SyncIbGib_V1, SyncInitData, SyncConflictStrategy,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
SyncOptions,
|
|
27
28
|
} from "./sync-types.mjs";
|
|
28
29
|
import { getSyncIb, isPastFrame } from "./sync-helpers.mjs";
|
|
29
|
-
import { getSyncSagaDependencyGraph } from "./sync-helpers.mjs";
|
|
30
|
+
import { getSyncSagaDependencyGraph as getSyncSagaDependencyGraphForThisFrameOnly } from "./sync-helpers.mjs";
|
|
30
31
|
import { getDependencyGraph } from "../common/other/graph-helper.mjs";
|
|
31
32
|
import {
|
|
32
33
|
SyncSagaMessageData_V1, SyncSagaMessageInitData_V1,
|
|
@@ -37,16 +38,33 @@ import { getSyncSagaMessageIb } from "./sync-saga-message/sync-saga-message-help
|
|
|
37
38
|
import { SYNC_SAGA_MSG_ATOM } from "./sync-saga-message/sync-saga-message-constants.mjs";
|
|
38
39
|
import { SyncSagaInfo } from "./sync-types.mjs";
|
|
39
40
|
import { SyncPeerWitness } from "./sync-peer/sync-peer-types.mjs";
|
|
40
|
-
import { SyncSagaContextIbGib_V1,
|
|
41
|
+
import { SyncSagaContextIbGib_V1, } from "./sync-saga-context/sync-saga-context-types.mjs";
|
|
41
42
|
import { createSyncSagaContext } from "./sync-saga-context/sync-saga-context-helpers.mjs";
|
|
42
|
-
import { newupSubject } from "../common/pubsub/subject/subject-helper.mjs";
|
|
43
|
+
import { newupSubject, } from "../common/pubsub/subject/subject-helper.mjs";
|
|
43
44
|
import { SubjectWitness } from "../common/pubsub/subject/subject-types.mjs";
|
|
44
45
|
|
|
45
46
|
import { mergeDivergentTimelines } from "./strategies/conflict-optimistic.mjs";
|
|
46
47
|
import { getSyncSagaMessageFromFrame } from "./sync-saga-message/sync-saga-message-helpers.mjs";
|
|
48
|
+
import { fnObs } from "../common/pubsub/observer/observer-helper.mjs";
|
|
49
|
+
import { SubscriptionWitness } from "../common/pubsub/subscription/subscription-types.mjs";
|
|
50
|
+
import { ErrorIbGib_V1 } from "../common/error/error-types.mjs";
|
|
51
|
+
import { SyncPeerInnerspace_V1 } from "./sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs";
|
|
47
52
|
|
|
48
53
|
|
|
49
|
-
const logalot = GLOBAL_LOG_A_LOT || true;
|
|
54
|
+
// const logalot = GLOBAL_LOG_A_LOT || true;
|
|
55
|
+
const logalot = false;
|
|
56
|
+
const logalotControlDomain = true;
|
|
57
|
+
const lcControlDomain = '[ControlDomain]';
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Result of handling a saga frame.
|
|
61
|
+
* Separates control and domain payloads.
|
|
62
|
+
*/
|
|
63
|
+
export interface HandleSagaFrameResult {
|
|
64
|
+
frame: SyncIbGib_V1;
|
|
65
|
+
payloadIbGibsControl?: IbGib_V1[];
|
|
66
|
+
payloadIbGibsDomain?: IbGib_V1[];
|
|
67
|
+
}
|
|
50
68
|
|
|
51
69
|
/**
|
|
52
70
|
* Orchestrates the synchronization process between two spaces (Source and Destination).
|
|
@@ -157,6 +175,13 @@ export class SyncSagaCoordinator {
|
|
|
157
175
|
});
|
|
158
176
|
|
|
159
177
|
// 4. EXECUTE SAGA LOOP (FSM)
|
|
178
|
+
// Inject tempSpace into peer so it can pull control payloads to the right place
|
|
179
|
+
// if ('opts' in peer && peer.opts) {
|
|
180
|
+
if (!peer.data) { throw new Error(`(UNEXPECTED) peer.data falsy? (E: 8546a884c82ffb1999e95d9867da2826)`); }
|
|
181
|
+
if (peer.data.classname === SyncPeerInnerspace_V1.name) {
|
|
182
|
+
// (peer as SyncPeerInnerspace_V1).senderTempSpace = tempSpace;
|
|
183
|
+
}
|
|
184
|
+
|
|
160
185
|
const syncedIbGibs = await this.executeSagaLoop({
|
|
161
186
|
initialFrame: initFrame,
|
|
162
187
|
srcGraph,
|
|
@@ -260,7 +285,6 @@ export class SyncSagaCoordinator {
|
|
|
260
285
|
srcGraph: { [addr: string]: IbGib_V1 },
|
|
261
286
|
peer: SyncPeerWitness,
|
|
262
287
|
sessionIdentity?: KeystoneIbGib_V1,
|
|
263
|
-
// updates$: Subject_V1<SyncSagaContextIbGib_V1>,
|
|
264
288
|
updates$: SubjectWitness<SyncSagaContextIbGib_V1>,
|
|
265
289
|
localSpace: IbGibSpaceAny,
|
|
266
290
|
tempSpace: IbGibSpaceAny,
|
|
@@ -271,144 +295,213 @@ export class SyncSagaCoordinator {
|
|
|
271
295
|
// The current frame we just generated (e.g., Init or Delta Request)
|
|
272
296
|
let currentFrame: SyncIbGib_V1 | null = initialFrame;
|
|
273
297
|
// The payload we need to attach to the message (data we are sending)
|
|
274
|
-
let
|
|
298
|
+
let nextDomainIbGibs: IbGib_V1[] = [];
|
|
275
299
|
// Accumulator for all data we've successfully pulled from the remote
|
|
276
300
|
const allReceivedIbGibs: IbGib_V1[] = [];
|
|
277
301
|
|
|
278
302
|
while (currentFrame) {
|
|
279
303
|
// A. Create Context (Request)
|
|
280
304
|
// 1. Calculate Full Dependency Graph (including Ancestors/DNA)
|
|
281
|
-
//
|
|
282
|
-
|
|
305
|
+
// TODO: adjust this algorithm to only do the dependencies that the other end doesn't need (diff between tip and LCA)
|
|
306
|
+
// We must do this BEFORE creating the Context so we can list them
|
|
307
|
+
// all in payloadAddrsDomain and payloadAddrsControl.
|
|
308
|
+
// const depsDomainIbGibs: IbGib_V1[] = [];
|
|
309
|
+
// const depsControlIbGibs: IbGib_V1[] = [];
|
|
310
|
+
const payloadIbGibsControl: IbGib_V1[] = [];
|
|
311
|
+
const payloadIbGibsDomain: IbGib_V1[] = [];
|
|
283
312
|
|
|
284
313
|
// A. Payload (Standard Deep Deps)
|
|
285
|
-
for (const
|
|
286
|
-
let
|
|
287
|
-
if (!
|
|
288
|
-
|
|
314
|
+
for (const nextDomainIbGib of nextDomainIbGibs) {
|
|
315
|
+
let nextDomainIbGibGraph = await getDependencyGraph({ ibGib: nextDomainIbGib, space: localSpace });
|
|
316
|
+
if (!nextDomainIbGibGraph) {
|
|
317
|
+
nextDomainIbGibGraph = await getDependencyGraph({ ibGib: nextDomainIbGib, space: tempSpace });
|
|
289
318
|
}
|
|
290
319
|
|
|
291
|
-
if (
|
|
292
|
-
|
|
320
|
+
if (nextDomainIbGibGraph) {
|
|
321
|
+
payloadIbGibsDomain.push(...Object.values(nextDomainIbGibGraph));
|
|
293
322
|
} else {
|
|
294
|
-
|
|
323
|
+
throw new Error(`(UNEXPECTED) we couldn't get the graph for a known domain ibgib? nextDomainIbGib addr: ${getIbGibAddr({ ibGib: nextDomainIbGib })} (E: 01b3e4db8768b5b77db72e486f4f7826)`);
|
|
295
324
|
}
|
|
296
325
|
}
|
|
297
|
-
if (logalot) {
|
|
298
|
-
// console.log(`${lc} allDeps count: ${allDeps.length}`);
|
|
299
|
-
}
|
|
326
|
+
if (logalot) { console.log(`${lc} payloadIbGibsDomain count: ${payloadIbGibsDomain.length} (I: 2beda8ca7dc5ac0f48ed9e25e704b826)`); }
|
|
300
327
|
|
|
301
328
|
// B. Frames (Shallow Sync Deps)
|
|
302
329
|
if (currentFrame) {
|
|
303
|
-
const
|
|
304
|
-
if (
|
|
330
|
+
const depsCurrentFrame = await getSyncSagaDependencyGraphForThisFrameOnly({ ibGib: currentFrame, space: tempSpace });
|
|
331
|
+
if (depsCurrentFrame.length > 0) {
|
|
332
|
+
depsCurrentFrame.forEach(x => payloadIbGibsControl.push(x));
|
|
333
|
+
} else {
|
|
334
|
+
throw new Error(`(UNEXPECTED) couldn't get deps for currentFrame? currentFrame: ${JSON.stringify(currentFrame)} (E: 06344d07adc80d80b809211171444d26)`);
|
|
335
|
+
}
|
|
305
336
|
}
|
|
306
337
|
|
|
307
338
|
// 2. Create Context (Envelope)
|
|
308
|
-
|
|
309
|
-
const
|
|
339
|
+
const domainPayloadsMap = new Map<string, IbGib_V1>();
|
|
340
|
+
const sublc = `${lc}[peer.payloadIbGibsDomainReceived$]`;
|
|
341
|
+
let subscription: SubscriptionWitness;
|
|
342
|
+
if (peer && peer.payloadIbGibsDomainReceived$) {
|
|
343
|
+
// Subscribe to stream
|
|
344
|
+
subscription = await peer.payloadIbGibsDomainReceived$.subscribe(fnObs({
|
|
345
|
+
next: async (ibgib: IbGib_V1) => {
|
|
346
|
+
if (logalot) { console.log(`${sublc} next fired. (I: 2b4bdf502a38a90ba33d9711e7cb7826)`); }
|
|
347
|
+
const addr = getIbGibAddr({ ibGib: ibgib });
|
|
348
|
+
if (logalotControlDomain) { console.log(`${lc}${lcControlDomain} DOMAIN STREAM RECEIVED <- observable: ${addr} (I: d69ee80fcaece272483ec33b2d289826)`); }
|
|
349
|
+
domainPayloadsMap.set(addr, ibgib);
|
|
350
|
+
},
|
|
351
|
+
error: async (e: string | Error | ErrorIbGib_V1) => {
|
|
352
|
+
if (isIbGib(e)) {
|
|
353
|
+
console.error(`${sublc} error fired. error: ${JSON.stringify((e as IbGib_V1).data)} (E: 01cc08ba05ad99682831174fd7c31a26)`);
|
|
354
|
+
} else {
|
|
355
|
+
console.dir(e);
|
|
356
|
+
console.error(`${sublc} error fired. error: ${extractErrorMsg(e)} (E: 73d3d61464e8e4ce4cd6efd8b9675826)`);
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
complete: async () => {
|
|
360
|
+
if (logalot) { console.log(`${sublc} complete fired. (I: a47218aa9e4433fdb97c068880a45826)`); }
|
|
361
|
+
await subscription.unsubscribe();
|
|
362
|
+
},
|
|
363
|
+
}));
|
|
364
|
+
}
|
|
310
365
|
|
|
366
|
+
// 2b. Request Context
|
|
311
367
|
const requestCtx = await createSyncSagaContext({
|
|
312
|
-
cmd: SyncSagaContextCmd.process,
|
|
313
368
|
sagaFrame: currentFrame,
|
|
314
369
|
sessionKeystones: sessionIdentity ? [sessionIdentity] : undefined,
|
|
315
|
-
|
|
370
|
+
payloadIbGibsDomain,
|
|
316
371
|
});
|
|
317
372
|
|
|
318
|
-
//
|
|
319
|
-
if (
|
|
320
|
-
const
|
|
321
|
-
|
|
373
|
+
// Log what we're sending
|
|
374
|
+
if (logalotControlDomain) {
|
|
375
|
+
const controlAddrs = payloadIbGibsControl.map(p => getIbGibAddr({ ibGib: p }));
|
|
376
|
+
const domainAddrs = payloadIbGibsDomain.map(p => getIbGibAddr({ ibGib: p }));
|
|
377
|
+
console.log(`${lc}${lcControlDomain} SENDER TRANSMIT -> peer.witness (I: b3c4d5e6f7a8b9c0)`);
|
|
378
|
+
console.log(`${lc}${lcControlDomain} Context: ${getIbGibAddr({ ibGib: requestCtx })}`);
|
|
379
|
+
console.log(`${lc}${lcControlDomain} Frame: ${getIbGibAddr({ ibGib: currentFrame })}`);
|
|
380
|
+
console.log(`${lc}${lcControlDomain} CONTROL Payloads (${controlAddrs.length}): ${controlAddrs.join(', ') || '(none)'}`);
|
|
381
|
+
console.log(`${lc}${lcControlDomain} DOMAIN Payloads (${domainAddrs.length}): ${domainAddrs.join(', ') || '(none)'}`);
|
|
322
382
|
}
|
|
323
383
|
|
|
384
|
+
// Add Context Deps
|
|
385
|
+
// do we need to add requestCtx to the payload ibgibs?
|
|
386
|
+
// if (requestCtx) {
|
|
387
|
+
// const deps = await getSyncSagaDependencyGraphForThisFrameOnly({ ibGib: requestCtx, space: tempSpace });
|
|
388
|
+
// if (deps) { deps.forEach(x => payloadIbGibsControl.push(x)); }
|
|
389
|
+
// }
|
|
390
|
+
|
|
324
391
|
// 3. Identity (if exists)
|
|
325
392
|
// Identity might be deep? Keystone? Usually self-contained or shallow references.
|
|
326
393
|
if (sessionIdentity) {
|
|
327
|
-
|
|
394
|
+
payloadIbGibsControl.push(sessionIdentity);
|
|
328
395
|
}
|
|
329
396
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
397
|
+
// we only put the **CONTROL** payload ibgibs in localSpace. we
|
|
398
|
+
// don't put any domain ibgibs into this durable space until the
|
|
399
|
+
// final commit phase.
|
|
400
|
+
// The requestCtx envelope itself also goes to localSpace so transfer can find it.
|
|
401
|
+
await putInSpace({ space: localSpace, ibGib: requestCtx });
|
|
402
|
+
if (payloadIbGibsControl.length > 0) {
|
|
403
|
+
await putInSpace({ space: localSpace, ibGibs: payloadIbGibsControl });
|
|
335
404
|
}
|
|
336
405
|
|
|
337
406
|
// B. Transmit
|
|
338
407
|
// if (logalot) { console.log(`${lc} transmitting... requestCtx: ${pretty(requestCtx)} (I: 8cf20817c66899abdb1e76df50356826)`); }
|
|
339
|
-
updates$.next(requestCtx);
|
|
408
|
+
updates$.next(requestCtx); // spins off (don't remove this comment!)
|
|
409
|
+
|
|
340
410
|
const responseCtx = await peer.witness(requestCtx);
|
|
341
411
|
|
|
342
412
|
// C. Handle Response
|
|
343
413
|
if (!responseCtx) {
|
|
344
|
-
// Check if we just sent a Commit frame. If so, peer's silence is success/expected.
|
|
345
414
|
if (currentFrame) {
|
|
415
|
+
// Check for Commit (Peer silence expected)
|
|
346
416
|
const msg = await getSyncSagaMessageFromFrame({ frameIbGib: currentFrame, space: localSpace });
|
|
347
|
-
if (logalot) { console.log(`${lc} Checking currentFrame stage: ${msg?.data?.stage} (Expected: ${SyncStage.commit})`); }
|
|
348
417
|
if (msg?.data?.stage === SyncStage.commit) {
|
|
349
418
|
if (logalot) { console.log(`${lc} Sender sent Commit. Peer returned no response. Saga Complete.`); }
|
|
350
419
|
currentFrame = null;
|
|
351
420
|
break;
|
|
421
|
+
} else {
|
|
422
|
+
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)`);
|
|
352
423
|
}
|
|
424
|
+
} else {
|
|
425
|
+
throw new Error(`(UNEXPECTED) no response and currentFrame falsy? (E: 8d1085ea2f28cfc3f9c922649864a826)`);
|
|
353
426
|
}
|
|
354
|
-
|
|
355
|
-
throw new Error(`responseCtx falsy. Peer returned no response context (E: c099d8073b48d85e881f917835158f26)`);
|
|
356
|
-
// console.warn(`${lc} Peer returned no response context. Ending loop.`);
|
|
357
|
-
// currentFrame = null;
|
|
358
|
-
// break;
|
|
359
427
|
}
|
|
360
428
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
429
|
+
// ---------------------------------------------------------------------
|
|
430
|
+
// 2d. HANDLE RESPONSE
|
|
431
|
+
// ---------------------------------------------------------------------
|
|
432
|
+
if (!responseCtx.data) { throw new Error(`(UNEXPECTED) responseCtx.data falsy? (E: a969992bae53ab18a827ec58aec15826)`); }
|
|
433
|
+
updates$.next(responseCtx); // spins off -- don't remove this comment!
|
|
364
434
|
|
|
365
|
-
|
|
435
|
+
// Extract expected domain addresses from response context
|
|
436
|
+
const responsePayloadAddrsDomain = responseCtx.data[SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN] as string[] || [];
|
|
366
437
|
|
|
367
|
-
//
|
|
368
|
-
|
|
369
|
-
if
|
|
370
|
-
|
|
371
|
-
|
|
438
|
+
// 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.
|
|
439
|
+
|
|
440
|
+
// Poll for them if needed
|
|
441
|
+
if (responsePayloadAddrsDomain.length > 0) {
|
|
442
|
+
await this.pollForDomainPayloads({
|
|
443
|
+
expectedAddrs: responsePayloadAddrsDomain,
|
|
444
|
+
domainPayloadsMap,
|
|
445
|
+
tempSpace,
|
|
446
|
+
});
|
|
372
447
|
}
|
|
373
448
|
|
|
374
|
-
//
|
|
375
|
-
|
|
376
|
-
if (!
|
|
377
|
-
|
|
378
|
-
|
|
449
|
+
// Extract Response Frame
|
|
450
|
+
const responseFrameAddr = responseCtx.rel8ns?.sagaFrame?.[0];
|
|
451
|
+
if (!responseFrameAddr) { throw new Error(`${lc} Peer response missing sagaFrame (E: 83a0)`); }
|
|
452
|
+
|
|
453
|
+
// Log what we received back
|
|
454
|
+
if (logalotControlDomain) {
|
|
455
|
+
const responseControlAddrs = responseCtx.data?.['@payloadAddrsControl'] as string[] || [];
|
|
456
|
+
console.log(`${lc}${lcControlDomain} SENDER RECEIVED <- peer.witness (I: c4d5e6f7a8b9c0d1)`);
|
|
457
|
+
console.log(`${lc}${lcControlDomain} Response Context: ${getIbGibAddr({ ibGib: responseCtx })}`);
|
|
458
|
+
console.log(`${lc}${lcControlDomain} Response Frame: ${responseFrameAddr}`);
|
|
459
|
+
console.log(`${lc}${lcControlDomain} CONTROL Payloads (${responseControlAddrs.length}): ${responseControlAddrs.join(', ') || '(none)'}`);
|
|
460
|
+
console.log(`${lc}${lcControlDomain} DOMAIN Payloads (${responsePayloadAddrsDomain.length}): ${responsePayloadAddrsDomain.join(', ') || '(none)'}`);
|
|
379
461
|
}
|
|
380
|
-
const remoteFrame = resRemoteFrame.ibGibs?.[0];
|
|
381
462
|
|
|
382
|
-
|
|
383
|
-
|
|
463
|
+
// Get response frame from localSpace (SyncPeer puts it there)
|
|
464
|
+
let resResponseFrame = await getFromSpace({ space: localSpace, addr: responseFrameAddr });
|
|
465
|
+
if (!resResponseFrame.success || !resResponseFrame.ibGibs?.length) {
|
|
466
|
+
// Fallback to tempSpace
|
|
467
|
+
resResponseFrame = await getFromSpace({ space: tempSpace, addr: responseFrameAddr });
|
|
468
|
+
}
|
|
469
|
+
const responseFrame = resResponseFrame.ibGibs?.[0] as any;
|
|
470
|
+
if (!responseFrame) throw new Error(`${lc} Response frame not found (E: 7c2a)`);
|
|
471
|
+
|
|
472
|
+
// Handle Response Frame
|
|
473
|
+
const handleResult = await this.handleSagaFrame({
|
|
474
|
+
sagaIbGib: responseFrame,
|
|
475
|
+
srcGraph: {},
|
|
476
|
+
destSpace: localSpace,
|
|
477
|
+
tempSpace,
|
|
478
|
+
metaspace,
|
|
479
|
+
domainPayloadsMap,
|
|
480
|
+
expectedDomainAddrs: responsePayloadAddrsDomain,
|
|
481
|
+
});
|
|
384
482
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if (remoteDeps && remoteDeps.length > 0) {
|
|
389
|
-
await putInSpace({ space: tempSpace, ibGibs: remoteDeps });
|
|
483
|
+
if (!handleResult) {
|
|
484
|
+
if (logalot) { console.log(`${lc} Handler returned null (Saga End).`); }
|
|
485
|
+
break;
|
|
390
486
|
}
|
|
391
487
|
|
|
488
|
+
currentFrame = handleResult.frame;
|
|
392
489
|
|
|
393
|
-
//
|
|
394
|
-
//
|
|
395
|
-
|
|
396
|
-
// i.e., We Sent Delta -> Got Delta. This calls handleDeltaFrame.
|
|
397
|
-
const result = await this.handleSagaFrame({
|
|
398
|
-
sagaIbGib: remoteFrame as SyncIbGib_V1,
|
|
399
|
-
srcGraph,
|
|
400
|
-
destSpace: localSpace, // Query existing data from localSpace (Source)
|
|
401
|
-
tempSpace: tempSpace, // Transaction space for saga frames
|
|
402
|
-
identity: sessionIdentity,
|
|
403
|
-
metaspace
|
|
404
|
-
});
|
|
490
|
+
// Collect next DOMAIN payloads for the NEXT request
|
|
491
|
+
// Control payloads are handled separately by ensureSagaFrameInBothSpaces
|
|
492
|
+
nextDomainIbGibs = [...(handleResult.payloadIbGibsDomain || [])];
|
|
405
493
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
494
|
+
// Log handler output for next iteration
|
|
495
|
+
if (logalotControlDomain) {
|
|
496
|
+
const handlerControlAddrs = (handleResult.payloadIbGibsControl || []).map(p => getIbGibAddr({ ibGib: p }));
|
|
497
|
+
const handlerDomainAddrs = nextDomainIbGibs.map(p => getIbGibAddr({ ibGib: p }));
|
|
498
|
+
console.log(`${lc}${lcControlDomain} HANDLER RESULT -> next iteration (I: d5e6f7a8b9c0d1e2)`);
|
|
499
|
+
console.log(`${lc}${lcControlDomain} Next Frame: ${getIbGibAddr({ ibGib: currentFrame })}`);
|
|
500
|
+
console.log(`${lc}${lcControlDomain} CONTROL for next (${handlerControlAddrs.length}): ${handlerControlAddrs.join(', ') || '(none)'} (saved via ensureSagaFrameInBothSpaces)`);
|
|
501
|
+
console.log(`${lc}${lcControlDomain} DOMAIN for next (${handlerDomainAddrs.length}): ${handlerDomainAddrs.join(', ') || '(none)'}`);
|
|
411
502
|
}
|
|
503
|
+
|
|
504
|
+
// Note: currentFrame is automatically added to dependencies at start of next loop via B. Frames logic.
|
|
412
505
|
}
|
|
413
506
|
|
|
414
507
|
return allReceivedIbGibs;
|
|
@@ -432,7 +525,7 @@ export class SyncSagaCoordinator {
|
|
|
432
525
|
const lc = `${this.lc}[${this.getKnowledgeVector.name}]`;
|
|
433
526
|
try {
|
|
434
527
|
if (logalot) { console.log(`${lc} starting... (I: e184f8a7818666febfbbd2d841ed3826)`); }
|
|
435
|
-
console.dir(space)
|
|
528
|
+
// console.dir(space);
|
|
436
529
|
|
|
437
530
|
if (!(domainIbGibs && domainIbGibs.length > 0) &&
|
|
438
531
|
!(tjpAddrs && tjpAddrs.length > 0)
|
|
@@ -451,19 +544,19 @@ export class SyncSagaCoordinator {
|
|
|
451
544
|
tjps = tjpAddrs;
|
|
452
545
|
} else if (domainIbGibs && domainIbGibs.length > 0) {
|
|
453
546
|
// Extract TJPs from domain Ibgibs
|
|
454
|
-
if (
|
|
547
|
+
// if (false) { console.log(`${lc} domainIbGibs (${domainIbGibs.length}) provided. (I: a378995a0658af1f086ac1f297486c26)`); }
|
|
455
548
|
|
|
456
549
|
const { mapWithTjp_YesDna, mapWithTjp_NoDna } =
|
|
457
550
|
splitPerTjpAndOrDna({ ibGibs: domainIbGibs });
|
|
458
|
-
if (
|
|
459
|
-
if (
|
|
551
|
+
if (false) { console.log(`${lc}[TEST DEBUG] mapWithTjp_YesDna: ${JSON.stringify(mapWithTjp_YesDna)} (I: 287e22897148298e185712c8d50cfb26)`); }
|
|
552
|
+
if (false) { console.log(`${lc}[TEST DEBUG] mapWithTjp_NoDna: ${JSON.stringify(mapWithTjp_NoDna)} (I: 1bdc62656294aed0f9df334647dc7326)`); }
|
|
460
553
|
|
|
461
554
|
const allWithTjp = [...Object.values(mapWithTjp_YesDna), ...Object.values(mapWithTjp_NoDna)];
|
|
462
555
|
const timelineMap = getTimelinesGroupedByTjp({ ibGibs: allWithTjp });
|
|
463
|
-
if (
|
|
556
|
+
if (false) { console.log(`${lc}[TEST DEBUG] timelineMap: ${JSON.stringify(timelineMap)} (I: 2cc04898e5f85179fb1ac7f827abc426)`); }
|
|
464
557
|
|
|
465
558
|
tjps = Object.keys(timelineMap);
|
|
466
|
-
if (
|
|
559
|
+
if (false) { console.log(`${lc}[TEST DEBUG] tjps: ${tjps} (I: 3dd548667cbd967c68e57c88dc570826)`); }
|
|
467
560
|
} else {
|
|
468
561
|
// No info provided. Return empty? Or throw?
|
|
469
562
|
// User test context implied "everything", but implementation requires scope.
|
|
@@ -473,14 +566,14 @@ export class SyncSagaCoordinator {
|
|
|
473
566
|
|
|
474
567
|
if (tjps.length === 0) { return {}; }
|
|
475
568
|
|
|
476
|
-
if (
|
|
569
|
+
if (false) { console.log(`${lc} getting latest addrs for tjps: ${tjps} (I: d4e7080b8ba8187c583b82fd91ac0626)`); }
|
|
477
570
|
|
|
478
571
|
const res = await getLatestAddrs({ space, tjpAddrs: tjps });
|
|
479
572
|
if (!res.data || !res.data.latestAddrsMap) {
|
|
480
573
|
throw new Error(`${lc} Failed to get latest addrs. (E: 7a8b9c0d)`);
|
|
481
574
|
}
|
|
482
575
|
|
|
483
|
-
if (
|
|
576
|
+
// if (false) { console.log(`${lc}[TEST DEBUG] res.data.latestAddrsMap: ${JSON.stringify(res.data.latestAddrsMap)} (I: a8e128bdf80898ac2e6d8021a5bff726)`); }
|
|
484
577
|
|
|
485
578
|
return res.data.latestAddrsMap;
|
|
486
579
|
} catch (error) {
|
|
@@ -622,18 +715,64 @@ export class SyncSagaCoordinator {
|
|
|
622
715
|
}
|
|
623
716
|
|
|
624
717
|
/**
|
|
625
|
-
*
|
|
626
|
-
*
|
|
627
|
-
* @remarks
|
|
628
|
-
* **Execution Context**: **Universal (Both Sender and Receiver)**.
|
|
629
|
-
*
|
|
630
|
-
* This method acts as the "Reducer" for the Sync FSM. It determines the current stage
|
|
631
|
-
* based on the incoming frame and delegates to the appropriate handler.
|
|
632
|
-
*
|
|
633
|
-
* * If running on **Receiver**: Handles `Init` (via `handleInitFrame`).
|
|
634
|
-
* * If running on **Sender**: Handles `Ack` (via `handleAckFrame`).
|
|
635
|
-
* * If running on **Either**: Handles `Delta` (via `handleDeltaFrame`) or `Commit`.
|
|
718
|
+
* Helper to poll for streaming domain payloads and put them in the
|
|
719
|
+
* local {@link tempSpace}.
|
|
636
720
|
*/
|
|
721
|
+
protected async pollForDomainPayloads({
|
|
722
|
+
expectedAddrs,
|
|
723
|
+
domainPayloadsMap,
|
|
724
|
+
tempSpace,
|
|
725
|
+
}: {
|
|
726
|
+
expectedAddrs: string[],
|
|
727
|
+
domainPayloadsMap: Map<string, IbGib_V1>,
|
|
728
|
+
tempSpace: IbGibSpaceAny,
|
|
729
|
+
}): Promise<void> {
|
|
730
|
+
const lc = `${this.lc}[${this.pollForDomainPayloads.name}]`;
|
|
731
|
+
try {
|
|
732
|
+
if (logalot) { console.log(`${lc} starting... (I: 26dce86bfca572939885798802d6e926)`); }
|
|
733
|
+
|
|
734
|
+
let pending = [...expectedAddrs];
|
|
735
|
+
const start = Date.now();
|
|
736
|
+
/**
|
|
737
|
+
* This needs
|
|
738
|
+
*/
|
|
739
|
+
const timeoutMs = 5 * 60 * 1000; // 5 minutes...arbitrary at this point. This needs to be pulled out and improved eesh.
|
|
740
|
+
|
|
741
|
+
while (pending.length > 0) {
|
|
742
|
+
if (Date.now() - start > timeoutMs) {
|
|
743
|
+
throw new Error(`Timeout waiting for payloads: ${pending.join(', ')} (E: 46e1683c9578095261aaf798bd5e1826)`);
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
const stillPending: string[] = [];
|
|
747
|
+
const found: IbGib_V1[] = [];
|
|
748
|
+
|
|
749
|
+
for (const addr of pending) {
|
|
750
|
+
if (domainPayloadsMap.has(addr)) {
|
|
751
|
+
found.push(domainPayloadsMap.get(addr)!);
|
|
752
|
+
domainPayloadsMap.delete(addr);
|
|
753
|
+
} else {
|
|
754
|
+
stillPending.push(addr);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
if (found.length > 0) {
|
|
759
|
+
await putInSpace({ space: tempSpace, ibGibs: found });
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
pending = stillPending;
|
|
763
|
+
|
|
764
|
+
if (pending.length > 0) {
|
|
765
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
} catch (error) {
|
|
769
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
770
|
+
throw error;
|
|
771
|
+
} finally {
|
|
772
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
637
776
|
async handleSagaFrame({
|
|
638
777
|
sagaIbGib,
|
|
639
778
|
srcGraph,
|
|
@@ -650,7 +789,9 @@ export class SyncSagaCoordinator {
|
|
|
650
789
|
identity?: KeystoneIbGib_V1,
|
|
651
790
|
identitySecret?: string,
|
|
652
791
|
metaspace: MetaspaceService,
|
|
653
|
-
|
|
792
|
+
domainPayloadsMap?: Map<string, IbGib_V1>,
|
|
793
|
+
expectedDomainAddrs?: string[],
|
|
794
|
+
}): Promise<HandleSagaFrameResult | null> {
|
|
654
795
|
const lc = `${this.lc}[${this.handleSagaFrame.name}]`;
|
|
655
796
|
try {
|
|
656
797
|
if (logalot) { console.log(`${lc} starting... (I: 5deec8a1f7a6d263c88cd458ad990826)`); }
|
|
@@ -717,7 +858,7 @@ export class SyncSagaCoordinator {
|
|
|
717
858
|
metaspace: MetaspaceService,
|
|
718
859
|
identity?: KeystoneIbGib_V1,
|
|
719
860
|
identitySecret?: string,
|
|
720
|
-
}): Promise<
|
|
861
|
+
}): Promise<HandleSagaFrameResult | null> {
|
|
721
862
|
const lc = `${this.lc}[${this.handleInitFrame.name}]`;
|
|
722
863
|
console.log(`${lc} [TEST DEBUG] Received destSpace: ${destSpace.data?.name || destSpace.ib} (uuid: ${destSpace.data?.uuid || '[no uuid]'})`);
|
|
723
864
|
if (logalot) { console.log(`${lc} starting...`); }
|
|
@@ -1002,7 +1143,11 @@ export class SyncSagaCoordinator {
|
|
|
1002
1143
|
|
|
1003
1144
|
// if (logalot) { console.log(`${lc} ackFrame created: ${pretty(ackFrame)} (I: be24480592eec478086bb3da49286826)`); }
|
|
1004
1145
|
|
|
1005
|
-
|
|
1146
|
+
// Build control payloads: frame + its dependencies (msg stone, identity)
|
|
1147
|
+
const payloadIbGibsControl: IbGib_V1[] = [ackFrame, ackStone];
|
|
1148
|
+
if (identity) { payloadIbGibsControl.push(identity); }
|
|
1149
|
+
|
|
1150
|
+
return { frame: ackFrame, payloadIbGibsControl };
|
|
1006
1151
|
}
|
|
1007
1152
|
|
|
1008
1153
|
/**
|
|
@@ -1031,7 +1176,7 @@ export class SyncSagaCoordinator {
|
|
|
1031
1176
|
tempSpace: IbGibSpaceAny,
|
|
1032
1177
|
metaspace: MetaspaceService,
|
|
1033
1178
|
identity?: KeystoneIbGib_V1,
|
|
1034
|
-
}): Promise<
|
|
1179
|
+
}): Promise<HandleSagaFrameResult | null> {
|
|
1035
1180
|
const lc = `${this.lc}[${this.handleAckFrame.name}]`;
|
|
1036
1181
|
try {
|
|
1037
1182
|
if (logalot) { console.log(`${lc} starting... (I: 605b6860e898267a5b50c6d85704be26)`); }
|
|
@@ -1130,62 +1275,7 @@ export class SyncSagaCoordinator {
|
|
|
1130
1275
|
// PULL these frames from Peer into Local Space
|
|
1131
1276
|
// (Validation: We trust peer for now / verification happens on put)
|
|
1132
1277
|
for (const addr of receiverOnlyAddrs) {
|
|
1133
|
-
|
|
1134
|
-
// The Coordinator 'peer' passed in 'sync()' might be needed here?
|
|
1135
|
-
// Wait, `handleAckFrame` doesn't have reference to `peer`?
|
|
1136
|
-
// It only has `space`, `metaspace`.
|
|
1137
|
-
// The `peer` is held by the `executeSagaLoop`.
|
|
1138
|
-
|
|
1139
|
-
// PROBLEM: `handleAckFrame` is pure logic on the Space/Data?
|
|
1140
|
-
// No, it's a method on Coordinator.
|
|
1141
|
-
// But `executeSagaLoop` calls it.
|
|
1142
|
-
// We might need to return "Requirements" to the loop?
|
|
1143
|
-
|
|
1144
|
-
// Checking return type: `{ frame: SyncIbGib_V1, payloadIbGibs?: ... }`
|
|
1145
|
-
// It returns the NEXT frame (Delta).
|
|
1146
|
-
|
|
1147
|
-
// If we need to fetch data, we are blocked.
|
|
1148
|
-
// We can't easily "Pull" here without the Peer reference.
|
|
1149
|
-
|
|
1150
|
-
// OPTION A: Pass `peer` to `handleAckFrame`.
|
|
1151
|
-
// OPTION B: Return a strict list of "MissingDeps" and let Loop handle it.
|
|
1152
|
-
|
|
1153
|
-
// Let's assume we can resolve this by adding `peer` to signature or using `metaspace` if it's a peer-witness?
|
|
1154
|
-
// No, Peer is ephemeral connection.
|
|
1155
|
-
|
|
1156
|
-
// Let's add `peer` to `handleAckFrame` signature?
|
|
1157
|
-
// It breaks the pattern of just handling frame + space.
|
|
1158
|
-
|
|
1159
|
-
// ALTERNATIVE: Use the `Delta` frame to request data?
|
|
1160
|
-
// `SyncSagaMessageDeltaData` has `requests?: string[]`.
|
|
1161
|
-
// Sender sends Delta Frame.
|
|
1162
|
-
// Does Receiver handle Delta Requests?
|
|
1163
|
-
// `handleDeltaFrame` (Receiver) -> checks `requests`.
|
|
1164
|
-
// YES.
|
|
1165
|
-
|
|
1166
|
-
// So Sender puts `receiverOnlyAddrs` into `deltaFrame.requests`.
|
|
1167
|
-
// Receiver sees them, fetches them, and includes them in the Response (Commit?).
|
|
1168
|
-
// Wait, Init->Ack->Delta->Commit.
|
|
1169
|
-
// If Receiver sends data in Commit, that's "too late" for Sender to Merge in THIS saga round?
|
|
1170
|
-
// Unless Commit is not the end?
|
|
1171
|
-
|
|
1172
|
-
// Or we do a "Delta 2" loop?
|
|
1173
|
-
|
|
1174
|
-
// "Iterative Resolution Loop" from plan.
|
|
1175
|
-
// If we request data in Delta, Receiver sends it in Commit (or Delta-Response).
|
|
1176
|
-
// Sender gets Commit. Sees data. Merges.
|
|
1177
|
-
// Then Sender needs to Send the MERGE result.
|
|
1178
|
-
// Needs another Push/Delta.
|
|
1179
|
-
|
|
1180
|
-
// REFINED FLOW:
|
|
1181
|
-
// 1. Sender sends Delta Frame with `requests: [receiverOnlyAddrs]`.
|
|
1182
|
-
// 2. Receiver responds (Commit? or Ack 2?) with Payload (Divergent Frames).
|
|
1183
|
-
// 3. Sender handles response -> Merges.
|
|
1184
|
-
// 4. Sender sends Commit (containing Merge Frame).
|
|
1185
|
-
|
|
1186
|
-
// Issue: Current state machine is Init->Ack->Delta->Commit.
|
|
1187
|
-
// We need to keep Saga open.
|
|
1188
|
-
// If Sender sends Delta with requests, does it transition to Commit?
|
|
1278
|
+
console.error(`${lc} [CONFLICT DEBUG] NOT IMPLEMENTED (E: e6bf1a9d2758c469bb2f97514062d826)`);
|
|
1189
1279
|
}
|
|
1190
1280
|
|
|
1191
1281
|
// Compute DELTA dependencies for each receiver-only frame
|
|
@@ -1371,7 +1461,11 @@ export class SyncSagaCoordinator {
|
|
|
1371
1461
|
|
|
1372
1462
|
if (logalot) { console.log(`${lc} Delta Frame created. Rel8ns: ${JSON.stringify(deltaFrame.rel8ns)}`); }
|
|
1373
1463
|
|
|
1374
|
-
|
|
1464
|
+
// Build control payloads: frame + its dependencies (msg stone, identity)
|
|
1465
|
+
const payloadIbGibsControl: IbGib_V1[] = [deltaFrame, deltaStone];
|
|
1466
|
+
if (identity) { payloadIbGibsControl.push(identity); }
|
|
1467
|
+
|
|
1468
|
+
return { frame: deltaFrame, payloadIbGibsControl, payloadIbGibsDomain: payloadIbGibs };
|
|
1375
1469
|
} catch (error) {
|
|
1376
1470
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
1377
1471
|
throw error;
|
|
@@ -1404,7 +1498,7 @@ export class SyncSagaCoordinator {
|
|
|
1404
1498
|
tempSpace: IbGibSpaceAny,
|
|
1405
1499
|
metaspace: MetaspaceService,
|
|
1406
1500
|
identity?: KeystoneIbGib_V1,
|
|
1407
|
-
}): Promise<
|
|
1501
|
+
}): Promise<HandleSagaFrameResult | null> {
|
|
1408
1502
|
const lc = `${this.lc}[${this.handleDeltaFrame.name}]`;
|
|
1409
1503
|
if (logalot) { console.log(`${lc} starting...`); }
|
|
1410
1504
|
|
|
@@ -1629,7 +1723,11 @@ export class SyncSagaCoordinator {
|
|
|
1629
1723
|
// IMMEDIATELY persist to both spaces for audit trail
|
|
1630
1724
|
await this.ensureSagaFrameInBothSpaces({ frame: deltaFrame, destSpace, tempSpace, metaspace });
|
|
1631
1725
|
|
|
1632
|
-
|
|
1726
|
+
// Build control payloads: frame + its dependencies (msg stone, identity)
|
|
1727
|
+
const payloadIbGibsControl: IbGib_V1[] = [deltaFrame, deltaStone];
|
|
1728
|
+
if (identity) { payloadIbGibsControl.push(identity); }
|
|
1729
|
+
|
|
1730
|
+
return { frame: deltaFrame, payloadIbGibsControl, payloadIbGibsDomain: outgoingPayload };
|
|
1633
1731
|
|
|
1634
1732
|
} else {
|
|
1635
1733
|
// We have nothing to send.
|
|
@@ -1659,7 +1757,11 @@ export class SyncSagaCoordinator {
|
|
|
1659
1757
|
// IMMEDIATELY persist to both spaces for audit trail
|
|
1660
1758
|
await this.ensureSagaFrameInBothSpaces({ frame: commitFrame, destSpace, tempSpace, metaspace });
|
|
1661
1759
|
|
|
1662
|
-
|
|
1760
|
+
// Build control payloads for commit
|
|
1761
|
+
const commitCtrlPayloads: IbGib_V1[] = [commitFrame, commitStone];
|
|
1762
|
+
if (identity) { commitCtrlPayloads.push(identity); }
|
|
1763
|
+
|
|
1764
|
+
return { frame: commitFrame, payloadIbGibsControl: commitCtrlPayloads };
|
|
1663
1765
|
|
|
1664
1766
|
} else {
|
|
1665
1767
|
// peer did NOT propose commit (maybe they just sent data/requests and didn't ready flag).
|
|
@@ -1718,10 +1820,18 @@ export class SyncSagaCoordinator {
|
|
|
1718
1820
|
// IMMEDIATELY persist to both spaces for audit trail
|
|
1719
1821
|
await this.ensureSagaFrameInBothSpaces({ frame: commitFrame, destSpace, tempSpace, metaspace });
|
|
1720
1822
|
|
|
1721
|
-
|
|
1823
|
+
// Build control payloads for commit
|
|
1824
|
+
const commitCtrlPayloads2: IbGib_V1[] = [commitFrame, commitStone];
|
|
1825
|
+
if (identity) { commitCtrlPayloads2.push(identity); }
|
|
1826
|
+
|
|
1827
|
+
return { frame: commitFrame, payloadIbGibsControl: commitCtrlPayloads2 };
|
|
1722
1828
|
}
|
|
1723
1829
|
|
|
1724
|
-
|
|
1830
|
+
// Build control payloads for delta propose
|
|
1831
|
+
const deltaCtrlPayloads: IbGib_V1[] = [deltaFrame, deltaStone];
|
|
1832
|
+
if (identity) { deltaCtrlPayloads.push(identity); }
|
|
1833
|
+
|
|
1834
|
+
return { frame: deltaFrame, payloadIbGibsControl: deltaCtrlPayloads };
|
|
1725
1835
|
}
|
|
1726
1836
|
}
|
|
1727
1837
|
}
|
|
@@ -1739,7 +1849,7 @@ export class SyncSagaCoordinator {
|
|
|
1739
1849
|
tempSpace: IbGibSpaceAny,
|
|
1740
1850
|
metaspace: MetaspaceService,
|
|
1741
1851
|
identity?: KeystoneIbGib_V1,
|
|
1742
|
-
}): Promise<
|
|
1852
|
+
}): Promise<HandleSagaFrameResult | null> {
|
|
1743
1853
|
const lc = `${this.lc}[${this.handleCommitFrame.name}]`;
|
|
1744
1854
|
if (logalot) { console.log(`${lc} Commit received.`); }
|
|
1745
1855
|
|