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 { graphsAreEquivalent } from '@ibgib/core-gib/dist/common/other/graph-helper.mjs'; import { SpaceGibApiBridge } from '../api/space-gib-api-bridge.mjs'; import { debugState, devLog, lc, setupDomainAndDelegateIdentities, runSyncPass } from './common.mjs'; // Phase-specific state for targets that don't fit in debugState slots interface Phase46State { targetAlphaV1?: any; targetBetaV2?: any; } const state: Phase46State = {}; const MASTER_SECRET = 'test-sender-secret-phase4-6b'; export function init4_6bSetupButton(): void { const btn = document.getElementById('btn-4-6b-setup') as HTMLButtonElement | null; if (!btn) { return; } btn.addEventListener('click', async () => { try { btn.disabled = true; devLog('4.6B Setup: Generating Domain Keystone (I) and two independent target timelines (Alpha and Beta)...'); const metaspace = await getGlobalMetaspace_waitIfNeeded(); const space = await metaspace.getLocalUserSpace({}); if (!space) { throw new Error("No default space."); } const apiBridge = new SpaceGibApiBridge(); // 1. Create domain + delegate identities (DRY helper) await setupDomainAndDelegateIdentities({ masterSecret: MASTER_SECRET, syncSalt: 'senderidentitysyncsaltphase4-6b', manageSalt: 'senderidentitymanagesaltphase4-6b', metaspace, space, apiBridge, phaseText: '4.6B' }); // 2. Create Timeline A (root A -> mutant A1) const resAlphaV0 = await factory.firstGen({ parentIbGib: ROOT, ib: 'timeline_root_alpha_4_6b', data: { type: 'root', label: 'Alpha4_6b', random: Math.random() }, dna: true, nCounter: true, tjp: { uuid: true, timestamp: true } }); const r1_alpha_v0 = resAlphaV0.newIbGib; await metaspace.persistTransformResult({ resTransform: resAlphaV0, space }); await metaspace.registerNewIbGib({ ibGib: r1_alpha_v0, space }); const r1_alpha_v1 = await mut8Timeline({ timeline: r1_alpha_v0, mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'A1_4_6b' } }, metaspace, space, }); state.targetAlphaV1 = r1_alpha_v1; debugState.targetC1 = r1_alpha_v1; devLog(`4.6B Setup: ✓ Local Timeline A created. A1 Tip: ${getIbGibAddr({ ibGib: r1_alpha_v1 })}`); // 3. Create Timeline B (root B -> mutant B1 -> mutant B2) const resBetaV0 = await factory.firstGen({ parentIbGib: ROOT, ib: 'timeline_root_beta_4_6b', data: { type: 'root', label: 'Beta4_6b', random: Math.random() }, dna: true, nCounter: true, tjp: { uuid: true, timestamp: true } }); const r1_beta_v0 = resBetaV0.newIbGib; await metaspace.persistTransformResult({ resTransform: resBetaV0, space }); await metaspace.registerNewIbGib({ ibGib: r1_beta_v0, space }); const r1_beta_v1 = await mut8Timeline({ timeline: r1_beta_v0, mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'B1_4_6b' } }, metaspace, space, }); const r1_beta_v2 = await mut8Timeline({ timeline: r1_beta_v1, mut8Opts: { dataToAddOrPatch: { type: 'comment', label: 'B2_4_6b' } }, metaspace, space, }); state.targetBetaV2 = r1_beta_v2; debugState.targetC2 = r1_beta_v2; devLog(`4.6B Setup: ✓ Local Timeline B created. B2 Tip: ${getIbGibAddr({ ibGib: r1_beta_v2 })}`); devLog('✓ 4.6B Setup Complete! Timelines created locally. Ready for 4.6B Sync.'); btn.textContent = '✓ 4.6B Setup Complete'; const syncBtn = document.getElementById('btn-4-6b-sync') as HTMLButtonElement | null; if (syncBtn) { syncBtn.disabled = false; } } catch (error) { devLog(`✗ 4.6B Setup FAILED: ${extractErrorMsg(error)}`); console.error(error); btn.disabled = false; } }); } export function init4_6bSyncButton(): void { const btn = document.getElementById('btn-4-6b-sync') as HTMLButtonElement | null; if (!btn) { return; } btn.addEventListener('click', async () => { try { btn.disabled = true; devLog('4.6B Sync: Initiating WebSocket Sync for both Timeline A and Timeline B in one call...'); const targetAlphaV1 = state.targetAlphaV1; const targetBetaV2 = state.targetBetaV2; if (!debugState.domainI || !targetAlphaV1 || !targetBetaV2) { devLog('⚠ 4.6B Sync: Missing setup state. Please run Setup first.'); btn.disabled = false; return; } const metaspace = await getGlobalMetaspace_waitIfNeeded(); const space = await metaspace.getLocalUserSpace({}); if (!space) { throw new Error("No default space."); } // Sync both timelines in a single call await runSyncPass({ domainIbGibs: [targetAlphaV1, targetBetaV2], passLabel: 'Sync Alpha A1 + Beta B2', metaspace, space }); devLog('✓ 4.6B Sync Execution Complete! Ready for 4.6B Check.'); btn.textContent = '✓ 4.6B Sync Run'; const checkBtn = document.getElementById('btn-4-6b-check') as HTMLButtonElement | null; if (checkBtn) { checkBtn.disabled = false; } } catch (error) { devLog(`✗ 4.6B Sync FAILED: ${extractErrorMsg(error)}`); console.error(error); btn.disabled = false; } }); } export function init4_6bCheckButton(): void { const btn = document.getElementById('btn-4-6b-check') as HTMLButtonElement | null; if (!btn) { return; } btn.addEventListener('click', async () => { try { btn.disabled = true; devLog('4.6B Check: Verifying both Timeline A and Timeline B exist on the server with matching dependency graphs...'); const targetAlphaV1 = state.targetAlphaV1; const targetBetaV2 = state.targetBetaV2; if (!debugState.domainI || !targetAlphaV1 || !targetBetaV2) { devLog('⚠ 4.6B Check: Missing state. Did Setup and Sync run?'); btn.disabled = false; return; } const domainAddr = getIbGibAddr({ ibGib: debugState.domainI }); const alphaAddr = getIbGibAddr({ ibGib: targetAlphaV1 }); const betaAddr = getIbGibAddr({ ibGib: targetBetaV2 }); const metaspace = await getGlobalMetaspace_waitIfNeeded(); const space = await metaspace.getLocalUserSpace({}); if (!space) { throw new Error("No default space."); } const apiBridge = new SpaceGibApiBridge(); // 1. Verify Timeline A on server devLog('4.6B Check: Fetching Timeline A dependency graph from server...'); const resServerGraphAlpha = await apiBridge.getIbGibGraph(domainAddr, alphaAddr, true); if (!resServerGraphAlpha.success || !resServerGraphAlpha.graph) { throw new Error(`Failed to fetch Timeline A graph from server: ${resServerGraphAlpha.message}`); } const localGraphAlpha = await metaspace.getDependencyGraph({ ibGibAddr: alphaAddr, space }); if (!graphsAreEquivalent({ graphA: localGraphAlpha, graphB: resServerGraphAlpha.graph })) { throw new Error("Timeline A dependency graphs on local space and server are NOT equivalent."); } devLog('4.6B Check: ✓ Timeline A graphs are equivalent.'); // 2. Verify Timeline B on server devLog('4.6B Check: Fetching Timeline B dependency graph from server...'); const resServerGraphBeta = await apiBridge.getIbGibGraph(domainAddr, betaAddr, true); if (!resServerGraphBeta.success || !resServerGraphBeta.graph) { throw new Error(`Failed to fetch Timeline B graph from server: ${resServerGraphBeta.message}`); } const localGraphBeta = await metaspace.getDependencyGraph({ ibGibAddr: betaAddr, space }); if (!graphsAreEquivalent({ graphA: localGraphBeta, graphB: resServerGraphBeta.graph })) { throw new Error("Timeline B dependency graphs on local space and server are NOT equivalent."); } devLog('4.6B Check: ✓ Timeline B graphs are equivalent.'); devLog('✓ 4.6B Check SUCCESS: Both independent timelines are fully synced and identical on client and server!'); btn.textContent = '✓ 4.6B Check Success'; } catch (error) { devLog(`✗ 4.6B Check FAILED: ${extractErrorMsg(error)}`); console.error(error); btn.disabled = false; } }); }