@ibgib/core-gib 0.1.28 → 0.1.30
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/.vscode/launch.json +17 -1
- package/dist/common/meta-stone/meta-stone-helper.d.mts.map +1 -1
- package/dist/common/meta-stone/meta-stone-helper.mjs +30 -12
- package/dist/common/meta-stone/meta-stone-helper.mjs.map +1 -1
- package/dist/common/meta-stone/meta-stone-types.d.mts +5 -2
- package/dist/common/meta-stone/meta-stone-types.d.mts.map +1 -1
- package/dist/sync/strategies/conflict-optimistic.d.mts +16 -0
- package/dist/sync/strategies/conflict-optimistic.d.mts.map +1 -1
- package/dist/sync/strategies/conflict-optimistic.mjs +28 -1
- package/dist/sync/strategies/conflict-optimistic.mjs.map +1 -1
- package/dist/sync/sync-conflict.respec.mjs +5 -5
- package/dist/sync/sync-conflict.respec.mjs.map +1 -1
- package/dist/sync/sync-helpers.d.mts +4 -4
- package/dist/sync/sync-helpers.d.mts.map +1 -1
- package/dist/sync/sync-helpers.mjs +12 -8
- package/dist/sync/sync-helpers.mjs.map +1 -1
- package/dist/sync/sync-innerspace-constants.respec.mjs +36 -36
- package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs +3 -1
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs +62 -9
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace.respec.mjs +45 -16
- package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts +0 -9
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +25 -43
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.mjs +2 -2
- package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
- package/dist/sync/sync-saga-coordinator.d.mts +15 -10
- package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.mjs +304 -163
- package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
- package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts +3 -3
- package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts.map +1 -1
- package/dist/sync/sync-types.d.mts +12 -18
- package/dist/sync/sync-types.d.mts.map +1 -1
- package/dist/sync/sync-types.mjs +15 -21
- package/dist/sync/sync-types.mjs.map +1 -1
- package/dist/timeline/timeline-api.d.mts +12 -0
- package/dist/timeline/timeline-api.d.mts.map +1 -1
- package/dist/timeline/timeline-api.mjs +26 -0
- package/dist/timeline/timeline-api.mjs.map +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.d.mts +19 -0
- package/dist/witness/space/inner-space/inner-space-v1.d.mts.map +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.mjs +189 -30
- package/dist/witness/space/inner-space/inner-space-v1.mjs.map +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.respec.mjs +9 -0
- package/dist/witness/space/inner-space/inner-space-v1.respec.mjs.map +1 -1
- package/dist/witness/space/space-helper.d.mts.map +1 -1
- package/dist/witness/space/space-helper.mjs +2 -1
- package/dist/witness/space/space-helper.mjs.map +1 -1
- package/package.json +2 -1
- package/src/common/meta-stone/meta-stone-helper.mts +25 -11
- package/src/common/meta-stone/meta-stone-types.mts +5 -2
- package/src/sync/README.md +4 -4
- package/src/sync/docs/architecture.md +6 -6
- package/src/sync/strategies/conflict-optimistic.mts +41 -4
- package/src/sync/sync-conflict.respec.mts +5 -5
- package/src/sync/sync-helpers.mts +13 -9
- package/src/sync/sync-innerspace-constants.respec.mts +39 -39
- package/src/sync/sync-innerspace-deep-updates.respec.mts +5 -5
- package/src/sync/sync-innerspace-dest-ahead.respec.mts +73 -9
- package/src/sync/sync-innerspace.respec.mts +17 -16
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +23 -60
- package/src/sync/sync-peer/sync-peer-v1.mts +2 -2
- package/src/sync/sync-saga-coordinator.mts +231 -173
- package/src/sync/sync-saga-message/sync-saga-message-types.mts +3 -3
- package/src/sync/sync-types.mts +19 -26
- package/src/timeline/timeline-api.mts +51 -11
- package/src/witness/space/inner-space/inner-space-v1.mts +191 -29
- package/src/witness/space/inner-space/inner-space-v1.respec.mts +13 -0
- package/src/witness/space/space-helper.mts +3 -2
- package/test_output.log +0 -0
- package/tmp.md +170 -62
|
@@ -40,7 +40,7 @@ export interface SyncSagaMessageIbGib_V1 extends IbGib_V1<SyncSagaMessageData_V1
|
|
|
40
40
|
/**
|
|
41
41
|
* The "Hello" of the sync protocol.
|
|
42
42
|
*
|
|
43
|
-
* Exchanges knowledge
|
|
43
|
+
* Exchanges knowledge maps (what I have) and identity (who I am).
|
|
44
44
|
*/
|
|
45
45
|
export interface SyncSagaMessageInitData_V1 extends SyncSagaMessageData_V1 {
|
|
46
46
|
stage: typeof SyncStage.init;
|
|
@@ -51,7 +51,7 @@ export interface SyncSagaMessageInitData_V1 extends SyncSagaMessageData_V1 {
|
|
|
51
51
|
*
|
|
52
52
|
* IOW, this is a map of the starting and end points of an ibGib's timeline.
|
|
53
53
|
*/
|
|
54
|
-
|
|
54
|
+
knowledgeMap: { [tjp: string]: IbGibAddr };
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* The Keystone Identity of the sender.
|
|
@@ -149,7 +149,7 @@ export interface SyncSagaMessageAckData_V1 extends SyncSagaMessageData_V1 {
|
|
|
149
149
|
/**
|
|
150
150
|
* Infos regarding ibgibs that the receiver (generator of this ack)
|
|
151
151
|
* knows/believes that the sender does NOT have (after looking at knowledge
|
|
152
|
-
*
|
|
152
|
+
* map of sender).
|
|
153
153
|
*
|
|
154
154
|
* This includes addrs that will correspond to the context.payloadAddrsDomain
|
|
155
155
|
*
|
package/src/sync/sync-types.mts
CHANGED
|
@@ -54,40 +54,34 @@ export function isValidSyncConflictStrategy(strategy: string): strategy is SyncC
|
|
|
54
54
|
}
|
|
55
55
|
// #endregion SyncConflictStrategy
|
|
56
56
|
|
|
57
|
-
// #region
|
|
58
|
-
export const
|
|
59
|
-
export const
|
|
60
|
-
export type
|
|
61
|
-
| typeof
|
|
62
|
-
| typeof
|
|
57
|
+
// #region SyncSagaFrameOrigin
|
|
58
|
+
export const SYNC_SAGA_FRAME_ORIGIN_SENDER = 'sender';
|
|
59
|
+
export const SYNC_SAGA_FRAME_ORIGIN_RECEIVER = 'receiver';
|
|
60
|
+
export type SyncSagaFrameOrigin =
|
|
61
|
+
| typeof SYNC_SAGA_FRAME_ORIGIN_SENDER
|
|
62
|
+
| typeof SYNC_SAGA_FRAME_ORIGIN_RECEIVER
|
|
63
63
|
;
|
|
64
64
|
/**
|
|
65
|
-
* if the
|
|
66
|
-
*
|
|
67
|
-
* one responding).
|
|
65
|
+
* if the frame was created by the original sender (the initiator of the sync
|
|
66
|
+
* saga operation) or the other party, the "receiver" (the one responding).
|
|
68
67
|
*
|
|
69
68
|
* This is driven by looking at the latest value of `sagaFrame.data.n` value.
|
|
70
|
-
*
|
|
71
|
-
* NOTE: This is not to be confused with the sync saga context ibgib, which is
|
|
72
|
-
* something else entirely. That is the transport wrapper ibgib around the saga.
|
|
73
|
-
* this is strictly the enum for where the code is executing.
|
|
74
69
|
*/
|
|
75
|
-
export const
|
|
70
|
+
export const SyncSagaFrameOrigin = {
|
|
76
71
|
/**
|
|
77
|
-
* The
|
|
78
|
-
* sync.
|
|
72
|
+
* The frame was created on the initial location that started the sync.
|
|
79
73
|
*/
|
|
80
|
-
sender:
|
|
74
|
+
sender: SYNC_SAGA_FRAME_ORIGIN_SENDER,
|
|
81
75
|
/**
|
|
82
|
-
* The
|
|
83
|
-
*
|
|
84
|
-
*
|
|
76
|
+
* The frame was created on the receiving end, which is either a physically
|
|
77
|
+
* different location or is the logical "receiver" of an in-memory sync
|
|
78
|
+
* execution.
|
|
85
79
|
*/
|
|
86
|
-
receiver:
|
|
87
|
-
} satisfies { [key in
|
|
88
|
-
export const
|
|
89
|
-
export function
|
|
90
|
-
return
|
|
80
|
+
receiver: SYNC_SAGA_FRAME_ORIGIN_RECEIVER,
|
|
81
|
+
} satisfies { [key in SyncSagaFrameOrigin]: SyncSagaFrameOrigin };
|
|
82
|
+
export const SYNC_SAGA_FRAME_ORIGIN_VALID_VALUES = Object.values(SyncSagaFrameOrigin);
|
|
83
|
+
export function isValidSyncSagaFrameOrigin(sagaFrameOrigin: string): sagaFrameOrigin is SyncSagaFrameOrigin {
|
|
84
|
+
return SYNC_SAGA_FRAME_ORIGIN_VALID_VALUES.includes(sagaFrameOrigin as SyncSagaFrameOrigin);
|
|
91
85
|
}
|
|
92
86
|
// #endregion SyncConflictStrategy
|
|
93
87
|
|
|
@@ -113,7 +107,6 @@ export interface NextSagaFrameInfo_SagaComplete {
|
|
|
113
107
|
export type NextSagaFrameInfo =
|
|
114
108
|
NextSagaFrameInfo_Frame | NextSagaFrameInfo_SagaComplete;
|
|
115
109
|
|
|
116
|
-
|
|
117
110
|
export interface HandleSagaResponseContextResult_Base {
|
|
118
111
|
/**
|
|
119
112
|
* if truthy, handling saga context failed, else it succeeded.
|
|
@@ -43,16 +43,16 @@ export interface Rel8nRemovalInfo {
|
|
|
43
43
|
|
|
44
44
|
export interface CommonTimelineOptsSansSkipLock {
|
|
45
45
|
/**
|
|
46
|
-
* If true, dna will not be created when executing transforms.
|
|
47
|
-
*
|
|
46
|
+
* If true, dna will not be created when executing transforms.
|
|
47
|
+
*
|
|
48
48
|
* ## intent / driving use case
|
|
49
|
-
*
|
|
50
|
-
* We want to use the timeline api in working with the new sync saga code.
|
|
49
|
+
*
|
|
50
|
+
* We want to use the timeline api in working with the new sync saga code.
|
|
51
51
|
* However, we do not want dna, because the sync saga should not be merged
|
|
52
52
|
* and there should be no dynamic composition required from dna.
|
|
53
|
-
*
|
|
54
|
-
* But the default for this api should be for dna to be created, so we add
|
|
55
|
-
* this negative flag.
|
|
53
|
+
*
|
|
54
|
+
* But the default for this api should be for dna to be created, so we add
|
|
55
|
+
* this negative flag.
|
|
56
56
|
*/
|
|
57
57
|
noDna?: boolean,
|
|
58
58
|
/**
|
|
@@ -173,16 +173,16 @@ export async function appendToTimeline({
|
|
|
173
173
|
rel8nInfos: Rel8nInfo[],
|
|
174
174
|
/**
|
|
175
175
|
* if provided, will remove this rel8ns before appending {@link rel8nInfos}
|
|
176
|
-
*
|
|
176
|
+
*
|
|
177
177
|
* ## intent/driving use case
|
|
178
|
-
*
|
|
178
|
+
*
|
|
179
179
|
* we need to be able to clear out the existing rel8ns when evolving
|
|
180
180
|
* `SyncSagaIbGib_V1`. This is not quite linkedRel8ns, rather, we just need
|
|
181
181
|
* to clear out the message stones rel8n. The underlying {@link rel8}
|
|
182
182
|
* transform already supports this via this:
|
|
183
|
-
*
|
|
183
|
+
*
|
|
184
184
|
* {@link TransformOpts_Rel8.rel8nsToRemoveByAddr}
|
|
185
|
-
*
|
|
185
|
+
*
|
|
186
186
|
* So these removal infos will translate to those `rel8nsToRemoveByAddr`.
|
|
187
187
|
*/
|
|
188
188
|
rel8nRemovalInfos?: Rel8nRemovalInfo[],
|
|
@@ -1000,3 +1000,43 @@ export async function getHistory({
|
|
|
1000
1000
|
if (logalot) { console.log(`${lc} complete.`); }
|
|
1001
1001
|
}
|
|
1002
1002
|
}
|
|
1003
|
+
|
|
1004
|
+
export async function getHistoryAddrs({
|
|
1005
|
+
timeline,
|
|
1006
|
+
getLatest,
|
|
1007
|
+
metaspace,
|
|
1008
|
+
space,
|
|
1009
|
+
}: {
|
|
1010
|
+
/**
|
|
1011
|
+
* The ibGib at the head of the timeline whose history you want to retrieve.
|
|
1012
|
+
*/
|
|
1013
|
+
timeline: IbGib_V1,
|
|
1014
|
+
/**
|
|
1015
|
+
* if true, will first retrieve the latest ibgib in the {@link timeline} in
|
|
1016
|
+
* the given {@link space} if provided, else in the default local user space
|
|
1017
|
+
* according to the {@link metaspace}.
|
|
1018
|
+
*/
|
|
1019
|
+
getLatest?: boolean,
|
|
1020
|
+
} & CommonTimelineOptsSansSkipLock): Promise<IbGibAddr[]> {
|
|
1021
|
+
const lc = `[${getHistoryAddrs.name}]`;
|
|
1022
|
+
try {
|
|
1023
|
+
if (logalot) { console.log(`${lc} starting... (I: c7a328b14018642138ebb47870c15626)`); }
|
|
1024
|
+
|
|
1025
|
+
const historyInfo = await getHistory({
|
|
1026
|
+
timeline,
|
|
1027
|
+
getLatest,
|
|
1028
|
+
includeDna: false,
|
|
1029
|
+
metaspace,
|
|
1030
|
+
space,
|
|
1031
|
+
});
|
|
1032
|
+
|
|
1033
|
+
const addrs = historyInfo.orderedPastIbGibs.map(x => getIbGibAddr({ ibGib: x }));
|
|
1034
|
+
|
|
1035
|
+
return addrs;
|
|
1036
|
+
} catch (error) {
|
|
1037
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
1038
|
+
throw error;
|
|
1039
|
+
} finally {
|
|
1040
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { clone, extractErrorMsg, getUUID, groupBy, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
2
2
|
import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
|
|
3
|
-
import { getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
3
|
+
import { getIbAndGib, getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
4
4
|
import { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';
|
|
5
5
|
|
|
6
6
|
import { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';
|
|
@@ -15,6 +15,10 @@ import { ReconciliationSpaceBase, ReconciliationSpaceData, ReconciliationSpaceRe
|
|
|
15
15
|
import { DEFAULT_INNER_SPACE_DATA_V1, InnerSpaceData_V1, InnerSpaceRel8ns_V1 } from './inner-space-types.mjs';
|
|
16
16
|
import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
|
|
17
17
|
import { getGib } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';
|
|
18
|
+
import { isMetaStone, newUpMetaStone, parseMetaStoneIb } from '../../../common/meta-stone/meta-stone-helper.mjs';
|
|
19
|
+
import { MetaStoneIbGib_V1, MetaStoneIbInfo } from '../../../common/meta-stone/meta-stone-types.mjs';
|
|
20
|
+
import { GIB } from '@ibgib/ts-gib/dist/V1/constants.mjs';
|
|
21
|
+
import { META_STONE_TARGET_REL8N_NAME } from '../../../common/meta-stone/meta-stone-constants.mjs';
|
|
18
22
|
|
|
19
23
|
const logalot = GLOBAL_LOG_A_LOT;
|
|
20
24
|
|
|
@@ -53,6 +57,35 @@ export class InnerSpace_V1<
|
|
|
53
57
|
*/
|
|
54
58
|
ibGibs: { [key: string]: TIbGib } = {};
|
|
55
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Each tjp/timeline has its own map of metastones.
|
|
62
|
+
*
|
|
63
|
+
* NOTE: This is a map of maps.
|
|
64
|
+
*/
|
|
65
|
+
ibGibMetastones: { [tjpOrStoneGib: string]: { [metastoneAddr: string]: MetaStoneIbGib_V1 } } = {};
|
|
66
|
+
/**
|
|
67
|
+
* all known metastone addrs for this innerspace
|
|
68
|
+
*/
|
|
69
|
+
get metastoneAddrs(): IbGibAddr[] {
|
|
70
|
+
const resMetastones: IbGibAddr[] = [];
|
|
71
|
+
Object.values(this.ibGibMetastones).forEach(map => {
|
|
72
|
+
Object.keys(map)
|
|
73
|
+
.forEach(metastone => resMetastones.push(metastone));
|
|
74
|
+
});
|
|
75
|
+
return resMetastones;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* all known metastone ibgibs for this innerspace
|
|
79
|
+
*/
|
|
80
|
+
get metastoneIbGibs(): MetaStoneIbGib_V1[] {
|
|
81
|
+
const resMetastones: MetaStoneIbGib_V1[] = [];
|
|
82
|
+
Object.values(this.ibGibMetastones).forEach(map => {
|
|
83
|
+
Object.values(map)
|
|
84
|
+
.forEach(metastone => resMetastones.push(metastone));
|
|
85
|
+
});
|
|
86
|
+
return resMetastones;
|
|
87
|
+
}
|
|
88
|
+
|
|
56
89
|
constructor(
|
|
57
90
|
initialData: TData,
|
|
58
91
|
initialRel8ns?: TRel8ns,
|
|
@@ -226,10 +259,30 @@ export class InnerSpace_V1<
|
|
|
226
259
|
for (let i = 0; i < ibGibs?.length; i++) {
|
|
227
260
|
const ibGib = ibGibs[i];
|
|
228
261
|
const addr = getIbGibAddr({ ibGib });
|
|
229
|
-
|
|
230
|
-
|
|
262
|
+
|
|
263
|
+
if (isMetaStone({ ibGib })) {
|
|
264
|
+
const metastone = ibGib as unknown as MetaStoneIbGib_V1;
|
|
265
|
+
if (!metastone.data) { throw new Error(`(UNEXPECTED) ibGib is a metastone, but metastone.data falsy? (E: f3a05815c68821d564cb101821b91326)`); }
|
|
266
|
+
const { tjpGib } = metastone.data.targetData;
|
|
267
|
+
if (this.ibGibMetastones[tjpGib]) {
|
|
268
|
+
// has existing metastones for this timeline/stone
|
|
269
|
+
if (!Object.keys(this.ibGibMetastones[tjpGib]).includes(addr)) {
|
|
270
|
+
this.ibGibMetastones[tjpGib][addr] = metastone;
|
|
271
|
+
} else {
|
|
272
|
+
addrsAlreadyHave.push(addr);
|
|
273
|
+
}
|
|
274
|
+
} else {
|
|
275
|
+
// no existing metastones for this timeline/stone
|
|
276
|
+
this.ibGibMetastones[tjpGib] = {
|
|
277
|
+
[addr]: metastone,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
231
280
|
} else {
|
|
232
|
-
|
|
281
|
+
if (!Object.keys(this.ibGibs).includes(addr)) {
|
|
282
|
+
this.ibGibs[addr] = ibGib;
|
|
283
|
+
} else {
|
|
284
|
+
addrsAlreadyHave.push(addr);
|
|
285
|
+
}
|
|
233
286
|
}
|
|
234
287
|
}
|
|
235
288
|
} catch (error) {
|
|
@@ -301,46 +354,155 @@ export class InnerSpace_V1<
|
|
|
301
354
|
if (!arg.data) { throw new Error(`(UNEXPECTED) !arg.data? (E: 60869288f3deeff5d1dd93be5f4b8624)`); }
|
|
302
355
|
if (!arg.data.ibGibAddrs) { throw new Error(`(UNEXPECTED) !arg.data.ibGibAddrs? (E: d62cfac462daacc5b2f50c7c3ae45d24)`); }
|
|
303
356
|
|
|
304
|
-
// get all ibgibs in the space and group them by their tjp address
|
|
305
|
-
const ibGibsInSpace = Object.values(this.ibGibs);
|
|
306
|
-
const ibGibsInSpaceByTjp = groupBy({ items: ibGibsInSpace, keyFn: x => getTjpAddr({ ibGib: x })! });
|
|
307
|
-
|
|
308
|
-
if (logalot) { console.log(`${lc} ibGibsInSpaceByTjp: ${pretty(ibGibsInSpaceByTjp)} (I: af9f88985b96822b68ad4928eb6f6a25)`); }
|
|
309
|
-
|
|
310
357
|
const latestAddrsMap: { [addr: string]: IbGibAddr | null } = {};
|
|
311
358
|
|
|
312
|
-
//
|
|
359
|
+
// #region new impl with metastones
|
|
360
|
+
|
|
313
361
|
for (const localAddr of arg.data.ibGibAddrs) {
|
|
362
|
+
if (isMetaStone({ addr: localAddr })) {
|
|
363
|
+
if (logalot) { console.log(`${lc} localAddr not found: ${localAddr} (I: 12c7668bbdb8e4a86ceb5f455eb00826)`); }
|
|
364
|
+
if (this.metastoneAddrs.includes(localAddr)) {
|
|
365
|
+
latestAddrsMap[localAddr] = localAddr;
|
|
366
|
+
} else {
|
|
367
|
+
if (logalot) { console.log(`${lc} metastone addr NOT found...what are we getting latest on metastone anyway? (I: 0e71b8a9234fcc93b8259578eb491626)`); }
|
|
368
|
+
latestAddrsMap[localAddr] = null;
|
|
369
|
+
}
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
314
372
|
const localIbGib = this.ibGibs[localAddr];
|
|
315
373
|
if (!localIbGib) {
|
|
374
|
+
if (logalot) { console.log(`${lc} localAddr not found: ${localAddr} (I: 12c7668bbdb8e4a86ceb5f455eb00826)`); }
|
|
316
375
|
latestAddrsMap[localAddr] = null; // or handle as error/not found
|
|
317
376
|
continue;
|
|
318
377
|
}
|
|
319
378
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
379
|
+
// we have the ibgib, now see if we have any metastones for it.
|
|
380
|
+
const tjpAddr =
|
|
381
|
+
getTjpAddr({ ibGib: localIbGib, defaultIfNone: 'incomingAddr' }) ??
|
|
382
|
+
getIbGibAddr({ ibGib: localIbGib });
|
|
383
|
+
const { gib: tjpGib } = getIbAndGib({ ibGibAddr: tjpAddr });
|
|
384
|
+
// examine metastones
|
|
385
|
+
const metastoneMap = this.ibGibMetastones[tjpGib];
|
|
386
|
+
if (!metastoneMap) {
|
|
387
|
+
// no metastones for this, so there is no latest
|
|
388
|
+
latestAddrsMap[localAddr] = localAddr;
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
324
391
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
392
|
+
// we DO have metastone(s) for this timeline/stone, so analyze
|
|
393
|
+
// these metastones and get the latest according to them
|
|
394
|
+
|
|
395
|
+
const metaStoneAddrs = Object.keys(metastoneMap);
|
|
396
|
+
if (metaStoneAddrs.length === 0) {
|
|
397
|
+
throw new Error(`(UNEXPECTED) we have a metastoneMap but no addrs? (E: 82a448407c08585f685a9b2543923826)`);
|
|
398
|
+
}
|
|
331
399
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
400
|
+
const metaStoneAddrsAndIbInfos: [IbGibAddr, MetaStoneIbInfo][] = metaStoneAddrs
|
|
401
|
+
.map(xAddr => [xAddr, getIbAndGib({ ibGibAddr: xAddr }).ib])
|
|
402
|
+
.map(([xAddr, metaStoneIb]) => [xAddr, parseMetaStoneIb({ ib: metaStoneIb })]);
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* sort mutates the actual array (shuffle sort I think), but
|
|
406
|
+
* we're storing it in a different variable name to be more
|
|
407
|
+
* explicit.
|
|
408
|
+
*/
|
|
409
|
+
const metaStoneAddrsAndIbInfos_descending = metaStoneAddrsAndIbInfos.sort((a, b) => {
|
|
410
|
+
const [_aAddr, aInfo] = a;
|
|
411
|
+
const [_bAddr, bInfo] = b;
|
|
412
|
+
// we want the highest n, with tiebreaker going to
|
|
413
|
+
// timestampInTicks. if that's the same also, then what are we
|
|
414
|
+
// quibbling about?
|
|
415
|
+
if (aInfo.n > bInfo.n) {
|
|
416
|
+
return -1;
|
|
417
|
+
} else if (aInfo.n < bInfo.n) {
|
|
418
|
+
return 1;
|
|
419
|
+
} else if (aInfo.timestampInTicks > bInfo.timestampInTicks) {
|
|
420
|
+
return -1;
|
|
421
|
+
} else if (aInfo.timestampInTicks < bInfo.timestampInTicks) {
|
|
422
|
+
return 1;
|
|
336
423
|
} else {
|
|
337
|
-
|
|
424
|
+
// neither discriminator is different.
|
|
425
|
+
return 0;
|
|
338
426
|
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
|
|
427
|
+
});
|
|
428
|
+
if (logalot) {
|
|
429
|
+
console.log(`${lc} console.dir(metaStoneAddrsAndIbInfos_descending)... (I: 5ce425f199283e2185a2cc0801264826)`);
|
|
430
|
+
console.dir(metaStoneAddrsAndIbInfos_descending);
|
|
342
431
|
}
|
|
432
|
+
|
|
433
|
+
// since we sorted into a descending order, the latest is the very
|
|
434
|
+
// first item. and we have already guaranteed that there is at
|
|
435
|
+
// least 1 in the array.
|
|
436
|
+
if (metaStoneAddrsAndIbInfos_descending.length === 0) { throw new Error(`(UNEXPECTED) metaStoneAddrsAndIbInfos_descending is empty? earlier in the function there should have been a check. did getMetaStoneAddrs return a populated list but no stones were found? (E: 63c035ebed77741f2330c7a625823f23)`); }
|
|
437
|
+
|
|
438
|
+
const [latestMetaStoneAddr, latestMetaStoneInfo] = metaStoneAddrsAndIbInfos_descending[0];
|
|
439
|
+
if (logalot) { console.log(`${lc} [latestMetaStoneAddr, latestMetaStoneInfo]: ${[latestMetaStoneAddr, latestMetaStoneInfo]} (I: 1307ca46b4abd62c7a30fe87c08fa923)`); }
|
|
440
|
+
|
|
441
|
+
let latestMetaStoneIbGib: MetaStoneIbGib_V1;
|
|
442
|
+
latestMetaStoneIbGib = metastoneMap[latestMetaStoneAddr];
|
|
443
|
+
|
|
444
|
+
// latestMetaStoneIbGib.rel8ns ensured via validation at this point
|
|
445
|
+
const latestMetaStoneRel8ns = latestMetaStoneIbGib.rel8ns!;
|
|
446
|
+
/**
|
|
447
|
+
* this is accurate as the punctiliar address that corresponds to
|
|
448
|
+
* the metastone.
|
|
449
|
+
*
|
|
450
|
+
* atow (11/2023) interface of rel8ns
|
|
451
|
+
* [META_STONE_TARGET_REL8N_NAME]: IbGibAddr[];
|
|
452
|
+
* [META_STONE_TARGET_TJP_REL8N_NAME]?: IbGibAddr[];
|
|
453
|
+
*/
|
|
454
|
+
const latestAddr = latestMetaStoneRel8ns[META_STONE_TARGET_REL8N_NAME].at(0);
|
|
455
|
+
if (!latestAddr) { throw new Error(`metastone passed validation but latestMetaStoneRel8ns[META_STONE_TARGET_REL8N_NAME].at(0) is empty? (E: c188ec0089ad86efe4d925c118599d23)`); }
|
|
456
|
+
|
|
457
|
+
latestAddrsMap[localAddr] = latestAddr;
|
|
343
458
|
}
|
|
459
|
+
// #region new impl with metastones
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
// #region old inefficient no metastones
|
|
463
|
+
|
|
464
|
+
// // wildly inefficient with a decent number of ibgibs
|
|
465
|
+
// // get all ibgibs in the space and group them by their tjp address
|
|
466
|
+
// const ibGibsInSpace = Object.values(this.ibGibs);
|
|
467
|
+
// const ibGibsInSpaceByTjp = groupBy({ items: ibGibsInSpace, keyFn: x => getTjpAddr({ ibGib: x })! });
|
|
468
|
+
|
|
469
|
+
// if (logalot) { console.log(`${lc} ibGibsInSpaceByTjp: ${pretty(ibGibsInSpaceByTjp)} (I: af9f88985b96822b68ad4928eb6f6a25)`); }
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
// // iterate over each address we're looking for
|
|
473
|
+
// for (const localAddr of arg.data.ibGibAddrs) {
|
|
474
|
+
// const localIbGib = this.ibGibs[localAddr];
|
|
475
|
+
// if (!localIbGib) {
|
|
476
|
+
// latestAddrsMap[localAddr] = null; // or handle as error/not found
|
|
477
|
+
// continue;
|
|
478
|
+
// }
|
|
479
|
+
|
|
480
|
+
// const tjpAddr = getTjpAddr({ ibGib: localIbGib });
|
|
481
|
+
// if (tjpAddr && ibGibsInSpaceByTjp[tjpAddr]) {
|
|
482
|
+
// // if we have a timeline for this tjp, find the latest
|
|
483
|
+
// const timeline = ibGibsInSpaceByTjp[tjpAddr];
|
|
484
|
+
|
|
485
|
+
// if (timeline.some(ibGib => ibGib.data?.n === undefined)) {
|
|
486
|
+
// const filtered = timeline.filter(ibGib => ibGib.data?.n === undefined);
|
|
487
|
+
// console.warn(`${lc} timeline includes ibgibs with ibGib.data?.n === undefined.\nfiltered:\n${filtered.map(x => pretty(x)).join('\n')}}(W: 7360a8e81b05accf244fb4b86e796325)`);
|
|
488
|
+
// }
|
|
489
|
+
// // sort mutates array in place
|
|
490
|
+
// timeline.sort((a, b) => (a.data?.n ?? -1) > (b.data?.n ?? -1) ? 1 : -1); // sorts ascending, e.g., 0,1,2...[Highest]
|
|
491
|
+
|
|
492
|
+
// // last one is the latest
|
|
493
|
+
// let latestInTimeline = timeline.at(-1);
|
|
494
|
+
// if (latestInTimeline) {
|
|
495
|
+
// latestAddrsMap[localAddr] = getIbGibAddr({ ibGib: latestInTimeline });
|
|
496
|
+
// } else {
|
|
497
|
+
// latestAddrsMap[localAddr] = null;
|
|
498
|
+
// }
|
|
499
|
+
// } else {
|
|
500
|
+
// // if it has no tjp, it is its own latest if it exists
|
|
501
|
+
// latestAddrsMap[localAddr] = this.ibGibs[localAddr] ? localAddr : null;
|
|
502
|
+
// }
|
|
503
|
+
// }
|
|
504
|
+
|
|
505
|
+
// #endregion old inefficient no metastones
|
|
344
506
|
|
|
345
507
|
resultData.latestAddrsMap = latestAddrsMap;
|
|
346
508
|
resultData.success = true;
|
|
@@ -201,4 +201,17 @@ await respecfully(sir, `[${InnerSpace_V1.name} specs]`, async () => {
|
|
|
201
201
|
|
|
202
202
|
});
|
|
203
203
|
|
|
204
|
+
// await respecfully(sir, 'latest and metastone related', async () => {
|
|
205
|
+
|
|
206
|
+
// with the current innerspace implementation (01/26/2026), I am getting
|
|
207
|
+
// "latest already exist" warnings when calls to registerNewIbGib are
|
|
208
|
+
// called. this is because the initial implementation always gets the
|
|
209
|
+
// latest by brute forcing splitting ALL in-memory ibgibs by timelines,
|
|
210
|
+
// which is ridiculously inefficient. So I am adding metastone indexing
|
|
211
|
+
// to the innerspace.
|
|
212
|
+
|
|
213
|
+
//
|
|
214
|
+
|
|
215
|
+
// });
|
|
216
|
+
|
|
204
217
|
});
|
|
@@ -979,7 +979,8 @@ export async function registerNewIbGib({
|
|
|
979
979
|
} else {
|
|
980
980
|
// not newer
|
|
981
981
|
if (logalot) { console.log(`is not newer, so we don't need to do anything else. (I: 14c25dc3314748dc909d61b77eb64354)`) }
|
|
982
|
-
|
|
982
|
+
debugger; // temp remove this...
|
|
983
|
+
console.warn(`${lc} incoming ibGib (${ibGibAddr}) is NOT NEWER than existing latest (${existingLatestAddr}). multiple branches for the same timeline? ignoring incoming ibGibAddr. n_ibGib: ${n_ibGib}. n_existingLatest: ${n_existingLatest}. space.ib: ${space.ib} (W: 057baadca494473dabb26fb4fb879774)`)
|
|
983
984
|
return; /* <<<< returns early */
|
|
984
985
|
}
|
|
985
986
|
} else {
|
|
@@ -3434,7 +3435,7 @@ export function spaceNameIsValid(name: string): boolean {
|
|
|
3434
3435
|
|
|
3435
3436
|
/**
|
|
3436
3437
|
* wrapper for getting dependency graph from a space.
|
|
3437
|
-
*
|
|
3438
|
+
*
|
|
3438
3439
|
* NOTE: This calls the witness space with the command. This is NOT the
|
|
3439
3440
|
* same as the logic helper in graph-helper.mts which performs the graph
|
|
3440
3441
|
* traversal logic potentially in-memory or naively.
|
package/test_output.log
CHANGED
|
Binary file
|