import { extractErrorMsg, getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs'; import { Factory_V1 as factory } from '@ibgib/ts-gib/dist/V1/factory.mjs'; import { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs'; import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs'; import { KeystoneIbGib_V1 } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs'; import { getGlobalMetaspace_waitIfNeeded } from "@ibgib/web-gib/dist/helpers.mjs"; import { mut8Timeline } from '@ibgib/core-gib/dist/timeline/timeline-api.mjs'; import { getTjpAddr } from '@ibgib/core-gib/dist/common/other/ibgib-helper.mjs'; import { SyncSagaCoordinator } from '@ibgib/core-gib/dist/sync/sync-saga-coordinator.mjs'; import { GRAFT_BASE_REL8N_NAME, GRAFT_ORPHAN_REL8N_NAME, GRAFT_INFO_REL8N_NAME } from '@ibgib/core-gib/dist/sync/graft-info/graft-info-constants.mjs'; import { SpaceGibApiBridge } from '../api/space-gib-api-bridge.mjs'; import { debugState, devLog, lc, setupDomainAndDelegateIdentities, runSyncPass, runSyncPassFromSpace, copyIdentitiesToSpace } from './common.mjs'; interface Phase47State { testRoot?: any; targetAlphaV2a?: any; targetBetaV2b?: any; } const state: Phase47State = {}; const MASTER_SECRET = 'test-sender-secret-phase4-7b'; export function init4_7bSetupButton(): void { const btn = document.getElementById('btn-4-7b-setup') as HTMLButtonElement | null; if (!btn) { return; } btn.addEventListener('click', async () => { try { btn.disabled = true; devLog('4.7B Setup: Setting up identities, seeding history, and creating divergent branches...'); const metaspace = await getGlobalMetaspace_waitIfNeeded(); const space = await metaspace.getLocalUserSpace({}) as any; if (!space) { throw new Error("No default space."); } const apiBridge = new SpaceGibApiBridge(); await setupDomainAndDelegateIdentities({ masterSecret: MASTER_SECRET, syncSalt: 'senderidentitysyncsaltphase4-7b', manageSalt: 'senderidentitymanagesaltphase4-7b', metaspace, space, apiBridge, phaseText: '4.7B' }); const domainI = debugState.domainI!; const remoteSpace = await metaspace.createNewLocalSpace({ opts: { allowCancel: false, spaceName: 'remote_space_4_7b', getFnPrompt: metaspace.getFnPrompt! } }) as any; await remoteSpace.initialized; await metaspace.put({ ibGib: domainI, space: remoteSpace }); await metaspace.registerNewIbGib({ ibGib: domainI, space: remoteSpace }); const resRoot = await factory.firstGen({ parentIbGib: ROOT, ib: 'timeline_root_conflict_4_7b', data: { type: 'root', label: 'CommonRoot', random: Math.random() }, dna: true, nCounter: true, tjp: { uuid: true, timestamp: true } }); const testRoot = resRoot.newIbGib; await metaspace.persistTransformResult({ resTransform: resRoot, space }); await metaspace.registerNewIbGib({ ibGib: testRoot, space }); state.testRoot = testRoot; const v1_common = await mut8Timeline({ timeline: testRoot, mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'V1Common' } }, metaspace, space, }); const graphRoot = await metaspace.getDependencyGraph({ ibGibAddr: getIbGibAddr({ ibGib: testRoot }), space }); const graphV1 = await metaspace.getDependencyGraph({ ibGibAddr: getIbGibAddr({ ibGib: v1_common }), space }); await metaspace.put({ ibGibs: Object.values({ ...graphRoot, ...graphV1 }), space: remoteSpace }); await metaspace.registerNewIbGib({ ibGib: testRoot, space: remoteSpace }); await metaspace.registerNewIbGib({ ibGib: v1_common, space: remoteSpace }); devLog('4.7B Setup: Syncing v1_common to server...'); await runSyncPass({ domainIbGibs: [v1_common], passLabel: 'Seed v1_common', metaspace, space }); devLog('4.7B Setup: ✓ Seeding complete on server.'); const domainIEvolved = debugState.domainI!; await copyIdentitiesToSpace({ domainI: domainIEvolved, metaspace, fromSpace: space, toSpace: remoteSpace }); const v2a = await mut8Timeline({ timeline: v1_common, mut8Opts: { dataToAddOrPatch: { fieldA: 'source_edit' } }, metaspace, space, }); state.targetAlphaV2a = v2a; devLog(`4.7B Setup: ✓ Created client divergent edit V2a: ${getIbGibAddr({ ibGib: v2a })}`); const v2b = await mut8Timeline({ timeline: v1_common, mut8Opts: { dataToAddOrPatch: { fieldB: 'dest_edit' } }, metaspace, space: remoteSpace, }); state.targetBetaV2b = v2b; devLog(`4.7B Setup: ✓ Created remote divergent edit V2b: ${getIbGibAddr({ ibGib: v2b })}`); devLog('4.7B Setup: Pushing V2b from remote space to server...'); await runSyncPassFromSpace({ domainIbGibs: [v2b], passLabel: 'Push V2b from remoteSpace', metaspace, space: remoteSpace, primarySpace: space, domainI: domainIEvolved, masterSecret: MASTER_SECRET, }); devLog('4.7B Setup: ✓ Server tip is now V2b.'); devLog('✓ 4.7B Setup Complete! Ready for 4.7B Sync.'); btn.textContent = '✓ 4.7B Setup Complete'; const syncBtn = document.getElementById('btn-4-7b-sync') as HTMLButtonElement | null; if (syncBtn) { syncBtn.disabled = false; } } catch (error) { devLog(`✗ 4.7B Setup FAILED: ${extractErrorMsg(error)}`); console.error(error); btn.disabled = false; } }); } export function init4_7bSyncButton(): void { const btn = document.getElementById('btn-4-7b-sync') as HTMLButtonElement | null; if (!btn) { return; } btn.addEventListener('click', async () => { try { btn.disabled = true; devLog('4.7B Sync: Initiating WebSocket Sync for divergent edit V2a...'); const targetAlphaV2a = state.targetAlphaV2a; if (!debugState.domainI || !targetAlphaV2a) { devLog('⚠ 4.7B Sync: Missing setup state. Please run Setup first.'); btn.disabled = false; return; } const metaspace = await getGlobalMetaspace_waitIfNeeded(); const space = await metaspace.getLocalUserSpace({}) as any; if (!space) { throw new Error("No default space."); } await runSyncPass({ domainIbGibs: [targetAlphaV2a], passLabel: 'Sync V2a (conflict merge)', metaspace, space }); devLog('✓ 4.7B Sync Execution Complete! Ready for 4.7B Check.'); btn.textContent = '✓ 4.7B Sync Run'; const checkBtn = document.getElementById('btn-4-7b-check') as HTMLButtonElement | null; if (checkBtn) { checkBtn.disabled = false; } } catch (error) { devLog(`✗ 4.7B Sync FAILED: ${extractErrorMsg(error)}`); console.error(error); btn.disabled = false; } }); } export function init4_7bCheckButton(): void { const btn = document.getElementById('btn-4-7b-check') as HTMLButtonElement | null; if (!btn) { return; } btn.addEventListener('click', async () => { try { btn.disabled = true; devLog('4.7B Check: Verifying merged tip (V3) contains both edits on client and server...'); const testRoot = state.testRoot; const targetAlphaV2a = state.targetAlphaV2a; const targetBetaV2b = state.targetBetaV2b; if (!debugState.domainI || !testRoot || !targetAlphaV2a || !targetBetaV2b) { devLog('⚠ 4.7B Check: Missing state. Did Setup and Sync run?'); btn.disabled = false; return; } const domainAddr = getIbGibAddr({ ibGib: debugState.domainI }); const tjpAddr = getTjpAddr({ ibGib: testRoot, defaultIfNone: 'incomingAddr' }) ?? getIbGibAddr({ ibGib: testRoot }); const metaspace = await getGlobalMetaspace_waitIfNeeded(); const space = await metaspace.getLocalUserSpace({}) as any; if (!space) { throw new Error("No default space."); } const clientKV = await (metaspace.getLocalUserSpace({}) as Promise).then((sp: any) => new SyncSagaCoordinator().getKnowledgeMap({ space: sp, metaspace, domainIbGibs: [testRoot] }) ); const clientTipAddr = clientKV[tjpAddr]; devLog(`4.7B Check: Client tip address: ${clientTipAddr}`); if (!clientTipAddr) { throw new Error("Client default space is missing the timeline tip."); } const resTip = await metaspace.get({ addr: clientTipAddr, space }); if (!resTip.success || !resTip.ibGibs?.length) { throw new Error("Client tip not found in default local space."); } const clientTip = resTip.ibGibs[0]; if (!clientTip.data?.fieldA || !clientTip.data?.fieldB) { throw new Error(`Merged client tip missing edits: fieldA: ${clientTip.data?.fieldA}, fieldB: ${clientTip.data?.fieldB}`); } devLog('4.7B Check: ✓ Client tip has both fieldA and fieldB edits.'); const graftInfoRel = clientTip.rel8ns?.[GRAFT_INFO_REL8N_NAME]; if (!graftInfoRel?.[0]) { throw new Error("Client tip is missing graftinfo relations."); } const resGraft = await metaspace.get({ addr: graftInfoRel[0], space }); if (!resGraft.success || !resGraft.ibGibs?.length) { throw new Error("GraftInfo not found in local space."); } const graftInfo = resGraft.ibGibs[0]; if (!graftInfo.rel8ns?.[GRAFT_BASE_REL8N_NAME] || !graftInfo.rel8ns?.[GRAFT_ORPHAN_REL8N_NAME]) { throw new Error("GraftInfo is missing graftbase or graftorphan relations."); } devLog('4.7B Check: ✓ Client graft base and orphan relations are correctly set.'); const apiBridge = new SpaceGibApiBridge(); const resServerGraph = await apiBridge.getIbGibGraph(domainAddr, clientTipAddr, true); if (!resServerGraph.success || !resServerGraph.graph) { throw new Error(`Failed to fetch merged graph from server: ${resServerGraph.message}`); } const serverTip = resServerGraph.graph[clientTipAddr]; if (!serverTip) { throw new Error("Merged V3 tip is not present on the server!"); } if (serverTip.data?.fieldA !== 'source_edit' || serverTip.data?.fieldB !== 'dest_edit') { throw new Error("Server tip data edits do not match merged values."); } devLog('4.7B Check: ✓ Server tip has matching merged edits.'); devLog('✓ 4.7B Check SUCCESS: Divergent branches merged successfully via optimistic graft!'); btn.textContent = '✓ 4.7B Check Success'; } catch (error) { devLog(`✗ 4.7B Check FAILED: ${extractErrorMsg(error)}`); console.error(error); btn.disabled = false; } }); }