@ibgib/core-gib 0.1.13 → 0.1.14

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 (100) hide show
  1. package/dist/keystone/keystone-helpers.mjs +3 -3
  2. package/dist/keystone/keystone-helpers.mjs.map +1 -1
  3. package/dist/sync/sync-constants.d.mts +4 -1
  4. package/dist/sync/sync-constants.d.mts.map +1 -1
  5. package/dist/sync/sync-constants.mjs +3 -0
  6. package/dist/sync/sync-constants.mjs.map +1 -1
  7. package/dist/sync/sync-helpers.d.mts +18 -2
  8. package/dist/sync/sync-helpers.d.mts.map +1 -1
  9. package/dist/sync/sync-helpers.mjs +84 -3
  10. package/dist/sync/sync-helpers.mjs.map +1 -1
  11. package/dist/sync/sync-innerspace.respec.d.mts +0 -6
  12. package/dist/sync/sync-innerspace.respec.d.mts.map +1 -1
  13. package/dist/sync/sync-innerspace.respec.mjs +395 -404
  14. package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
  15. package/dist/sync/sync-peer/sync-peer-types.d.mts +31 -0
  16. package/dist/sync/sync-peer/sync-peer-types.d.mts.map +1 -0
  17. package/dist/sync/sync-peer/sync-peer-types.mjs +5 -0
  18. package/dist/sync/sync-peer/sync-peer-types.mjs.map +1 -0
  19. package/dist/sync/sync-peer/sync-peer-v1.d.mts +22 -0
  20. package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -0
  21. package/dist/sync/sync-peer/sync-peer-v1.mjs +13 -0
  22. package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -0
  23. package/dist/sync/sync-saga-context/sync-saga-context-constants.d.mts +8 -0
  24. package/dist/sync/sync-saga-context/sync-saga-context-constants.d.mts.map +1 -0
  25. package/dist/sync/sync-saga-context/sync-saga-context-constants.mjs +8 -0
  26. package/dist/sync/sync-saga-context/sync-saga-context-constants.mjs.map +1 -0
  27. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +54 -0
  28. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -0
  29. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +87 -0
  30. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -0
  31. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +66 -0
  32. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -0
  33. package/dist/sync/sync-saga-context/sync-saga-context-types.mjs +12 -0
  34. package/dist/sync/sync-saga-context/sync-saga-context-types.mjs.map +1 -0
  35. package/dist/sync/sync-saga-coordinator.d.mts +115 -125
  36. package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
  37. package/dist/sync/sync-saga-coordinator.mjs +539 -456
  38. package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
  39. package/dist/sync/sync-saga-coordinator.respec.mjs +7 -7
  40. package/dist/sync/sync-saga-coordinator.respec.mjs.map +1 -1
  41. package/dist/sync/sync-saga-message/sync-saga-message-constants.d.mts +2 -0
  42. package/dist/sync/sync-saga-message/sync-saga-message-constants.d.mts.map +1 -0
  43. package/dist/sync/sync-saga-message/sync-saga-message-constants.mjs +2 -0
  44. package/dist/sync/sync-saga-message/sync-saga-message-constants.mjs.map +1 -0
  45. package/dist/sync/sync-saga-message/sync-saga-message-helpers.d.mts +15 -0
  46. package/dist/sync/sync-saga-message/sync-saga-message-helpers.d.mts.map +1 -0
  47. package/dist/sync/sync-saga-message/sync-saga-message-helpers.mjs +43 -0
  48. package/dist/sync/sync-saga-message/sync-saga-message-helpers.mjs.map +1 -0
  49. package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts +39 -0
  50. package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts.map +1 -0
  51. package/dist/sync/sync-saga-message/sync-saga-message-types.mjs +2 -0
  52. package/dist/sync/sync-saga-message/sync-saga-message-types.mjs.map +1 -0
  53. package/dist/sync/sync-types.d.mts +81 -3
  54. package/dist/sync/sync-types.d.mts.map +1 -1
  55. package/dist/sync/sync-types.mjs +27 -1
  56. package/dist/sync/sync-types.mjs.map +1 -1
  57. package/dist/timeline/timeline-api.d.mts +16 -3
  58. package/dist/timeline/timeline-api.d.mts.map +1 -1
  59. package/dist/timeline/timeline-api.mjs +7 -7
  60. package/dist/timeline/timeline-api.mjs.map +1 -1
  61. package/dist/witness/space/outer-space/outer-space-types.d.mts +2 -0
  62. package/dist/witness/space/outer-space/outer-space-types.d.mts.map +1 -1
  63. package/dist/witness/space/space-base-v1.d.mts +19 -1
  64. package/dist/witness/space/space-base-v1.d.mts.map +1 -1
  65. package/dist/witness/space/space-base-v1.mjs +66 -6
  66. package/dist/witness/space/space-base-v1.mjs.map +1 -1
  67. package/dist/witness/space/space-helper.d.mts +14 -0
  68. package/dist/witness/space/space-helper.d.mts.map +1 -1
  69. package/dist/witness/space/space-helper.mjs +44 -1
  70. package/dist/witness/space/space-helper.mjs.map +1 -1
  71. package/dist/witness/space/space-respec-helper.d.mts.map +1 -1
  72. package/dist/witness/space/space-respec-helper.mjs +1 -1
  73. package/dist/witness/space/space-respec-helper.mjs.map +1 -1
  74. package/dist/witness/space/space-types.d.mts +12 -1
  75. package/dist/witness/space/space-types.d.mts.map +1 -1
  76. package/dist/witness/space/space-types.mjs +4 -0
  77. package/dist/witness/space/space-types.mjs.map +1 -1
  78. package/package.json +2 -2
  79. package/src/keystone/keystone-helpers.mts +3 -3
  80. package/src/sync/README.md +275 -0
  81. package/src/sync/sync-constants.mts +5 -0
  82. package/src/sync/sync-helpers.mts +105 -6
  83. package/src/sync/sync-innerspace.respec.mts +458 -457
  84. package/src/sync/sync-peer/sync-peer-types.mts +43 -0
  85. package/src/sync/sync-peer/sync-peer-v1.mts +28 -0
  86. package/src/sync/sync-saga-context/sync-saga-context-constants.mts +8 -0
  87. package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +147 -0
  88. package/src/sync/sync-saga-context/sync-saga-context-types.mts +80 -0
  89. package/src/sync/sync-saga-coordinator.mts +709 -526
  90. package/src/sync/sync-saga-coordinator.respec.mts +7 -7
  91. package/src/sync/sync-saga-message/sync-saga-message-constants.mts +1 -0
  92. package/src/sync/sync-saga-message/sync-saga-message-helpers.mts +59 -0
  93. package/src/sync/sync-saga-message/sync-saga-message-types.mts +53 -0
  94. package/src/sync/sync-types.mts +103 -3
  95. package/src/timeline/timeline-api.mts +20 -4
  96. package/src/witness/space/space-base-v1.mts +62 -12
  97. package/src/witness/space/space-helper.mts +50 -1
  98. package/src/witness/space/space-respec-helper.mts +2 -1
  99. package/src/witness/space/space-types.mts +13 -1
  100. package/tmp.md +3 -9
@@ -33,13 +33,13 @@ await respecfully(sir, 'SyncSagaCoordinator', async () => {
33
33
  const identitySecret = 'secret';
34
34
 
35
35
  // Execute Sync
36
- await coordinator.sync({
37
- source: sourceSpace,
38
- dest: destSpace,
39
- identity,
40
- domainIbGibs: [], // Empty for test
41
- identitySecret
42
- });
36
+ // await coordinator.deprecated_sync({
37
+ // source: sourceSpace,
38
+ // dest: destSpace,
39
+ // identity,
40
+ // domainIbGibs: [], // Empty for test
41
+ // identitySecret
42
+ // });
43
43
 
44
44
  // Verify Dest has received frames
45
45
  // We look for any ibgibs in the destSpace witness output
@@ -0,0 +1 @@
1
+ export const SYNC_SAGA_MSG_ATOM = 'sync_sagamsg';
@@ -0,0 +1,59 @@
1
+ import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
2
+ import { Ib } from "@ibgib/ts-gib/dist/types.mjs";
3
+ import { SYNC_SAGA_MSG_ATOM } from "./sync-saga-message-constants.mjs";
4
+ import { SyncSagaMessageData_V1, SyncSagaMessageIb_V1 } from "./sync-saga-message-types.mjs";
5
+
6
+ /**
7
+ * Constructs the standard 'ib' string for a Sync Saga Message stone.
8
+ */
9
+ export async function getSyncSagaMessageIb({
10
+ data,
11
+ }: {
12
+ data: SyncSagaMessageData_V1,
13
+ }): Promise<Ib> {
14
+ const lc = `[${getSyncSagaMessageIb.name}]`;
15
+ try {
16
+ // sync_saga_msg sagaId stage
17
+ const ib = [
18
+ SYNC_SAGA_MSG_ATOM,
19
+ data.sagaId,
20
+ data.stage
21
+ ].join(' ');
22
+
23
+ return ib;
24
+ } catch (error) {
25
+ console.error(`${lc} ${extractErrorMsg(error)}`);
26
+ throw error;
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Parses a standard Sync Saga Message 'ib' string.
32
+ */
33
+ export async function parseSyncSagaMessageIb({
34
+ ib,
35
+ }: {
36
+ ib: Ib,
37
+ }): Promise<SyncSagaMessageIb_V1> {
38
+ const lc = `[${parseSyncSagaMessageIb.name}]`;
39
+ try {
40
+ const parts = ib.split(' ');
41
+ if (parts.length !== 3) {
42
+ throw new Error(`Invalid sync saga message ib. Expected 3 parts [atom sagaId stage]. Got ${parts.length}. (E: 7abec847426bd8f41a475cafcc118826)`);
43
+ }
44
+ const [
45
+ atom,
46
+ sagaId,
47
+ stage
48
+ ] = parts;
49
+
50
+ if (atom !== SYNC_SAGA_MSG_ATOM) {
51
+ throw new Error(`Atom mismatch. Expected ${SYNC_SAGA_MSG_ATOM}. Got ${atom}. (E: 1b4ddf426ed87e474816ed48cedb8a26)`);
52
+ }
53
+
54
+ return { atom, sagaId, stage };
55
+ } catch (error) {
56
+ console.error(`${lc} ${extractErrorMsg(error)}`);
57
+ throw error;
58
+ }
59
+ }
@@ -0,0 +1,53 @@
1
+ import { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
2
+ import { KeystoneIbGib_V1 } from "../../keystone/keystone-types.mjs";
3
+ import { SyncStage } from "../sync-constants.mjs";
4
+ import { SyncMode, SyncConflictStrategy, SyncInitData, SyncRequestData, SyncDeltaData, SyncCommitData } from "../sync-types.mjs";
5
+ import { SYNC_SAGA_MSG_ATOM } from "./sync-saga-message-constants.mjs";
6
+
7
+ export interface SyncSagaMessageIb_V1 {
8
+ atom: typeof SYNC_SAGA_MSG_ATOM;
9
+ sagaId: string;
10
+ stage: string;
11
+ }
12
+
13
+ export interface SyncSagaMessageData_V1 extends IbGibData_V1 {
14
+ /**
15
+ * Unique ID for the synchronization session (saga).
16
+ */
17
+ sagaId: string;
18
+
19
+ /**
20
+ * Current stage of the protocol.
21
+ */
22
+ stage: SyncStage;
23
+ }
24
+
25
+ export interface SyncSagaMessageRel8ns_V1 extends IbGibRel8ns_V1 {
26
+ // potentially link to previous message in chain if we wanted chain-of-stones?
27
+ // For now, stones are independent or linked by the saga frame.
28
+ }
29
+
30
+ export interface SyncSagaMessageIbGib_V1 extends IbGib_V1<SyncSagaMessageData_V1, SyncSagaMessageRel8ns_V1> { }
31
+
32
+ // ===========================================================================
33
+ // CONCRETE MESSAGE PAYLOADS (EXTENDING DATA)
34
+ // ===========================================================================
35
+
36
+ export interface SyncSagaMessageInitData_V1 extends SyncSagaMessageData_V1, SyncInitData {
37
+ stage: typeof SyncStage.init;
38
+ }
39
+
40
+ export interface SyncSagaMessageAckData_V1 extends SyncSagaMessageData_V1 {
41
+ stage: typeof SyncStage.ack;
42
+ deltaReqAddrs: string[];
43
+ pushOfferAddrs: string[];
44
+ }
45
+
46
+ export interface SyncSagaMessageDeltaData_V1 extends SyncSagaMessageData_V1, SyncDeltaData {
47
+ stage: typeof SyncStage.delta;
48
+ requests?: string[];
49
+ }
50
+
51
+ export interface SyncSagaMessageCommitData_V1 extends SyncSagaMessageData_V1, SyncCommitData {
52
+ stage: typeof SyncStage.commit;
53
+ }
@@ -1,6 +1,82 @@
1
1
  import { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
2
+
2
3
  import { KeystoneIbGib_V1, KeystoneProof } from "../keystone/keystone-types.mjs";
3
4
  import { SYNC_ATOM, SyncStage } from "./sync-constants.mjs";
5
+ import { IbGibSpaceAny } from "../witness/space/space-base-v1.mjs";
6
+ import { MetaspaceService } from "../witness/space/metaspace/metaspace-types.mjs";
7
+
8
+
9
+ // #region SyncMode
10
+ export const SYNC_MODE_PUSH = 'push';
11
+ export const SYNC_MODE_PULL = 'pull';
12
+ export const SYNC_MODE_SYNC = 'sync';
13
+ export type SyncMode =
14
+ | typeof SYNC_MODE_PUSH
15
+ | typeof SYNC_MODE_PULL
16
+ | typeof SYNC_MODE_SYNC;
17
+ export const SyncMode = {
18
+ push: SYNC_MODE_PUSH,
19
+ pull: SYNC_MODE_PULL,
20
+ sync: SYNC_MODE_SYNC,
21
+ } satisfies { [key in SyncMode]: SyncMode };
22
+ export const SYNC_MODE_VALID_VALUES = Object.values(SyncMode);
23
+ export function isValidSyncMode(mode: string): mode is SyncMode {
24
+ return SYNC_MODE_VALID_VALUES.includes(mode as SyncMode);
25
+ }
26
+ // #endregion SyncMode
27
+
28
+ // #region SyncConflictStrategy
29
+ export const SYNC_CONFLICT_STRATEGY_ABORT = 'abort';
30
+ export const SYNC_CONFLICT_STRATEGY_OPTIMISTIC = 'optimistic';
31
+ export const SYNC_CONFLICT_STRATEGY_MANUAL = 'manual';
32
+ export type SyncConflictStrategy =
33
+ | typeof SYNC_CONFLICT_STRATEGY_ABORT
34
+ | typeof SYNC_CONFLICT_STRATEGY_OPTIMISTIC
35
+ | typeof SYNC_CONFLICT_STRATEGY_MANUAL;
36
+ export const SyncConflictStrategy = {
37
+ abort: SYNC_CONFLICT_STRATEGY_ABORT,
38
+ optimistic: SYNC_CONFLICT_STRATEGY_OPTIMISTIC,
39
+ manual: SYNC_CONFLICT_STRATEGY_MANUAL,
40
+ } satisfies { [key in SyncConflictStrategy]: SyncConflictStrategy };
41
+ export const SYNC_CONFLICT_STRATEGY_VALID_VALUES = Object.values(SyncConflictStrategy);
42
+ export function isValidSyncConflictStrategy(strategy: string): strategy is SyncConflictStrategy {
43
+ return SYNC_CONFLICT_STRATEGY_VALID_VALUES.includes(strategy as SyncConflictStrategy);
44
+ }
45
+ // #endregion SyncConflictStrategy
46
+
47
+ export interface SyncOptions {
48
+ /**
49
+ * The ibgibs we wish to sync.
50
+ *
51
+ * These should all exist in {@link source}
52
+ */
53
+ domainIbGibs: IbGib_V1[],
54
+ /**
55
+ * The space containing the data we want to send.
56
+ */
57
+ source: IbGibSpaceAny;
58
+ /**
59
+ * The space receiving the data.
60
+ */
61
+ dest: IbGibSpaceAny;
62
+ /**
63
+ * The metaspace context (for registering sync sagas locally).
64
+ */
65
+ metaspace: MetaspaceService;
66
+ /**
67
+ * The identity authorizing this sync.
68
+ */
69
+ identity: KeystoneIbGib_V1;
70
+ /**
71
+ * The secret for the identity (to sign the commit).
72
+ */
73
+ identitySecret: string;
74
+ /**
75
+ * How to handle conflicts when both Source and Dest have diverged on the same timeline.
76
+ * @default 'abort'
77
+ */
78
+ conflictStrategy?: SyncConflictStrategy;
79
+ }
4
80
 
5
81
  // ===========================================================================
6
82
  // PROTOCOL PAYLOADS
@@ -28,7 +104,7 @@ export interface SyncInitData {
28
104
  * e.g. "push" (I have data for you) or "pull" (Give me data).
29
105
  * @default 'push'
30
106
  */
31
- mode?: 'push' | 'pull';
107
+ mode?: SyncMode;
32
108
  }
33
109
 
34
110
  /**
@@ -77,7 +153,7 @@ export interface SyncCommitData {
77
153
  // IBGIB DATA STRUCTURES
78
154
  // ===========================================================================
79
155
 
80
- export interface SyncIbInfo_V1 {
156
+ export interface SyncIb_V1 {
81
157
  atom: typeof SYNC_ATOM;
82
158
  uuid: string;
83
159
  stage: SyncStage;
@@ -106,7 +182,7 @@ export interface SyncData_V1 extends IbGibData_V1 {
106
182
  /**
107
183
  * Polymorphic payload based on stage.
108
184
  */
109
- payload: SyncInitData | SyncRequestData | SyncDeltaData | SyncCommitData;
185
+ payload?: SyncInitData | SyncRequestData | SyncDeltaData | SyncCommitData;
110
186
  }
111
187
 
112
188
  export interface SyncRel8ns_V1 extends IbGibRel8ns_V1 {
@@ -118,3 +194,27 @@ export interface SyncRel8ns_V1 extends IbGibRel8ns_V1 {
118
194
  }
119
195
 
120
196
  export interface SyncIbGib_V1 extends IbGib_V1<SyncData_V1, SyncRel8ns_V1> { }
197
+
198
+ /**
199
+ * Information returned when starting a Sync Saga.
200
+ * Allows the caller to subscribe to updates and await completion.
201
+ */
202
+ import { SubjectWitness } from "../common/pubsub/subject/subject-types.mjs";
203
+ import { SyncSagaContextIbGib_V1 } from "./sync-saga-context/sync-saga-context-types.mjs";
204
+
205
+ export interface SyncSagaInfo {
206
+ /**
207
+ * The unique ID of the saga.
208
+ */
209
+ sagaId: string;
210
+ /**
211
+ * Stream of context updates happening during the saga.
212
+ * Subscribe to this to receive real-time progress.
213
+ */
214
+ updates$: SubjectWitness<SyncSagaContextIbGib_V1>;
215
+
216
+ /**
217
+ * Promise that resolves when the saga completes successfully.
218
+ */
219
+ done: Promise<void>;
220
+ }
@@ -36,6 +36,19 @@ export interface Rel8nInfo {
36
36
  }
37
37
 
38
38
  export interface CommonTimelineOptsSansSkipLock {
39
+ /**
40
+ * If true, dna will not be created when executing transforms.
41
+ *
42
+ * ## intent / driving use case
43
+ *
44
+ * We want to use the timeline api in working with the new sync saga code.
45
+ * However, we do not want dna, because the sync saga should not be merged
46
+ * and there should be no dynamic composition required from dna.
47
+ *
48
+ * But the default for this api should be for dna to be created, so we add
49
+ * this negative flag.
50
+ */
51
+ noDna?: boolean,
39
52
  /**
40
53
  * space of spaces. Should be a singleton. @see {@link MetaspaceService}
41
54
  */
@@ -144,6 +157,7 @@ export async function appendToTimeline({
144
157
  metaspace,
145
158
  space,
146
159
  skipLock,
160
+ noDna,
147
161
  }: {
148
162
  timeline: IbGib_V1,
149
163
  /**
@@ -222,7 +236,7 @@ export async function appendToTimeline({
222
236
  type: 'rel8', // assuming rel8 is the transform type
223
237
  src: latestTimelineIbGibDto, // Use the latest as the source
224
238
  rel8nsToAddByAddr,
225
- dna: true,
239
+ dna: noDna ? false : true,
226
240
  nCounter: true,
227
241
  });
228
242
  const newTimelineIbGib = resRel8.newIbGib;
@@ -550,6 +564,7 @@ export async function mut8Timeline<TData extends IbGibData_V1 = any>({
550
564
  space,
551
565
  skipLock,
552
566
  timelineIndexInfo,
567
+ noDna,
553
568
  }: {
554
569
  /**
555
570
  * timeline ibgib whose `data` we're mutating.
@@ -619,7 +634,7 @@ export async function mut8Timeline<TData extends IbGibData_V1 = any>({
619
634
  const resMut8 = await mut8({
620
635
  ...mut8Opts,
621
636
  src: latestTimelineIbGibDto,
622
- dna: true,
637
+ dna: noDna ? false : true,
623
638
  nCounter: true,
624
639
  }) as TransformResult<IbGib_V1<TData, any>>;
625
640
  const newTimelineIbGib = resMut8.newIbGib;
@@ -728,6 +743,7 @@ export async function createTimeline<TData extends IbGibData_V1 = IbGibData_V1>(
728
743
  ib,
729
744
  data,
730
745
  rel8ns,
746
+ noDna,
731
747
  parentIb,
732
748
  parentIbGib,
733
749
  metaspace,
@@ -790,9 +806,9 @@ export async function createTimeline<TData extends IbGibData_V1 = IbGibData_V1>(
790
806
  ib,
791
807
  data,
792
808
  rel8ns,
793
- // these options are what make this a "timeline"
794
- dna: true,
809
+ dna: noDna ? false : true,
795
810
  nCounter: true,
811
+ squash: noDna ? true : false,
796
812
  tjp: { timestamp: true, uuid: true },
797
813
  });
798
814
 
@@ -1,21 +1,20 @@
1
+ import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
1
2
  import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
2
3
  import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';
4
+ import { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';
3
5
 
4
-
6
+ import { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';
5
7
  import { WitnessBase_V1, } from '../witness-base-v1.mjs';
6
8
  import {
7
- IbGibSpace, IbGibSpaceData, IbGibSpaceOptionsCmd,
8
- IbGibSpaceOptionsCmdModifier, IbGibSpaceOptionsData, IbGibSpaceOptionsIbGib,
9
- IbGibSpaceOptionsRel8ns, IbGibSpaceRel8ns, IbGibSpaceResultData,
10
- IbGibSpaceResultIbGib, IbGibSpaceResultRel8ns
11
- } from '../../witness/space/space-types.mjs';
12
- import { getSpaceResultMetadata } from '../../witness/space/space-helper.mjs';
13
- import { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';
14
- // import { argy_, resulty_ } from '../witness-helper.mjs';
9
+ GetDependencyGraphResultData, IbGibSpace, IbGibSpaceData,
10
+ IbGibSpaceOptionsCmd, IbGibSpaceOptionsCmdModifier, IbGibSpaceOptionsData,
11
+ IbGibSpaceOptionsIbGib, IbGibSpaceOptionsRel8ns, IbGibSpaceRel8ns,
12
+ IbGibSpaceResultData, IbGibSpaceResultIbGib, IbGibSpaceResultRel8ns
13
+ } from './space-types.mjs';
14
+ import { getSpaceResultMetadata } from './space-helper.mjs';
15
+ import { getDependencyGraph, GetGraphOptions } from '../../common/other/graph-helper.mjs';
15
16
  import { argy_, resulty_ } from '../../witness/witness-helper.mjs';
16
- // import { IbGibCacheService } from '../../types/ibgib.mjs';
17
17
  import { IbGibCacheService } from '../../common/cache/cache-types.mjs';
18
- import { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';
19
18
 
20
19
  const logalot = GLOBAL_LOG_A_LOT;
21
20
 
@@ -139,6 +138,8 @@ export abstract class SpaceBase_V1<
139
138
  }
140
139
  } else if (cmdModifiers.includes('addrs')) {
141
140
  return this.getAddrs(arg);
141
+ } else if (cmdModifiers.includes('dependency-graph')) {
142
+ return this.getDependencyGraph(arg);
142
143
  } else {
143
144
  return this.get(arg);
144
145
  }
@@ -280,6 +281,55 @@ export abstract class SpaceBase_V1<
280
281
  throw new Error(`${lc} not implemented in base class`);
281
282
  }
282
283
 
284
+ /**
285
+ * gets the entire dependency graph(s) of incoming addr(s).
286
+ *
287
+ * NOTE: Caller will have to manually convert the result.ibGibs to a flag
288
+ * ibgib graph to match the existing {@link getDependencyGraph} return if
289
+ * desired. This should be a trivial conversion though, as the keys to the
290
+ * flat graph are just the {@link getIbGibAddr} on the ibGib itself.
291
+ *
292
+ * @returns resulty ibgib with {@link GetDependencyGraphResultData}
293
+ */
294
+ protected getDependencyGraph(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.getDependencyGraphImpl(arg); }
295
+ /**
296
+ * Default implementation of getDependencyGraph uses the helper function
297
+ * {@link getDependencyGraph} in space-helpers.mts.
298
+ *
299
+ * Override this in subclasses for optimized behavior (e.g. Postgres).
300
+ */
301
+ protected async getDependencyGraphImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {
302
+ const lc = `${this.lc}[${this.getDependencyGraphImpl.name}]`;
303
+ try {
304
+ if (logalot) { console.log(`${lc} starting... (I: 0e5fe807a0169224781f6c2833f34826)`); }
305
+ if (!arg.data) { throw new Error(`(UNEXPECTED) arg.data falsy? (E: 45eba816295a97a0e55f981861a03f26)`); }
306
+ if ((arg.data.ibGibAddrs ?? []).length === 0) {
307
+ throw new Error(`arg.data.ibGibAddrs is falsy/empty (E: 70adc939c7b80c9938d8fa18fd7c5826)`);
308
+ }
309
+ const opts: GetGraphOptions = {
310
+ space: this,
311
+ ibGibAddrs: arg.data.ibGibAddrs!,
312
+ live: (arg.data as any).live || true,
313
+ };
314
+ const graph = await getDependencyGraph(opts);
315
+ const ibGibs = Object.values(graph) as TIbGib[];
316
+ const resultData: GetDependencyGraphResultData = {
317
+ optsAddr: getIbGibAddr({ ibGib: arg }),
318
+ count: ibGibs.length,
319
+ addrs: Object.keys(graph),
320
+ };
321
+ return this.resulty({
322
+ resultData: resultData as any as TResultData,
323
+ ibGibs,
324
+ });
325
+ } catch (error) {
326
+ console.error(`${lc} ${extractErrorMsg(error)}`);
327
+ throw error;
328
+ } finally {
329
+ if (logalot) { console.log(`${lc} complete.`); }
330
+ }
331
+ }
332
+
283
333
  /**
284
334
  * Centralized location for general argument validation for a given witness.
285
335
  *
@@ -362,7 +412,7 @@ export abstract class SpaceBase_V1<
362
412
  }
363
413
  return errors;
364
414
  } catch (error) {
365
- console.error(`${lc} ${error.message}`);
415
+ console.error(`${lc} ${extractErrorMsg(error)}`);
366
416
  throw error;
367
417
  } finally {
368
418
  if (errors?.length > 0) { console.error(`${lc} errors: ${errors}`); }
@@ -25,7 +25,8 @@ import { TagData_V1, TagIbGib_V1 } from '../../common/tag/tag-types.mjs';
25
25
  import { BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY, BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY, BOOTSTRAP_IBGIB_ADDR } from './bootstrap/bootstrap-constants.mjs';
26
26
  import {
27
27
  SpaceLockScope, IbGibSpaceLockIbGib, SpaceId, IbGibSpaceLockOptions, TxId,
28
- IbGibSpaceResultIbGib, IbGibSpaceResultData, IbGibSpaceResultRel8ns, SpaceType, SpaceSubtype, VALID_SPACE_TYPES, VALID_SPACE_SUBTYPES, IbGibSpaceData
28
+ IbGibSpaceResultIbGib, IbGibSpaceResultData, IbGibSpaceResultRel8ns, SpaceType, SpaceSubtype, VALID_SPACE_TYPES, VALID_SPACE_SUBTYPES, IbGibSpaceData,
29
+ IbGibSpaceOptionsCmd, IbGibSpaceOptionsCmdModifier,
29
30
  } from './space-types.mjs';
30
31
  import { getAppIb, } from '../app/app-helper.mjs';
31
32
  import { AppData_V1, AppIbGib_V1 } from '../app/app-types.mjs';
@@ -3430,3 +3431,51 @@ export function spaceNameIsValid(name: string): boolean {
3430
3431
  return false;
3431
3432
  }
3432
3433
  }
3434
+
3435
+ /**
3436
+ * wrapper for getting dependency graph from a space.
3437
+ *
3438
+ * NOTE: This calls the witness space with the command. This is NOT the
3439
+ * same as the logic helper in graph-helper.mts which performs the graph
3440
+ * traversal logic potentially in-memory or naively.
3441
+ */
3442
+ export async function getDependencyGraph({
3443
+ space,
3444
+ ibGibAddrs,
3445
+ live,
3446
+ }: {
3447
+ space: IbGibSpaceAny,
3448
+ ibGibAddrs: IbGibAddr[],
3449
+ live?: boolean,
3450
+ }): Promise<{ [addr: string]: IbGib_V1 } | null> {
3451
+ const lc = `[${getDependencyGraph.name}]`;
3452
+ try {
3453
+ if (!space) { throw new Error(`space required (E: 8f2441c099084898953153549725f778)`); }
3454
+ if ((ibGibAddrs ?? []).length === 0) { throw new Error(`ibGibAddrs required (E: 9c3b8853609841808093153927649526)`); }
3455
+
3456
+ const argData: any = {
3457
+ cmd: IbGibSpaceOptionsCmd.get,
3458
+ cmdModifiers: [IbGibSpaceOptionsCmdModifier.dependencyGraph],
3459
+ ibGibAddrs,
3460
+ live,
3461
+ };
3462
+ const arg = await space.argy({ argData });
3463
+
3464
+ const result = await space.witness(arg);
3465
+ if (result?.data?.success) {
3466
+ const graph: { [addr: string]: IbGib_V1 } = {};
3467
+ if (result.ibGibs) {
3468
+ for (const ibGib of result.ibGibs) {
3469
+ const addr = getIbGibAddr({ ibGib });
3470
+ graph[addr] = ibGib;
3471
+ }
3472
+ }
3473
+ return graph;
3474
+ } else {
3475
+ return null;
3476
+ }
3477
+ } catch (error) {
3478
+ console.error(`${lc} ${extractErrorMsg(error)}`);
3479
+ throw error;
3480
+ }
3481
+ }
@@ -29,7 +29,8 @@ import { Factory_V1 as factory } from '@ibgib/ts-gib/dist/V1/factory.mjs';
29
29
 
30
30
  import {
31
31
  deleteFromSpace, getFromSpace, getLatestAddrs, parseSpaceIb,
32
- persistTransformResult, putInSpace, registerNewIbGib
32
+ persistTransformResult, putInSpace, registerNewIbGib,
33
+ getDependencyGraph,
33
34
  } from "./space-helper.mjs";
34
35
  import { IbGibSpaceAny } from "./space-base-v1.mjs";
35
36
  import { IbGibTimelineUpdateInfo } from '../../common/other/other-types.mjs';
@@ -226,7 +226,7 @@ export const IbGibSpaceOptionsCmd = {
226
226
  * Flags to affect the command's interpretation.
227
227
  */
228
228
  export type IbGibSpaceOptionsCmdModifier =
229
- 'can' | 'addrs' | 'latest' | 'watch' | 'unwatch' | 'tjps';
229
+ 'can' | 'addrs' | 'latest' | 'watch' | 'unwatch' | 'tjps' | 'dependency-graph';
230
230
  /**
231
231
  * Flags to affect the command's interpretation.
232
232
  */
@@ -266,6 +266,10 @@ export const IbGibSpaceOptionsCmdModifier = {
266
266
  * Get the tjp ibgibs/addrs for given ibgib(s)
267
267
  */
268
268
  tjps: 'tjps' as IbGibSpaceOptionsCmdModifier,
269
+ /**
270
+ * Modifies the get command to retrieve a dependency graph.
271
+ */
272
+ dependencyGraph: 'dependency-graph' as IbGibSpaceOptionsCmdModifier,
269
273
  }
270
274
 
271
275
  /** Information for interacting with spaces. */
@@ -485,3 +489,11 @@ export interface IbGibSpaceLockIbGib
485
489
  * Marker type to indicate that a string is meant to be a transmission id.
486
490
  */
487
491
  export type TxId = 'string';
492
+
493
+ /**
494
+ * we have a getDependencyGraph wrapper in the space base. This is the type of
495
+ * that's result data.
496
+ */
497
+ export interface GetDependencyGraphResultData extends IbGibSpaceResultData {
498
+ count: number;
499
+ }
package/tmp.md CHANGED
@@ -1,11 +1,5 @@
1
- OK, ty. The space-wide sync approach is not tenable. That is like trying to sync Alice's entire logical drive with Bob's entire logical drive instead of a particular folder on the drive. Your thinking that a single Domain IbGib does not contain many timelines is faulty. A dependency graph of a "single" domain may contain multiple, or even many/a great many, timelines. Think of this like in set theory and we are creating an isomorphic projection of nodes. I say isomorphic and not homomorphic, because we may have to do merges for timelines, so it really is a "one-way" projection. Though obviously, with "sync" being bi-directional, we are ultimately converging on both endpoints having "equivalent" timelines (there may be orphans on one and/or the other after merges, with either endpoint effectively doing a "rebase"). So our sync process has to start with getting a "live" dependency graph of a single domain ibgib. We can actually do multiple domain ibgibs, and then unify the entire dependency graph in the sync transmission ibgib, but I think it's best to just build for the single ibgib scenario. You can look at@beautifulMention, but I would really recommend looking at the entire @beautifulMentionfile. This is a non-trivial recursive function, but you should be able to fully grok it by looking at both the jsdocs/comments in that file and the code itself. Always look at the code itself of course!
1
+ OK nice sketch! We need to drastically wrangle in the complexity to nice methods, like we have with `createSyncMsgStone`, `evolveSyncSagaIbGib`, etc.
2
2
 
3
- That dependency graph comes in the form a @beautifulMention as defined by this:
4
-
5
- ```
6
- /**
7
- * Map of addr -> ibGib
8
- */
9
- export type FlatIbGibGraph = { [addr: string]: IbGib_V1 };
10
- ```
3
+ Also, we need to get this to a finite state machine-like execution. The `sync` method should do the initial setup regarding the saga info object, the temp space, and the session identity. But the analyzeTimelines is specific to the init frame and should be refactored into the FSM method specific to init. So we need to separate the saga meta-setup and the saga initial frame.
11
4
 
5
+ Also, I don't think we can just naively call `updates$.complete()` like that at the end. This will end up being a recursive or do/while loop with msg/response with the peer.