@ibgib/space-gib 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +20 -0
  2. package/dist/client/bootstrap.mjs +31 -31
  3. package/dist/client/bootstrap.mjs.map +3 -3
  4. package/dist/client/chunk-RXFIBFRK.mjs +42 -0
  5. package/dist/client/chunk-RXFIBFRK.mjs.map +7 -0
  6. package/dist/client/chunk-ULFNE26Y.mjs +2216 -0
  7. package/dist/client/chunk-ULFNE26Y.mjs.map +7 -0
  8. package/dist/client/index.html +35 -14
  9. package/dist/client/index.mjs +1 -1
  10. package/dist/client/script.mjs +1 -1
  11. package/dist/client/style.css +29 -5
  12. package/dist/server/server.mjs +1447 -270
  13. package/dist/server/server.mjs.map +4 -4
  14. package/package.json +5 -5
  15. package/space-gib.localhost-1783713259760.log +45 -0
  16. package/src/client/AUTO-GENERATED-version.mts +1 -1
  17. package/src/client/bootstrap.mts +9 -0
  18. package/src/client/components/identity-header/identity-header.css +40 -2
  19. package/src/client/components/identity-header/identity-header.html +3 -2
  20. package/src/client/components/identity-header/identity-header.mts +127 -49
  21. package/src/client/components/identity-manager/identity-manager.css +57 -353
  22. package/src/client/components/identity-manager/identity-manager.html +0 -94
  23. package/src/client/components/identity-manager/identity-manager.mts +356 -484
  24. package/src/client/components/keystone-creator/keystone-creator.mts +90 -13
  25. package/src/client/components/keystone-details/keystone-details.css +472 -0
  26. package/src/client/components/keystone-details/keystone-details.html +99 -0
  27. package/src/client/components/keystone-details/keystone-details.mts +821 -0
  28. package/src/client/components/keystone-scrubber/SCRUBBER_IMPLEMENTATION.md +33 -0
  29. package/src/client/components/keystone-scrubber/keystone-scrubber.css +46 -0
  30. package/src/client/components/keystone-scrubber/keystone-scrubber.html +15 -0
  31. package/src/client/components/keystone-scrubber/keystone-scrubber.mts +356 -0
  32. package/src/client/dev-tools/common.mts +505 -10
  33. package/src/client/dev-tools/phase-4-1.mts +19 -4
  34. package/src/client/dev-tools/phase-4-10.mts +77 -305
  35. package/src/client/dev-tools/phase-4-2.mts +46 -212
  36. package/src/client/dev-tools/phase-4-3.mts +57 -198
  37. package/src/client/dev-tools/phase-4-4.mts +57 -170
  38. package/src/client/dev-tools/phase-4-5.mts +48 -204
  39. package/src/client/dev-tools/phase-4-6.mts +37 -103
  40. package/src/client/dev-tools/phase-4-7.mts +44 -228
  41. package/src/client/dev-tools/phase-4-8.mts +33 -136
  42. package/src/client/dev-tools/phase-4-9.mts +33 -137
  43. package/src/client/dev-tools/phase-4.mts +30 -6
  44. package/src/client/dev-tools.mts +18 -0
  45. package/src/client/index.html +35 -14
  46. package/src/client/style.css +29 -5
  47. package/src/client/types.mts +4 -1
  48. package/src/client/ui/shell/space-gib-shell-service.mts +4 -0
  49. package/src/server/path-constants.mts +12 -0
  50. package/src/server/serve-gib/handlers/api/keystone/sso-config.handler.mts +66 -0
  51. package/src/server/serve-gib/handlers/api/keystone/sso-link.handler.mts +119 -0
  52. package/src/server/serve-gib/handlers/api/keystone/sso-login.handler.mts +189 -0
  53. package/src/server/server.mts +6 -0
  54. package/dist/client/chunk-ANGVYAEK.mjs +0 -42
  55. package/dist/client/chunk-ANGVYAEK.mjs.map +0 -7
  56. package/dist/client/chunk-IRGFDQRD.mjs +0 -1920
  57. package/dist/client/chunk-IRGFDQRD.mjs.map +0 -7
  58. package/dist/respec-gib.node.mjs +0 -5
@@ -1,140 +1,75 @@
1
- import { extractErrorMsg, getUUID, getTimestamp } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
1
+ import { extractErrorMsg, getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
2
2
  import { Factory_V1 as factory } from '@ibgib/ts-gib/dist/V1/factory.mjs';
3
3
  import { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';
4
4
  import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
5
5
  import { KeystoneIbGib_V1 } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';
6
- import { KeystoneService_V1 } from '@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs';
7
6
  import { getGlobalMetaspace_waitIfNeeded } from "@ibgib/web-gib/dist/helpers.mjs";
8
7
  import { mut8Timeline } from '@ibgib/core-gib/dist/timeline/timeline-api.mjs';
9
8
  import { graphsAreEquivalent } from '@ibgib/core-gib/dist/common/other/graph-helper.mjs';
10
- import { SyncPeerWebSocketSender_V1 } from '@ibgib/core-gib/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs';
11
- import { SyncSagaCoordinator } from '@ibgib/core-gib/dist/sync/sync-saga-coordinator.mjs';
12
- import { SyncConflictStrategy } from '@ibgib/core-gib/dist/sync/sync-constants.mjs';
13
- import { SESSION_KEYSTONE_POLICY, getSpaceGibPoolConfig } from "../../common/keystone-policies.mjs";
14
9
  import { SpaceGibApiBridge } from '../api/space-gib-api-bridge.mjs';
15
10
 
16
- import { debugState, devLog, lc } from './common.mjs';
11
+ import {
12
+ debugState, devLog, lc,
13
+ setupDomainAndDelegateIdentities, runSyncPass, runSyncPassFromSpace, copyIdentitiesToSpace
14
+ } from './common.mjs';
17
15
 
18
- // Extend debugState to support our phase-specific storage
16
+ // Phase-specific state for items that don't fit in debugState
19
17
  interface Phase45State {
20
- domainI_latest?: KeystoneIbGib_V1;
21
- targetV1?: any;
22
18
  targetV2?: any;
23
19
  }
24
-
25
20
  const state: Phase45State = {};
26
21
 
22
+ const MASTER_SECRET = 'test-sender-secret-phase4-5b';
23
+
27
24
  export function init4_5bSetupButton(): void {
28
25
  const btn = document.getElementById('btn-4-5b-setup') as HTMLButtonElement | null;
29
26
  if (!btn) { return; }
30
27
  btn.addEventListener('click', async () => {
31
28
  try {
32
29
  btn.disabled = true;
33
- devLog('4.5B Setup: Generating Domain Keystone (I) and Target timeline V0 -> V1 in default local space...');
30
+ devLog('4.5B Setup: Generating Domain Keystone (I), target timeline, and seeding server from two spaces...');
34
31
 
35
32
  const metaspace = await getGlobalMetaspace_waitIfNeeded();
36
33
  const space = await metaspace.getLocalUserSpace({});
37
34
  if (!space) { throw new Error("No default space."); }
38
35
 
39
- const keystoneService = new KeystoneService_V1();
36
+ const apiBridge = new SpaceGibApiBridge();
40
37
 
41
- // 1. Generate Domain Keystone (I) locally in default space
42
- const domainI = await keystoneService.genesis({
43
- masterSecret: 'test-sender-secret-phase4-5b',
44
- configs: [
45
- getSpaceGibPoolConfig('sync', 'senderidentitysyncsaltphase4-5b'),
46
- getSpaceGibPoolConfig('manage', 'senderidentitymanagesaltphase4-5b'),
47
- ],
48
- metaspace,
49
- space,
50
- frameDetails: { client: 'space-gib-web-dev', timestamp: getTimestamp() }
38
+ // 1. Create domain + delegate identities (DRY helper)
39
+ await setupDomainAndDelegateIdentities({
40
+ masterSecret: MASTER_SECRET,
41
+ syncSalt: 'senderidentitysyncsaltphase4-5b',
42
+ manageSalt: 'senderidentitymanagesaltphase4-5b',
43
+ metaspace, space, apiBridge,
44
+ phaseText: '4.5B'
51
45
  });
52
46
 
53
- debugState.domainI = domainI;
54
- debugState.domainIMasterSecret = 'test-sender-secret-phase4-5b';
55
-
56
- devLog(`4.5B Setup: ✓ Domain Keystone (I) created locally: ${getIbGibAddr({ ibGib: domainI })}`);
57
-
58
- // 2. Post Genesis Domain Keystone to server
59
- const apiBridge = new SpaceGibApiBridge();
60
- const resGenesis = await apiBridge.postGenesisKeystone(domainI);
61
- if (resGenesis.success) {
62
- devLog(`4.5B Setup: ✓ Domain Keystone registered on server.`);
63
- } else {
64
- throw new Error(`Server rejected genesis domain keystone: ${resGenesis.message}`);
65
- }
66
-
67
- // 3. Create target timeline root V0
47
+ // 2. Create target timeline root V0
68
48
  const resV0 = await factory.firstGen({
69
49
  parentIbGib: ROOT,
70
50
  ib: 'timeline_root_partial_4_5b',
71
51
  data: { type: 'root', label: 'Root4_5b', random: Math.random() },
72
- dna: true,
73
- nCounter: true,
74
- tjp: { uuid: true, timestamp: true }
52
+ dna: true, nCounter: true, tjp: { uuid: true, timestamp: true }
75
53
  });
76
54
  const r1_v0 = resV0.newIbGib;
77
55
  await metaspace.persistTransformResult({ resTransform: resV0, space });
78
56
  await metaspace.registerNewIbGib({ ibGib: r1_v0, space });
79
57
 
80
- // 4. Mutate V0 -> V1 in default space
58
+ // 3. Mutate V0 V1 in default space
81
59
  const r1_v1 = await mut8Timeline({
82
60
  timeline: r1_v0,
83
61
  mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'V1_4_5b' } },
84
- metaspace,
85
- space,
62
+ metaspace, space,
86
63
  });
87
- state.targetV1 = r1_v1;
88
-
64
+ debugState.targetC1 = r1_v1;
89
65
  devLog(`4.5B Setup: ✓ Local timeline V0 -> V1 created. V1 Tip: ${getIbGibAddr({ ibGib: r1_v1 })}`);
90
66
 
91
- // 5. Run Pass 1 Sync from default local space to server via WebSocket to seed V1 on the server
67
+ // 4. Sync V1 to server from default space (Pass 1 seeds V1 on the server)
92
68
  devLog('4.5B Setup: Seeding V1 to the server via WebSocket...');
93
- const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
94
- const domainAddr = getIbGibAddr({ ibGib: domainI });
95
-
96
- const senderPeer1 = new SyncPeerWebSocketSender_V1({
97
- classname: 'SyncPeerWebSocketSender_V1',
98
- httpEvolveUrl: `${location.protocol}//${location.host}/api/keystone/evolve/${encodeURIComponent(domainAddr)}`,
99
- wsUrl: `${protocol}//${location.host}/api/sync/ws/${encodeURIComponent(domainAddr)}`
100
- });
101
-
102
- const coordinator1 = new SyncSagaCoordinator();
103
- const sagaId1 = await getUUID();
104
-
105
- await senderPeer1.initializeOpts({
106
- localMetaspace: metaspace,
107
- localSpace: space,
108
- senderIdentity: domainI,
109
- fnSenderSecret: async () => 'test-sender-secret-phase4-5b',
110
- sagaId: sagaId1,
111
- sessionConnectPoolConfig: SESSION_KEYSTONE_POLICY.CONNECT_POOL as any,
112
- sessionSyncPoolConfig: SESSION_KEYSTONE_POLICY.DEFAULT_POOL as any,
113
- targetAddrs: [domainAddr]
114
- });
115
-
116
- const syncSaga1 = await coordinator1.sync({
117
- domainIbGibs: [r1_v1],
118
- senderIdentity: domainI,
119
- fnSenderSecret: async () => 'test-sender-secret-phase4-5b',
120
- peer: senderPeer1,
121
- localSpace: space,
122
- metaspace,
123
- conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
124
- });
125
- await syncSaga1.done;
69
+ await runSyncPass({ domainIbGibs: [r1_v1], passLabel: 'Seed V1 to server', metaspace, space });
126
70
  devLog('4.5B Setup: ✓ Pass 1 Sync (V1 to server) complete.');
127
71
 
128
- // 6. Retrieve evolved I tip from default space
129
- const latestSenderAddr1 = await metaspace.getLatestAddr({
130
- addr: domainAddr,
131
- space,
132
- });
133
- if (!latestSenderAddr1) { throw new Error("Could not get latest sender address from default space."); }
134
- const resGetLatestI1 = await metaspace.get({ addrs: [latestSenderAddr1], space });
135
- const senderIdentityEvolved1 = resGetLatestI1.ibGibs![0] as KeystoneIbGib_V1;
136
-
137
- // 7. Create remoteSpace (simulating a remote client)
72
+ // 5. Create remoteSpace (simulating a remote client)
138
73
  devLog('4.5B Setup: Creating secondary local space simulating "remote" client...');
139
74
  const remoteSpaceName = `remote-${await getUUID()}`;
140
75
  const remoteSpace = await metaspace.createNewLocalSpace({
@@ -147,25 +82,16 @@ export function init4_5bSetupButton(): void {
147
82
  if (!remoteSpace) { throw new Error("Failed to create remote space"); }
148
83
  await remoteSpace.initialized;
149
84
 
150
- // 8. Copy V1 and its dependency graph from default space to remoteSpace
151
- const graphV1 = await metaspace.getDependencyGraph({
152
- ibGibAddr: getIbGibAddr({ ibGib: r1_v1 }),
153
- space
154
- });
85
+ // 6. Copy V1 and its dependency graph + identity to remoteSpace
86
+ const graphV1 = await metaspace.getDependencyGraph({ ibGibAddr: getIbGibAddr({ ibGib: r1_v1 }), space });
155
87
  await metaspace.put({ ibGibs: Object.values(graphV1), space: remoteSpace });
156
88
  await metaspace.registerNewIbGib({ ibGib: r1_v1, space: remoteSpace });
157
89
 
158
- // 9. Copy evolved I and its dependency graph from default space to remoteSpace
159
- const graphI1 = await metaspace.getDependencyGraph({
160
- ibGibAddr: latestSenderAddr1,
161
- space
162
- });
163
- await metaspace.put({ ibGibs: Object.values(graphI1), space: remoteSpace });
164
- await metaspace.registerNewIbGib({ ibGib: senderIdentityEvolved1, space: remoteSpace });
90
+ const domainI = debugState.domainI!;
91
+ await copyIdentitiesToSpace({ domainI, metaspace, fromSpace: space, toSpace: remoteSpace });
92
+ devLog('4.5B Setup: ✓ Copied V1 and identities (domain and delegate) to remoteSpace.');
165
93
 
166
- devLog('4.5B Setup: ✓ Copied V1 and identity I to remoteSpace.');
167
-
168
- // 10. Mutate V1 -> V2 in remoteSpace ONLY
94
+ // 7. Mutate V1 V2 in remoteSpace ONLY
169
95
  devLog('4.5B Setup: Mutating V1 -> V2 in remoteSpace...');
170
96
  const r1_v2 = await mut8Timeline({
171
97
  timeline: r1_v1,
@@ -176,56 +102,18 @@ export function init4_5bSetupButton(): void {
176
102
  state.targetV2 = r1_v2;
177
103
  devLog(`4.5B Setup: ✓ Mutated to V2 in remoteSpace: ${getIbGibAddr({ ibGib: r1_v2 })}`);
178
104
 
179
- // 11. Run Pass 2 Sync from remoteSpace to server via WebSocket to push V2
105
+ // 8. Sync V2 from remoteSpace to server (Pass 2 server now has V2)
180
106
  devLog('4.5B Setup: Syncing V2 from remoteSpace to the server...');
181
- const senderPeer2 = new SyncPeerWebSocketSender_V1({
182
- classname: 'SyncPeerWebSocketSender_V1',
183
- httpEvolveUrl: `${location.protocol}//${location.host}/api/keystone/evolve/${encodeURIComponent(domainAddr)}`,
184
- wsUrl: `${protocol}//${location.host}/api/sync/ws/${encodeURIComponent(domainAddr)}`
185
- });
186
-
187
- const coordinator2 = new SyncSagaCoordinator();
188
- const sagaId2 = await getUUID();
189
-
190
- await senderPeer2.initializeOpts({
191
- localMetaspace: metaspace,
192
- localSpace: remoteSpace,
193
- senderIdentity: senderIdentityEvolved1,
194
- fnSenderSecret: async () => 'test-sender-secret-phase4-5b',
195
- sagaId: sagaId2,
196
- sessionConnectPoolConfig: SESSION_KEYSTONE_POLICY.CONNECT_POOL as any,
197
- sessionSyncPoolConfig: SESSION_KEYSTONE_POLICY.DEFAULT_POOL as any,
198
- targetAddrs: [domainAddr]
199
- });
200
-
201
- const syncSaga2 = await coordinator2.sync({
107
+ await runSyncPassFromSpace({
202
108
  domainIbGibs: [r1_v2],
203
- senderIdentity: senderIdentityEvolved1,
204
- fnSenderSecret: async () => 'test-sender-secret-phase4-5b',
205
- peer: senderPeer2,
206
- localSpace: remoteSpace,
109
+ passLabel: 'Seed V2 from remoteSpace',
207
110
  metaspace,
208
- conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
209
- });
210
- await syncSaga2.done;
211
- devLog('4.5B Setup: ✓ Pass 2 Sync (V2 to server) complete.');
212
-
213
- // 12. Copy evolved I tip from remoteSpace back to default space so identity remains synchronized
214
- const latestSenderAddr2 = await metaspace.getLatestAddr({
215
- addr: domainAddr,
216
111
  space: remoteSpace,
112
+ primarySpace: space,
113
+ domainI,
114
+ masterSecret: MASTER_SECRET
217
115
  });
218
- if (!latestSenderAddr2) { throw new Error("Could not get latest sender address from remoteSpace."); }
219
- const resGetLatestI2 = await metaspace.get({ addrs: [latestSenderAddr2], space: remoteSpace });
220
- const senderIdentityEvolved2 = resGetLatestI2.ibGibs![0] as KeystoneIbGib_V1;
221
- state.domainI_latest = senderIdentityEvolved2;
222
-
223
- const graphI2 = await metaspace.getDependencyGraph({
224
- ibGibAddr: latestSenderAddr2,
225
- space: remoteSpace
226
- });
227
- await metaspace.put({ ibGibs: Object.values(graphI2), space });
228
- await metaspace.registerNewIbGib({ ibGib: senderIdentityEvolved2, space });
116
+ devLog('4.5B Setup: Pass 2 Sync (V2 to server) complete. debugState.domainI updated.');
229
117
 
230
118
  devLog('✓ 4.5B Setup Complete! Server has V2, default local space has V1. Ready for 4.5B Sync.');
231
119
  btn.textContent = '✓ 4.5B Setup Complete';
@@ -249,53 +137,20 @@ export function init4_5bSyncButton(): void {
249
137
  btn.disabled = true;
250
138
  devLog('4.5B Sync: Initiating WebSocket Sync from default local space (which has V1, server has V2)...');
251
139
 
252
- const domainI = state.domainI_latest;
253
- const targetV1 = state.targetV1;
254
- if (!domainI || !targetV1) {
140
+ const targetV1 = debugState.targetC1;
141
+ if (!debugState.domainI || !targetV1) {
255
142
  devLog('⚠ 4.5B Sync: Missing setup state. Please run Setup first.');
256
143
  btn.disabled = false;
257
144
  return;
258
145
  }
259
146
 
260
- const domainAddr = getIbGibAddr({ ibGib: domainI });
261
147
  const metaspace = await getGlobalMetaspace_waitIfNeeded();
262
148
  const space = await metaspace.getLocalUserSpace({});
263
149
  if (!space) { throw new Error("No default space."); }
264
150
 
265
- const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
266
-
267
- const senderPeer = new SyncPeerWebSocketSender_V1({
268
- classname: 'SyncPeerWebSocketSender_V1',
269
- httpEvolveUrl: `${location.protocol}//${location.host}/api/keystone/evolve/${encodeURIComponent(domainAddr)}`,
270
- wsUrl: `${protocol}//${location.host}/api/sync/ws/${encodeURIComponent(domainAddr)}`
271
- });
272
-
273
- const coordinator = new SyncSagaCoordinator();
274
- const sagaId = await getUUID();
275
-
276
- await senderPeer.initializeOpts({
277
- localMetaspace: metaspace,
278
- localSpace: space,
279
- senderIdentity: domainI,
280
- fnSenderSecret: async () => 'test-sender-secret-phase4-5b',
281
- sagaId,
282
- sessionConnectPoolConfig: SESSION_KEYSTONE_POLICY.CONNECT_POOL as any,
283
- sessionSyncPoolConfig: SESSION_KEYSTONE_POLICY.DEFAULT_POOL as any,
284
- targetAddrs: [domainAddr]
285
- });
286
-
287
- // Run Sync targeting our local tip V1.
288
- // Since the server is ahead with V2, the coordinator should pull down V2.
289
- const syncSaga = await coordinator.sync({
290
- domainIbGibs: [targetV1],
291
- senderIdentity: domainI,
292
- fnSenderSecret: async () => 'test-sender-secret-phase4-5b',
293
- peer: senderPeer,
294
- localSpace: space,
295
- metaspace,
296
- conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
297
- });
298
- await syncSaga.done;
151
+ // Sync targeting our local tip V1. Since the server is ahead with V2,
152
+ // the coordinator should pull down V2 via delta resolution.
153
+ await runSyncPass({ domainIbGibs: [targetV1], passLabel: 'Pull V2 from server', metaspace, space });
299
154
 
300
155
  devLog('✓ 4.5B Sync Execution Complete! Ready for 4.5B Check.');
301
156
  btn.textContent = '✓ 4.5B Sync Run';
@@ -320,13 +175,14 @@ export function init4_5bCheckButton(): void {
320
175
  devLog('4.5B Check: Verifying that V2 was pulled down to default local space...');
321
176
 
322
177
  const targetV2 = state.targetV2;
323
- if (!targetV2) {
178
+ if (!targetV2 || !debugState.domainI) {
324
179
  devLog('⚠ 4.5B Check: Missing target V2 in state. Did Setup run?');
325
180
  btn.disabled = false;
326
181
  return;
327
182
  }
328
183
 
329
184
  const targetV2Addr = getIbGibAddr({ ibGib: targetV2 });
185
+ const domainAddr = getIbGibAddr({ ibGib: debugState.domainI });
330
186
  const metaspace = await getGlobalMetaspace_waitIfNeeded();
331
187
  const space = await metaspace.getLocalUserSpace({});
332
188
  if (!space) { throw new Error("No default space."); }
@@ -339,27 +195,15 @@ export function init4_5bCheckButton(): void {
339
195
  const localV2 = resGetV2.ibGibs[0];
340
196
  devLog(`4.5B Check: ✓ V2 Tip found locally. Label: "${localV2.data?.label}"`);
341
197
 
342
- // 2. Fetch full dependency graph of V2 from local space
343
- const localGraph = await metaspace.getDependencyGraph({
344
- ibGibAddr: targetV2Addr,
345
- space
346
- });
347
-
348
- // 3. Fetch full dependency graph of V2 from the server
198
+ // 2. Fetch full dependency graph of V2 from local space and server, assert equivalence
199
+ const localGraph = await metaspace.getDependencyGraph({ ibGibAddr: targetV2Addr, space });
349
200
  devLog('4.5B Check: Fetching V2 dependency graph from server...');
350
- const domainAddr = getIbGibAddr({ ibGib: state.domainI_latest! });
351
201
  const apiBridge = new SpaceGibApiBridge();
352
202
  const resServerGraph = await apiBridge.getIbGibGraph(domainAddr, targetV2Addr, true);
353
203
  if (!resServerGraph.success || !resServerGraph.graph) {
354
204
  throw new Error(`Failed to fetch V2 graph from server: ${resServerGraph.message}`);
355
205
  }
356
-
357
- // 4. Assert graphs are equivalent
358
- const equal = graphsAreEquivalent({
359
- graphA: localGraph,
360
- graphB: resServerGraph.graph
361
- });
362
-
206
+ const equal = graphsAreEquivalent({ graphA: localGraph, graphB: resServerGraph.graph });
363
207
  if (equal) {
364
208
  devLog('✓ 4.5B Check SUCCESS: V2 and all dependencies are fully equivalent on client and server!');
365
209
  btn.textContent = '✓ 4.5B Check Success';
@@ -1,78 +1,56 @@
1
- import { extractErrorMsg, getUUID, getTimestamp } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
1
+ import { extractErrorMsg, getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
2
2
  import { Factory_V1 as factory } from '@ibgib/ts-gib/dist/V1/factory.mjs';
3
3
  import { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';
4
4
  import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
5
5
  import { KeystoneIbGib_V1 } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';
6
- import { KeystoneService_V1 } from '@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs';
7
6
  import { getGlobalMetaspace_waitIfNeeded } from "@ibgib/web-gib/dist/helpers.mjs";
8
7
  import { mut8Timeline } from '@ibgib/core-gib/dist/timeline/timeline-api.mjs';
9
8
  import { graphsAreEquivalent } from '@ibgib/core-gib/dist/common/other/graph-helper.mjs';
10
- import { SyncPeerWebSocketSender_V1 } from '@ibgib/core-gib/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs';
11
- import { SyncSagaCoordinator } from '@ibgib/core-gib/dist/sync/sync-saga-coordinator.mjs';
12
- import { SyncConflictStrategy } from '@ibgib/core-gib/dist/sync/sync-constants.mjs';
13
- import { SESSION_KEYSTONE_POLICY, getSpaceGibPoolConfig } from "../../common/keystone-policies.mjs";
14
9
  import { SpaceGibApiBridge } from '../api/space-gib-api-bridge.mjs';
15
10
 
16
- import { debugState, devLog, lc } from './common.mjs';
11
+ import {
12
+ debugState, devLog, lc,
13
+ setupDomainAndDelegateIdentities, runSyncPass
14
+ } from './common.mjs';
17
15
 
18
- // Extend debugState to support our phase-specific storage
16
+ // Phase-specific state for targets that don't fit in debugState slots
19
17
  interface Phase46State {
20
- domainI_latest?: KeystoneIbGib_V1;
21
18
  targetAlphaV1?: any;
22
19
  targetBetaV2?: any;
23
20
  }
24
-
25
21
  const state: Phase46State = {};
26
22
 
23
+ const MASTER_SECRET = 'test-sender-secret-phase4-6b';
24
+
27
25
  export function init4_6bSetupButton(): void {
28
26
  const btn = document.getElementById('btn-4-6b-setup') as HTMLButtonElement | null;
29
27
  if (!btn) { return; }
30
28
  btn.addEventListener('click', async () => {
31
29
  try {
32
30
  btn.disabled = true;
33
- devLog('4.6B Setup: Generating Domain Keystone (I) and two independent target timelines (Alpha and Beta) in default local space...');
31
+ devLog('4.6B Setup: Generating Domain Keystone (I) and two independent target timelines (Alpha and Beta)...');
34
32
 
35
33
  const metaspace = await getGlobalMetaspace_waitIfNeeded();
36
34
  const space = await metaspace.getLocalUserSpace({});
37
35
  if (!space) { throw new Error("No default space."); }
38
36
 
39
- const keystoneService = new KeystoneService_V1();
37
+ const apiBridge = new SpaceGibApiBridge();
40
38
 
41
- // 1. Generate Domain Keystone (I) locally in default space
42
- const domainI = await keystoneService.genesis({
43
- masterSecret: 'test-sender-secret-phase4-6b',
44
- configs: [
45
- getSpaceGibPoolConfig('sync', 'senderidentitysyncsaltphase4-6b'),
46
- getSpaceGibPoolConfig('manage', 'senderidentitymanagesaltphase4-6b'),
47
- ],
48
- metaspace,
49
- space,
50
- frameDetails: { client: 'space-gib-web-dev', timestamp: getTimestamp() }
39
+ // 1. Create domain + delegate identities (DRY helper)
40
+ await setupDomainAndDelegateIdentities({
41
+ masterSecret: MASTER_SECRET,
42
+ syncSalt: 'senderidentitysyncsaltphase4-6b',
43
+ manageSalt: 'senderidentitymanagesaltphase4-6b',
44
+ metaspace, space, apiBridge,
45
+ phaseText: '4.6B'
51
46
  });
52
47
 
53
- state.domainI_latest = domainI;
54
- debugState.domainI = domainI;
55
- debugState.domainIMasterSecret = 'test-sender-secret-phase4-6b';
56
-
57
- devLog(`4.6B Setup: ✓ Domain Keystone (I) created locally: ${getIbGibAddr({ ibGib: domainI })}`);
58
-
59
- // 2. Post Genesis Domain Keystone to server
60
- const apiBridge = new SpaceGibApiBridge();
61
- const resGenesis = await apiBridge.postGenesisKeystone(domainI);
62
- if (resGenesis.success) {
63
- devLog(`4.6B Setup: ✓ Domain Keystone registered on server.`);
64
- } else {
65
- throw new Error(`Server rejected genesis domain keystone: ${resGenesis.message}`);
66
- }
67
-
68
- // 3. Create Timeline A (root A -> mutant A1)
48
+ // 2. Create Timeline A (root A -> mutant A1)
69
49
  const resAlphaV0 = await factory.firstGen({
70
50
  parentIbGib: ROOT,
71
51
  ib: 'timeline_root_alpha_4_6b',
72
52
  data: { type: 'root', label: 'Alpha4_6b', random: Math.random() },
73
- dna: true,
74
- nCounter: true,
75
- tjp: { uuid: true, timestamp: true }
53
+ dna: true, nCounter: true, tjp: { uuid: true, timestamp: true }
76
54
  });
77
55
  const r1_alpha_v0 = resAlphaV0.newIbGib;
78
56
  await metaspace.persistTransformResult({ resTransform: resAlphaV0, space });
@@ -81,20 +59,18 @@ export function init4_6bSetupButton(): void {
81
59
  const r1_alpha_v1 = await mut8Timeline({
82
60
  timeline: r1_alpha_v0,
83
61
  mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'A1_4_6b' } },
84
- metaspace,
85
- space,
62
+ metaspace, space,
86
63
  });
87
64
  state.targetAlphaV1 = r1_alpha_v1;
65
+ debugState.targetC1 = r1_alpha_v1;
88
66
  devLog(`4.6B Setup: ✓ Local Timeline A created. A1 Tip: ${getIbGibAddr({ ibGib: r1_alpha_v1 })}`);
89
67
 
90
- // 4. Create Timeline B (root B -> mutant B1 -> mutant B2)
68
+ // 3. Create Timeline B (root B -> mutant B1 -> mutant B2)
91
69
  const resBetaV0 = await factory.firstGen({
92
70
  parentIbGib: ROOT,
93
71
  ib: 'timeline_root_beta_4_6b',
94
72
  data: { type: 'root', label: 'Beta4_6b', random: Math.random() },
95
- dna: true,
96
- nCounter: true,
97
- tjp: { uuid: true, timestamp: true }
73
+ dna: true, nCounter: true, tjp: { uuid: true, timestamp: true }
98
74
  });
99
75
  const r1_beta_v0 = resBetaV0.newIbGib;
100
76
  await metaspace.persistTransformResult({ resTransform: resBetaV0, space });
@@ -103,17 +79,15 @@ export function init4_6bSetupButton(): void {
103
79
  const r1_beta_v1 = await mut8Timeline({
104
80
  timeline: r1_beta_v0,
105
81
  mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'B1_4_6b' } },
106
- metaspace,
107
- space,
82
+ metaspace, space,
108
83
  });
109
-
110
84
  const r1_beta_v2 = await mut8Timeline({
111
85
  timeline: r1_beta_v1,
112
86
  mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'B2_4_6b' } },
113
- metaspace,
114
- space,
87
+ metaspace, space,
115
88
  });
116
89
  state.targetBetaV2 = r1_beta_v2;
90
+ debugState.targetC2 = r1_beta_v2;
117
91
  devLog(`4.6B Setup: ✓ Local Timeline B created. B2 Tip: ${getIbGibAddr({ ibGib: r1_beta_v2 })}`);
118
92
 
119
93
  devLog('✓ 4.6B Setup Complete! Timelines created locally. Ready for 4.6B Sync.');
@@ -138,53 +112,24 @@ export function init4_6bSyncButton(): void {
138
112
  btn.disabled = true;
139
113
  devLog('4.6B Sync: Initiating WebSocket Sync for both Timeline A and Timeline B in one call...');
140
114
 
141
- const domainI = state.domainI_latest;
142
115
  const targetAlphaV1 = state.targetAlphaV1;
143
116
  const targetBetaV2 = state.targetBetaV2;
144
- if (!domainI || !targetAlphaV1 || !targetBetaV2) {
117
+ if (!debugState.domainI || !targetAlphaV1 || !targetBetaV2) {
145
118
  devLog('⚠ 4.6B Sync: Missing setup state. Please run Setup first.');
146
119
  btn.disabled = false;
147
120
  return;
148
121
  }
149
122
 
150
- const domainAddr = getIbGibAddr({ ibGib: domainI });
151
123
  const metaspace = await getGlobalMetaspace_waitIfNeeded();
152
124
  const space = await metaspace.getLocalUserSpace({});
153
125
  if (!space) { throw new Error("No default space."); }
154
126
 
155
- const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
156
-
157
- const senderPeer = new SyncPeerWebSocketSender_V1({
158
- classname: 'SyncPeerWebSocketSender_V1',
159
- httpEvolveUrl: `${location.protocol}//${location.host}/api/keystone/evolve/${encodeURIComponent(domainAddr)}`,
160
- wsUrl: `${protocol}//${location.host}/api/sync/ws/${encodeURIComponent(domainAddr)}`
161
- });
162
-
163
- const coordinator = new SyncSagaCoordinator();
164
- const sagaId = await getUUID();
165
-
166
- await senderPeer.initializeOpts({
167
- localMetaspace: metaspace,
168
- localSpace: space,
169
- senderIdentity: domainI,
170
- fnSenderSecret: async () => 'test-sender-secret-phase4-6b',
171
- sagaId,
172
- sessionConnectPoolConfig: SESSION_KEYSTONE_POLICY.CONNECT_POOL as any,
173
- sessionSyncPoolConfig: SESSION_KEYSTONE_POLICY.DEFAULT_POOL as any,
174
- targetAddrs: [domainAddr]
175
- });
176
-
177
- // Run Sync targeting both Alpha A1 and Beta B2 tips
178
- const syncSaga = await coordinator.sync({
127
+ // Sync both timelines in a single call
128
+ await runSyncPass({
179
129
  domainIbGibs: [targetAlphaV1, targetBetaV2],
180
- senderIdentity: domainI,
181
- fnSenderSecret: async () => 'test-sender-secret-phase4-6b',
182
- peer: senderPeer,
183
- localSpace: space,
184
- metaspace,
185
- conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
130
+ passLabel: 'Sync Alpha A1 + Beta B2',
131
+ metaspace, space
186
132
  });
187
- await syncSaga.done;
188
133
 
189
134
  devLog('✓ 4.6B Sync Execution Complete! Ready for 4.6B Check.');
190
135
  btn.textContent = '✓ 4.6B Sync Run';
@@ -208,16 +153,15 @@ export function init4_6bCheckButton(): void {
208
153
  btn.disabled = true;
209
154
  devLog('4.6B Check: Verifying both Timeline A and Timeline B exist on the server with matching dependency graphs...');
210
155
 
211
- const domainI = state.domainI_latest;
212
156
  const targetAlphaV1 = state.targetAlphaV1;
213
157
  const targetBetaV2 = state.targetBetaV2;
214
- if (!domainI || !targetAlphaV1 || !targetBetaV2) {
158
+ if (!debugState.domainI || !targetAlphaV1 || !targetBetaV2) {
215
159
  devLog('⚠ 4.6B Check: Missing state. Did Setup and Sync run?');
216
160
  btn.disabled = false;
217
161
  return;
218
162
  }
219
163
 
220
- const domainAddr = getIbGibAddr({ ibGib: domainI });
164
+ const domainAddr = getIbGibAddr({ ibGib: debugState.domainI });
221
165
  const alphaAddr = getIbGibAddr({ ibGib: targetAlphaV1 });
222
166
  const betaAddr = getIbGibAddr({ ibGib: targetBetaV2 });
223
167
 
@@ -227,36 +171,26 @@ export function init4_6bCheckButton(): void {
227
171
 
228
172
  const apiBridge = new SpaceGibApiBridge();
229
173
 
230
- // 1. Verify Timeline A (Alpha V1) on server
174
+ // 1. Verify Timeline A on server
231
175
  devLog('4.6B Check: Fetching Timeline A dependency graph from server...');
232
176
  const resServerGraphAlpha = await apiBridge.getIbGibGraph(domainAddr, alphaAddr, true);
233
177
  if (!resServerGraphAlpha.success || !resServerGraphAlpha.graph) {
234
178
  throw new Error(`Failed to fetch Timeline A graph from server: ${resServerGraphAlpha.message}`);
235
179
  }
236
-
237
180
  const localGraphAlpha = await metaspace.getDependencyGraph({ ibGibAddr: alphaAddr, space });
238
- const equalAlpha = graphsAreEquivalent({
239
- graphA: localGraphAlpha,
240
- graphB: resServerGraphAlpha.graph
241
- });
242
- if (!equalAlpha) {
181
+ if (!graphsAreEquivalent({ graphA: localGraphAlpha, graphB: resServerGraphAlpha.graph })) {
243
182
  throw new Error("Timeline A dependency graphs on local space and server are NOT equivalent.");
244
183
  }
245
184
  devLog('4.6B Check: ✓ Timeline A graphs are equivalent.');
246
185
 
247
- // 2. Verify Timeline B (Beta V2) on server
186
+ // 2. Verify Timeline B on server
248
187
  devLog('4.6B Check: Fetching Timeline B dependency graph from server...');
249
188
  const resServerGraphBeta = await apiBridge.getIbGibGraph(domainAddr, betaAddr, true);
250
189
  if (!resServerGraphBeta.success || !resServerGraphBeta.graph) {
251
190
  throw new Error(`Failed to fetch Timeline B graph from server: ${resServerGraphBeta.message}`);
252
191
  }
253
-
254
192
  const localGraphBeta = await metaspace.getDependencyGraph({ ibGibAddr: betaAddr, space });
255
- const equalBeta = graphsAreEquivalent({
256
- graphA: localGraphBeta,
257
- graphB: resServerGraphBeta.graph
258
- });
259
- if (!equalBeta) {
193
+ if (!graphsAreEquivalent({ graphA: localGraphBeta, graphB: resServerGraphBeta.graph })) {
260
194
  throw new Error("Timeline B dependency graphs on local space and server are NOT equivalent.");
261
195
  }
262
196
  devLog('4.6B Check: ✓ Timeline B graphs are equivalent.');