{"version":3,"file":"sync-engine.mjs","sources":["../../../../src/lib/data/sync/sync-engine.ts"],"sourcesContent":["/**\n * @file Sync Engine\n * @description Multi-source data synchronization engine with priority-based\n * conflict resolution, offline support, and real-time sync capabilities.\n *\n * Features:\n * - Multiple data source adapters (API, localStorage, IndexedDB, WebSocket)\n * - Priority-based source selection\n * - Automatic sync scheduling\n * - Partial/incremental sync\n * - Offline queue management\n * - Sync status tracking\n *\n * @example\n * ```typescript\n * import { createSyncEngine, createApiSource, createLocalStorageSource } from '@/lib/data/sync';\n *\n * const engine = createSyncEngine({\n *   sources: [\n *     createApiSource('/api', { priority: 1 }),\n *     createLocalStorageSource('app-data', { priority: 2 }),\n *   ],\n *   conflictStrategy: 'server-wins',\n * });\n *\n * engine.sync('users', userId);\n * ```\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Sync source priority (lower = higher priority)\n */\nexport type SourcePriority = number;\n\n/**\n * Sync direction\n */\nexport type SyncDirection = 'push' | 'pull' | 'bidirectional';\n\n/**\n * Sync status for an entity\n */\nexport type SyncStatus =\n  | 'idle'\n  | 'synced'\n  | 'pending'\n  | 'syncing'\n  | 'conflict'\n  | 'error'\n  | 'offline';\n\n/**\n * Entity metadata for sync tracking\n */\nexport interface SyncMetadata {\n  /** Entity ID */\n  id: string;\n  /** Entity type */\n  type: string;\n  /** Last sync timestamp */\n  lastSyncedAt: number;\n  /** Last modified timestamp (local) */\n  localModifiedAt: number;\n  /** Last modified timestamp (remote) */\n  remoteModifiedAt?: number;\n  /** Version or ETag */\n  version?: string;\n  /** Sync status */\n  status: SyncStatus;\n  /** Error message if status is 'error' */\n  error?: string;\n  /** Retry count */\n  retryCount: number;\n  /** Source that owns this data */\n  sourceId: string;\n}\n\n/**\n * Sync event types\n */\nexport type SyncEventType =\n  | 'sync:start'\n  | 'sync:complete'\n  | 'sync:error'\n  | 'sync:conflict'\n  | 'sync:offline'\n  | 'sync:online'\n  | 'entity:changed'\n  | 'entity:deleted'\n  | 'entity:created'\n  | 'offline-queue-change'\n  | 'conflict-resolved';\n\n/**\n * Sync event payload\n */\nexport interface SyncEvent<T = unknown> {\n  type: SyncEventType;\n  entityType: string;\n  entityId?: string;\n  data?: T;\n  metadata?: SyncMetadata;\n  error?: Error;\n  timestamp: number;\n  sourceId: string;\n}\n\n/**\n * Sync source interface\n */\nexport interface SyncSource<T = unknown> {\n  /** Unique source identifier */\n  id: string;\n  /** Source priority (lower = higher) */\n  priority: SourcePriority;\n  /** Whether source is available */\n  isAvailable: () => boolean | Promise<boolean>;\n  /** Fetch entity by ID */\n  get: (entityType: string, id: string) => Promise<T | null>;\n  /** Fetch multiple entities */\n  getMany: (entityType: string, ids: string[]) => Promise<Map<string, T>>;\n  /** Fetch all entities of a type */\n  getAll: (entityType: string, options?: QueryOptions) => Promise<T[]>;\n  /** Save entity */\n  set: (entityType: string, id: string, data: T) => Promise<void>;\n  /** Save multiple entities */\n  setMany: (entityType: string, entities: Map<string, T>) => Promise<void>;\n  /** Delete entity */\n  delete: (entityType: string, id: string) => Promise<void>;\n  /** Delete multiple entities */\n  deleteMany: (entityType: string, ids: string[]) => Promise<void>;\n  /** Subscribe to changes (if supported) */\n  subscribe?: (entityType: string, callback: (event: SyncEvent<T>) => void) => () => void;\n  /** Get last modified timestamp */\n  getLastModified?: (entityType: string, id: string) => Promise<number | null>;\n  /** Check if entity exists */\n  exists?: (entityType: string, id: string) => Promise<boolean>;\n}\n\n/**\n * Query options for fetching entities\n */\nexport interface QueryOptions {\n  /** Filter conditions */\n  filter?: Record<string, unknown>;\n  /** Sort order */\n  sort?: { field: string; direction: 'asc' | 'desc' }[];\n  /** Pagination limit */\n  limit?: number;\n  /** Pagination offset */\n  offset?: number;\n  /** Cursor for cursor-based pagination */\n  cursor?: string;\n  /** Only fetch modified since timestamp */\n  modifiedSince?: number;\n}\n\n/**\n * Sync engine configuration\n */\nexport interface SyncEngineConfig {\n  /** Data sources */\n  sources: SyncSource[];\n  /** Default conflict resolution strategy */\n  conflictStrategy?: 'server-wins' | 'client-wins' | 'latest-wins' | 'manual';\n  /** Sync interval in milliseconds (0 = manual only) */\n  syncInterval?: number;\n  /** Max retry attempts for failed syncs */\n  maxRetries?: number;\n  /** Retry delay base in milliseconds */\n  retryDelayBase?: number;\n  /** Enable offline queue */\n  offlineQueue?: boolean;\n  /** Debug mode */\n  debug?: boolean;\n  /** Entity type configurations */\n  entities?: Record<string, EntitySyncConfig>;\n}\n\n/**\n * Entity-specific sync configuration\n */\nexport interface EntitySyncConfig {\n  /** Sync direction */\n  direction?: SyncDirection;\n  /** Conflict strategy override */\n  conflictStrategy?: 'server-wins' | 'client-wins' | 'latest-wins' | 'manual';\n  /** Custom merge function */\n  merge?: <T>(local: T, remote: T, base?: T) => T;\n  /** Sync interval override */\n  syncInterval?: number;\n  /** Excluded fields from sync */\n  excludeFields?: string[];\n  /** Primary source ID */\n  primarySource?: string;\n}\n\n/**\n * Sync operation for queuing\n */\nexport interface SyncOperation {\n  id: string;\n  type: 'create' | 'update' | 'delete';\n  entityType: string;\n  entityId: string;\n  data?: unknown;\n  timestamp: number;\n  retryCount: number;\n  status: 'pending' | 'processing' | 'failed';\n  error?: string;\n}\n\n/**\n * Sync engine instance\n */\nexport interface SyncEngine {\n  /** Sync a single entity */\n  sync: <T = unknown>(\n    entityType: string,\n    id: string,\n    options?: SyncOptions\n  ) => Promise<SyncResult<T>>;\n  /** Sync multiple entities */\n  syncMany: <T = unknown>(\n    entityType: string,\n    ids: string[],\n    options?: SyncOptions\n  ) => Promise<SyncResult<T>[]>;\n  /** Sync all entities of a type */\n  syncAll: <T = unknown>(entityType: string, options?: SyncOptions) => Promise<SyncResult<T>>;\n  /** Create entity */\n  create: <T>(entityType: string, data: Partial<T>) => Promise<T>;\n  /** Update entity */\n  update: <T>(entityType: string, id: string, data: Partial<T>) => Promise<T>;\n  /** Delete entity */\n  delete: (entityType: string, id: string) => Promise<void>;\n  /** Resolve conflict */\n  resolveConflict: (conflictId: string, resolution: unknown) => Promise<void>;\n  /** Retry failed operations */\n  retryFailed: () => Promise<void>;\n  /** Clear offline queue */\n  clearOfflineQueue: () => void;\n  /** Push local changes to remote */\n  push: (entityType: string, id: string) => Promise<void>;\n  /** Pull remote changes to local */\n  pull: (entityType: string, id: string) => Promise<void>;\n  /** Get sync status for entity */\n  getStatus: (entityType: string, id: string) => SyncMetadata | undefined;\n  /** Get all pending operations */\n  getPendingOperations: () => SyncOperation[];\n  /** Subscribe to sync events */\n  subscribe: (callback: (event: SyncEvent) => void) => () => void;\n  /** Check if online */\n  isOnline: () => boolean;\n  /** Force retry pending operations */\n  retryPending: () => Promise<void>;\n  /** Clear sync metadata */\n  clearMetadata: (entityType?: string) => void;\n  /** Start automatic sync */\n  start: () => void;\n  /** Stop automatic sync */\n  stop: () => void;\n  /** Destroy and cleanup */\n  destroy: () => void;\n}\n\n/**\n * Sync options\n */\nexport interface SyncOptions {\n  /** Force sync even if no changes detected */\n  force?: boolean;\n  /** Specific source to sync with */\n  sourceId?: string;\n  /** Skip conflict resolution */\n  skipConflictResolution?: boolean;\n  /** Timeout in milliseconds */\n  timeout?: number;\n}\n\n/**\n * Sync result\n */\nexport interface SyncResult<T = unknown> {\n  success: boolean;\n  entityType: string;\n  entityId?: string;\n  data?: T[];\n  status: SyncStatus;\n  conflicts?: SyncConflict<T>[];\n  error?: string;\n  syncedAt: number;\n}\n\n/**\n * Sync conflict\n */\nexport interface SyncConflict<T = unknown> {\n  id: string;\n  entityType: string;\n  entityId: string;\n  localData: T;\n  remoteData: T;\n  baseData?: T;\n  localModifiedAt: number;\n  remoteModifiedAt: number;\n  resolution?: 'local' | 'remote' | 'merged';\n  mergedData?: T;\n}\n\n// =============================================================================\n// SYNC ENGINE IMPLEMENTATION\n// =============================================================================\n\n/**\n * Create sync engine\n */\nexport function createSyncEngine(config: SyncEngineConfig): SyncEngine {\n  const {\n    sources,\n    conflictStrategy = 'server-wins',\n    syncInterval = 0,\n    maxRetries = 3,\n    offlineQueue = true,\n    debug = false,\n    entities = {},\n  } = config;\n\n  // State\n  const metadata = new Map<string, SyncMetadata>();\n  const pendingOperations: SyncOperation[] = [];\n  const subscribers = new Set<(event: SyncEvent) => void>();\n  let isOnlineState = typeof navigator !== 'undefined' ? navigator.onLine : true;\n  let syncIntervalId: ReturnType<typeof setInterval> | null = null;\n\n  // Sort sources by priority\n  const sortedSources = [...sources].sort((a, b) => a.priority - b.priority);\n\n  // Logger\n  const log = debug ? (...args: unknown[]) => console.info('[SyncEngine]', ...args) : () => {};\n\n  // Emit event to subscribers\n  function emit(event: SyncEvent): void {\n    for (const subscriber of subscribers) {\n      try {\n        subscriber(event);\n      } catch (error) {\n        console.error('[SyncEngine] Subscriber error:', error);\n      }\n    }\n  }\n\n  // Get metadata key\n  function getMetadataKey(entityType: string, id: string): string {\n    return `${entityType}:${id}`;\n  }\n\n  // Get or create metadata\n  function getOrCreateMetadata(entityType: string, id: string, sourceId: string): SyncMetadata {\n    const key = getMetadataKey(entityType, id);\n    let meta = metadata.get(key);\n\n    if (!meta) {\n      meta = {\n        id,\n        type: entityType,\n        lastSyncedAt: 0,\n        localModifiedAt: Date.now(),\n        status: 'pending',\n        retryCount: 0,\n        sourceId,\n      };\n      metadata.set(key, meta);\n    }\n\n    return meta;\n  }\n\n  // Update metadata immutably\n  function updateMetadata(entityType: string, id: string, updates: Partial<SyncMetadata>): void {\n    const key = getMetadataKey(entityType, id);\n    const meta = metadata.get(key);\n    if (meta) {\n      // Create new object instead of mutating to maintain immutability\n      metadata.set(key, { ...meta, ...updates });\n    }\n  }\n\n  // Get entity config\n  function getEntityConfig(entityType: string): EntitySyncConfig {\n    return entities[entityType] ?? {};\n  }\n\n  // Find available source\n  async function findAvailableSource(preferredId?: string): Promise<SyncSource | null> {\n    if (preferredId != null && preferredId.length > 0) {\n      const preferred = sortedSources.find((s) => s.id === preferredId);\n      if (preferred != null && (await preferred.isAvailable())) {\n        return preferred;\n      }\n    }\n\n    for (const source of sortedSources) {\n      if (await source.isAvailable()) {\n        return source;\n      }\n    }\n\n    return null;\n  }\n\n  // Queue operation for offline\n  function queueOperation(operation: Omit<SyncOperation, 'id'>): void {\n    if (!offlineQueue) return;\n\n    const op: SyncOperation = {\n      ...operation,\n      id: crypto.randomUUID(),\n    };\n\n    pendingOperations.push(op);\n    log('Queued operation:', op.type, op.entityType, op.entityId);\n  }\n\n  // Process pending operations\n  async function processPendingOperations(): Promise<void> {\n    if (pendingOperations.length === 0) return;\n    if (!isOnlineState) return;\n\n    log('Processing pending operations:', pendingOperations.length);\n\n    const toProcess = [...pendingOperations];\n\n    for (const operation of toProcess) {\n      if (operation.status === 'processing') continue;\n\n      operation.status = 'processing';\n\n      try {\n        const source = await findAvailableSource();\n        if (!source) {\n          operation.status = 'pending';\n          continue;\n        }\n\n        switch (operation.type) {\n          case 'create':\n          case 'update':\n            await source.set(operation.entityType, operation.entityId, operation.data);\n            break;\n          case 'delete':\n            await source.delete(operation.entityType, operation.entityId);\n            break;\n        }\n\n        // Remove from queue\n        const index = pendingOperations.indexOf(operation);\n        if (index > -1) {\n          pendingOperations.splice(index, 1);\n        }\n\n        // Update metadata\n        updateMetadata(operation.entityType, operation.entityId, {\n          status: 'synced',\n          lastSyncedAt: Date.now(),\n          retryCount: 0,\n        });\n\n        log('Processed operation:', operation.type, operation.entityId);\n      } catch (error) {\n        operation.status = 'failed';\n        operation.retryCount++;\n        operation.error = error instanceof Error ? error.message : 'Unknown error';\n\n        if (operation.retryCount >= maxRetries) {\n          updateMetadata(operation.entityType, operation.entityId, {\n            status: 'error',\n            error: operation.error,\n          });\n        } else {\n          operation.status = 'pending';\n        }\n\n        log('Operation failed:', operation.type, operation.entityId, operation.error);\n      }\n    }\n  }\n\n  // Resolve conflict\n  function resolveConflict<T>(entityType: string, conflict: SyncConflict<T>): T {\n    const entityConfig = getEntityConfig(entityType);\n    const strategy = entityConfig.conflictStrategy ?? conflictStrategy;\n\n    switch (strategy) {\n      case 'server-wins':\n        return conflict.remoteData;\n\n      case 'client-wins':\n        return conflict.localData;\n\n      case 'latest-wins':\n        if (conflict.localModifiedAt > conflict.remoteModifiedAt) {\n          return conflict.localData;\n        }\n        return conflict.remoteData;\n\n      case 'manual':\n        if (entityConfig.merge) {\n          return entityConfig.merge(conflict.localData, conflict.remoteData, conflict.baseData);\n        }\n        // Fall through to server-wins if no merge function\n        return conflict.remoteData;\n\n      default:\n        return conflict.remoteData;\n    }\n  }\n\n  // Sync single entity\n  async function syncEntity(\n    entityType: string,\n    id: string,\n    options: SyncOptions = {}\n  ): Promise<SyncResult> {\n    const startTime = Date.now();\n    const entityConfig = getEntityConfig(entityType);\n\n    log('Syncing entity:', entityType, id);\n\n    // Check online status\n    if (!isOnlineState && offlineQueue) {\n      return {\n        success: false,\n        entityType,\n        entityId: id,\n        status: 'offline',\n        error: 'Offline - operation queued',\n        syncedAt: startTime,\n      };\n    }\n\n    try {\n      // Find available source\n      const source = await findAvailableSource(options.sourceId);\n      if (!source) {\n        return {\n          success: false,\n          entityType,\n          entityId: id,\n          status: 'error',\n          error: 'No available source',\n          syncedAt: startTime,\n        };\n      }\n\n      // Get metadata\n      const meta = getOrCreateMetadata(entityType, id, source.id);\n      // Update status immutably instead of direct mutation\n      updateMetadata(entityType, id, { status: 'syncing' });\n\n      // Emit start event\n      emit({\n        type: 'sync:start',\n        entityType,\n        entityId: id,\n        metadata: meta,\n        timestamp: Date.now(),\n        sourceId: source.id,\n      });\n\n      // Get remote data\n      const remoteData = await source.get(entityType, id);\n      const remoteModifiedAt = source.getLastModified\n        ? await source.getLastModified(entityType, id)\n        : Date.now();\n\n      // Get local data from secondary sources\n      let localData: unknown = null;\n      for (const secondarySource of sortedSources) {\n        if (secondarySource.id === source.id) continue;\n        if (await secondarySource.isAvailable()) {\n          localData = await secondarySource.get(entityType, id);\n          if (localData !== undefined && localData !== null) break;\n        }\n      }\n\n      // Check for conflict\n      let finalData = remoteData;\n      const conflicts: SyncConflict[] = [];\n\n      if (\n        localData !== undefined &&\n        localData !== null &&\n        remoteData !== undefined &&\n        remoteData !== null &&\n        meta.localModifiedAt > meta.lastSyncedAt\n      ) {\n        // Potential conflict\n        if (options.skipConflictResolution !== true) {\n          const conflict: SyncConflict = {\n            id: crypto.randomUUID(),\n            entityType,\n            entityId: id,\n            localData,\n            remoteData,\n            localModifiedAt: meta.localModifiedAt,\n            remoteModifiedAt: remoteModifiedAt ?? Date.now(),\n          };\n\n          finalData = await resolveConflict(entityType, conflict);\n          conflict.resolution = finalData === localData ? 'local' : 'remote';\n          conflict.mergedData = finalData;\n          conflicts.push(conflict);\n\n          emit({\n            type: 'sync:conflict',\n            entityType,\n            entityId: id,\n            data: conflict,\n            timestamp: Date.now(),\n            sourceId: source.id,\n          });\n        }\n      }\n\n      // Propagate to secondary sources\n      if (finalData !== undefined && finalData !== null) {\n        const direction = entityConfig.direction ?? 'bidirectional';\n        if (direction === 'bidirectional' || direction === 'pull') {\n          for (const secondarySource of sortedSources) {\n            if (secondarySource.id === source.id) continue;\n            if (await secondarySource.isAvailable()) {\n              try {\n                await secondarySource.set(entityType, id, finalData);\n              } catch (error) {\n                log('Failed to propagate to secondary source:', secondarySource.id, error);\n              }\n            }\n          }\n        }\n      }\n\n      // Update metadata immutably\n      updateMetadata(entityType, id, {\n        status: 'synced',\n        lastSyncedAt: Date.now(),\n        remoteModifiedAt:\n          remoteModifiedAt !== null && remoteModifiedAt !== undefined && remoteModifiedAt !== 0\n            ? remoteModifiedAt\n            : Date.now(),\n        retryCount: 0,\n      });\n\n      // Emit complete event\n      emit({\n        type: 'sync:complete',\n        entityType,\n        entityId: id,\n        data: finalData,\n        metadata: metadata.get(getMetadataKey(entityType, id)),\n        timestamp: Date.now(),\n        sourceId: source.id,\n      });\n\n      log('Sync complete:', entityType, id);\n\n      return {\n        success: true,\n        entityType,\n        entityId: id,\n        status: 'synced',\n        conflicts: conflicts.length > 0 ? conflicts : undefined,\n        syncedAt: Date.now(),\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n      // Update metadata\n      const currentRetryCount = metadata.get(getMetadataKey(entityType, id))?.retryCount;\n      updateMetadata(entityType, id, {\n        status: 'error',\n        error: errorMessage,\n        retryCount:\n          (currentRetryCount !== undefined && currentRetryCount !== 0 ? currentRetryCount : 0) + 1,\n      });\n\n      // Emit error event\n      emit({\n        type: 'sync:error',\n        entityType,\n        entityId: id,\n        error: error instanceof Error ? error : new Error(errorMessage),\n        timestamp: Date.now(),\n        sourceId:\n          options.sourceId !== undefined && options.sourceId !== '' ? options.sourceId : 'unknown',\n      });\n\n      log('Sync error:', entityType, id, errorMessage);\n\n      return {\n        success: false,\n        entityType,\n        entityId: id,\n        status: 'error',\n        error: errorMessage,\n        syncedAt: Date.now(),\n      };\n    }\n  }\n\n  // Sync multiple entities\n  async function syncManyEntities(\n    entityType: string,\n    ids: string[],\n    options: SyncOptions = {}\n  ): Promise<SyncResult[]> {\n    const results: SyncResult[] = [];\n\n    for (const id of ids) {\n      const result = await syncEntity(entityType, id, options);\n      results.push(result);\n    }\n\n    return results;\n  }\n\n  // Sync all entities of a type\n  async function syncAllEntities(\n    entityType: string,\n    options: SyncOptions = {}\n  ): Promise<SyncResult> {\n    log('Syncing all:', entityType);\n\n    try {\n      const source = await findAvailableSource(options.sourceId);\n      if (!source) {\n        return {\n          success: false,\n          entityType,\n          status: 'error',\n          error: 'No available source',\n          syncedAt: Date.now(),\n        };\n      }\n\n      // Get all entities from primary source\n      const entities = await source.getAll(entityType);\n\n      // Sync each entity\n      for (const entity of entities) {\n        const entityWithId = entity as { id?: string };\n        if (entityWithId.id !== undefined && entityWithId.id !== '') {\n          await syncEntity(entityType, entityWithId.id, options);\n        }\n      }\n\n      return {\n        success: true,\n        entityType,\n        status: 'synced',\n        syncedAt: Date.now(),\n      };\n    } catch (error) {\n      return {\n        success: false,\n        entityType,\n        status: 'error',\n        error: error instanceof Error ? error.message : 'Unknown error',\n        syncedAt: Date.now(),\n      };\n    }\n  }\n\n  // Push local changes\n  async function pushEntity(entityType: string, id: string): Promise<void> {\n    const source = await findAvailableSource();\n    if (!source) {\n      if (offlineQueue) {\n        // Get local data\n        for (const localSource of sortedSources) {\n          if (await localSource.isAvailable()) {\n            const data = await localSource.get(entityType, id);\n            if (data !== undefined && data !== null) {\n              queueOperation({\n                type: 'update',\n                entityType,\n                entityId: id,\n                data,\n                timestamp: Date.now(),\n                retryCount: 0,\n                status: 'pending',\n              });\n              return;\n            }\n          }\n        }\n      }\n      throw new Error('No available source');\n    }\n\n    // Get local data\n    let localData: unknown = null;\n    for (const localSource of sortedSources) {\n      if (localSource.id === source.id) continue;\n      if (await localSource.isAvailable()) {\n        localData = await localSource.get(entityType, id);\n        if (localData !== undefined && localData !== null) break;\n      }\n    }\n\n    if (localData != null) {\n      await source.set(entityType, id, localData);\n      updateMetadata(entityType, id, {\n        status: 'synced',\n        lastSyncedAt: Date.now(),\n      });\n    }\n  }\n\n  // Pull remote changes\n  async function pullEntity(entityType: string, id: string): Promise<void> {\n    const source = await findAvailableSource();\n    if (!source) {\n      throw new Error('No available source');\n    }\n\n    const remoteData = await source.get(entityType, id);\n\n    if (remoteData != null) {\n      // Update secondary sources\n      for (const secondarySource of sortedSources) {\n        if (secondarySource.id === source.id) continue;\n        if (await secondarySource.isAvailable()) {\n          await secondarySource.set(entityType, id, remoteData);\n        }\n      }\n\n      updateMetadata(entityType, id, {\n        status: 'synced',\n        lastSyncedAt: Date.now(),\n      });\n    }\n  }\n\n  // Setup online/offline handlers\n  function setupNetworkHandlers(): void {\n    if (typeof window === 'undefined') return;\n\n    const handleOnline = (): void => {\n      isOnlineState = true;\n      log('Online - processing pending operations');\n      emit({\n        type: 'sync:online',\n        entityType: '*',\n        timestamp: Date.now(),\n        sourceId: 'system',\n      });\n      void processPendingOperations();\n    };\n\n    const handleOffline = (): void => {\n      isOnlineState = false;\n      log('Offline');\n      emit({\n        type: 'sync:offline',\n        entityType: '*',\n        timestamp: Date.now(),\n        sourceId: 'system',\n      });\n    };\n\n    window.addEventListener('online', handleOnline);\n    window.addEventListener('offline', handleOffline);\n\n    isOnlineState = navigator.onLine;\n  }\n\n  // Start automatic sync\n  function start(): void {\n    if (syncInterval > 0 && syncIntervalId === null) {\n      syncIntervalId = setInterval(() => {\n        if (isOnlineState) {\n          void processPendingOperations();\n        }\n      }, syncInterval);\n      log('Started automatic sync with interval:', syncInterval);\n    }\n\n    setupNetworkHandlers();\n  }\n\n  // Stop automatic sync\n  function stop(): void {\n    if (syncIntervalId) {\n      clearInterval(syncIntervalId);\n      syncIntervalId = null;\n      log('Stopped automatic sync');\n    }\n  }\n\n  // Destroy\n  function destroy(): void {\n    stop();\n    metadata.clear();\n    pendingOperations.length = 0;\n    subscribers.clear();\n    log('Destroyed');\n  }\n\n  // Create entity\n  async function createEntity<T>(entityType: string, data: Partial<T>): Promise<T> {\n    // Placeholder implementation\n    const dataWithId = data as Record<string, unknown>;\n    const id =\n      typeof dataWithId.id === 'string' && dataWithId.id !== ''\n        ? dataWithId.id\n        : crypto.randomUUID();\n    const [source] = sortedSources; // Use primary source\n    if (source !== undefined) {\n      await source.set(entityType, id, data);\n    }\n    return data as T;\n  }\n\n  // Update entity\n  async function updateEntity<T>(entityType: string, id: string, data: Partial<T>): Promise<T> {\n    // Placeholder implementation\n    const [source] = sortedSources; // Use primary source\n    if (source !== undefined) {\n      await source.set(entityType, id, data);\n    }\n    return data as T;\n  }\n\n  // Delete entity\n  async function deleteEntity(entityType: string, id: string): Promise<void> {\n    // Placeholder implementation\n    const [source] = sortedSources; // Use primary source\n    if (source !== undefined) {\n      await source.delete(entityType, id);\n    }\n  }\n\n  // Resolve conflict\n  async function resolveConflictManual(_conflictId: string, _resolution: unknown): Promise<void> {\n    // Placeholder implementation\n    // In a real implementation, this would find the conflict by ID and apply the resolution\n  }\n\n  // Clear offline queue\n  function clearOfflineQueue(): void {\n    pendingOperations.length = 0;\n  }\n\n  return {\n    sync: syncEntity as <T = unknown>(\n      entityType: string,\n      id: string,\n      options?: SyncOptions\n    ) => Promise<SyncResult<T>>,\n    syncMany: syncManyEntities as <T = unknown>(\n      entityType: string,\n      ids: string[],\n      options?: SyncOptions\n    ) => Promise<SyncResult<T>[]>,\n    syncAll: syncAllEntities as <T = unknown>(\n      entityType: string,\n      options?: SyncOptions\n    ) => Promise<SyncResult<T>>,\n    create: createEntity,\n    update: updateEntity,\n    delete: deleteEntity,\n    resolveConflict: resolveConflictManual,\n    retryFailed: processPendingOperations,\n    clearOfflineQueue,\n    push: pushEntity,\n    pull: pullEntity,\n\n    getStatus: (entityType, id) => metadata.get(getMetadataKey(entityType, id)),\n    getPendingOperations: () => [...pendingOperations],\n\n    subscribe: (callback) => {\n      subscribers.add(callback);\n      return () => subscribers.delete(callback);\n    },\n\n    isOnline: () => isOnlineState,\n    retryPending: processPendingOperations,\n\n    clearMetadata: (entityType) => {\n      if (entityType !== undefined && entityType !== '') {\n        for (const [key] of metadata) {\n          if (key.startsWith(`${entityType}:`)) {\n            metadata.delete(key);\n          }\n        }\n      } else {\n        metadata.clear();\n      }\n    },\n\n    start,\n    stop,\n    destroy,\n  };\n}\n\n// =============================================================================\n// SOURCE FACTORIES\n// =============================================================================\n\n/**\n * Create an API sync source\n */\nexport function createApiSource(\n  baseUrl: string,\n  options: {\n    priority?: SourcePriority;\n    headers?: Record<string, string>;\n    timeout?: number;\n  } = {}\n): SyncSource {\n  const { priority = 1, headers = {}, timeout = 30000 } = options;\n\n  return {\n    id: 'api',\n    priority,\n\n    isAvailable: async () => {\n      if (typeof navigator !== 'undefined' && !navigator.onLine) {\n        return false;\n      }\n      try {\n        const response = await fetch(`${baseUrl}/health`, {\n          method: 'HEAD',\n          signal: AbortSignal.timeout(5000),\n        });\n        return response.ok;\n      } catch {\n        return false;\n      }\n    },\n\n    get: async (entityType, id) => {\n      const response = await fetch(`${baseUrl}/${entityType}/${id}`, {\n        headers,\n        signal: AbortSignal.timeout(timeout),\n      });\n      if (!response.ok) return null;\n      return (await response.json()) as Promise<unknown>;\n    },\n\n    getMany: async (entityType, ids) => {\n      const results = new Map();\n      const response = await fetch(`${baseUrl}/${entityType}?ids=${ids.join(',')}`, {\n        headers,\n        signal: AbortSignal.timeout(timeout),\n      });\n      if (response.ok) {\n        const data = (await response.json()) as unknown[];\n        for (const item of data) {\n          const itemWithId = item as { id?: string };\n          if (itemWithId.id !== undefined && itemWithId.id !== '') {\n            results.set(itemWithId.id, item);\n          }\n        }\n      }\n      return results;\n    },\n\n    getAll: async (entityType, options) => {\n      const params = new URLSearchParams();\n      if (options?.limit !== undefined && options.limit !== 0)\n        params.set('limit', String(options.limit));\n      if (options?.offset !== undefined && options.offset !== 0)\n        params.set('offset', String(options.offset));\n      if (options?.modifiedSince !== undefined && options.modifiedSince !== 0)\n        params.set('since', String(options.modifiedSince));\n\n      const url = `${baseUrl}/${entityType}${params.toString() ? `?${params}` : ''}`;\n      const response = await fetch(url, {\n        headers,\n        signal: AbortSignal.timeout(timeout),\n      });\n      if (!response.ok) return [];\n      return (await response.json()) as Promise<unknown[]>;\n    },\n\n    set: async (entityType, id, data) => {\n      await fetch(`${baseUrl}/${entityType}/${id}`, {\n        method: 'PUT',\n        headers: { ...headers, 'Content-Type': 'application/json' },\n        body: JSON.stringify(data),\n        signal: AbortSignal.timeout(timeout),\n      });\n    },\n\n    setMany: async (entityType, entities) => {\n      await fetch(`${baseUrl}/${entityType}/batch`, {\n        method: 'PUT',\n        headers: { ...headers, 'Content-Type': 'application/json' },\n        body: JSON.stringify(Object.fromEntries(entities)),\n        signal: AbortSignal.timeout(timeout),\n      });\n    },\n\n    delete: async (entityType, id) => {\n      await fetch(`${baseUrl}/${entityType}/${id}`, {\n        method: 'DELETE',\n        headers,\n        signal: AbortSignal.timeout(timeout),\n      });\n    },\n\n    deleteMany: async (entityType, ids) => {\n      await fetch(`${baseUrl}/${entityType}/batch`, {\n        method: 'DELETE',\n        headers: { ...headers, 'Content-Type': 'application/json' },\n        body: JSON.stringify({ ids }),\n        signal: AbortSignal.timeout(timeout),\n      });\n    },\n  };\n}\n\n/**\n * Create a localStorage sync source\n */\nexport function createLocalStorageSource(\n  prefix: string,\n  options: { priority?: SourcePriority } = {}\n): SyncSource {\n  const { priority = 2 } = options;\n\n  function getKey(entityType: string, id?: string): string {\n    return id !== undefined && id !== ''\n      ? `${prefix}:${entityType}:${id}`\n      : `${prefix}:${entityType}`;\n  }\n\n  function getAllKeys(entityType: string): string[] {\n    const keys: string[] = [];\n    const keyPrefix = `${getKey(entityType)}:`;\n    for (let i = 0; i < localStorage.length; i++) {\n      const key = localStorage.key(i);\n      if (key?.startsWith(keyPrefix) === true) {\n        keys.push(key);\n      }\n    }\n    return keys;\n  }\n\n  return {\n    id: 'localStorage',\n    priority,\n\n    isAvailable: () => {\n      try {\n        const testKey = '__storage_test__';\n        localStorage.setItem(testKey, testKey);\n        localStorage.removeItem(testKey);\n        return true;\n      } catch {\n        return false;\n      }\n    },\n\n    get: async (entityType, id) => {\n      await Promise.resolve();\n      const data = localStorage.getItem(getKey(entityType, id));\n      return data !== null && data !== '' ? (JSON.parse(data) as unknown) : null;\n    },\n\n    getMany: async (entityType, ids) => {\n      await Promise.resolve();\n      const results = new Map();\n      for (const id of ids) {\n        const data = localStorage.getItem(getKey(entityType, id));\n        if (data !== null && data !== '') {\n          results.set(id, JSON.parse(data) as unknown);\n        }\n      }\n      return results;\n    },\n\n    getAll: async (entityType) => {\n      await Promise.resolve();\n      const keys = getAllKeys(entityType);\n      const results: unknown[] = [];\n      for (const key of keys) {\n        const data = localStorage.getItem(key);\n        if (data !== null && data !== '') {\n          results.push(JSON.parse(data) as unknown);\n        }\n      }\n      return results;\n    },\n\n    set: async (entityType, id, data) => {\n      await Promise.resolve();\n      localStorage.setItem(getKey(entityType, id), JSON.stringify(data));\n    },\n\n    setMany: async (entityType, entities) => {\n      await Promise.resolve();\n      for (const [id, data] of entities) {\n        localStorage.setItem(getKey(entityType, id), JSON.stringify(data));\n      }\n    },\n\n    delete: async (entityType, id) => {\n      await Promise.resolve();\n      localStorage.removeItem(getKey(entityType, id));\n    },\n\n    deleteMany: async (entityType, ids) => {\n      await Promise.resolve();\n      for (const id of ids) {\n        localStorage.removeItem(getKey(entityType, id));\n      }\n    },\n  };\n}\n\n/**\n * Create a memory sync source (for testing)\n */\nexport function createMemorySource(options: { priority?: SourcePriority } = {}): SyncSource {\n  const { priority = 10 } = options;\n  const store = new Map<string, Map<string, unknown>>();\n\n  function getEntityStore(entityType: string): Map<string, unknown> {\n    let entityStore = store.get(entityType);\n    if (!entityStore) {\n      entityStore = new Map();\n      store.set(entityType, entityStore);\n    }\n    return entityStore;\n  }\n\n  return {\n    id: 'memory',\n    priority,\n\n    isAvailable: () => true,\n\n    get: async (entityType, id) => {\n      await Promise.resolve();\n      const value = getEntityStore(entityType).get(id);\n      return value ?? null;\n    },\n\n    getMany: async (entityType, ids) => {\n      await Promise.resolve();\n      const entityStore = getEntityStore(entityType);\n      const results = new Map<string, unknown>();\n      for (const id of ids) {\n        const data = entityStore.get(id);\n        if (data !== undefined && data !== null) results.set(id, data);\n      }\n      return results;\n    },\n\n    getAll: async (entityType) => {\n      await Promise.resolve();\n      return Array.from(getEntityStore(entityType).values());\n    },\n\n    set: async (entityType, id, data) => {\n      await Promise.resolve();\n      getEntityStore(entityType).set(id, data);\n    },\n\n    setMany: async (entityType, entities) => {\n      await Promise.resolve();\n      const entityStore = getEntityStore(entityType);\n      for (const [id, data] of entities) {\n        entityStore.set(id, data);\n      }\n    },\n\n    delete: async (entityType, id) => {\n      await Promise.resolve();\n      getEntityStore(entityType).delete(id);\n    },\n\n    deleteMany: async (entityType, ids) => {\n      await Promise.resolve();\n      const entityStore = getEntityStore(entityType);\n      for (const id of ids) {\n        entityStore.delete(id);\n      }\n    },\n  };\n}\n"],"names":["createSyncEngine","config","sources","conflictStrategy","syncInterval","maxRetries","offlineQueue","debug","entities","metadata","pendingOperations","subscribers","isOnlineState","syncIntervalId","sortedSources","a","b","log","args","emit","event","subscriber","error","getMetadataKey","entityType","id","getOrCreateMetadata","sourceId","key","meta","updateMetadata","updates","getEntityConfig","findAvailableSource","preferredId","preferred","s","source","queueOperation","operation","op","processPendingOperations","toProcess","index","resolveConflict","conflict","entityConfig","syncEntity","options","startTime","remoteData","remoteModifiedAt","localData","secondarySource","finalData","conflicts","direction","errorMessage","currentRetryCount","syncManyEntities","ids","results","result","syncAllEntities","entity","entityWithId","pushEntity","localSource","data","pullEntity","setupNetworkHandlers","handleOnline","handleOffline","start","stop","destroy","createEntity","dataWithId","updateEntity","deleteEntity","resolveConflictManual","_conflictId","_resolution","clearOfflineQueue","callback","createApiSource","baseUrl","priority","headers","timeout","response","item","itemWithId","params","url","createLocalStorageSource","prefix","getKey","getAllKeys","keys","keyPrefix","i","testKey","createMemorySource","store","getEntityStore","entityStore"],"mappings":"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"}