diff --git a/stores/sync-manager.ts b/stores/sync-manager.ts index 473488121d..813516dfd6 100644 --- a/stores/sync-manager.ts +++ b/stores/sync-manager.ts @@ -2,10 +2,11 @@ import { useWorkflowRegistry } from './workflow/registry/store' import { BlockState } from './workflow/types' import { mergeSubblockState } from './workflow/utils' +// Type definitions interface WorkflowSyncPayload { id: string name: string - description?: string | undefined + description?: string state: { blocks: Record edges: any @@ -14,16 +15,50 @@ interface WorkflowSyncPayload { } } -// Track deleted workflow IDs until they're synced -const deletedWorkflowIds = new Set() +// API configuration +const SYNC_INTERVAL_MS = 30000 +const API_ENDPOINTS = { + SYNC: '/api/db/sync', + LOGIN: '/login', +} as const -export function addDeletedWorkflow(id: string) { +// Global state +const deletedWorkflowIds = new Set() +let syncInterval: NodeJS.Timeout | null = null + +// Workflow deletion tracking +export function addDeletedWorkflow(id: string): void { deletedWorkflowIds.add(id) } +// Prepare workflow data +async function prepareSyncPayload( + id: string, + metadata: { name: string; description?: string } +): Promise { + const savedState = localStorage.getItem(`workflow-${id}`) + if (!savedState) return null + + const state = JSON.parse(savedState) + const mergedBlocks = mergeSubblockState(state.blocks) + + return { + id, + name: metadata.name, + description: metadata.description, + state: { + blocks: mergedBlocks, + edges: state.edges, + loops: state.loops, + lastSaved: state.lastSaved, + }, + } +} + +// Server sync logic async function syncWorkflowsToServer(payloads: WorkflowSyncPayload[]): Promise { try { - const response = await fetch('/api/db/sync', { + const response = await fetch(API_ENDPOINTS.SYNC, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ @@ -35,13 +70,12 @@ async function syncWorkflowsToServer(payloads: WorkflowSyncPayload[]): Promise { const { workflows } = useWorkflowRegistry.getState() - // Prepare sync payloads for all workflows - const syncPayloads: (WorkflowSyncPayload | null)[] = await Promise.all( - Object.entries(workflows).map(async ([id, metadata]) => { - const savedState = localStorage.getItem(`workflow-${id}`) - if (!savedState) return null - - const state = JSON.parse(savedState) - const mergedBlocks = mergeSubblockState(state.blocks) - - return { - id, - name: metadata.name, - description: metadata.description, - state: { - blocks: mergedBlocks, - edges: state.edges, - loops: state.loops, - lastSaved: state.lastSaved, - }, - } - }) + const syncPayloads = await Promise.all( + Object.entries(workflows).map(([id, metadata]) => prepareSyncPayload(id, metadata)) ) - // Filter out null values and sync if there are workflows to sync const validPayloads = syncPayloads.filter( (payload): payload is WorkflowSyncPayload => payload !== null ) @@ -89,58 +102,31 @@ async function performSync() { } } -export function initializeSyncManager() { +// Sync manager initialization +export function initializeSyncManager(): (() => void) | undefined { if (typeof window === 'undefined') return - // Start periodic sync - syncInterval = setInterval(performSync, 30000) // Sync every 30 seconds + syncInterval = setInterval(performSync, SYNC_INTERVAL_MS) const handleBeforeUnload = async (event: BeforeUnloadEvent) => { const { workflows } = useWorkflowRegistry.getState() - - // Prepare sync payloads for all workflows - const syncPayloads: (WorkflowSyncPayload | null)[] = await Promise.all( - Object.entries(workflows).map(async ([id, metadata]) => { - // Get workflow state from localStorage - const savedState = localStorage.getItem(`workflow-${id}`) - if (!savedState) return null - - const state = JSON.parse(savedState) - // Merge subblock states for all blocks in the workflow - const mergedBlocks = mergeSubblockState(state.blocks) - - return { - id, - name: metadata.name, - description: metadata.description, - state: { - blocks: mergedBlocks, - edges: state.edges, - loops: state.loops, - lastSaved: state.lastSaved, - }, - } - }) + const syncPayloads = await Promise.all( + Object.entries(workflows).map(([id, metadata]) => prepareSyncPayload(id, metadata)) ) - // Filter out null values and sync if there are workflows to sync const validPayloads = syncPayloads.filter( (payload): payload is WorkflowSyncPayload => payload !== null ) if (validPayloads.length > 0) { - // Show confirmation dialog event.preventDefault() event.returnValue = '' - - // Attempt to sync await syncWorkflowsToServer(validPayloads) } } window.addEventListener('beforeunload', handleBeforeUnload) - // Return cleanup function return () => { window.removeEventListener('beforeunload', handleBeforeUnload) if (syncInterval) {