@ibgib/core-gib 0.1.26 → 0.1.28

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 (34) hide show
  1. package/dist/sync/sync-helpers.d.mts +23 -2
  2. package/dist/sync/sync-helpers.d.mts.map +1 -1
  3. package/dist/sync/sync-helpers.mjs +121 -4
  4. package/dist/sync/sync-helpers.mjs.map +1 -1
  5. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
  6. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +30 -9
  7. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
  8. package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
  9. package/dist/sync/sync-peer/sync-peer-v1.mjs +1 -0
  10. package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
  11. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
  12. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +17 -3
  13. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
  14. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +8 -0
  15. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
  16. package/dist/sync/sync-saga-coordinator.d.mts +30 -153
  17. package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
  18. package/dist/sync/sync-saga-coordinator.mjs +585 -406
  19. package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
  20. package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts +13 -18
  21. package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts.map +1 -1
  22. package/dist/sync/sync-types.d.mts +36 -6
  23. package/dist/sync/sync-types.d.mts.map +1 -1
  24. package/dist/sync/sync-types.mjs +32 -0
  25. package/dist/sync/sync-types.mjs.map +1 -1
  26. package/package.json +2 -2
  27. package/src/sync/sync-helpers.mts +113 -6
  28. package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +30 -8
  29. package/src/sync/sync-peer/sync-peer-v1.mts +2 -0
  30. package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +14 -2
  31. package/src/sync/sync-saga-context/sync-saga-context-types.mts +13 -5
  32. package/src/sync/sync-saga-coordinator.mts +656 -463
  33. package/src/sync/sync-saga-message/sync-saga-message-types.mts +27 -32
  34. package/src/sync/sync-types.mts +45 -8
@@ -1,16 +1,18 @@
1
- import { extractErrorMsg, getUUID } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
1
+ import { extractErrorMsg, getUUID, pretty } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
2
2
  import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
3
3
  import { Ib } from "@ibgib/ts-gib/dist/types.mjs";
4
4
  import { validateIbGibIntrinsically } from "@ibgib/ts-gib/dist/V1/validate-helper.mjs";
5
+ import { isDna, isPrimitive } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
6
+ import { getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
5
7
 
6
8
  import { GLOBAL_LOG_A_LOT } from "../core-constants.mjs";
7
9
  import { SYNC_ATOM, SYNC_MSG_REL8N_NAME } from "./sync-constants.mjs";
8
- import { isValidSyncConflictStrategy, SYNC_CONFLICT_STRATEGY_VALID_VALUES, SyncData_V1, SyncIb_V1, SyncIbGib_V1, SyncSagaFrameDependencyGraph } from "./sync-types.mjs";
10
+ import { isValidSyncConflictStrategy, SYNC_CONFLICT_STRATEGY_VALID_VALUES, SyncData_V1, SyncExecutionContext, SyncIb_V1, SyncIbGib_V1, SyncSagaFrameDependencyGraph } from "./sync-types.mjs";
9
11
  import { IbGibSpaceAny } from "../witness/space/space-base-v1.mjs";
10
12
  import { getFromSpace, putInSpace } from "../witness/space/space-helper.mjs";
11
13
  import { IbGibSpaceResultData, IbGibSpaceResultIbGib, IbGibSpaceResultRel8ns } from "../witness/space/space-types.mjs";
12
14
  import { KeystoneIbGib_V1 } from "../keystone/keystone-types.mjs";
13
- import { isDna, isPrimitive } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
15
+ import { SyncSagaMessageCommitData_V1, SyncSagaMessageIbGib_V1 } from "./sync-saga-message/sync-saga-message-types.mjs";
14
16
 
15
17
  const logalot = GLOBAL_LOG_A_LOT;
16
18
 
@@ -178,7 +180,7 @@ export async function getSyncSagaFrameDependencyGraph({
178
180
  const resIbGib =
179
181
  resGet.rawResultIbGib as IbGibSpaceResultIbGib<IbGib_V1, IbGibSpaceResultData, IbGibSpaceResultRel8ns>
180
182
  if (!resIbGib.data) { throw new Error(`(UNEXPECTED) resGet.rawResultIbGib.data falsy? (E: c26c681d2f831fc537ba6f48fee36d26)`); }
181
- throw new Error(`(UNEXPECTED) couldn't find addrs? addrsNotFound: ${resIbGib.data.addrsNotFound}? (E: 43b7b5a6ad982715c8f3eed69bfa0d26)`);
183
+ throw new Error(`(UNEXPECTED) couldn't find addrs? addrsNotFound: ${resIbGib.data.addrsNotFound}? space.ib: ${localSpace.ib} (E: 43b7b5a6ad982715c8f3eed69bfa0d26)`);
182
184
  }
183
185
  };
184
186
 
@@ -191,7 +193,7 @@ export async function getSyncSagaFrameDependencyGraph({
191
193
 
192
194
  // msg stones
193
195
  const msgStoneAddrs = sagaIbGib.rel8ns[SYNC_MSG_REL8N_NAME]!;
194
- const msgStones = await fnGet(msgStoneAddrs);
196
+ const msgStones = await fnGet(msgStoneAddrs) as SyncSagaMessageIbGib_V1[];
195
197
 
196
198
  // identities
197
199
  const identities = sagaIbGib.rel8ns.identity && sagaIbGib.rel8ns.identity.length > 0 ?
@@ -201,6 +203,58 @@ export async function getSyncSagaFrameDependencyGraph({
201
203
  return { sagaIbGib, msgStones, identities, };
202
204
  }
203
205
 
206
+ /**
207
+ * gets the {@link SyncSagaFrameDependencyGraph} for each step in the saga,
208
+ * including the {@link sagaIbGib} passed in.
209
+ * @returns ordered array of saga frame dependency graphs
210
+ */
211
+ export async function getFullSyncSagaHistory({
212
+ sagaIbGib,
213
+ space,
214
+ }: {
215
+ sagaIbGib: SyncIbGib_V1,
216
+ space: IbGibSpaceAny,
217
+ }): Promise<SyncSagaFrameDependencyGraph[]> {
218
+ const lc = `[${getFullSyncSagaHistory.name}]`;
219
+ try {
220
+ if (logalot) { console.log(`${lc} starting... (I: 1ea3f804dd07d1e917a2afaaad497826)`); }
221
+ if (!sagaIbGib.data) { throw new Error(`(UNEXPECTED) sagaIbGib.data falsy? (E: fe0a0d0965e87ac852fe7ba4710cc826)`); }
222
+ if (!sagaIbGib.rel8ns) { throw new Error(`(UNEXPECTED) sagaIbGib.rel8ns falsy? (E: b79ff82a732346bdf8a9e1eb9ac96826)`); }
223
+
224
+ const sagaAddr = getIbGibAddr({ ibGib: sagaIbGib });
225
+
226
+ const addrs = sagaIbGib.rel8ns.past && sagaIbGib.rel8ns.past.length > 0 ?
227
+ [...sagaIbGib.rel8ns.past, sagaAddr] :
228
+ [sagaAddr];
229
+
230
+ const resGraphs: SyncSagaFrameDependencyGraph[] = [];
231
+ for (const addr of addrs) {
232
+ let sagaFrame: SyncIbGib_V1;
233
+ let resGet = await getFromSpace({ addr, space });
234
+ if (resGet.success && resGet.ibGibs && resGet.ibGibs.length === 1) {
235
+ sagaFrame = resGet.ibGibs[0] as SyncIbGib_V1;
236
+ } else {
237
+ if (logalot) { console.log(`${lc} failed getting full history of sagaIbGib:\n${pretty(sagaIbGib)} (I: 2a35685bfe038f63182c7db39b44c826)`); }
238
+ throw new Error(`couldn't get saga addr (${addr}) from space (${space.ib}) (E: 865b78ecd918c244158813650bea7d26)`);
239
+ }
240
+ const graph = await getSyncSagaFrameDependencyGraph({
241
+ sagaIbGib: sagaFrame, localSpace: space,
242
+ });
243
+ resGraphs.push(graph);
244
+ }
245
+
246
+ // the \n are my my attempt at lining up an indent
247
+ if (logalot) { console.log(`${lc} resGraphs:...\n ${pretty(resGraphs).split('\n').join('\n ')}\n...(I: d8e11827d88a3454d887ff05fb4ff526)`); }
248
+
249
+ return resGraphs;
250
+ } catch (error) {
251
+ console.error(`${lc} ${extractErrorMsg(error)}`);
252
+ throw error;
253
+ } finally {
254
+ if (logalot) { console.log(`${lc} complete.`); }
255
+ }
256
+ }
257
+
204
258
  /**
205
259
  * only validates this single frame. does not validate any dependencies or past.
206
260
  * @returns array of errors, empty if valid
@@ -282,6 +336,23 @@ export async function validateSyncSagaFrame({
282
336
  }
283
337
  }
284
338
 
339
+ export async function validateFullSyncSagaHistory({
340
+ history,
341
+ }: {
342
+ history: SyncSagaFrameDependencyGraph[],
343
+ }): Promise<string[]> {
344
+ const lc = `[${validateFullSyncSagaHistory.name}]`;
345
+ try {
346
+ if (logalot) { console.log(`${lc} starting... (I: df02b802f6989096b8d8f728e2c0a526)`); }
347
+ console.error(`${lc} NAG ERROR (NOT THROWN) need to implement more validation on full saga history. (E: 9bfcc9247a1c783fd361a4a8216fef26)`)
348
+ return [];
349
+ } catch (error) {
350
+ console.error(`${lc} ${extractErrorMsg(error)}`);
351
+ throw error;
352
+ } finally {
353
+ if (logalot) { console.log(`${lc} complete.`); }
354
+ }
355
+ }
285
356
 
286
357
  export async function putInSpace_dnasThenNonDnas({
287
358
  ibGibs,
@@ -289,7 +360,7 @@ export async function putInSpace_dnasThenNonDnas({
289
360
  }: {
290
361
  ibGibs: IbGib_V1[],
291
362
  space: IbGibSpaceAny,
292
- }): Promise<void> {
363
+ }): Promise<{ payload_Dnas: IbGib_V1[], payload_NonDnas: IbGib_V1[] }> {
293
364
  const lc = `[${putInSpace_dnasThenNonDnas.name}]`;
294
365
  try {
295
366
  if (logalot) { console.log(`${lc} starting... (I: aa3ab828402836b3914800a8ffa1b826)`); }
@@ -313,6 +384,42 @@ export async function putInSpace_dnasThenNonDnas({
313
384
 
314
385
  // then put all non-dnas ("regular" ibgibs) in the space
315
386
  await putInSpace({ ibGibs: payload_NonDnas, isDna: false, space, });
387
+
388
+ return { payload_Dnas, payload_NonDnas };
389
+ } catch (error) {
390
+ console.error(`${lc} ${extractErrorMsg(error)}`);
391
+ throw error;
392
+ } finally {
393
+ if (logalot) { console.log(`${lc} complete.`); }
394
+ }
395
+ }
396
+
397
+ /**
398
+ * @see {@link SyncExecutionContext}
399
+ */
400
+ export function getExecutionContext({
401
+ sagaFrame,
402
+ }: {
403
+ sagaFrame: SyncIbGib_V1,
404
+ }): SyncExecutionContext {
405
+ const lc = `[${getExecutionContext.name}]`;
406
+ try {
407
+ if (logalot) { console.log(`${lc} starting... (I: 93521332d0dd2f5e88398b7db95e8126)`); }
408
+ if (!sagaFrame) { throw new Error(`(UNEXPECTED) sagaFrame falsy? (E: 01fb28be6668d88ea49bb298c739c926)`); }
409
+ if (!sagaFrame.data) { throw new Error(`(UNEXPECTED) sagaFrame.data falsy? (E: 998298eb17685bdb9a85b46488ccd826)`); }
410
+ if (!sagaFrame.data.n && sagaFrame.data.n !== 0) { throw new Error(`(UNEXPECTED) sagaFrame.data.n falsy and not 0? (E: 0394919d5b58300ceb09ba6a264ad826)`); }
411
+
412
+ const modulo = sagaFrame.data.n % 2;
413
+ // even => sender
414
+ // odd => receiver
415
+
416
+ if (modulo === 0) {
417
+ return SyncExecutionContext.sender;
418
+ } else if (modulo === 1) {
419
+ return SyncExecutionContext.receiver;
420
+ } else {
421
+ throw new Error(`(UNEXPECTED) modulo is neither 0 nor 1? my logic sucks! This was way too defensive on my part... (E: 559488a2eef8d17b57079ca8886ee826)`);
422
+ }
316
423
  } catch (error) {
317
424
  console.error(`${lc} ${extractErrorMsg(error)}`);
318
425
  throw error;
@@ -2,7 +2,7 @@
2
2
  * @module SyncPeerInnerspace_V1
3
3
  */
4
4
 
5
- import { delay, extractErrorMsg, unique } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
5
+ import { delay, extractErrorMsg, pretty, unique } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
6
6
  import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
7
7
  import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
8
8
  import { IbGib_V1, IbGibData_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
@@ -21,8 +21,9 @@ import { InitializeSyncPeerOpts } from '../sync-peer-types.mjs';
21
21
  import { getSyncSagaMessageFromFrame } from '../../sync-saga-message/sync-saga-message-helpers.mjs';
22
22
  import { SYNC_STAGE_VALID_VALUES, SyncStage } from '../../sync-constants.mjs';
23
23
  import { SyncSagaMessageAckData_V1, SyncSagaMessageCommitData_V1, SyncSagaMessageData_V1, SyncSagaMessageDeltaData_V1, SyncSagaMessageInitData_V1 } from '../../sync-saga-message/sync-saga-message-types.mjs';
24
- import { getSyncSagaFrameDependencyGraph, putInSpace_dnasThenNonDnas } from '../../sync-helpers.mjs';
24
+ import { getExecutionContext, getSyncSagaFrameDependencyGraph, putInSpace_dnasThenNonDnas } from '../../sync-helpers.mjs';
25
25
  import { splitPerTjpAndOrDna, toDto } from '../../../common/other/ibgib-helper.mjs';
26
+ import { SyncExecutionContext } from '../../sync-types.mjs';
26
27
 
27
28
 
28
29
  const logalot = GLOBAL_LOG_A_LOT || true;
@@ -133,8 +134,25 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1<InitializeSyncPeerInnersp
133
134
  if (!sagaFrame.data) { throw new Error(`(UNEXPECTED) sagaFrame.data falsy? (E: f30e290a8b770e1b387377420ea73a26)`); }
134
135
  if (!sagaFrame.rel8ns) { throw new Error(`(UNEXPECTED) sagaFrame.rel8ns falsy? (E: f888caa698b8cf6b4893b7fd6df09726)`); }
135
136
  if (!receiverTempSpace) { throw new Error(`(UNEXPECTED) receiverTempSpace falsy? (E: 3b46d838f6fc645c58b29215bfddb826)`); }
137
+ if (!senderTempSpace) { throw new Error(`(UNEXPECTED) senderTempSpace falsy? (E: b187a8f913c2295ae90d7ae2b47b6a26)`); }
136
138
  // #endregion sanity validation assertions
137
139
 
140
+ // let localSpace: IbGibSpaceAny;
141
+ // let localTempSpace: IbGibSpaceAny;
142
+ // let remoteSpace: IbGibSpaceAny;
143
+ // let remoteTempSpace: IbGibSpaceAny;
144
+ // if (getExecutionContext({ sagaFrame: context.sagaFrame }) === SyncExecutionContext.sender) {
145
+ // localSpace = senderSpace;
146
+ // localTempSpace = senderTempSpace;
147
+ // remoteSpace = receiverSpace;
148
+ // remoteTempSpace = receiverTempSpace;
149
+ // } else {
150
+ // localSpace = receiverSpace;
151
+ // localTempSpace = receiverTempSpace;
152
+ // remoteSpace = senderSpace;
153
+ // remoteTempSpace = senderSpace;
154
+ // }
155
+
138
156
  const { sagaIbGib: _alreadyHave, msgStones, identities } = await getSyncSagaFrameDependencyGraph({
139
157
  sagaIbGib: sagaFrame,
140
158
  localSpace: senderSpace,
@@ -184,27 +202,31 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1<InitializeSyncPeerInnersp
184
202
  // the payload ibgibs. so the receiver coordinator should be ready
185
203
  // to do its thing.
186
204
 
187
- const responseCtx = await receiverCoordinator.receiverContinueSync({
205
+ const responseCtx = await receiverCoordinator.continueSync({
188
206
  sagaContext: context,
189
207
  metaspace: receiverMetaspace,
190
208
  mySpace: receiverSpace,
191
209
  myTempSpace: receiverTempSpace,
192
210
  });
193
211
 
212
+ if (logalot) { console.log(`${lc} receiverCoordinator.continueSync responseCtx: ${responseCtx ? pretty(responseCtx) : 'undefined'} (I: fb2831decde1f2b3589021f85ab19126)`); }
213
+
194
214
  if (!responseCtx) {
195
215
  if (logalot) { console.log(`${lc} receiver produced undefined response context. (I: 2e1888ffc9e836689d5b171887c36d26)`); }
196
216
  return undefined; /* <<<< returns early */
197
217
  }
198
218
 
199
219
  // at this point, we have received the full response from the
200
- // receiver coordinator. Put the response's control ibgibs in the
201
- // sender's durable space (but don't register them), spin off the
202
- // process of any response payloads, and return the context.
220
+ // receiver coordinator. That coordinator has put the control ibgibs
221
+ // in its durable space. Now we need to put the response's control
222
+ // ibgibs in the sender's durable space (register them??), spin off
223
+ // the process of any response payloads, and return the context.
203
224
 
225
+ // get control ibgibs from the receiver space...
204
226
  const { msgStones: msgStonesResponse, identities: identitiesResponse } =
205
227
  await getSyncSagaFrameDependencyGraph({
206
228
  sagaIbGib: responseCtx.sagaFrame,
207
- localSpace: senderSpace,
229
+ localSpace: receiverSpace,
208
230
  });
209
231
  if (msgStonesResponse.length !== 1) { throw new Error(`(UNEXPECTED) msgStonesResponse.length !== 1? we're only geared for a single msg stone that is always present (not 0, not greater than 1) (E: 2d3138ed130f1aca116551889483e826)`); }
210
232
  const msgResponse = msgStonesResponse[0];
@@ -212,6 +234,7 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1<InitializeSyncPeerInnersp
212
234
  const responsePayloadIbGibsControl = [
213
235
  ...identities, msgResponse, responseCtx.sagaFrame, context
214
236
  ].map(x => toDto({ ibGib: x }));
237
+ // ...put into sender's durable space
215
238
  await putInSpace({
216
239
  ibGibs: responsePayloadIbGibsControl,
217
240
  space: senderSpace,
@@ -240,7 +263,6 @@ export class SyncPeerInnerspace_V1 extends SyncPeer_V1<InitializeSyncPeerInnersp
240
263
  await delay(delayMs);
241
264
  }
242
265
 
243
- if (!senderTempSpace) { throw new Error(`(UNEXPECTED) senderTempSpace falsy? (E: b187a8f913c2295ae90d7ae2b47b6a26)`); }
244
266
 
245
267
  await putInSpace_dnasThenNonDnas({
246
268
  ibGibs: payloadIbGibsDomain_response,
@@ -189,6 +189,8 @@ export abstract class SyncPeer_V1<TInitializeOpts extends InitializeSyncPeerOpts
189
189
 
190
190
  // at this point, we have a valid, authenticated, authorized context
191
191
 
192
+ await this.ensureReceiverTempSpace();
193
+
192
194
  // execute the transfer of control domain ibgibs & outgoing payload
193
195
  // ibgibs...
194
196
  const response = await this.sendContextRequest(context);
@@ -60,9 +60,10 @@ export async function getSyncSagaContextIb({
60
60
  if (!data) { throw new Error(`data required (E: 839d82138c234b3e89582855594191fe)`); }
61
61
 
62
62
  const payloadCount = data['@payloadAddrsDomain'] ? data['@payloadAddrsDomain'].length : 0;
63
- // sync_sagacontext cmd
63
+
64
64
  const ib = [
65
65
  SYNC_SAGA_CONTEXT_ATOM,
66
+ data.sagaN,
66
67
  payloadCount,
67
68
  ].join(' ');
68
69
 
@@ -89,6 +90,7 @@ export async function parseSyncSagaContextIb({
89
90
  }
90
91
  const [
91
92
  atom,
93
+ sagaNStr,
92
94
  payloadCountStr,
93
95
  ] = parts;
94
96
 
@@ -96,13 +98,19 @@ export async function parseSyncSagaContextIb({
96
98
  throw new Error(`Atom mismatch. Expected ${SYNC_SAGA_CONTEXT_ATOM}. Got ${atom}. (E: 67d71fc0f8d04840b178652309f471f5)`);
97
99
  }
98
100
 
101
+ if (!sagaNStr) { throw new Error(`invalid ib. second piece should be sagaN but is falsy (E: 081ed475aeb8fe25a66f60466b2e5826)`); }
102
+ const sagaN = parseInt(sagaNStr);
103
+ if (isNaN(sagaN)) {
104
+ throw new Error(`sagaNStr is not a number. (E: 3d6b580d5a48c5e03ecec288896e2826)`);
105
+ }
106
+
99
107
  if (!payloadCountStr) { throw new Error(`invalid ib. second piece should be payloadCount but is falsy (E: 0bb7580793d800ca02227828a7294826)`); }
100
108
  const payloadCount = parseInt(payloadCountStr);
101
109
  if (isNaN(payloadCount)) {
102
110
  throw new Error(`payloadCountStr is not a number. (E: 49457814282a44069871630987588722)`);
103
111
  }
104
112
 
105
- return { atom, payloadCount };
113
+ return { atom, sagaN, payloadCount };
106
114
  } catch (error) {
107
115
  console.error(`${lc} ${extractErrorMsg(error)}`);
108
116
  throw error;
@@ -130,6 +138,9 @@ export async function createSyncSagaContext({
130
138
  try {
131
139
  if (logalot) { console.log(`${lc} starting... (I: 6b87bee313e811d1d2fc90e87fbec826)`); }
132
140
 
141
+ if (!sagaFrame.data) { throw new Error(`(UNEXPECTED) sagaFrame.data falsy? (E: 04c49b4cccba6842a8b52e4c6f570726)`); }
142
+ if (!sagaFrame.data.n && sagaFrame.data.n !== 0) { throw new Error(`(UNEXPECTED) sagaFrame.data.n falsy and not 0? (E: 45b508da64a8b28428b11765d684b826)`); }
143
+
133
144
  const date = new Date();
134
145
  const timestamp = getTimestamp(date);
135
146
  const timestampMs = date.getMilliseconds();
@@ -137,6 +148,7 @@ export async function createSyncSagaContext({
137
148
  const data: SyncSagaContextData_V1 = {
138
149
  timestamp,
139
150
  timestampMs,
151
+ sagaN: sagaFrame.data.n,
140
152
  };
141
153
 
142
154
  // Domain Payloads
@@ -11,6 +11,10 @@ import { SYNC_SAGA_CONTEXT_ATOM } from './sync-saga-context-constants.mjs';
11
11
 
12
12
  export interface SyncSagaContextIb_V1 {
13
13
  atom: typeof SYNC_SAGA_CONTEXT_ATOM;
14
+ /**
15
+ * sagaFrame.data.n value
16
+ */
17
+ sagaN: number;
14
18
  /**
15
19
  * simple metadata count of data["@payloadAddrsDomain"]
16
20
  */
@@ -21,6 +25,10 @@ export interface SyncSagaContextIb_V1 {
21
25
  * Data payload for the Sync Saga Context.
22
26
  */
23
27
  export interface SyncSagaContextData_V1 extends IbGibData_V1 {
28
+ /**
29
+ * context's sagaFrame.data.n value
30
+ */
31
+ sagaN: number;
24
32
  /**
25
33
  * Payload data addresses for DOMAIN ibGibs (Timeline frames, user content).
26
34
  * Soft-linked via data property to avoid hard-linking graph dependencies.
@@ -35,7 +43,7 @@ export interface SyncSagaContextData_V1 extends IbGibData_V1 {
35
43
  export interface SyncSagaContextRel8ns_V1 extends IbGibRel8ns_V1 {
36
44
  /**
37
45
  * The primary Saga Frame being transported (Init, Ack, Delta, etc.).
38
- *
46
+ *
39
47
  * Should be a single addr.
40
48
  */
41
49
  sagaFrame: IbGibAddr[];
@@ -43,9 +51,9 @@ export interface SyncSagaContextRel8ns_V1 extends IbGibRel8ns_V1 {
43
51
  /**
44
52
  * The Ephemeral Session Keystone Identity used for this saga.
45
53
  * Required for validating the saga frame signature.
46
- *
54
+ *
47
55
  * ## notes
48
- *
56
+ *
49
57
  * This will be different for the sender and receiver, yes? hmm...
50
58
  * I think I need to put "sender" or "receiver" in the session keystone ib.
51
59
  */
@@ -59,7 +67,7 @@ export interface SyncSagaContextRel8ns_V1 extends IbGibRel8ns_V1 {
59
67
  export interface SyncSagaContextIbGib_V1 extends IbGib_V1<SyncSagaContextData_V1, SyncSagaContextRel8ns_V1> {
60
68
  /**
61
69
  * Domain ibgibs - OUTBOUND only.
62
- *
70
+ *
63
71
  * For inbound, the domain payload ibgibs are streamed via observable in the
64
72
  * peer.
65
73
  */
@@ -67,7 +75,7 @@ export interface SyncSagaContextIbGib_V1 extends IbGib_V1<SyncSagaContextData_V1
67
75
 
68
76
  /**
69
77
  * Reference to the actual sync saga frame that this context conveys.
70
- *
78
+ *
71
79
  * This frame's addr should be {@link SyncSagaContextRel8ns_V1.sagaFrame}.
72
80
  */
73
81
  sagaFrame: SyncIbGib_V1;