diff --git a/stores/sync-core.ts b/stores/sync-core.ts index 345550d204..2ca6ce0641 100644 --- a/stores/sync-core.ts +++ b/stores/sync-core.ts @@ -2,6 +2,21 @@ * Core sync types and utilities for optimistic state synchronization */ +/** + * Simple utility to check if we're in localStorage mode + * This is the single source of truth for this check + */ +export function isLocalStorageMode(): boolean { + if (typeof window === 'undefined') return false + + return ( + localStorage.getItem('USE_LOCAL_STORAGE') === 'true' || + process.env.USE_LOCAL_STORAGE === 'true' || + process.env.NEXT_PUBLIC_USE_LOCAL_STORAGE === 'true' || + process.env.DISABLE_DB_SYNC === 'true' + ) +} + // Configuration for a sync operation export interface SyncConfig { // Required configuration @@ -17,9 +32,6 @@ export interface SyncConfig { syncInterval?: number onSyncSuccess?: (response: any) => void onSyncError?: (error: any) => void - - // Local storage key for standalone mode - localStorageKey?: string } export const DEFAULT_SYNC_CONFIG: Partial = { @@ -38,6 +50,16 @@ export interface SyncOperations { // Performs sync operation with automatic retry export async function performSync(config: SyncConfig): Promise { try { + // In localStorage mode, just return success immediately - no need to sync to server + if (isLocalStorageMode()) { + // Still call onSyncSuccess to maintain expected behavior + if (config.onSyncSuccess) { + config.onSyncSuccess({ success: true, message: 'Skipped sync in localStorage mode' }) + } + return true + } + + // Get the payload to sync const payload = await Promise.resolve(config.preparePayload()) // Skip sync if the payload indicates it should be skipped @@ -45,43 +67,13 @@ export async function performSync(config: SyncConfig): Promise { return true } - // Check if we're in local storage mode - const useLocalStorage = - typeof window !== 'undefined' && - (window.localStorage.getItem('USE_LOCAL_STORAGE') === 'true' || - process.env.NEXT_PUBLIC_USE_LOCAL_STORAGE === 'true' || - process.env.DISABLE_DB_SYNC === 'true') - - if (useLocalStorage && config.localStorageKey) { - // In local storage mode, save directly to localStorage - try { - window.localStorage.setItem( - config.localStorageKey, - JSON.stringify({ - data: payload, - timestamp: new Date().toISOString(), - }) - ) - - if (config.onSyncSuccess) { - config.onSyncSuccess({ success: true, message: 'Saved to local storage' }) - } - - return true - } catch (error) { - if (config.onSyncError) { - config.onSyncError(error) - } - return false - } - } - - // If not in local storage mode or no localStorageKey provided, use API + // Normal API sync flow return await sendWithRetry(config.endpoint, payload, config) } catch (error) { if (config.onSyncError) { config.onSyncError(error) } + console.error(`Sync error: ${error}`) return false } } diff --git a/stores/sync-registry.ts b/stores/sync-registry.ts index 7f5bc4d10d..2771fca9b6 100644 --- a/stores/sync-registry.ts +++ b/stores/sync-registry.ts @@ -2,6 +2,7 @@ import { environmentSync, fetchEnvironmentVariables } from './settings/environment/sync' import { SyncManager } from './sync' +import { isLocalStorageMode } from './sync-core' import { fetchWorkflowsFromDB, workflowSync } from './workflows/sync' // Initialize managers lazily @@ -40,14 +41,8 @@ export async function initializeSyncManagers(): Promise { managers = [workflowSync, environmentSync] try { - // Check if we're in local storage mode - const useLocalStorage = - typeof window !== 'undefined' && - (window.localStorage.getItem('USE_LOCAL_STORAGE') === 'true' || - process.env.NEXT_PUBLIC_USE_LOCAL_STORAGE === 'true' || - process.env.DISABLE_DB_SYNC === 'true') - - if (useLocalStorage) { + // Use our centralized function to check for localStorage mode + if (isLocalStorageMode()) { console.log('Running in local storage mode - skipping DB sync') // In local storage mode, we don't need to fetch from DB // Just load from localStorage directly diff --git a/stores/sync.ts b/stores/sync.ts index a5991ae46c..3cfb41d5eb 100644 --- a/stores/sync.ts +++ b/stores/sync.ts @@ -2,7 +2,13 @@ import { useEffect } from 'react' import { SYNC_INTERVALS } from './constants' -import { DEFAULT_SYNC_CONFIG, SyncConfig, SyncOperations, performSync } from './sync-core' +import { + DEFAULT_SYNC_CONFIG, + SyncConfig, + SyncOperations, + isLocalStorageMode, + performSync, +} from './sync-core' // Client-side sync manager with lifecycle and registry management export interface SyncManager extends SyncOperations { @@ -134,6 +140,19 @@ export function createSingletonSyncManager( } } + // Use our centralized function to check for localStorage mode + if (isLocalStorageMode()) { + // Return a no-op manager for localStorage mode + return { + id: key, + config: configFactory(), + sync: () => console.log(`[LocalStorage Mode] Skipping sync for ${key}`), + startIntervalSync: () => {}, + stopIntervalSync: () => {}, + dispose: () => {}, + } + } + const existing = syncManagerRegistry.get(key) if (existing) { return existing