@ibgib/core-gib 0.1.11 → 0.1.12
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/CHANGELOG.md +18 -0
- package/dist/sync/sync-innerspace.respec.mjs +147 -25
- package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
- package/dist/timeline/timeline-api.respec.mjs +34 -7
- package/dist/timeline/timeline-api.respec.mjs.map +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.d.mts +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.d.mts.map +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.mjs +4 -3
- package/dist/witness/space/inner-space/inner-space-v1.mjs.map +1 -1
- package/dist/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace-helper.d.mts +18 -0
- package/dist/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace-helper.d.mts.map +1 -1
- package/dist/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace-helper.mjs +39 -10
- package/dist/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace-helper.mjs.map +1 -1
- package/dist/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.d.mts.map +1 -1
- package/dist/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mjs +2 -1
- package/dist/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mjs.map +1 -1
- package/dist/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.respec.mjs +6 -4
- package/dist/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.respec.mjs.map +1 -1
- package/dist/witness/space/space-helper.d.mts.map +1 -1
- package/dist/witness/space/space-helper.mjs +1 -0
- package/dist/witness/space/space-helper.mjs.map +1 -1
- package/package.json +1 -1
- package/src/sync/sync-innerspace.respec.mts +170 -25
- package/src/timeline/timeline-api.respec.mts +34 -16
- package/src/witness/space/inner-space/inner-space-v1.mts +5 -3
- package/src/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace-helper.mts +39 -10
- package/src/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mts +2 -1
- package/src/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.respec.mts +5 -3
- package/src/witness/space/space-helper.mts +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module sync-innerspace.respec
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Verifies SyncSagaCoordinator using InnerSpace (in-memory/local) spaces.
|
|
5
5
|
* This avoids disk I/O issues and focuses on the synchronization logic.
|
|
6
6
|
*/
|
|
@@ -18,6 +18,7 @@ import { Metaspace_Innerspace } from '../witness/space/metaspace/metaspace-inner
|
|
|
18
18
|
import { InnerSpace_V1 } from '../witness/space/inner-space/inner-space-v1.mjs';
|
|
19
19
|
import { createStoneHelper, createTimelineRootHelper, getTestKeystoneServiceHelper } from '../agent-helpers.mjs';
|
|
20
20
|
import { mut8Timeline, appendToTimeline } from '../timeline/timeline-api.mjs';
|
|
21
|
+
import { getDependencyGraph } from '../common/other/graph-helper.mjs';
|
|
21
22
|
|
|
22
23
|
const logalot = true;
|
|
23
24
|
const lc = `[sync-innerspace.respec]`;
|
|
@@ -28,11 +29,10 @@ await respecfully(sir, `Sync InnerSpaces`, async () => {
|
|
|
28
29
|
let sourceSpace: InnerSpace_V1;
|
|
29
30
|
let destSpace: InnerSpace_V1;
|
|
30
31
|
|
|
31
|
-
// Setup before each test? Or once?
|
|
32
|
+
// Setup before each test? Or once?
|
|
32
33
|
// For now, let's just do it inside the test block to be safe/simple.
|
|
33
34
|
|
|
34
35
|
await ifWe(sir, `Basic Push Sync (Source -> Dest)`, async () => {
|
|
35
|
-
// await ifWeMight(sir, `Basic Push Sync (Source -> Dest)`, async () => {
|
|
36
36
|
// 1. Setup Spaces
|
|
37
37
|
metaspace = new Metaspace_Innerspace(undefined);
|
|
38
38
|
await metaspace.initialize({
|
|
@@ -113,32 +113,177 @@ await respecfully(sir, `Sync InnerSpaces`, async () => {
|
|
|
113
113
|
identity
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
-
// 5. Verify Dest
|
|
117
|
-
console.log(`${lc} Verifying Destination...`);
|
|
116
|
+
// 5. Verify Dest (Full Dependency Graph)
|
|
117
|
+
console.log(`${lc} Verifying Destination (Full Graph)...`);
|
|
118
118
|
|
|
119
|
-
//
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
// We expect the graph to contain:
|
|
120
|
+
// 1. childWithRel
|
|
121
|
+
// 2. child (past of childWithRel)
|
|
122
|
+
// 3. root (ancestor of child, past of child)
|
|
123
|
+
// 4. stone (linked to childWithRel)
|
|
124
|
+
// 5. primitives (timeline_root, child, stone_data, identity, fork, mut8, rel8, root^gib, etc.)
|
|
124
125
|
|
|
125
|
-
//
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
// Let's get the graph from the source first to know what to expect (ground truth)
|
|
127
|
+
const sourceGraph = await getDependencyGraph({
|
|
128
|
+
ibGibs: [childWithRel],
|
|
129
|
+
space: sourceSpace,
|
|
130
|
+
});
|
|
131
|
+
const sourceAddrs = Object.keys(sourceGraph);
|
|
132
|
+
console.log(`${lc} Source Graph Size: ${sourceAddrs.length}`);
|
|
133
|
+
|
|
134
|
+
// Now get the graph from the destination
|
|
135
|
+
const destGraph = await getDependencyGraph({
|
|
136
|
+
ibGibs: [childWithRel],
|
|
137
|
+
space: destSpace,
|
|
138
|
+
});
|
|
139
|
+
const destAddrs = Object.keys(destGraph);
|
|
140
|
+
console.log(`${lc} Dest Graph Size: ${destAddrs.length}`);
|
|
141
|
+
|
|
142
|
+
// Assert
|
|
143
|
+
iReckon(sir, destAddrs.length).asTo('dest graph size').isGonnaBe(sourceAddrs.length);
|
|
144
|
+
|
|
145
|
+
for (const addr of sourceAddrs) {
|
|
146
|
+
const inDest = !!destGraph[addr];
|
|
147
|
+
if (!inDest) {
|
|
148
|
+
console.error(`${lc} Missing in dest: ${addr}`);
|
|
149
|
+
}
|
|
150
|
+
iReckon(sir, inDest).asTo(`addr present in dest: ${addr}`).isGonnaBeTrue();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log(`${lc} Verified Full Dependency Graph synced.`);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
await ifWe(sir, `Idempotency (No-op if already synced)`, async () => {
|
|
157
|
+
// 1. Setup Spaces
|
|
158
|
+
const metaspace = new Metaspace_Innerspace(undefined);
|
|
159
|
+
await metaspace.initialize({
|
|
160
|
+
getFnAlert: () => async ({ title, msg }) => { console.log(`[Alert] ${title}: ${msg}`); },
|
|
161
|
+
getFnPrompt: () => async ({ title, msg }) => { console.log(`[Prompt] ${title}: ${msg}`); return ''; },
|
|
162
|
+
getFnPromptPassword: () => async (title, msg) => { console.log(`[PromptPwd] ${title}: ${msg}`); return null; },
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const sourceSpace = new InnerSpace_V1({ name: 'source_idem', uuid: 'source_idem_uuid' } as any);
|
|
166
|
+
await (sourceSpace as any).initialize();
|
|
167
|
+
|
|
168
|
+
const destSpace = new InnerSpace_V1({ name: 'dest_idem', uuid: 'dest_idem_uuid' } as any);
|
|
169
|
+
await (destSpace as any).initialize();
|
|
170
|
+
|
|
171
|
+
// 2. Seed Source and Sync ONCE
|
|
172
|
+
const root = await createTimelineRootHelper({
|
|
173
|
+
ib: 'timeline_root',
|
|
174
|
+
data: { type: 'root', n: 0 },
|
|
175
|
+
space: sourceSpace,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
const mockKeystone = await getTestKeystoneServiceHelper();
|
|
179
|
+
const identity = await (mockKeystone as any).getIdentity();
|
|
180
|
+
const coordinator = new SyncSagaCoordinator(mockKeystone);
|
|
181
|
+
|
|
182
|
+
console.log(`${lc} Running First Sync...`);
|
|
183
|
+
await coordinator.sync({
|
|
184
|
+
source: sourceSpace,
|
|
185
|
+
dest: destSpace,
|
|
186
|
+
domainIbGibs: [root],
|
|
187
|
+
identity
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Verify Initial State
|
|
191
|
+
const rootAddr = getIbGibAddr({ ibGib: root });
|
|
192
|
+
const getRoot1 = await getFromSpace({ space: destSpace, addr: rootAddr });
|
|
193
|
+
iReckon(sir, getRoot1.success).asTo('First Sync success').isGonnaBeTrue();
|
|
130
194
|
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
195
|
+
// 3. Run Sync AGAIN (Should be No-op)
|
|
196
|
+
console.log(`${lc} Running Second Sync...`);
|
|
197
|
+
await coordinator.sync({
|
|
198
|
+
source: sourceSpace,
|
|
199
|
+
dest: destSpace,
|
|
200
|
+
domainIbGibs: [root],
|
|
201
|
+
identity
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// 4. Verify State Unchanged / Still Valid
|
|
205
|
+
const getRoot2 = await getFromSpace({ space: destSpace, addr: rootAddr });
|
|
206
|
+
iReckon(sir, getRoot2.success).asTo('Second Sync success').isGonnaBeTrue();
|
|
207
|
+
|
|
208
|
+
// Ensure no duplication or errors in destination (checking count in dependency graph might be good proxy?)
|
|
209
|
+
const destGraph = await getDependencyGraph({
|
|
210
|
+
ibGibs: [root],
|
|
211
|
+
space: destSpace,
|
|
212
|
+
});
|
|
213
|
+
iReckon(sir, Object.keys(destGraph).length).asTo('Dest Graph Size unchanged').isGonnaBe(Object.keys(destGraph).length); // Trivial assertion, mostly checking for no throw
|
|
214
|
+
|
|
215
|
+
console.log(`${lc} Verified Idempotency.`);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
await ifWeMight(sir, `Dest Ahead (Pull/Fast-Backward)`, async () => {
|
|
219
|
+
// 1. Setup Spaces
|
|
220
|
+
const metaspace = new Metaspace_Innerspace(undefined);
|
|
221
|
+
await metaspace.initialize({
|
|
222
|
+
getFnAlert: () => async ({ title, msg }) => { console.log(`[Alert] ${title}: ${msg}`); },
|
|
223
|
+
getFnPrompt: () => async ({ title, msg }) => { console.log(`[Prompt] ${title}: ${msg}`); return ''; },
|
|
224
|
+
getFnPromptPassword: () => async (title, msg) => { console.log(`[PromptPwd] ${title}: ${msg}`); return null; },
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
const sourceSpace = new InnerSpace_V1({ name: 'source_pull', uuid: 'source_pull_uuid' } as any);
|
|
228
|
+
await (sourceSpace as any).initialize();
|
|
229
|
+
|
|
230
|
+
const destSpace = new InnerSpace_V1({ name: 'dest_pull', uuid: 'dest_pull_uuid' } as any);
|
|
231
|
+
await (destSpace as any).initialize();
|
|
232
|
+
|
|
233
|
+
// 2. Setup Initial Shared State
|
|
234
|
+
// Create root in Source, Sync to Dest
|
|
235
|
+
console.log(`${lc} Seeding initial shared state...`);
|
|
236
|
+
const root = await createTimelineRootHelper({
|
|
237
|
+
ib: 'timeline_pull',
|
|
238
|
+
data: { type: 'root', n: 0, state: 'initial' },
|
|
239
|
+
space: sourceSpace,
|
|
240
|
+
});
|
|
241
|
+
const rootAddr = getIbGibAddr({ ibGib: root });
|
|
242
|
+
|
|
243
|
+
const mockKeystone = await getTestKeystoneServiceHelper();
|
|
244
|
+
const identity = await (mockKeystone as any).getIdentity();
|
|
245
|
+
const coordinator = new SyncSagaCoordinator(mockKeystone);
|
|
246
|
+
|
|
247
|
+
await coordinator.sync({
|
|
248
|
+
source: sourceSpace,
|
|
249
|
+
dest: destSpace,
|
|
250
|
+
domainIbGibs: [root],
|
|
251
|
+
identity
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// 3. Evolve DESTINATION (Simulate external update)
|
|
255
|
+
// We act "as if" we are on Dest side evolving it
|
|
256
|
+
console.log(`${lc} Evolving Destination (making Source behind)...`);
|
|
257
|
+
const childDest = await mut8Timeline({
|
|
258
|
+
timeline: root, // works because mut8Timeline just needs the ib/data/rel8ns/n, doesn't need to be "in" the space object-wise, but we persist to destSpace
|
|
259
|
+
mut8Opts: { dataToAddOrPatch: { n: 1, state: 'ahead' } },
|
|
260
|
+
metaspace,
|
|
261
|
+
space: destSpace,
|
|
262
|
+
});
|
|
263
|
+
const childDestAddr = getIbGibAddr({ ibGib: childDest });
|
|
264
|
+
|
|
265
|
+
// Verify Source DOES NOT have childDest
|
|
266
|
+
const getChildInSource = await getFromSpace({ space: sourceSpace, addr: childDestAddr });
|
|
267
|
+
iReckon(sir, getChildInSource.success).asTo('Source is behind').isGonnaBeFalse(); // Or success=true/addrsNotFound depending on impl
|
|
268
|
+
|
|
269
|
+
// 4. Run Sync from Source
|
|
270
|
+
// Checks:
|
|
271
|
+
// - Source should detect it is behind (or "conflict" in current generic terms).
|
|
272
|
+
// - Source should Pull 'childDest' from Dest.
|
|
273
|
+
// - Source should update itself.
|
|
274
|
+
console.log(`${lc} Running Sync (Pull)...`);
|
|
275
|
+
await coordinator.sync({
|
|
276
|
+
source: sourceSpace,
|
|
277
|
+
dest: destSpace,
|
|
278
|
+
domainIbGibs: [root], // We start with what Source knows (root)
|
|
279
|
+
identity
|
|
280
|
+
});
|
|
136
281
|
|
|
137
|
-
//
|
|
138
|
-
const
|
|
139
|
-
iReckon(sir,
|
|
140
|
-
iReckon(sir,
|
|
141
|
-
console.log(`${lc} Verified Timeline Tip synced.`);
|
|
282
|
+
// 5. Verify Source Caught Up
|
|
283
|
+
const getChildInSourcePost = await getFromSpace({ space: sourceSpace, addr: childDestAddr });
|
|
284
|
+
iReckon(sir, getChildInSourcePost.success).asTo('Source pulled new frame').isGonnaBeTrue();
|
|
285
|
+
iReckon(sir, getChildInSourcePost.ibGibs?.[0]).asTo('Source has childDest').isGonnaBeTruthy();
|
|
142
286
|
|
|
287
|
+
console.log(`${lc} Verified Dest Ahead / Pull.`);
|
|
143
288
|
});
|
|
144
289
|
});
|
|
@@ -9,24 +9,22 @@ import {
|
|
|
9
9
|
lastOfEach, lastOfAll,
|
|
10
10
|
ifWeMight, iReckon, respecfully, respecfullyDear
|
|
11
11
|
} from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
|
|
12
|
+
const maam = `[${import.meta.url}]`, sir = maam;
|
|
13
|
+
import { getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
14
|
+
import { IbGibData_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
|
|
15
|
+
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
12
16
|
|
|
13
|
-
import {
|
|
17
|
+
import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';
|
|
14
18
|
import { InnerSpace_V1 } from '../witness/space/inner-space/inner-space-v1.mjs';
|
|
15
|
-
import {
|
|
19
|
+
import { getLatestAddrs, getFromSpace } from '../witness/space/space-helper.mjs';
|
|
16
20
|
import {
|
|
17
|
-
|
|
18
|
-
} from '../witness/space/space-helper.mjs';
|
|
19
|
-
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
20
|
-
import {
|
|
21
|
-
createTimeline, mut8Timeline, appendToTimeline, getHistory
|
|
21
|
+
createTimeline, mut8Timeline, getHistory, appendToTimeline
|
|
22
22
|
} from './timeline-api.mjs';
|
|
23
|
-
import { MetaspaceService } from '../witness/space/metaspace/metaspace-types.mjs';
|
|
24
|
-
import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
|
|
25
|
-
import { IbGibSpaceAny } from '../witness/space/space-base-v1.mjs';
|
|
26
|
-
|
|
27
23
|
import { Metaspace_Innerspace } from '../witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mjs';
|
|
24
|
+
import { resetInnerSpaces } from '../witness/space/metaspace/metaspace-innerspace/metaspace-innerspace-helper.mjs';
|
|
25
|
+
|
|
26
|
+
const logalot = GLOBAL_LOG_A_LOT;
|
|
28
27
|
|
|
29
|
-
const maam = `[${import.meta.url}]`, sir = maam;
|
|
30
28
|
|
|
31
29
|
interface TestData extends IbGibData_V1 {
|
|
32
30
|
note?: string;
|
|
@@ -40,11 +38,12 @@ respecfully(sir, `[timeline-api]`, async () => {
|
|
|
40
38
|
let metaspace: Metaspace_Innerspace;
|
|
41
39
|
|
|
42
40
|
firstOfEach(sir, async () => {
|
|
41
|
+
resetInnerSpaces();
|
|
43
42
|
metaspace = new Metaspace_Innerspace(undefined);
|
|
44
43
|
await metaspace.initialize({
|
|
45
44
|
getFnAlert: () => async ({ title, msg }) => { console.log(`[Alert] ${title}: ${msg}`); },
|
|
46
45
|
getFnPrompt: () => async ({ title, msg }) => { console.log(`[Prompt] ${title}: ${msg}`); return ''; },
|
|
47
|
-
getFnPromptPassword: () => async (title, msg) => { console.log(`[PromptPwd] ${title}: ${msg}`); return
|
|
46
|
+
getFnPromptPassword: () => async (title, msg) => { console.log(`[PromptPwd] ${title}: ${msg}`); return 'password'; },
|
|
48
47
|
});
|
|
49
48
|
space = metaspace.zeroSpace as InnerSpace_V1;
|
|
50
49
|
});
|
|
@@ -165,7 +164,8 @@ respecfully(sir, `[timeline-api]`, async () => {
|
|
|
165
164
|
const concurrencyLevels = [1, 2, 5, 50];
|
|
166
165
|
|
|
167
166
|
for (const N of concurrencyLevels) {
|
|
168
|
-
console.log(`[Stress Test] Testing concurrency level: ${N}`);
|
|
167
|
+
if (logalot) { console.log(`[Stress Test] Testing concurrency level: ${N}`); }
|
|
168
|
+
|
|
169
169
|
|
|
170
170
|
// Arrange: Baseline
|
|
171
171
|
let tInitial = (await createTimeline<TestData>({
|
|
@@ -179,8 +179,26 @@ respecfully(sir, `[timeline-api]`, async () => {
|
|
|
179
179
|
const initialN = (tInitial.data!.n || 0); // should be 1
|
|
180
180
|
const historyInitial = await getHistory({ timeline: tInitial, metaspace, space });
|
|
181
181
|
const initialHistoryLength = historyInitial.orderedPastIbGibs.length; // should be 1 (genesis)
|
|
182
|
+
console.log(`already had addr for fork expected (I: 585a392f1c5aa0eedc1aedd8bbc31325)`);
|
|
182
183
|
|
|
183
184
|
// Act: Launch N mutations simultaneously
|
|
185
|
+
/**
|
|
186
|
+
* I'm getting output (warnings?) that the transform ibgib addr
|
|
187
|
+
* already exists. This stems from the fact that dna/transform
|
|
188
|
+
* ibgibs do not have timestamps or anything, they simply are
|
|
189
|
+
* memoized args to the transform functions. So we need something
|
|
190
|
+
* unique _in the arg itself_, which in this case means in the
|
|
191
|
+
* `dataToAddOrPatch` field.
|
|
192
|
+
*
|
|
193
|
+
* Note, however, that it is expected for the original `fork`
|
|
194
|
+
* transform that created tInitial to be common and for it to
|
|
195
|
+
* already have this fork dna ibgib. But this shouldn't happen for
|
|
196
|
+
* each mut8 transform.
|
|
197
|
+
*/
|
|
198
|
+
const uniqueIdsForUniqueTransforms: string[] = [];
|
|
199
|
+
for (let i = 0; i < N; i++) {
|
|
200
|
+
uniqueIdsForUniqueTransforms.push(await getUUID());
|
|
201
|
+
}
|
|
184
202
|
const promises: Promise<any>[] = [];
|
|
185
203
|
for (let i = 0; i < N; i++) {
|
|
186
204
|
promises.push(mut8Timeline<TestData>({
|
|
@@ -191,7 +209,7 @@ respecfully(sir, `[timeline-api]`, async () => {
|
|
|
191
209
|
space,
|
|
192
210
|
mut8Opts: {
|
|
193
211
|
dataToAddOrPatch: {
|
|
194
|
-
|
|
212
|
+
uniqueId: uniqueIdsForUniqueTransforms.pop(),
|
|
195
213
|
}
|
|
196
214
|
}
|
|
197
215
|
// No skipLock! We want them to contend.
|
|
@@ -225,7 +243,7 @@ respecfully(sir, `[timeline-api]`, async () => {
|
|
|
225
243
|
const expectedHistoryLength = initialHistoryLength + N;
|
|
226
244
|
iReckon(sir, history.orderedPastIbGibs.length).asTo(`[N=${N}] history length`).isGonnaBe(expectedHistoryLength);
|
|
227
245
|
|
|
228
|
-
console.log(`[Stress Test] [N=${N}] SUCCESS. Final n=${latestIbGib.data!.n}`);
|
|
246
|
+
if (logalot) { console.log(`[Stress Test] [N=${N}] SUCCESS. Final n=${latestIbGib.data!.n}`); }
|
|
229
247
|
|
|
230
248
|
} catch (err) {
|
|
231
249
|
console.error(`[Stress Test] [N=${N}] FAILED:`, err);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { clone, extractErrorMsg, groupBy, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
2
2
|
import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
|
|
3
3
|
import { getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
4
|
-
import { IbGib_V1, getGib, } from '@ibgib/ts-gib/dist/V1/index.mjs';
|
|
5
4
|
import { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';
|
|
6
5
|
|
|
7
6
|
import { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';
|
|
@@ -14,6 +13,8 @@ import { getSpaceIb, } from '../space-helper.mjs';
|
|
|
14
13
|
import { getTjpAddr } from '../../../common/other/ibgib-helper.mjs';
|
|
15
14
|
import { ReconciliationSpaceBase, ReconciliationSpaceData, ReconciliationSpaceRel8ns } from '../reconciliation-space/reconciliation-space-base.mjs';
|
|
16
15
|
import { DEFAULT_INNER_SPACE_DATA_V1, InnerSpaceData_V1, InnerSpaceRel8ns_V1 } from './inner-space-types.mjs';
|
|
16
|
+
import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
|
|
17
|
+
import { getGib } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';
|
|
17
18
|
|
|
18
19
|
const logalot = GLOBAL_LOG_A_LOT;
|
|
19
20
|
|
|
@@ -197,7 +198,7 @@ export class InnerSpace_V1<
|
|
|
197
198
|
|
|
198
199
|
if (addrsAlreadyHave.length > 0) {
|
|
199
200
|
resultData.addrsAlreadyHave = addrsAlreadyHave;
|
|
200
|
-
resultData.warnings = (resultData.warnings || []).concat([`${lc} already had addr(s)
|
|
201
|
+
resultData.warnings = (resultData.warnings || []).concat([`${lc} already had addr(s): ${addrsAlreadyHave.join('|')}`]);
|
|
201
202
|
}
|
|
202
203
|
resultData.success = true;
|
|
203
204
|
} catch (error) {
|
|
@@ -321,7 +322,8 @@ export class InnerSpace_V1<
|
|
|
321
322
|
const timeline = ibGibsInSpaceByTjp[tjpAddr];
|
|
322
323
|
|
|
323
324
|
if (timeline.some(ibGib => ibGib.data?.n === undefined)) {
|
|
324
|
-
|
|
325
|
+
const filtered = timeline.filter(ibGib => ibGib.data?.n === undefined);
|
|
326
|
+
console.warn(`${lc} timeline includes ibgibs with ibGib.data?.n === undefined.\nfiltered:\n${filtered.map(x => pretty(x)).join('\n')}}(W: 7360a8e81b05accf244fb4b86e796325)`);
|
|
325
327
|
}
|
|
326
328
|
// sort mutates array in place
|
|
327
329
|
timeline.sort((a, b) => (a.data?.n ?? -1) > (b.data?.n ?? -1) ? 1 : -1); // sorts ascending, e.g., 0,1,2...[Highest]
|
|
@@ -10,7 +10,39 @@ import { InnerSpace_V1, } from "../../inner-space/inner-space-v1.mjs";
|
|
|
10
10
|
import { InnerSpaceData_V1 } from "../../inner-space/inner-space-types.mjs";
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
const innerSpaces: { [
|
|
13
|
+
const innerSpaces: { [spaceId: string]: IbGibSpaceAny } = {};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Extracts the spaceId from the ib string.
|
|
17
|
+
*
|
|
18
|
+
* ib format: `witness space [classname] [name] [id] [type] [subtype]`
|
|
19
|
+
*/
|
|
20
|
+
export function getSpaceIdFromIb(ib: string): string {
|
|
21
|
+
if (!ib) { throw new Error(`ib required. (E: 7c28c8e1a8a24345bb344155b4131422)`); }
|
|
22
|
+
const parts = ib.split(' ');
|
|
23
|
+
// witness space classname name id ...
|
|
24
|
+
// 0 1 2 3 4
|
|
25
|
+
if (parts.length < 5) { throw new Error(`invalid space ib format: ${ib} (E: 14a84497e59648949822067786481223)`); }
|
|
26
|
+
return parts[4];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Manually registers a space in the module-level registry.
|
|
31
|
+
* Use this when creating spaces outside of the standard factory functions
|
|
32
|
+
* (e.g. via direct constructor calls) to ensure they are resolvable by DTO.
|
|
33
|
+
*/
|
|
34
|
+
export const registerInnerSpace = (space: IbGibSpaceAny) => {
|
|
35
|
+
const spaceId = getSpaceIdFromIb(space.ib);
|
|
36
|
+
innerSpaces[spaceId] = space;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Resets the internal registry of spaces.
|
|
41
|
+
* USE FOR TESTING ONLY.
|
|
42
|
+
*/
|
|
43
|
+
export const resetInnerSpaces = () => {
|
|
44
|
+
Object.keys(innerSpaces).forEach(key => delete innerSpaces[key]);
|
|
45
|
+
}
|
|
14
46
|
|
|
15
47
|
export const fnCreateNewLocalSpace: LocalSpaceFactoryFunction = async ({
|
|
16
48
|
allowCancel,
|
|
@@ -74,9 +106,7 @@ Enter space name:
|
|
|
74
106
|
if (newLocalSpace.gib === GIB) { throw new Error(`localSpace.gib not updated correctly.`); }
|
|
75
107
|
if (logalot) { console.log(`${lc} localSpace.gib: ${newLocalSpace.gib} (after sha256v1)`); }
|
|
76
108
|
|
|
77
|
-
|
|
78
|
-
const tjpGib = gibInfo.tjpGib ?? newLocalSpace.gib!;
|
|
79
|
-
innerSpaces[tjpGib] = newLocalSpace;
|
|
109
|
+
registerInnerSpace(newLocalSpace as IbGibSpaceAny);
|
|
80
110
|
|
|
81
111
|
return newLocalSpace as IbGibSpaceAny;
|
|
82
112
|
} catch (error) {
|
|
@@ -103,9 +133,9 @@ export const fnDtoToSpace: DtoToSpaceFunction = async (spaceDto) => {
|
|
|
103
133
|
if (!spaceDto.data) { throw new Error(`invalid spaceDto. InnerSpace_V1 should have truthy data. (E: d402fda7a6a53668b655c2885029a423)`); }
|
|
104
134
|
// console.dir(spaceDto); // I want to keep this in if we need to turn the logging back on
|
|
105
135
|
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
const existingSpace = innerSpaces[
|
|
136
|
+
const spaceId = getSpaceIdFromIb(spaceDto.ib);
|
|
137
|
+
// console.log(`${lc} spaceDto.gib: ${spaceDto.gib}\ninnerSpaces keys:\n${Object.keys(innerSpaces).join('\n')}`);
|
|
138
|
+
const existingSpace = innerSpaces[spaceId];
|
|
109
139
|
if (existingSpace) {
|
|
110
140
|
return existingSpace;
|
|
111
141
|
} else {
|
|
@@ -113,9 +143,8 @@ export const fnDtoToSpace: DtoToSpaceFunction = async (spaceDto) => {
|
|
|
113
143
|
console.warn(`${lc} in memory innerspace dto that isnt' the reference to the object itself in memory, and we don't have it in the inner spaces map? i guess we'll create a new one from the dto (W: b8973f3a43f546eeaf59f60331896e75)`)
|
|
114
144
|
let space = new InnerSpace_V1(spaceDto.data as InnerSpaceData_V1, spaceDto.rel8ns);
|
|
115
145
|
await space.initialized;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
innerSpaces[tjpGib] = space;
|
|
146
|
+
|
|
147
|
+
registerInnerSpace(space);
|
|
119
148
|
return space;
|
|
120
149
|
}
|
|
121
150
|
}
|
|
@@ -12,7 +12,7 @@ import { IbGibSpaceAny } from '../../../../witness/space/space-base-v1.mjs';
|
|
|
12
12
|
import { InnerSpace_V1 } from '../../../../witness/space/inner-space/inner-space-v1.mjs';
|
|
13
13
|
import { IbGibCacheService } from '../../../../common/cache/cache-types.mjs';
|
|
14
14
|
import { MetaspaceFactory } from '../metaspace-types.mjs';
|
|
15
|
-
import { fnCreateNewLocalSpace, fnDtoToSpace } from './metaspace-innerspace-helper.mjs';
|
|
15
|
+
import { fnCreateNewLocalSpace, fnDtoToSpace, registerInnerSpace } from './metaspace-innerspace-helper.mjs';
|
|
16
16
|
import { MetaspaceBase } from '../metaspace-base.mjs';
|
|
17
17
|
|
|
18
18
|
const logalot = GLOBAL_LOG_A_LOT;
|
|
@@ -75,6 +75,7 @@ export class Metaspace_Innerspace extends MetaspaceBase {
|
|
|
75
75
|
const zeroSpace = new InnerSpace_V1(/*initialData*/ undefined as any, /*initialRel8ns*/ undefined);
|
|
76
76
|
zeroSpace.gib = 'gib';
|
|
77
77
|
this._zeroSpace = zeroSpace;
|
|
78
|
+
registerInnerSpace(this._zeroSpace);
|
|
78
79
|
return zeroSpace;
|
|
79
80
|
}
|
|
80
81
|
};
|
|
@@ -16,6 +16,7 @@ import { InnerSpace_V1 } from '../../../../witness/space/inner-space/inner-space
|
|
|
16
16
|
import { Metaspace_Innerspace } from './metaspace-innerspace.mjs';
|
|
17
17
|
import { createTimeline, mut8Timeline } from '../../../../timeline/timeline-api.mjs';
|
|
18
18
|
import { MetaspaceService } from '../metaspace-types.mjs';
|
|
19
|
+
import { resetInnerSpaces } from './metaspace-innerspace-helper.mjs';
|
|
19
20
|
|
|
20
21
|
const maam = `[${import.meta.url}]`, sir = maam;
|
|
21
22
|
|
|
@@ -24,6 +25,7 @@ respecfully(sir, `[metaspace-innerspace]`, async () => {
|
|
|
24
25
|
let metaspace: Metaspace_Innerspace;
|
|
25
26
|
|
|
26
27
|
firstOfEach(sir, async () => {
|
|
28
|
+
resetInnerSpaces();
|
|
27
29
|
metaspace = new Metaspace_Innerspace(undefined); // no cache for now
|
|
28
30
|
await metaspace.initialize({
|
|
29
31
|
getFnAlert: () => async ({ title, msg }) => { console.log(`[Alert] ${title}: ${msg}`); },
|
|
@@ -32,17 +34,17 @@ respecfully(sir, `[metaspace-innerspace]`, async () => {
|
|
|
32
34
|
});
|
|
33
35
|
});
|
|
34
36
|
|
|
35
|
-
await
|
|
37
|
+
await ifWe(sir, `can instantiate`, async () => {
|
|
36
38
|
iReckon(sir, metaspace).asTo('metaspace').isGonnaBeTruthy();
|
|
37
39
|
iReckon(sir, metaspace.initialized).asTo('initialized').isGonnaBeTrue();
|
|
38
40
|
});
|
|
39
41
|
|
|
40
|
-
await
|
|
42
|
+
await ifWe(sir, `has zeroSpace`, async () => {
|
|
41
43
|
const zs = metaspace.zeroSpace;
|
|
42
44
|
iReckon(sir, zs).asTo('zeroSpace').isGonnaBeTruthy();
|
|
43
45
|
});
|
|
44
46
|
|
|
45
|
-
await
|
|
47
|
+
await ifWe(sir, `can createTimeline and track latest`, async () => {
|
|
46
48
|
// This implicitly tests getLatestAddr/s via timeline-api usage if we were using it,
|
|
47
49
|
// but here we call it directly or via minimal timeline op.
|
|
48
50
|
|
|
@@ -51,7 +51,6 @@ import { validateBootstrapIbGib } from './bootstrap/bootstrap-helper.mjs';
|
|
|
51
51
|
import { BootstrapData, BootstrapIbGib, BootstrapRel8ns } from './bootstrap/bootstrap-types.mjs';
|
|
52
52
|
import { newUpMetaStone } from '../../common/meta-stone/meta-stone-helper.mjs';
|
|
53
53
|
import { WITNESS_ATOM } from '../witness-constants.mjs';
|
|
54
|
-
import { SyncSpaceIbGib } from './outer-space/outer-space-types.mjs';
|
|
55
54
|
|
|
56
55
|
let logalot = GLOBAL_LOG_A_LOT;
|
|
57
56
|
|
|
@@ -1620,6 +1619,7 @@ async function createRootIbGib({
|
|
|
1620
1619
|
linkedRel8ns: [Rel8n.past, Rel8n.ancestor],
|
|
1621
1620
|
tjp: { uuid: true, timestamp: true },
|
|
1622
1621
|
dna: true,
|
|
1622
|
+
nCounter: true,
|
|
1623
1623
|
});
|
|
1624
1624
|
const { newIbGib } = resNewIbGib;
|
|
1625
1625
|
await persistTransformResult({
|