@ibgib/core-gib 0.1.60 → 0.1.62
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 +16 -0
- package/dist/common/other/graph-helper.d.mts.map +1 -1
- package/dist/common/other/graph-helper.mjs +7 -6
- package/dist/common/other/graph-helper.mjs.map +1 -1
- package/dist/keystone/keystone-config-builder.d.mts +1 -2
- package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
- package/dist/keystone/keystone-config-builder.mjs +4 -19
- package/dist/keystone/keystone-config-builder.mjs.map +1 -1
- package/dist/keystone/keystone-constants.d.mts +2 -1
- package/dist/keystone/keystone-constants.d.mts.map +1 -1
- package/dist/keystone/keystone-constants.mjs +2 -1
- package/dist/keystone/keystone-constants.mjs.map +1 -1
- package/dist/keystone/keystone-helpers.d.mts +28 -16
- package/dist/keystone/keystone-helpers.d.mts.map +1 -1
- package/dist/keystone/keystone-helpers.mjs +155 -76
- package/dist/keystone/keystone-helpers.mjs.map +1 -1
- package/dist/keystone/keystone-policy-types.d.mts +6 -4
- package/dist/keystone/keystone-policy-types.d.mts.map +1 -1
- package/dist/keystone/keystone-service-v1.d.mts +38 -2
- package/dist/keystone/keystone-service-v1.d.mts.map +1 -1
- package/dist/keystone/keystone-service-v1.mjs +177 -11
- package/dist/keystone/keystone-service-v1.mjs.map +1 -1
- package/dist/keystone/keystone-service-v1.respec.mjs +527 -41
- package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -1
- package/dist/keystone/keystone-types.d.mts +53 -11
- package/dist/keystone/keystone-types.d.mts.map +1 -1
- package/dist/keystone/policy/keystone-profile-builder.d.mts +25 -0
- package/dist/keystone/policy/keystone-profile-builder.d.mts.map +1 -0
- package/dist/keystone/policy/keystone-profile-builder.mjs +117 -0
- package/dist/keystone/policy/keystone-profile-builder.mjs.map +1 -0
- package/dist/keystone/policy/profiles/profile-high.json +84 -0
- package/dist/keystone/policy/profiles/profile-low.json +84 -0
- package/dist/keystone/policy/profiles/profile-medium.json +84 -0
- package/dist/keystone/policy/profiles/profile-session.json +84 -0
- package/dist/keystone/policy/profiles/profile-test.json +84 -0
- package/dist/keystone/policy/schemas/connect-pool.high.schema.json +23 -0
- package/dist/keystone/policy/schemas/connect-pool.low.schema.json +23 -0
- package/dist/keystone/policy/schemas/connect-pool.medium.schema.json +23 -0
- package/dist/keystone/policy/schemas/keystone.high.schema.json +26 -0
- package/dist/keystone/policy/schemas/keystone.low.schema.json +26 -0
- package/dist/keystone/policy/schemas/keystone.medium.schema.json +26 -0
- package/dist/keystone/policy/schemas/manage-pool.high.schema.json +23 -0
- package/dist/keystone/policy/schemas/manage-pool.low.schema.json +23 -0
- package/dist/keystone/policy/schemas/manage-pool.medium.schema.json +23 -0
- package/dist/keystone/policy/schemas/revoke-pool.high.schema.json +23 -0
- package/dist/keystone/policy/schemas/revoke-pool.low.schema.json +23 -0
- package/dist/keystone/policy/schemas/revoke-pool.medium.schema.json +23 -0
- package/dist/keystone/policy/schemas/sign-pool.high.schema.json +23 -0
- package/dist/keystone/policy/schemas/sign-pool.low.schema.json +23 -0
- package/dist/keystone/policy/schemas/sign-pool.medium.schema.json +23 -0
- package/dist/keystone/policy/schemas/sync-pool.high.schema.json +23 -0
- package/dist/keystone/policy/schemas/sync-pool.low.schema.json +23 -0
- package/dist/keystone/policy/schemas/sync-pool.medium.schema.json +23 -0
- package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.d.mts +8 -0
- package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.mjs +582 -0
- package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-conflict-basic-divergence.withid.respec.d.mts +7 -0
- package/dist/sync/sync-conflict-basic-divergence.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-conflict-basic-divergence.withid.respec.mjs +274 -0
- package/dist/sync/sync-conflict-basic-divergence.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.d.mts +8 -0
- package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.mjs +322 -0
- package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-conflict-text-merge.withid.respec.d.mts +7 -0
- package/dist/sync/sync-conflict-text-merge.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-conflict-text-merge.withid.respec.mjs +307 -0
- package/dist/sync/sync-conflict-text-merge.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace-constants.withid.respec.d.mts +8 -0
- package/dist/sync/sync-innerspace-constants.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace-constants.withid.respec.mjs +233 -0
- package/dist/sync/sync-innerspace-constants.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace-deep-updates.withid.respec.d.mts +7 -0
- package/dist/sync/sync-innerspace-deep-updates.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace-deep-updates.withid.respec.mjs +233 -0
- package/dist/sync/sync-innerspace-deep-updates.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace-dest-ahead.withid.respec.d.mts +7 -0
- package/dist/sync/sync-innerspace-dest-ahead.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace-dest-ahead.withid.respec.mjs +225 -0
- package/dist/sync/sync-innerspace-dest-ahead.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.d.mts +7 -0
- package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.mjs +235 -0
- package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace-partial-update.withid.respec.d.mts +7 -0
- package/dist/sync/sync-innerspace-partial-update.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace-partial-update.withid.respec.mjs +211 -0
- package/dist/sync/sync-innerspace-partial-update.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace.withid.respec.d.mts +8 -0
- package/dist/sync/sync-innerspace.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace.withid.respec.mjs +260 -0
- package/dist/sync/sync-innerspace.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs +13 -4
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts +1 -1
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs +5 -3
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs.map +1 -1
- package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.mjs +165 -145
- package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
- package/dist/sync/sync-withid.pingpong.respec.mjs +8 -8
- package/dist/sync/sync-withid.pingpong.respec.mjs.map +1 -1
- package/dist/timeline/timeline-api.d.mts.map +1 -1
- package/dist/timeline/timeline-api.mjs +1 -14
- package/dist/timeline/timeline-api.mjs.map +1 -1
- package/dist/witness/space/reconciliation-space/reconciliation-space-base.d.mts.map +1 -1
- package/dist/witness/space/reconciliation-space/reconciliation-space-base.mjs +0 -40
- package/dist/witness/space/reconciliation-space/reconciliation-space-base.mjs.map +1 -1
- package/dist/witness/space/reconciliation-space/reconciliation-space-helper.d.mts.map +1 -1
- package/dist/witness/space/reconciliation-space/reconciliation-space-helper.mjs +6 -6
- package/dist/witness/space/reconciliation-space/reconciliation-space-helper.mjs.map +1 -1
- package/ibgib-foundations.md +2 -1
- package/package.json +1 -1
- package/src/common/other/graph-helper.mts +7 -6
- package/src/keystone/README.md +34 -17
- package/src/keystone/docs/CRYPTANALYSIS.md +185 -0
- package/src/keystone/docs/architecture.md +45 -3
- package/src/keystone/docs/delegation.md +57 -0
- package/src/keystone/docs/profiles.md +124 -0
- package/src/keystone/keystone-config-builder.mts +3 -21
- package/src/keystone/keystone-constants.mts +2 -1
- package/src/keystone/keystone-helpers.mts +204 -81
- package/src/keystone/keystone-policy-types.mts +6 -4
- package/src/keystone/keystone-service-v1.mts +223 -11
- package/src/keystone/keystone-service-v1.respec.mts +596 -39
- package/src/keystone/keystone-types.mts +55 -9
- package/src/keystone/policy/IMPLEMENTATION.md +60 -0
- package/src/keystone/policy/README.md +94 -0
- package/src/keystone/policy/keystone-profile-builder.mts +131 -0
- package/src/keystone/policy/profiles/profile-high.json +84 -0
- package/src/keystone/policy/profiles/profile-low.json +84 -0
- package/src/keystone/policy/profiles/profile-medium.json +84 -0
- package/src/keystone/policy/profiles/profile-session.json +84 -0
- package/src/keystone/policy/profiles/profile-test.json +84 -0
- package/src/keystone/policy/schemas/connect-pool.high.schema.json +23 -0
- package/src/keystone/policy/schemas/connect-pool.low.schema.json +23 -0
- package/src/keystone/policy/schemas/connect-pool.medium.schema.json +23 -0
- package/src/keystone/policy/schemas/keystone.high.schema.json +26 -0
- package/src/keystone/policy/schemas/keystone.low.schema.json +26 -0
- package/src/keystone/policy/schemas/keystone.medium.schema.json +26 -0
- package/src/keystone/policy/schemas/manage-pool.high.schema.json +23 -0
- package/src/keystone/policy/schemas/manage-pool.low.schema.json +23 -0
- package/src/keystone/policy/schemas/manage-pool.medium.schema.json +23 -0
- package/src/keystone/policy/schemas/revoke-pool.high.schema.json +23 -0
- package/src/keystone/policy/schemas/revoke-pool.low.schema.json +23 -0
- package/src/keystone/policy/schemas/revoke-pool.medium.schema.json +23 -0
- package/src/keystone/policy/schemas/sign-pool.high.schema.json +23 -0
- package/src/keystone/policy/schemas/sign-pool.low.schema.json +23 -0
- package/src/keystone/policy/schemas/sign-pool.medium.schema.json +23 -0
- package/src/keystone/policy/schemas/sync-pool.high.schema.json +23 -0
- package/src/keystone/policy/schemas/sync-pool.low.schema.json +23 -0
- package/src/keystone/policy/schemas/sync-pool.medium.schema.json +23 -0
- package/src/sync/docs/security.md +54 -21
- package/src/sync/sync-conflict-adv-multitimelines.withid.respec.mts +706 -0
- package/src/sync/sync-conflict-basic-divergence.withid.respec.mts +321 -0
- package/src/sync/sync-conflict-basic-multitimelines.withid.respec.mts +374 -0
- package/src/sync/sync-conflict-text-merge.withid.respec.mts +347 -0
- package/src/sync/sync-innerspace-constants.withid.respec.mts +264 -0
- package/src/sync/sync-innerspace-deep-updates.withid.respec.mts +272 -0
- package/src/sync/sync-innerspace-dest-ahead.withid.respec.mts +266 -0
- package/src/sync/sync-innerspace-multiple-timelines.respec.mts +0 -1
- package/src/sync/sync-innerspace-multiple-timelines.withid.respec.mts +273 -0
- package/src/sync/sync-innerspace-partial-update.withid.respec.mts +249 -0
- package/src/sync/sync-innerspace.withid.respec.mts +265 -0
- package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mts +12 -4
- package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mts +5 -3
- package/src/sync/sync-saga-coordinator.mts +159 -143
- package/src/sync/sync-withid.pingpong.respec.mts +8 -8
- package/src/timeline/timeline-api.mts +1 -15
- package/src/timeline/timeline-api.respec.mts +3 -3
- package/src/witness/space/reconciliation-space/reconciliation-space-base.mts +0 -46
- package/src/witness/space/reconciliation-space/reconciliation-space-helper.mts +6 -5
- package/tsconfig.json +6 -1
- package/src/keystone/keystone-policy.schema.json +0 -51
- package/src/witness/space/reconciliation-space/reconciliation-space-base.mts.OLD.md +0 -884
- package/src/witness/space/reconciliation-space/reconciliation-space-helper.mts.OLD.md +0 -125
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "LowSecuritySyncPool",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"id": { "type": "string", "const": "sync" },
|
|
7
|
+
"allowedVerbs": { "type": "array", "items": { "const": "sync" } },
|
|
8
|
+
"algo": { "type": "string", "const": "SHA-256" },
|
|
9
|
+
"rounds": { "type": "integer", "minimum": 1 },
|
|
10
|
+
"behavior": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"properties": {
|
|
13
|
+
"size": { "type": "integer", "minimum": 12 },
|
|
14
|
+
"replenish": { "type": "string", "const": "top-up" },
|
|
15
|
+
"selectSequentially": { "type": "integer", "minimum": 1 },
|
|
16
|
+
"selectRandomly": { "type": "integer", "minimum": 1 },
|
|
17
|
+
"targetBindingCount": { "type": "integer", "minimum": 3 }
|
|
18
|
+
},
|
|
19
|
+
"required": ["size", "replenish", "selectSequentially", "selectRandomly", "targetBindingCount"]
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"required": ["id", "allowedVerbs", "algo", "rounds", "behavior"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "MediumSecuritySyncPool",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"id": { "type": "string", "const": "sync" },
|
|
7
|
+
"allowedVerbs": { "type": "array", "items": { "const": "sync" } },
|
|
8
|
+
"algo": { "type": "string", "enum": ["SHA-256", "SHA-512"] },
|
|
9
|
+
"rounds": { "type": "integer", "minimum": 2 },
|
|
10
|
+
"behavior": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"properties": {
|
|
13
|
+
"size": { "type": "integer", "minimum": 500 },
|
|
14
|
+
"replenish": { "type": "string", "const": "top-up" },
|
|
15
|
+
"selectSequentially": { "type": "integer", "minimum": 5 },
|
|
16
|
+
"selectRandomly": { "type": "integer", "minimum": 5 },
|
|
17
|
+
"targetBindingCount": { "type": "integer", "minimum": 10 }
|
|
18
|
+
},
|
|
19
|
+
"required": ["size", "replenish", "selectSequentially", "selectRandomly", "targetBindingCount"]
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"required": ["id", "allowedVerbs", "algo", "rounds", "behavior"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sync-conflict-adv-multitimelines.withid.respec
|
|
3
|
+
*
|
|
4
|
+
* Verifies Conflict Resolution strategies in SyncSagaCoordinator under identity.
|
|
5
|
+
* Reproduces divergence scenarios and asserts resolution behavior.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=sync-conflict-adv-multitimelines.withid.respec.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-conflict-adv-multitimelines.withid.respec.d.mts","sourceRoot":"","sources":["../../src/sync/sync-conflict-adv-multitimelines.withid.respec.mts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sync-conflict-adv-multitimelines.withid.respec
|
|
3
|
+
*
|
|
4
|
+
* Verifies Conflict Resolution strategies in SyncSagaCoordinator under identity.
|
|
5
|
+
* Reproduces divergence scenarios and asserts resolution behavior.
|
|
6
|
+
*/
|
|
7
|
+
import { respecfully, ifWe, iReckon } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
|
|
8
|
+
const maam = `[${import.meta.url}]`, sir = maam;
|
|
9
|
+
import { clone, delay } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
10
|
+
import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
|
|
11
|
+
import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';
|
|
12
|
+
import { TestTransformer, } from '../test-helpers.mjs';
|
|
13
|
+
import { SyncSagaCoordinator } from './sync-saga-coordinator.mjs';
|
|
14
|
+
import { getFromSpace } from '../witness/space/space-helper.mjs';
|
|
15
|
+
import { Metaspace_Innerspace } from '../witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mjs';
|
|
16
|
+
import { InnerSpace_V1 } from '../witness/space/inner-space/inner-space-v1.mjs';
|
|
17
|
+
import { SyncPeerInnerspace_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs';
|
|
18
|
+
import { DEFAULT_INNER_SPACE_DATA_V1 } from '../witness/space/inner-space/inner-space-types.mjs';
|
|
19
|
+
import { getIbGibsFromCache_fallbackToSpaces, getTjpAddr, } from '../common/other/ibgib-helper.mjs';
|
|
20
|
+
import { getDependencyGraph, graphsAreEquivalent } from '../common/other/graph-helper.mjs';
|
|
21
|
+
import { SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs';
|
|
22
|
+
import { SyncConflictStrategy } from './sync-constants.mjs';
|
|
23
|
+
import { KeystoneService_V1 } from '../keystone/keystone-service-v1.mjs';
|
|
24
|
+
import { KEYSTONE_VERB_SYNC, POOL_ID_SYNC, } from '../keystone/keystone-constants.mjs';
|
|
25
|
+
import { createStandardPoolConfig } from '../keystone/keystone-config-builder.mjs';
|
|
26
|
+
import { KeystoneReplenishStrategy } from '../keystone/keystone-types.mjs';
|
|
27
|
+
const logalot = GLOBAL_LOG_A_LOT;
|
|
28
|
+
const lc = sir;
|
|
29
|
+
const SENDER_SECRET = 'test-sender-secret-conflict-adv-multitimelines-withid';
|
|
30
|
+
const SENDER_IDENTITY_SYNC_POOL_CONFIG = createStandardPoolConfig({
|
|
31
|
+
id: POOL_ID_SYNC,
|
|
32
|
+
salt: 'senderidentitysyncsaltconflictadvmultitimelineswithid',
|
|
33
|
+
verbs: [KEYSTONE_VERB_SYNC],
|
|
34
|
+
size: 200,
|
|
35
|
+
sequential: 1,
|
|
36
|
+
random: 1,
|
|
37
|
+
targetBinding: 2,
|
|
38
|
+
replenishStrategy: KeystoneReplenishStrategy.topUp,
|
|
39
|
+
});
|
|
40
|
+
const TEST_REL8N_NAME = 'testrel8n';
|
|
41
|
+
await respecfully(sir, `Multi-round/timeline permutations with Identity`, async () => {
|
|
42
|
+
// #region Init/Setup
|
|
43
|
+
const metaspace = new Metaspace_Innerspace(undefined);
|
|
44
|
+
await metaspace.initialize({
|
|
45
|
+
getFnAlert: () => async ({ title, msg }) => { console.log(`[Alert] ${title}: ${msg}`); },
|
|
46
|
+
getFnPrompt: () => async ({ title, msg }) => { console.log(`[Prompt] ${title}: ${msg}`); return ''; },
|
|
47
|
+
getFnPromptPassword: () => async (title, msg) => { console.log(`[PromptPwd] ${title}: ${msg}`); return null; },
|
|
48
|
+
});
|
|
49
|
+
while (!metaspace.initialized) {
|
|
50
|
+
await delay(10);
|
|
51
|
+
}
|
|
52
|
+
const defaultLocalUserSpace = await metaspace.getLocalUserSpace({ lock: false });
|
|
53
|
+
await defaultLocalUserSpace.initialized;
|
|
54
|
+
const sourceSpace = new InnerSpace_V1({
|
|
55
|
+
...DEFAULT_INNER_SPACE_DATA_V1,
|
|
56
|
+
name: 'source',
|
|
57
|
+
uuid: 'source_uuid',
|
|
58
|
+
description: 'source test space',
|
|
59
|
+
});
|
|
60
|
+
await sourceSpace.initialized;
|
|
61
|
+
const destSpace = new InnerSpace_V1({
|
|
62
|
+
...DEFAULT_INNER_SPACE_DATA_V1,
|
|
63
|
+
name: 'dest',
|
|
64
|
+
uuid: 'dest_uuid',
|
|
65
|
+
description: 'dest test space',
|
|
66
|
+
});
|
|
67
|
+
await destSpace.initialized;
|
|
68
|
+
const testTransformer = new TestTransformer(metaspace, sourceSpace, destSpace);
|
|
69
|
+
if (logalot) {
|
|
70
|
+
console.log(`${lc} Setting up Coordinators...`);
|
|
71
|
+
}
|
|
72
|
+
const senderCoordinator = new SyncSagaCoordinator();
|
|
73
|
+
const receiverCoordinator = new SyncSagaCoordinator();
|
|
74
|
+
// Setup Identities
|
|
75
|
+
const keystoneSvc = new KeystoneService_V1();
|
|
76
|
+
const r1_senderIdentity_v0_source = await keystoneSvc.genesis({
|
|
77
|
+
masterSecret: SENDER_SECRET,
|
|
78
|
+
configs: [SENDER_IDENTITY_SYNC_POOL_CONFIG],
|
|
79
|
+
metaspace,
|
|
80
|
+
space: sourceSpace,
|
|
81
|
+
});
|
|
82
|
+
// Register identity in both spaces
|
|
83
|
+
await metaspace.put({ ibGib: r1_senderIdentity_v0_source, space: destSpace });
|
|
84
|
+
await metaspace.registerNewIbGib({ ibGib: r1_senderIdentity_v0_source, space: destSpace });
|
|
85
|
+
let senderIdentityLatestSource = r1_senderIdentity_v0_source;
|
|
86
|
+
async function newTestPeer() {
|
|
87
|
+
const peer = new SyncPeerInnerspace_V1(clone(SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1));
|
|
88
|
+
await peer.initialized;
|
|
89
|
+
await peer.initializeOpts({
|
|
90
|
+
localMetaspace: metaspace,
|
|
91
|
+
localSpace: sourceSpace,
|
|
92
|
+
receiverSpace: destSpace,
|
|
93
|
+
receiverCoordinator: receiverCoordinator,
|
|
94
|
+
receiverMetaspace: metaspace,
|
|
95
|
+
});
|
|
96
|
+
return peer;
|
|
97
|
+
}
|
|
98
|
+
// #endregion Init/Setup
|
|
99
|
+
// #region Round 1: Seed common history
|
|
100
|
+
const _r1 = testTransformer.newRound({
|
|
101
|
+
name: 'r1_seedCommonHistory',
|
|
102
|
+
description: 'Create alpha v0 and v1 on source, sync to dest so both v0 and v1 are established as synced.',
|
|
103
|
+
});
|
|
104
|
+
if (logalot) {
|
|
105
|
+
console.log(`${lc} Creating common History...`);
|
|
106
|
+
}
|
|
107
|
+
const r1_alpha_v0_source = await testTransformer.create({
|
|
108
|
+
atom: 'alpha',
|
|
109
|
+
in: 'source',
|
|
110
|
+
name: 'r1_alpha_v0_source',
|
|
111
|
+
});
|
|
112
|
+
const alpha_tjpAddr = getTjpAddr({ ibGib: r1_alpha_v0_source.ibGib, defaultIfNone: 'incomingAddr' });
|
|
113
|
+
// Create v1 (common) - will be synced to dest
|
|
114
|
+
const r1_alpha_v1_source_common = await testTransformer.mut8({
|
|
115
|
+
stepInfo: r1_alpha_v0_source,
|
|
116
|
+
strField: 'commonField',
|
|
117
|
+
name: 'r1_alpha_v1_source_common'
|
|
118
|
+
});
|
|
119
|
+
await respecfully(sir, `r1 verify pre`, async () => {
|
|
120
|
+
await ifWe(sir, 'dest should NOT have alpha', async () => {
|
|
121
|
+
const resGet = await getFromSpace({
|
|
122
|
+
space: destSpace,
|
|
123
|
+
addr: alpha_tjpAddr,
|
|
124
|
+
});
|
|
125
|
+
iReckon(sir, resGet.success).asTo('getFromSpace should return false for missing timeline').isGonnaBeFalse();
|
|
126
|
+
iReckon(sir, resGet.ibGibs?.length ?? 0).asTo('Dest should NOT have alpha timeline yet').isGonnaBe(0);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
const peerR1 = await newTestPeer();
|
|
130
|
+
const r1_syncSaga = await senderCoordinator.sync({
|
|
131
|
+
peer: peerR1,
|
|
132
|
+
localSpace: sourceSpace,
|
|
133
|
+
metaspace,
|
|
134
|
+
domainIbGibs: [r1_alpha_v1_source_common.ibGib],
|
|
135
|
+
conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
|
|
136
|
+
senderIdentity: senderIdentityLatestSource,
|
|
137
|
+
fnSenderSecret: async () => SENDER_SECRET,
|
|
138
|
+
});
|
|
139
|
+
await r1_syncSaga.done;
|
|
140
|
+
if (logalot) {
|
|
141
|
+
console.log(`${lc} r1_syncSaga Complete.`);
|
|
142
|
+
}
|
|
143
|
+
await respecfully(sir, `r1 verify post`, async () => {
|
|
144
|
+
await ifWe(sir, 'dest should have alpha', async () => {
|
|
145
|
+
const [alpha_dest] = await getIbGibsFromCache_fallbackToSpaces({
|
|
146
|
+
addrs: [r1_alpha_v0_source.addr],
|
|
147
|
+
space: destSpace,
|
|
148
|
+
});
|
|
149
|
+
iReckon(sir, alpha_dest).asTo('alpha exists in dest').isGonnaBeTruthy();
|
|
150
|
+
if (alpha_dest) {
|
|
151
|
+
const depGraph_alpha_source = await getDependencyGraph({ ibGib: r1_alpha_v0_source.ibGib, space: sourceSpace });
|
|
152
|
+
const depGraph_alpha_dest = await getDependencyGraph({ ibGib: alpha_dest, space: destSpace });
|
|
153
|
+
const alphaDepsAreEqual = graphsAreEquivalent({
|
|
154
|
+
graphA: depGraph_alpha_source, graphB: depGraph_alpha_dest
|
|
155
|
+
});
|
|
156
|
+
iReckon(sir, alphaDepsAreEqual).asTo('alpha got synced and graphs are equal').isGonnaBe(true);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
await ifWe(sir, 'sessionIdentity evolved for Round 1', async () => {
|
|
160
|
+
const latestS = peerR1.currentSessionIdentity;
|
|
161
|
+
iReckon(sir, latestS).asTo('session identity exists').isGonnaBeTruthy();
|
|
162
|
+
if (latestS) {
|
|
163
|
+
iReckon(sir, latestS.data?.n).asTo('session identity data.n').isGonnaBe(2);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
// Get alpha_v1_common from destSpace for Round 2
|
|
168
|
+
const resGetDest = await getFromSpace({ space: destSpace, addr: r1_alpha_v1_source_common.addr });
|
|
169
|
+
if (!resGetDest.success || !resGetDest.ibGibs || resGetDest.ibGibs.length === 0) {
|
|
170
|
+
throw new Error(`Failed to retrieve alpha from destSpace after sync. (E: r1_fail)`);
|
|
171
|
+
}
|
|
172
|
+
const alpha_v1_common_onDest = resGetDest.ibGibs[0];
|
|
173
|
+
// Fetch evolved user identity from space
|
|
174
|
+
const latestSenderIdentityAddrR1 = await metaspace.getLatestAddr({
|
|
175
|
+
addr: getIbGibAddr({ ibGib: r1_senderIdentity_v0_source }),
|
|
176
|
+
space: sourceSpace,
|
|
177
|
+
});
|
|
178
|
+
if (!latestSenderIdentityAddrR1) {
|
|
179
|
+
throw new Error("Could not find latest sender identity after R1");
|
|
180
|
+
}
|
|
181
|
+
const resGetSenderIR1 = await getFromSpace({ space: sourceSpace, addr: latestSenderIdentityAddrR1 });
|
|
182
|
+
senderIdentityLatestSource = resGetSenderIR1.ibGibs[0];
|
|
183
|
+
// Copy/register evolved user identity to dest space
|
|
184
|
+
await metaspace.put({ ibGib: senderIdentityLatestSource, space: destSpace });
|
|
185
|
+
await metaspace.registerNewIbGib({ ibGib: senderIdentityLatestSource, space: destSpace });
|
|
186
|
+
// #endregion Round 1: Seed common history
|
|
187
|
+
// #region Round 2: Create Divergence (v2source vs v2dest)
|
|
188
|
+
const _r2 = testTransformer.newRound({
|
|
189
|
+
name: 'r2_divergent_edits',
|
|
190
|
+
description: 'Create conflicts on alpha, add beta relation on source, separate edit on dest'
|
|
191
|
+
});
|
|
192
|
+
// #region r2 source edits
|
|
193
|
+
if (logalot) {
|
|
194
|
+
console.log(`${lc} Creating Divergence...`);
|
|
195
|
+
}
|
|
196
|
+
// Source: Create beta, mutate alpha fieldA, add beta relation
|
|
197
|
+
const r2_beta_v0_source = await testTransformer.create({
|
|
198
|
+
atom: 'beta',
|
|
199
|
+
in: 'source',
|
|
200
|
+
data: { fieldA: 'beta field A created on source' },
|
|
201
|
+
name: 'r2_beta_v0_source'
|
|
202
|
+
});
|
|
203
|
+
const r2_alpha_v2_source_arbitraryMut8 = await testTransformer.mut8({
|
|
204
|
+
ibGib: r1_alpha_v1_source_common.ibGib,
|
|
205
|
+
in: 'source',
|
|
206
|
+
strField: 'fieldA',
|
|
207
|
+
name: 'r2_alpha_v2_source_arbitraryMut8',
|
|
208
|
+
comments_snake_plus_CamelCase: 'editedOnSource',
|
|
209
|
+
});
|
|
210
|
+
const r2_alpha_v3_source_rel8dBeta = await testTransformer.rel8({
|
|
211
|
+
stepInfo: r2_alpha_v2_source_arbitraryMut8,
|
|
212
|
+
in: 'source',
|
|
213
|
+
targetIbGibs: [r2_beta_v0_source.ibGib],
|
|
214
|
+
rel8nName: TEST_REL8N_NAME,
|
|
215
|
+
name: 'r2_alpha_v3_source_rel8dBeta'
|
|
216
|
+
});
|
|
217
|
+
// #endregion r2 source edits
|
|
218
|
+
// #region r2 dest edits
|
|
219
|
+
// Dest: Mutate alpha fieldB
|
|
220
|
+
const r2_alpha_v2_dest_mut8FieldB = await testTransformer.mut8({
|
|
221
|
+
ibGib: alpha_v1_common_onDest,
|
|
222
|
+
in: 'dest',
|
|
223
|
+
strField: 'fieldB',
|
|
224
|
+
name: 'r2_alpha_v2_dest_mut8FieldB',
|
|
225
|
+
comments_snake_plus_CamelCase: 'editedOnDest',
|
|
226
|
+
});
|
|
227
|
+
if (logalot) {
|
|
228
|
+
console.log(`${lc} Divergence created.`);
|
|
229
|
+
}
|
|
230
|
+
// #endregion r2 dest edits
|
|
231
|
+
await respecfully(sir, `r2 verify pre`, async () => {
|
|
232
|
+
await ifWe(sir, 'dest has alpha v1 common', async () => {
|
|
233
|
+
const destKV = await receiverCoordinator.getKnowledgeMap({
|
|
234
|
+
space: destSpace,
|
|
235
|
+
metaspace,
|
|
236
|
+
domainIbGibs: [alpha_v1_common_onDest]
|
|
237
|
+
});
|
|
238
|
+
const alpha_v1_common_tjpAddr_onDest = getTjpAddr({ ibGib: alpha_v1_common_onDest, defaultIfNone: 'incomingAddr' });
|
|
239
|
+
const destTip = destKV[alpha_v1_common_tjpAddr_onDest];
|
|
240
|
+
iReckon(sir, !!destTip).asTo(`Dest KV has timeline tip`).isGonnaBeTruthy();
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
const peerR2 = await newTestPeer();
|
|
244
|
+
const r2_syncSaga = await senderCoordinator.sync({
|
|
245
|
+
peer: peerR2,
|
|
246
|
+
localSpace: sourceSpace,
|
|
247
|
+
metaspace,
|
|
248
|
+
domainIbGibs: [r2_alpha_v3_source_rel8dBeta.ibGib],
|
|
249
|
+
conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
|
|
250
|
+
senderIdentity: senderIdentityLatestSource,
|
|
251
|
+
fnSenderSecret: async () => SENDER_SECRET,
|
|
252
|
+
});
|
|
253
|
+
await r2_syncSaga.done;
|
|
254
|
+
await respecfully(sir, `r2 verify post`, async () => {
|
|
255
|
+
const alpha_sourceKV_afterSync = await senderCoordinator.getKnowledgeMap({
|
|
256
|
+
space: sourceSpace,
|
|
257
|
+
metaspace,
|
|
258
|
+
domainIbGibs: [r1_alpha_v0_source.ibGib]
|
|
259
|
+
});
|
|
260
|
+
const alpha_source_tipAddr = alpha_sourceKV_afterSync[alpha_tjpAddr];
|
|
261
|
+
const alpha_destKV_afterSync = await senderCoordinator.getKnowledgeMap({
|
|
262
|
+
space: destSpace,
|
|
263
|
+
metaspace,
|
|
264
|
+
domainIbGibs: [r1_alpha_v0_source.ibGib]
|
|
265
|
+
});
|
|
266
|
+
const alpha_dest_tipAddr = alpha_destKV_afterSync[alpha_tjpAddr];
|
|
267
|
+
await ifWe(sir, 'tip addrs match', async () => {
|
|
268
|
+
iReckon(sir, alpha_source_tipAddr).asTo('source/dest tip addrs').isGonnaBe(alpha_dest_tipAddr);
|
|
269
|
+
});
|
|
270
|
+
const resGet_alpha_source_tipAddr = await getFromSpace({ space: sourceSpace, addr: alpha_source_tipAddr });
|
|
271
|
+
const gotten_alpha_source_tipIbGib = resGet_alpha_source_tipAddr.ibGibs[0];
|
|
272
|
+
await ifWe(sir, 'r2 basics of alpha merge', async () => {
|
|
273
|
+
iReckon(sir, alpha_source_tipAddr).not.isGonnaBe(r2_alpha_v3_source_rel8dBeta.addr);
|
|
274
|
+
iReckon(sir, alpha_source_tipAddr).not.isGonnaBe(r2_alpha_v2_dest_mut8FieldB.addr);
|
|
275
|
+
const r2_source_mut8Info = r2_alpha_v2_source_arbitraryMut8.infos[0];
|
|
276
|
+
const r2_dest_mut8Info = r2_alpha_v2_dest_mut8FieldB.infos[0];
|
|
277
|
+
iReckon(sir, gotten_alpha_source_tipIbGib.data[r2_source_mut8Info.key]).isGonnaBe(r2_source_mut8Info.value);
|
|
278
|
+
iReckon(sir, gotten_alpha_source_tipIbGib.data[r2_dest_mut8Info.key]).isGonnaBe(r2_dest_mut8Info.value);
|
|
279
|
+
});
|
|
280
|
+
await ifWe(sir, 'r2 beta and deps synced', async () => {
|
|
281
|
+
const [beta_dest] = await getIbGibsFromCache_fallbackToSpaces({
|
|
282
|
+
addrs: [r2_beta_v0_source.addr],
|
|
283
|
+
space: destSpace,
|
|
284
|
+
});
|
|
285
|
+
iReckon(sir, beta_dest).asTo('beta exists in dest').isGonnaBeTruthy();
|
|
286
|
+
});
|
|
287
|
+
await ifWe(sir, 'sessionIdentity evolved for Round 2', async () => {
|
|
288
|
+
const latestS = peerR2.currentSessionIdentity;
|
|
289
|
+
iReckon(sir, latestS).asTo('session identity exists').isGonnaBeTruthy();
|
|
290
|
+
if (latestS) {
|
|
291
|
+
iReckon(sir, latestS.data?.n).asTo('session identity data.n').isGonnaBe(3);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
// Fetch evolved user identity from space
|
|
296
|
+
const latestSenderIdentityAddrR2 = await metaspace.getLatestAddr({
|
|
297
|
+
addr: getIbGibAddr({ ibGib: r1_senderIdentity_v0_source }),
|
|
298
|
+
space: sourceSpace,
|
|
299
|
+
});
|
|
300
|
+
if (!latestSenderIdentityAddrR2) {
|
|
301
|
+
throw new Error("Could not find latest sender identity after R2");
|
|
302
|
+
}
|
|
303
|
+
const resGetSenderIR2 = await getFromSpace({ space: sourceSpace, addr: latestSenderIdentityAddrR2 });
|
|
304
|
+
senderIdentityLatestSource = resGetSenderIR2.ibGibs[0];
|
|
305
|
+
// Copy/register evolved user identity to dest space
|
|
306
|
+
await metaspace.put({ ibGib: senderIdentityLatestSource, space: destSpace });
|
|
307
|
+
await metaspace.registerNewIbGib({ ibGib: senderIdentityLatestSource, space: destSpace });
|
|
308
|
+
// #endregion Round 2: Create Divergence
|
|
309
|
+
// #region Round 3: Multiple Timeline Conflicts
|
|
310
|
+
const _r3 = testTransformer.newRound({
|
|
311
|
+
name: 'r3_multiple_timeline_conflicts',
|
|
312
|
+
description: 'Both alpha AND beta have divergent edits on source vs dest - tests multiple simultaneous grafts'
|
|
313
|
+
});
|
|
314
|
+
// #region r3 source edits
|
|
315
|
+
const resGet_r3_alpha_source = await getFromSpace({ space: sourceSpace, addr: alpha_tjpAddr });
|
|
316
|
+
const r3_alpha_v3_graftPoint = resGet_r3_alpha_source.ibGibs[0];
|
|
317
|
+
const beta_tjpAddr = getTjpAddr({ ibGib: r2_beta_v0_source.ibGib, defaultIfNone: 'incomingAddr' });
|
|
318
|
+
const resGet_r3_beta_source = await getFromSpace({ space: sourceSpace, addr: beta_tjpAddr });
|
|
319
|
+
const r3_beta_v0_graftPoint = resGet_r3_beta_source.ibGibs[0];
|
|
320
|
+
// Mutate alpha fieldC on source
|
|
321
|
+
const r3_alpha_v4_source_mut8fieldC = await testTransformer.mut8({
|
|
322
|
+
ibGib: r3_alpha_v3_graftPoint,
|
|
323
|
+
in: 'source',
|
|
324
|
+
strField: 'fieldC',
|
|
325
|
+
name: 'r3_alpha_v4_source_mut8fieldC',
|
|
326
|
+
comments_snake_plus_CamelCase: 'postGraft',
|
|
327
|
+
});
|
|
328
|
+
// Mutate beta betaFieldA on source
|
|
329
|
+
const r3_beta_v1_source = await testTransformer.mut8({
|
|
330
|
+
ibGib: r3_beta_v0_graftPoint,
|
|
331
|
+
in: 'source',
|
|
332
|
+
strField: 'betaFieldA',
|
|
333
|
+
name: 'r3_beta_v1_source',
|
|
334
|
+
});
|
|
335
|
+
// #endregion r3 source edits
|
|
336
|
+
// #region r3 dest edits
|
|
337
|
+
const resGet_r3_alpha_dest = await getFromSpace({ space: destSpace, addr: alpha_tjpAddr });
|
|
338
|
+
const r3_alpha_v3_graftPoint_fromDest = resGet_r3_alpha_dest.ibGibs[0];
|
|
339
|
+
const resGet_r3_beta_dest = await getFromSpace({ space: destSpace, addr: beta_tjpAddr });
|
|
340
|
+
const r3_beta_v0_graftPoint_fromDest = resGet_r3_beta_dest.ibGibs[0];
|
|
341
|
+
// Mutate alpha fieldD on dest
|
|
342
|
+
const r3_alpha_v4_dest_mut8fieldD = await testTransformer.mut8({
|
|
343
|
+
ibGib: r3_alpha_v3_graftPoint_fromDest,
|
|
344
|
+
in: 'dest',
|
|
345
|
+
strField: 'fieldD',
|
|
346
|
+
name: 'r3_alpha_v4_dest_mut8fieldD',
|
|
347
|
+
comments_snake_plus_CamelCase: 'postGraft',
|
|
348
|
+
});
|
|
349
|
+
// Mutate beta betaFieldB on dest
|
|
350
|
+
const r3_beta_v1_dest = await testTransformer.mut8({
|
|
351
|
+
ibGib: r3_beta_v0_graftPoint_fromDest,
|
|
352
|
+
in: 'dest',
|
|
353
|
+
strField: 'betaFieldB',
|
|
354
|
+
name: 'r3_beta_v1_dest',
|
|
355
|
+
});
|
|
356
|
+
// #endregion r3 dest edits
|
|
357
|
+
await respecfully(sir, `r3 verify pre`, async () => {
|
|
358
|
+
await ifWe(sir, 'dest has both alpha and beta tips', async () => {
|
|
359
|
+
const destKV = await receiverCoordinator.getKnowledgeMap({
|
|
360
|
+
space: destSpace,
|
|
361
|
+
metaspace,
|
|
362
|
+
domainIbGibs: [r3_alpha_v3_graftPoint_fromDest, r3_beta_v0_graftPoint_fromDest]
|
|
363
|
+
});
|
|
364
|
+
iReckon(sir, !!destKV[alpha_tjpAddr]).isGonnaBeTruthy();
|
|
365
|
+
iReckon(sir, !!destKV[beta_tjpAddr]).isGonnaBeTruthy();
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
const peerR3 = await newTestPeer();
|
|
369
|
+
const r3_syncSaga = await senderCoordinator.sync({
|
|
370
|
+
peer: peerR3,
|
|
371
|
+
localSpace: sourceSpace,
|
|
372
|
+
metaspace,
|
|
373
|
+
domainIbGibs: [r3_alpha_v4_source_mut8fieldC.ibGib, r3_beta_v1_source.ibGib],
|
|
374
|
+
conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
|
|
375
|
+
senderIdentity: senderIdentityLatestSource,
|
|
376
|
+
fnSenderSecret: async () => SENDER_SECRET,
|
|
377
|
+
});
|
|
378
|
+
await r3_syncSaga.done;
|
|
379
|
+
await respecfully(sir, `r3 verify post`, async () => {
|
|
380
|
+
const alpha_sourceKV_afterR3 = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
|
|
381
|
+
const r3_alpha_source_tipAddr = alpha_sourceKV_afterR3[alpha_tjpAddr];
|
|
382
|
+
const alpha_destKV_afterR3 = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
|
|
383
|
+
const r3_alpha_dest_tipAddr = alpha_destKV_afterR3[alpha_tjpAddr];
|
|
384
|
+
const beta_sourceKV_afterR3 = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r2_beta_v0_source.ibGib] });
|
|
385
|
+
const r3_beta_source_tipAddr = beta_sourceKV_afterR3[beta_tjpAddr];
|
|
386
|
+
const beta_destKV_afterR3 = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r2_beta_v0_source.ibGib] });
|
|
387
|
+
const r3_beta_dest_tipAddr = beta_destKV_afterR3[beta_tjpAddr];
|
|
388
|
+
await ifWe(sir, 'r3 tip addrs match (both timelines)', async () => {
|
|
389
|
+
iReckon(sir, r3_alpha_source_tipAddr).asTo('alpha tip').isGonnaBe(r3_alpha_dest_tipAddr);
|
|
390
|
+
iReckon(sir, r3_beta_source_tipAddr).asTo('beta tip').isGonnaBe(r3_beta_dest_tipAddr);
|
|
391
|
+
});
|
|
392
|
+
const resGet_r3_alpha_tip = await getFromSpace({ space: sourceSpace, addr: r3_alpha_source_tipAddr });
|
|
393
|
+
const r3_alpha_tipIbGib = resGet_r3_alpha_tip.ibGibs[0];
|
|
394
|
+
const resGet_r3_beta_tip = await getFromSpace({ space: sourceSpace, addr: r3_beta_source_tipAddr });
|
|
395
|
+
const r3_beta_tipIbGib = resGet_r3_beta_tip.ibGibs[0];
|
|
396
|
+
await ifWe(sir, 'r3 alpha merge has all four fields (commonField, fieldA, fieldB, fieldC, fieldD)', async () => {
|
|
397
|
+
const r3_alpha_v4_source_mut8Info = r3_alpha_v4_source_mut8fieldC.infos[0];
|
|
398
|
+
const r3_alpha_v4_dest_mut8Info = r3_alpha_v4_dest_mut8fieldD.infos[0];
|
|
399
|
+
iReckon(sir, r3_alpha_tipIbGib.data[r3_alpha_v4_source_mut8Info.key]).isGonnaBe(r3_alpha_v4_source_mut8Info.value);
|
|
400
|
+
iReckon(sir, r3_alpha_tipIbGib.data[r3_alpha_v4_dest_mut8Info.key]).isGonnaBe(r3_alpha_v4_dest_mut8Info.value);
|
|
401
|
+
});
|
|
402
|
+
await ifWe(sir, 'r3 beta merge has both fields (betaFieldA, betaFieldB)', async () => {
|
|
403
|
+
const r3_source_beta_mut8Info = r3_beta_v1_source.infos[0];
|
|
404
|
+
const r3_dest_beta_mut8Info = r3_beta_v1_dest.infos[0];
|
|
405
|
+
iReckon(sir, r3_beta_tipIbGib.data[r3_source_beta_mut8Info.key]).isGonnaBe(r3_source_beta_mut8Info.value);
|
|
406
|
+
iReckon(sir, r3_beta_tipIbGib.data[r3_dest_beta_mut8Info.key]).isGonnaBe(r3_dest_beta_mut8Info.value);
|
|
407
|
+
});
|
|
408
|
+
await ifWe(sir, 'sessionIdentity evolved for Round 3', async () => {
|
|
409
|
+
const latestS = peerR3.currentSessionIdentity;
|
|
410
|
+
iReckon(sir, latestS).asTo('session identity exists').isGonnaBeTruthy();
|
|
411
|
+
if (latestS) {
|
|
412
|
+
iReckon(sir, latestS.data?.n).asTo('session identity data.n').isGonnaBe(3);
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
// Fetch evolved user identity from space
|
|
417
|
+
const latestSenderIdentityAddrR3 = await metaspace.getLatestAddr({
|
|
418
|
+
addr: getIbGibAddr({ ibGib: r1_senderIdentity_v0_source }),
|
|
419
|
+
space: sourceSpace,
|
|
420
|
+
});
|
|
421
|
+
if (!latestSenderIdentityAddrR3) {
|
|
422
|
+
throw new Error("Could not find latest sender identity after R3");
|
|
423
|
+
}
|
|
424
|
+
const resGetSenderIR3 = await getFromSpace({ space: sourceSpace, addr: latestSenderIdentityAddrR3 });
|
|
425
|
+
senderIdentityLatestSource = resGetSenderIR3.ibGibs[0];
|
|
426
|
+
// Copy/register evolved user identity to dest space
|
|
427
|
+
await metaspace.put({ ibGib: senderIdentityLatestSource, space: destSpace });
|
|
428
|
+
await metaspace.registerNewIbGib({ ibGib: senderIdentityLatestSource, space: destSpace });
|
|
429
|
+
// #endregion Round 3: Multiple Timeline Conflicts
|
|
430
|
+
// #region Round 4: Chain Edits After Graft
|
|
431
|
+
const _r4 = testTransformer.newRound({
|
|
432
|
+
name: 'r4_chain_edits_after_graft',
|
|
433
|
+
description: 'Post-graft chain edits: mut8 → create gamma → rel8 gamma → mut8 again, tests continued editing on grafted timelines'
|
|
434
|
+
});
|
|
435
|
+
// #region r4 source edits
|
|
436
|
+
const resGet_r4_alpha_source = await getFromSpace({ space: sourceSpace, addr: alpha_tjpAddr });
|
|
437
|
+
const r4_alpha_v4_graftPoint = resGet_r4_alpha_source.ibGibs[0];
|
|
438
|
+
// Mutate alpha v5 (fieldE) from R3 graft point
|
|
439
|
+
const r4_alpha_v5_source = await testTransformer.mut8({
|
|
440
|
+
ibGib: r4_alpha_v4_graftPoint,
|
|
441
|
+
in: 'source',
|
|
442
|
+
strField: 'fieldE',
|
|
443
|
+
name: 'r4_alpha_v5_source',
|
|
444
|
+
comments_snake_plus_CamelCase: 'postGraft2',
|
|
445
|
+
});
|
|
446
|
+
// Create new gamma timeline
|
|
447
|
+
const r4_gamma_v0_source = await testTransformer.create({
|
|
448
|
+
atom: 'gamma',
|
|
449
|
+
in: 'source',
|
|
450
|
+
data: { gammaField: 'gamma created on source' },
|
|
451
|
+
name: 'r4_gamma_v0_source'
|
|
452
|
+
});
|
|
453
|
+
// Relate alpha to gamma (creates v6)
|
|
454
|
+
const r4_alpha_v6_source_rel8dGamma = await testTransformer.rel8({
|
|
455
|
+
stepInfo: r4_alpha_v5_source,
|
|
456
|
+
in: 'source',
|
|
457
|
+
targetIbGibs: [r4_gamma_v0_source.ibGib],
|
|
458
|
+
rel8nName: TEST_REL8N_NAME,
|
|
459
|
+
name: 'r4_alpha_v6_source_rel8dGamma'
|
|
460
|
+
});
|
|
461
|
+
// Mutate alpha again v7 (fieldF)
|
|
462
|
+
const r4_alpha_v7_source = await testTransformer.mut8({
|
|
463
|
+
ibGib: r4_alpha_v6_source_rel8dGamma.ibGib,
|
|
464
|
+
in: 'source',
|
|
465
|
+
strField: 'fieldF',
|
|
466
|
+
name: 'r4_alpha_v7_source',
|
|
467
|
+
comments_snake_plus_CamelCase: 'chainEnd',
|
|
468
|
+
});
|
|
469
|
+
// Retrieve beta R3 graft point from source
|
|
470
|
+
const resGet_r4_beta_source = await getFromSpace({ space: sourceSpace, addr: beta_tjpAddr });
|
|
471
|
+
const r4_beta_v1_graftPoint = resGet_r4_beta_source.ibGibs[0];
|
|
472
|
+
// Mutate beta v2 (betaFieldD) on source
|
|
473
|
+
const r4_beta_v2_source = await testTransformer.mut8({
|
|
474
|
+
ibGib: r4_beta_v1_graftPoint,
|
|
475
|
+
in: 'source',
|
|
476
|
+
strField: 'betaFieldD',
|
|
477
|
+
name: 'r4_beta_v2_source',
|
|
478
|
+
});
|
|
479
|
+
// #endregion r4 source edits
|
|
480
|
+
// #region r4 dest edits
|
|
481
|
+
// Retrieve alpha R3 graft point from dest
|
|
482
|
+
const resGet_r4_alpha_dest = await getFromSpace({ space: destSpace, addr: alpha_tjpAddr });
|
|
483
|
+
const r4_alpha_v4_graftPoint_fromDest = resGet_r4_alpha_dest.ibGibs[0];
|
|
484
|
+
// Mutate alpha v5 (fieldG) from R3 graft point
|
|
485
|
+
const r4_alpha_v5_dest = await testTransformer.mut8({
|
|
486
|
+
ibGib: r4_alpha_v4_graftPoint_fromDest,
|
|
487
|
+
in: 'dest',
|
|
488
|
+
strField: 'fieldG',
|
|
489
|
+
name: 'r4_alpha_v5_dest',
|
|
490
|
+
comments_snake_plus_CamelCase: 'postGraft2',
|
|
491
|
+
});
|
|
492
|
+
// Retrieve beta R3 graft point from dest
|
|
493
|
+
const resGet_r4_beta_dest = await getFromSpace({ space: destSpace, addr: beta_tjpAddr });
|
|
494
|
+
const r4_beta_v1_graftPoint_fromDest = resGet_r4_beta_dest.ibGibs[0];
|
|
495
|
+
// Mutate beta v2 (betaFieldC) on dest
|
|
496
|
+
const r4_beta_v2_dest = await testTransformer.mut8({
|
|
497
|
+
ibGib: r4_beta_v1_graftPoint_fromDest,
|
|
498
|
+
in: 'dest',
|
|
499
|
+
strField: 'betaFieldC',
|
|
500
|
+
name: 'r4_beta_v2_dest',
|
|
501
|
+
});
|
|
502
|
+
// #endregion r4 dest edits
|
|
503
|
+
await respecfully(sir, `r4 verify pre`, async () => {
|
|
504
|
+
await ifWe(sir, 'dest has alpha and beta post-R3 tips', async () => {
|
|
505
|
+
const destKV = await receiverCoordinator.getKnowledgeMap({
|
|
506
|
+
space: destSpace,
|
|
507
|
+
metaspace,
|
|
508
|
+
domainIbGibs: [r4_alpha_v4_graftPoint_fromDest, r4_beta_v1_graftPoint_fromDest]
|
|
509
|
+
});
|
|
510
|
+
iReckon(sir, !!destKV[alpha_tjpAddr]).isGonnaBeTruthy();
|
|
511
|
+
iReckon(sir, !!destKV[beta_tjpAddr]).isGonnaBeTruthy();
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
const peerR4 = await newTestPeer();
|
|
515
|
+
const r4_syncSaga = await senderCoordinator.sync({
|
|
516
|
+
peer: peerR4,
|
|
517
|
+
localSpace: sourceSpace,
|
|
518
|
+
metaspace,
|
|
519
|
+
domainIbGibs: [r4_alpha_v7_source.ibGib, r4_gamma_v0_source.ibGib, r4_beta_v2_source.ibGib],
|
|
520
|
+
conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
|
|
521
|
+
senderIdentity: senderIdentityLatestSource,
|
|
522
|
+
fnSenderSecret: async () => SENDER_SECRET,
|
|
523
|
+
});
|
|
524
|
+
await r4_syncSaga.done;
|
|
525
|
+
await respecfully(sir, `r4 verify post`, async () => {
|
|
526
|
+
const gamma_tjpAddr = getTjpAddr({ ibGib: r4_gamma_v0_source.ibGib, defaultIfNone: 'incomingAddr' });
|
|
527
|
+
const r4_alpha_sourceKV = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
|
|
528
|
+
const r4_alpha_source_tipAddr = r4_alpha_sourceKV[alpha_tjpAddr];
|
|
529
|
+
const r4_alpha_destKV = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
|
|
530
|
+
const r4_alpha_dest_tipAddr = r4_alpha_destKV[alpha_tjpAddr];
|
|
531
|
+
const r4_beta_sourceKV = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r2_beta_v0_source.ibGib] });
|
|
532
|
+
const r4_beta_source_tipAddr = r4_beta_sourceKV[beta_tjpAddr];
|
|
533
|
+
const r4_beta_destKV = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r2_beta_v0_source.ibGib] });
|
|
534
|
+
const r4_beta_dest_tipAddr = r4_beta_destKV[beta_tjpAddr];
|
|
535
|
+
const r4_gamma_sourceKV = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r4_gamma_v0_source.ibGib] });
|
|
536
|
+
const r4_gamma_source_tipAddr = r4_gamma_sourceKV[gamma_tjpAddr];
|
|
537
|
+
const r4_gamma_destKV = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r4_gamma_v0_source.ibGib] });
|
|
538
|
+
const r4_gamma_dest_tipAddr = r4_gamma_destKV[gamma_tjpAddr];
|
|
539
|
+
await ifWe(sir, 'r4 tip addrs match (alpha, beta, gamma)', async () => {
|
|
540
|
+
iReckon(sir, r4_alpha_source_tipAddr).asTo('alpha tip').isGonnaBe(r4_alpha_dest_tipAddr);
|
|
541
|
+
iReckon(sir, r4_beta_source_tipAddr).asTo('beta tip').isGonnaBe(r4_beta_dest_tipAddr);
|
|
542
|
+
iReckon(sir, r4_gamma_source_tipAddr).asTo('gamma tip').isGonnaBe(r4_gamma_dest_tipAddr);
|
|
543
|
+
});
|
|
544
|
+
const resGet_r4_alpha_tip = await getFromSpace({ space: sourceSpace, addr: r4_alpha_source_tipAddr });
|
|
545
|
+
const r4_alpha_tipIbGib = resGet_r4_alpha_tip.ibGibs[0];
|
|
546
|
+
const resGet_r4_beta_tip = await getFromSpace({ space: sourceSpace, addr: r4_beta_source_tipAddr });
|
|
547
|
+
const r4_beta_tipIbGib = resGet_r4_beta_tip.ibGibs[0];
|
|
548
|
+
await ifWe(sir, 'r4 alpha has complete chain of edits and gamma relation', async () => {
|
|
549
|
+
const r4_source_alpha_v5_mut8Info = r4_alpha_v5_source.infos[0];
|
|
550
|
+
const r4_source_alpha_v7_mut8Info = r4_alpha_v7_source.infos[0];
|
|
551
|
+
const r4_dest_alpha_mut8Info = r4_alpha_v5_dest.infos[0];
|
|
552
|
+
iReckon(sir, r4_alpha_tipIbGib.data[r4_source_alpha_v5_mut8Info.key]).isGonnaBe(r4_source_alpha_v5_mut8Info.value);
|
|
553
|
+
iReckon(sir, r4_alpha_tipIbGib.data[r4_source_alpha_v7_mut8Info.key]).isGonnaBe(r4_source_alpha_v7_mut8Info.value);
|
|
554
|
+
iReckon(sir, r4_alpha_tipIbGib.data[r4_dest_alpha_mut8Info.key]).isGonnaBe(r4_dest_alpha_mut8Info.value);
|
|
555
|
+
const gammaAddr = getIbGibAddr({ ibGib: r4_gamma_v0_source.ibGib });
|
|
556
|
+
const alphaRel8ns = r4_alpha_tipIbGib.rel8ns?.[TEST_REL8N_NAME] || [];
|
|
557
|
+
iReckon(sir, alphaRel8ns.includes(gammaAddr)).isGonnaBeTrue();
|
|
558
|
+
});
|
|
559
|
+
await ifWe(sir, 'r4 beta has all edits', async () => {
|
|
560
|
+
const r4_source_beta_mut8Info = r4_beta_v2_source.infos[0];
|
|
561
|
+
const r4_dest_beta_mut8Info = r4_beta_v2_dest.infos[0];
|
|
562
|
+
iReckon(sir, r4_beta_tipIbGib.data[r4_source_beta_mut8Info.key]).isGonnaBe(r4_source_beta_mut8Info.value);
|
|
563
|
+
iReckon(sir, r4_beta_tipIbGib.data[r4_dest_beta_mut8Info.key]).isGonnaBe(r4_dest_beta_mut8Info.value);
|
|
564
|
+
});
|
|
565
|
+
await ifWe(sir, 'r4 gamma synced with deps', async () => {
|
|
566
|
+
const [gamma_dest] = await getIbGibsFromCache_fallbackToSpaces({
|
|
567
|
+
addrs: [r4_gamma_v0_source.addr],
|
|
568
|
+
space: destSpace,
|
|
569
|
+
});
|
|
570
|
+
iReckon(sir, gamma_dest).asTo('gamma exists in dest').isGonnaBeTruthy();
|
|
571
|
+
});
|
|
572
|
+
await ifWe(sir, 'sessionIdentity evolved for Round 4', async () => {
|
|
573
|
+
const latestS = peerR4.currentSessionIdentity;
|
|
574
|
+
iReckon(sir, latestS).asTo('session identity exists').isGonnaBeTruthy();
|
|
575
|
+
if (latestS) {
|
|
576
|
+
iReckon(sir, latestS.data?.n).asTo('session identity data.n').isGonnaBe(3);
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
});
|
|
580
|
+
// #endregion Round 4: Chain Edits After Graft
|
|
581
|
+
});
|
|
582
|
+
//# sourceMappingURL=sync-conflict-adv-multitimelines.withid.respec.mjs.map
|