@affectively/aeon 1.3.1 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/LICENSE +15 -21
  2. package/README.md +422 -342
  3. package/dist/compression/index.cjs +20 -3
  4. package/dist/compression/index.cjs.map +1 -1
  5. package/dist/compression/index.js +20 -3
  6. package/dist/compression/index.js.map +1 -1
  7. package/dist/crypto/index.cjs +30 -0
  8. package/dist/crypto/index.cjs.map +1 -1
  9. package/dist/crypto/index.js +29 -1
  10. package/dist/crypto/index.js.map +1 -1
  11. package/dist/distributed/index.cjs +15 -8
  12. package/dist/distributed/index.cjs.map +1 -1
  13. package/dist/distributed/index.js +15 -8
  14. package/dist/distributed/index.js.map +1 -1
  15. package/dist/index.cjs +6686 -3118
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.js +6642 -3117
  18. package/dist/index.js.map +1 -1
  19. package/dist/offline/index.cjs.map +1 -1
  20. package/dist/offline/index.js.map +1 -1
  21. package/dist/optimization/index.cjs +6 -3
  22. package/dist/optimization/index.cjs.map +1 -1
  23. package/dist/optimization/index.js +6 -3
  24. package/dist/optimization/index.js.map +1 -1
  25. package/dist/persistence/index.cjs +91 -29
  26. package/dist/persistence/index.cjs.map +1 -1
  27. package/dist/persistence/index.js +91 -29
  28. package/dist/persistence/index.js.map +1 -1
  29. package/dist/presence/index.cjs.map +1 -1
  30. package/dist/presence/index.js.map +1 -1
  31. package/dist/utils/index.cjs.map +1 -1
  32. package/dist/utils/index.js.map +1 -1
  33. package/dist/versioning/index.cjs +4 -3
  34. package/dist/versioning/index.cjs.map +1 -1
  35. package/dist/versioning/index.js +4 -3
  36. package/dist/versioning/index.js.map +1 -1
  37. package/package.json +195 -196
  38. package/dist/compression/index.d.cts +0 -189
  39. package/dist/compression/index.d.ts +0 -189
  40. package/dist/core/index.d.cts +0 -216
  41. package/dist/core/index.d.ts +0 -216
  42. package/dist/crypto/index.d.cts +0 -446
  43. package/dist/crypto/index.d.ts +0 -446
  44. package/dist/distributed/index.d.cts +0 -1016
  45. package/dist/distributed/index.d.ts +0 -1016
  46. package/dist/index.d.cts +0 -57
  47. package/dist/index.d.ts +0 -57
  48. package/dist/offline/index.d.cts +0 -154
  49. package/dist/offline/index.d.ts +0 -154
  50. package/dist/optimization/index.d.cts +0 -347
  51. package/dist/optimization/index.d.ts +0 -347
  52. package/dist/persistence/index.d.cts +0 -63
  53. package/dist/persistence/index.d.ts +0 -63
  54. package/dist/presence/index.d.cts +0 -283
  55. package/dist/presence/index.d.ts +0 -283
  56. package/dist/types-B7CxsoLh.d.cts +0 -33
  57. package/dist/types-B7CxsoLh.d.ts +0 -33
  58. package/dist/utils/index.d.cts +0 -38
  59. package/dist/utils/index.d.ts +0 -38
  60. package/dist/versioning/index.d.cts +0 -537
  61. package/dist/versioning/index.d.ts +0 -537
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/logger.ts","../../src/offline/OfflineOperationQueue.ts"],"names":["EventEmitter"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Aeon Logger Interface\r\n *\r\n * Provides a pluggable logging interface that can be configured\r\n * by consumers to integrate with their preferred logging solution.\r\n */\r\n\r\n/**\r\n * Logger interface that consumers can implement\r\n */\r\nexport interface Logger {\r\n debug: (...args: unknown[]) => void;\r\n info: (...args: unknown[]) => void;\r\n warn: (...args: unknown[]) => void;\r\n error: (...args: unknown[]) => void;\r\n}\r\n\r\n/**\r\n * Default console logger implementation\r\n */\r\nconst consoleLogger: Logger = {\r\n debug: (...args: unknown[]) => {\r\n // eslint-disable-next-line no-console\r\n console.debug('[AEON:DEBUG]', ...args);\r\n },\r\n info: (...args: unknown[]) => {\r\n // eslint-disable-next-line no-console\r\n console.info('[AEON:INFO]', ...args);\r\n },\r\n warn: (...args: unknown[]) => {\r\n // eslint-disable-next-line no-console\r\n console.warn('[AEON:WARN]', ...args);\r\n },\r\n error: (...args: unknown[]) => {\r\n // eslint-disable-next-line no-console\r\n console.error('[AEON:ERROR]', ...args);\r\n },\r\n};\r\n\r\n/**\r\n * No-op logger for production or when logging is disabled\r\n */\r\nconst noopLogger: Logger = {\r\n debug: () => {},\r\n info: () => {},\r\n warn: () => {},\r\n error: () => {},\r\n};\r\n\r\n/**\r\n * Current logger instance\r\n */\r\nlet currentLogger: Logger = consoleLogger;\r\n\r\n/**\r\n * Get the current logger instance\r\n */\r\nexport function getLogger(): Logger {\r\n return currentLogger;\r\n}\r\n\r\n/**\r\n * Set a custom logger implementation\r\n */\r\nexport function setLogger(logger: Logger): void {\r\n currentLogger = logger;\r\n}\r\n\r\n/**\r\n * Reset to the default console logger\r\n */\r\nexport function resetLogger(): void {\r\n currentLogger = consoleLogger;\r\n}\r\n\r\n/**\r\n * Disable all logging\r\n */\r\nexport function disableLogging(): void {\r\n currentLogger = noopLogger;\r\n}\r\n\r\n/**\r\n * Create a namespaced logger\r\n */\r\nexport function createNamespacedLogger(namespace: string): Logger {\r\n const logger = getLogger();\r\n return {\r\n debug: (...args: unknown[]) => logger.debug(`[${namespace}]`, ...args),\r\n info: (...args: unknown[]) => logger.info(`[${namespace}]`, ...args),\r\n warn: (...args: unknown[]) => logger.warn(`[${namespace}]`, ...args),\r\n error: (...args: unknown[]) => logger.error(`[${namespace}]`, ...args),\r\n };\r\n}\r\n\r\n// Export default logger for convenience\r\nexport const logger: Logger = {\r\n debug: (...args: unknown[]) => getLogger().debug(...args),\r\n info: (...args: unknown[]) => getLogger().info(...args),\r\n warn: (...args: unknown[]) => getLogger().warn(...args),\r\n error: (...args: unknown[]) => getLogger().error(...args),\r\n};\r\n","/**\r\n * Offline Operation Queue (Phase 11)\r\n *\r\n * Manages pending operations for offline-first clients.\r\n * Provides priority-based queuing, persistence, and retry logic.\r\n */\r\n\r\nimport { EventEmitter } from 'eventemitter3';\r\nimport { getLogger } from '../utils/logger';\r\nimport type { Operation, OperationPriority } from '../core/types';\r\nimport type {\r\n PersistedEnvelope,\r\n PersistenceDeserializer,\r\n PersistenceSerializer,\r\n StorageAdapter,\r\n} from '../persistence';\r\n\r\nconst logger = getLogger();\r\n\r\n// Re-export OperationPriority from core\r\nexport type { OperationPriority } from '../core/types';\r\n\r\nexport interface OfflineOperation {\r\n id: string;\r\n type: Operation['type'];\r\n data: Record<string, unknown>;\r\n sessionId: string;\r\n priority: OperationPriority;\r\n createdAt: number;\r\n retryCount: number;\r\n maxRetries: number;\r\n lastError?: string;\r\n status: 'pending' | 'syncing' | 'failed' | 'synced';\r\n}\r\n\r\nexport interface OfflineQueueStats {\r\n pending: number;\r\n syncing: number;\r\n failed: number;\r\n synced: number;\r\n totalOperations: number;\r\n oldestPendingMs: number;\r\n averageRetries: number;\r\n}\r\n\r\nexport interface OfflineQueueEvents {\r\n 'operation-added': (operation: OfflineOperation) => void;\r\n 'operation-synced': (operation: OfflineOperation) => void;\r\n 'operation-failed': (operation: OfflineOperation, error: Error) => void;\r\n 'queue-empty': () => void;\r\n 'sync-started': () => void;\r\n 'sync-completed': (stats: { synced: number; failed: number }) => void;\r\n}\r\n\r\nexport interface OfflineQueuePersistenceConfig {\r\n adapter: StorageAdapter;\r\n key?: string;\r\n autoPersist?: boolean;\r\n autoLoad?: boolean;\r\n persistDebounceMs?: number;\r\n serializer?: PersistenceSerializer<OfflineOperation[]>;\r\n deserializer?: PersistenceDeserializer<OfflineOperation[]>;\r\n}\r\n\r\nexport interface OfflineOperationQueueOptions {\r\n maxQueueSize?: number;\r\n defaultMaxRetries?: number;\r\n persistence?: OfflineQueuePersistenceConfig;\r\n}\r\n\r\n// ============================================================================\r\n// Offline Operation Queue\r\n// ============================================================================\r\n\r\nexport class OfflineOperationQueue extends EventEmitter<OfflineQueueEvents> {\r\n private static readonly DEFAULT_PERSIST_KEY = 'aeon:offline-queue:v1';\r\n private queue: Map<string, OfflineOperation> = new Map();\r\n private syncingIds: Set<string> = new Set();\r\n private maxQueueSize = 1000;\r\n private defaultMaxRetries = 3;\r\n private persistence:\r\n | (OfflineQueuePersistenceConfig & { key: string })\r\n | null = null;\r\n private persistTimer: ReturnType<typeof setTimeout> | null = null;\r\n private persistInFlight = false;\r\n private persistPending = false;\r\n\r\n constructor(\r\n maxQueueSizeOrOptions: number | OfflineOperationQueueOptions = 1000,\r\n defaultMaxRetries = 3\r\n ) {\r\n super();\r\n\r\n if (typeof maxQueueSizeOrOptions === 'number') {\r\n this.maxQueueSize = maxQueueSizeOrOptions;\r\n this.defaultMaxRetries = defaultMaxRetries;\r\n } else {\r\n this.maxQueueSize = maxQueueSizeOrOptions.maxQueueSize ?? 1000;\r\n this.defaultMaxRetries = maxQueueSizeOrOptions.defaultMaxRetries ?? 3;\r\n\r\n if (maxQueueSizeOrOptions.persistence) {\r\n this.persistence = {\r\n ...maxQueueSizeOrOptions.persistence,\r\n key:\r\n maxQueueSizeOrOptions.persistence.key ??\r\n OfflineOperationQueue.DEFAULT_PERSIST_KEY,\r\n autoPersist: maxQueueSizeOrOptions.persistence.autoPersist ?? true,\r\n autoLoad: maxQueueSizeOrOptions.persistence.autoLoad ?? false,\r\n persistDebounceMs:\r\n maxQueueSizeOrOptions.persistence.persistDebounceMs ?? 25,\r\n };\r\n\r\n if (this.persistence.autoLoad) {\r\n void this.loadFromPersistence().catch((error) => {\r\n logger.error('[OfflineOperationQueue] Failed to load persistence', {\r\n key: this.persistence?.key,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n });\r\n }\r\n }\r\n }\r\n\r\n logger.debug('[OfflineOperationQueue] Initialized', {\r\n maxQueueSize: this.maxQueueSize,\r\n defaultMaxRetries: this.defaultMaxRetries,\r\n persistenceEnabled: this.persistence !== null,\r\n });\r\n }\r\n\r\n /**\r\n * Add operation to the queue\r\n */\r\n enqueue(\r\n type: Operation['type'],\r\n data: Record<string, unknown>,\r\n sessionId: string,\r\n priority: OperationPriority = 'normal',\r\n maxRetries?: number\r\n ): OfflineOperation {\r\n if (this.queue.size >= this.maxQueueSize) {\r\n // Remove oldest low-priority operation\r\n const oldest = this.findOldestLowPriority();\r\n if (oldest) {\r\n this.queue.delete(oldest.id);\r\n logger.warn('[OfflineOperationQueue] Queue full, removed oldest', {\r\n removedId: oldest.id,\r\n });\r\n }\r\n }\r\n\r\n const operation: OfflineOperation = {\r\n id: `op-${Date.now()}-${Math.random().toString(36).slice(2)}`,\r\n type,\r\n data,\r\n sessionId,\r\n priority,\r\n createdAt: Date.now(),\r\n retryCount: 0,\r\n maxRetries: maxRetries ?? this.defaultMaxRetries,\r\n status: 'pending',\r\n };\r\n\r\n this.queue.set(operation.id, operation);\r\n this.emit('operation-added', operation);\r\n this.schedulePersist();\r\n\r\n logger.debug('[OfflineOperationQueue] Operation enqueued', {\r\n id: operation.id,\r\n type,\r\n priority,\r\n queueSize: this.queue.size,\r\n });\r\n\r\n return operation;\r\n }\r\n\r\n /**\r\n * Get next operations to sync (by priority)\r\n */\r\n getNextBatch(batchSize = 10): OfflineOperation[] {\r\n const pending = Array.from(this.queue.values())\r\n .filter((op) => op.status === 'pending' && !this.syncingIds.has(op.id))\r\n .sort((a, b) => {\r\n // Sort by priority first, then by creation time\r\n const priorityOrder = { high: 0, normal: 1, low: 2 };\r\n const priorityDiff =\r\n priorityOrder[a.priority] - priorityOrder[b.priority];\r\n if (priorityDiff !== 0) return priorityDiff;\r\n return a.createdAt - b.createdAt;\r\n });\r\n\r\n return pending.slice(0, batchSize);\r\n }\r\n\r\n /**\r\n * Mark operations as syncing\r\n */\r\n markSyncing(operationIds: string[]): void {\r\n let changed = false;\r\n for (const id of operationIds) {\r\n const op = this.queue.get(id);\r\n if (op) {\r\n op.status = 'syncing';\r\n this.syncingIds.add(id);\r\n changed = true;\r\n }\r\n }\r\n\r\n if (changed) {\r\n this.schedulePersist();\r\n }\r\n }\r\n\r\n /**\r\n * Mark operation as synced\r\n */\r\n markSynced(operationId: string): void {\r\n const op = this.queue.get(operationId);\r\n if (op) {\r\n op.status = 'synced';\r\n this.syncingIds.delete(operationId);\r\n this.emit('operation-synced', op);\r\n this.schedulePersist();\r\n\r\n // Remove synced operations after short delay\r\n setTimeout(() => {\r\n this.queue.delete(operationId);\r\n this.schedulePersist();\r\n if (this.getPendingCount() === 0) {\r\n this.emit('queue-empty');\r\n }\r\n }, 1000);\r\n }\r\n }\r\n\r\n /**\r\n * Mark operation as failed\r\n */\r\n markFailed(operationId: string, error: Error): void {\r\n const op = this.queue.get(operationId);\r\n if (op) {\r\n op.retryCount++;\r\n op.lastError = error.message;\r\n this.syncingIds.delete(operationId);\r\n\r\n if (op.retryCount >= op.maxRetries) {\r\n op.status = 'failed';\r\n this.emit('operation-failed', op, error);\r\n logger.error('[OfflineOperationQueue] Operation permanently failed', {\r\n id: operationId,\r\n retries: op.retryCount,\r\n error: error.message,\r\n });\r\n } else {\r\n op.status = 'pending';\r\n logger.warn('[OfflineOperationQueue] Operation failed, will retry', {\r\n id: operationId,\r\n retryCount: op.retryCount,\r\n maxRetries: op.maxRetries,\r\n });\r\n }\r\n\r\n this.schedulePersist();\r\n }\r\n }\r\n\r\n /**\r\n * Get operation by ID\r\n */\r\n getOperation(operationId: string): OfflineOperation | undefined {\r\n return this.queue.get(operationId);\r\n }\r\n\r\n /**\r\n * Get all pending operations\r\n */\r\n getPendingOperations(): OfflineOperation[] {\r\n return Array.from(this.queue.values()).filter(\r\n (op) => op.status === 'pending'\r\n );\r\n }\r\n\r\n /**\r\n * Get pending count\r\n */\r\n getPendingCount(): number {\r\n return Array.from(this.queue.values()).filter(\r\n (op) => op.status === 'pending'\r\n ).length;\r\n }\r\n\r\n /**\r\n * Get queue statistics\r\n */\r\n getStats(): OfflineQueueStats {\r\n const operations = Array.from(this.queue.values());\r\n\r\n const pending = operations.filter((op) => op.status === 'pending').length;\r\n const syncing = operations.filter((op) => op.status === 'syncing').length;\r\n const failed = operations.filter((op) => op.status === 'failed').length;\r\n const synced = operations.filter((op) => op.status === 'synced').length;\r\n\r\n const pendingOps = operations.filter((op) => op.status === 'pending');\r\n const oldestPendingMs =\r\n pendingOps.length > 0\r\n ? Date.now() - Math.min(...pendingOps.map((op) => op.createdAt))\r\n : 0;\r\n\r\n const averageRetries =\r\n operations.length > 0\r\n ? operations.reduce((sum, op) => sum + op.retryCount, 0) /\r\n operations.length\r\n : 0;\r\n\r\n return {\r\n pending,\r\n syncing,\r\n failed,\r\n synced,\r\n totalOperations: operations.length,\r\n oldestPendingMs,\r\n averageRetries,\r\n };\r\n }\r\n\r\n /**\r\n * Clear all operations\r\n */\r\n clear(): void {\r\n this.queue.clear();\r\n this.syncingIds.clear();\r\n this.schedulePersist();\r\n logger.debug('[OfflineOperationQueue] Queue cleared');\r\n }\r\n\r\n /**\r\n * Clear failed operations\r\n */\r\n clearFailed(): void {\r\n let changed = false;\r\n for (const [id, op] of this.queue.entries()) {\r\n if (op.status === 'failed') {\r\n this.queue.delete(id);\r\n changed = true;\r\n }\r\n }\r\n\r\n if (changed) {\r\n this.schedulePersist();\r\n }\r\n }\r\n\r\n /**\r\n * Retry failed operations\r\n */\r\n retryFailed(): void {\r\n let changed = false;\r\n for (const op of this.queue.values()) {\r\n if (op.status === 'failed') {\r\n op.status = 'pending';\r\n op.retryCount = 0;\r\n changed = true;\r\n }\r\n }\r\n\r\n if (changed) {\r\n this.schedulePersist();\r\n }\r\n }\r\n\r\n /**\r\n * Find oldest low-priority operation\r\n */\r\n private findOldestLowPriority(): OfflineOperation | null {\r\n const lowPriority = Array.from(this.queue.values())\r\n .filter((op) => op.priority === 'low' && op.status === 'pending')\r\n .sort((a, b) => a.createdAt - b.createdAt);\r\n\r\n return lowPriority[0] ?? null;\r\n }\r\n\r\n /**\r\n * Export queue for persistence\r\n */\r\n export(): OfflineOperation[] {\r\n return Array.from(this.queue.values());\r\n }\r\n\r\n /**\r\n * Import queue from persistence\r\n */\r\n import(operations: OfflineOperation[]): void {\r\n this.queue.clear();\r\n this.syncingIds.clear();\r\n\r\n for (const op of operations) {\r\n if (this.isValidOfflineOperation(op)) {\r\n this.queue.set(op.id, {\r\n ...op,\r\n status: op.status === 'syncing' ? 'pending' : op.status,\r\n });\r\n }\r\n }\r\n\r\n this.schedulePersist();\r\n\r\n logger.debug('[OfflineOperationQueue] Imported operations', {\r\n count: this.queue.size,\r\n });\r\n }\r\n\r\n /**\r\n * Persist current queue snapshot.\r\n */\r\n async saveToPersistence(): Promise<void> {\r\n if (!this.persistence) {\r\n return;\r\n }\r\n\r\n const envelope: PersistedEnvelope<OfflineOperation[]> = {\r\n version: 1,\r\n updatedAt: Date.now(),\r\n data: this.export(),\r\n };\r\n\r\n const serialize =\r\n this.persistence.serializer ??\r\n ((value: PersistedEnvelope<OfflineOperation[]>) => JSON.stringify(value));\r\n const raw = serialize(envelope);\r\n\r\n await this.persistence.adapter.setItem(this.persistence.key, raw);\r\n }\r\n\r\n /**\r\n * Load queue snapshot from persistence.\r\n */\r\n async loadFromPersistence(): Promise<number> {\r\n if (!this.persistence) {\r\n return 0;\r\n }\r\n\r\n const raw = await this.persistence.adapter.getItem(this.persistence.key);\r\n if (!raw) {\r\n return 0;\r\n }\r\n\r\n const deserialize =\r\n this.persistence.deserializer ??\r\n ((value: string) =>\r\n JSON.parse(value) as PersistedEnvelope<OfflineOperation[]>);\r\n\r\n const envelope = deserialize(raw);\r\n if (envelope.version !== 1 || !Array.isArray(envelope.data)) {\r\n throw new Error('Invalid offline queue persistence payload');\r\n }\r\n\r\n this.queue.clear();\r\n this.syncingIds.clear();\r\n\r\n let imported = 0;\r\n for (const operation of envelope.data) {\r\n if (this.isValidOfflineOperation(operation)) {\r\n this.queue.set(operation.id, {\r\n ...operation,\r\n status: operation.status === 'syncing' ? 'pending' : operation.status,\r\n });\r\n imported++;\r\n }\r\n }\r\n\r\n logger.debug('[OfflineOperationQueue] Loaded from persistence', {\r\n key: this.persistence.key,\r\n imported,\r\n });\r\n\r\n return imported;\r\n }\r\n\r\n /**\r\n * Remove persisted queue snapshot.\r\n */\r\n async clearPersistence(): Promise<void> {\r\n if (!this.persistence) {\r\n return;\r\n }\r\n await this.persistence.adapter.removeItem(this.persistence.key);\r\n }\r\n\r\n private schedulePersist(): void {\r\n if (!this.persistence || this.persistence.autoPersist === false) {\r\n return;\r\n }\r\n\r\n if (this.persistTimer) {\r\n clearTimeout(this.persistTimer);\r\n }\r\n\r\n this.persistTimer = setTimeout(() => {\r\n void this.persistSafely();\r\n }, this.persistence.persistDebounceMs ?? 25);\r\n }\r\n\r\n private async persistSafely(): Promise<void> {\r\n if (!this.persistence) {\r\n return;\r\n }\r\n\r\n if (this.persistInFlight) {\r\n this.persistPending = true;\r\n return;\r\n }\r\n\r\n this.persistInFlight = true;\r\n\r\n try {\r\n await this.saveToPersistence();\r\n } catch (error) {\r\n logger.error('[OfflineOperationQueue] Persistence write failed', {\r\n key: this.persistence.key,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n } finally {\r\n this.persistInFlight = false;\r\n const shouldRunAgain = this.persistPending;\r\n this.persistPending = false;\r\n if (shouldRunAgain) {\r\n void this.persistSafely();\r\n }\r\n }\r\n }\r\n\r\n private isValidOfflineOperation(value: unknown): value is OfflineOperation {\r\n if (typeof value !== 'object' || value === null) {\r\n return false;\r\n }\r\n\r\n const candidate = value as Partial<OfflineOperation>;\r\n const validType =\r\n candidate.type === 'create' ||\r\n candidate.type === 'update' ||\r\n candidate.type === 'delete' ||\r\n candidate.type === 'sync' ||\r\n candidate.type === 'batch';\r\n const validPriority =\r\n candidate.priority === 'high' ||\r\n candidate.priority === 'normal' ||\r\n candidate.priority === 'low';\r\n const validStatus =\r\n candidate.status === 'pending' ||\r\n candidate.status === 'syncing' ||\r\n candidate.status === 'failed' ||\r\n candidate.status === 'synced';\r\n\r\n return (\r\n typeof candidate.id === 'string' &&\r\n validType &&\r\n typeof candidate.data === 'object' &&\r\n candidate.data !== null &&\r\n !Array.isArray(candidate.data) &&\r\n typeof candidate.sessionId === 'string' &&\r\n validPriority &&\r\n typeof candidate.createdAt === 'number' &&\r\n typeof candidate.retryCount === 'number' &&\r\n typeof candidate.maxRetries === 'number' &&\r\n validStatus\r\n );\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Singleton Instance\r\n// ============================================================================\r\n\r\nlet offlineQueueInstance: OfflineOperationQueue | null = null;\r\n\r\nexport function getOfflineOperationQueue(): OfflineOperationQueue {\r\n if (!offlineQueueInstance) {\r\n offlineQueueInstance = new OfflineOperationQueue();\r\n }\r\n return offlineQueueInstance;\r\n}\r\n\r\nexport function resetOfflineOperationQueue(): void {\r\n offlineQueueInstance = null;\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/utils/logger.ts","../../src/offline/OfflineOperationQueue.ts"],"names":["EventEmitter"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Aeon Logger Interface\n *\n * Provides a pluggable logging interface that can be configured\n * by consumers to integrate with their preferred logging solution.\n */\n\n/**\n * Logger interface that consumers can implement\n */\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\n/**\n * Default console logger implementation\n */\nconst consoleLogger: Logger = {\n debug: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.debug('[AEON:DEBUG]', ...args);\n },\n info: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.info('[AEON:INFO]', ...args);\n },\n warn: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.warn('[AEON:WARN]', ...args);\n },\n error: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.error('[AEON:ERROR]', ...args);\n },\n};\n\n/**\n * No-op logger for production or when logging is disabled\n */\nconst noopLogger: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\n/**\n * Current logger instance\n */\nlet currentLogger: Logger = consoleLogger;\n\n/**\n * Get the current logger instance\n */\nexport function getLogger(): Logger {\n return currentLogger;\n}\n\n/**\n * Set a custom logger implementation\n */\nexport function setLogger(logger: Logger): void {\n currentLogger = logger;\n}\n\n/**\n * Reset to the default console logger\n */\nexport function resetLogger(): void {\n currentLogger = consoleLogger;\n}\n\n/**\n * Disable all logging\n */\nexport function disableLogging(): void {\n currentLogger = noopLogger;\n}\n\n/**\n * Create a namespaced logger\n */\nexport function createNamespacedLogger(namespace: string): Logger {\n const logger = getLogger();\n return {\n debug: (...args: unknown[]) => logger.debug(`[${namespace}]`, ...args),\n info: (...args: unknown[]) => logger.info(`[${namespace}]`, ...args),\n warn: (...args: unknown[]) => logger.warn(`[${namespace}]`, ...args),\n error: (...args: unknown[]) => logger.error(`[${namespace}]`, ...args),\n };\n}\n\n// Export default logger for convenience\nexport const logger: Logger = {\n debug: (...args: unknown[]) => getLogger().debug(...args),\n info: (...args: unknown[]) => getLogger().info(...args),\n warn: (...args: unknown[]) => getLogger().warn(...args),\n error: (...args: unknown[]) => getLogger().error(...args),\n};\n","/**\n * Offline Operation Queue (Phase 11)\n *\n * Manages pending operations for offline-first clients.\n * Provides priority-based queuing, persistence, and retry logic.\n */\n\nimport { EventEmitter } from 'eventemitter3';\nimport { getLogger } from '../utils/logger';\nimport type { Operation, OperationPriority } from '../core/types';\nimport type {\n PersistedEnvelope,\n PersistenceDeserializer,\n PersistenceSerializer,\n StorageAdapter,\n} from '../persistence';\n\nconst logger = getLogger();\n\n// Re-export OperationPriority from core\nexport type { OperationPriority } from '../core/types';\n\nexport interface OfflineOperation {\n id: string;\n type: Operation['type'];\n data: Record<string, unknown>;\n sessionId: string;\n priority: OperationPriority;\n createdAt: number;\n retryCount: number;\n maxRetries: number;\n lastError?: string;\n status: 'pending' | 'syncing' | 'failed' | 'synced';\n}\n\nexport interface OfflineQueueStats {\n pending: number;\n syncing: number;\n failed: number;\n synced: number;\n totalOperations: number;\n oldestPendingMs: number;\n averageRetries: number;\n}\n\nexport interface OfflineQueueEvents {\n 'operation-added': (operation: OfflineOperation) => void;\n 'operation-synced': (operation: OfflineOperation) => void;\n 'operation-failed': (operation: OfflineOperation, error: Error) => void;\n 'queue-empty': () => void;\n 'sync-started': () => void;\n 'sync-completed': (stats: { synced: number; failed: number }) => void;\n}\n\nexport interface OfflineQueuePersistenceConfig {\n adapter: StorageAdapter;\n key?: string;\n autoPersist?: boolean;\n autoLoad?: boolean;\n persistDebounceMs?: number;\n serializer?: PersistenceSerializer<OfflineOperation[]>;\n deserializer?: PersistenceDeserializer<OfflineOperation[]>;\n}\n\nexport interface OfflineOperationQueueOptions {\n maxQueueSize?: number;\n defaultMaxRetries?: number;\n persistence?: OfflineQueuePersistenceConfig;\n}\n\n// ============================================================================\n// Offline Operation Queue\n// ============================================================================\n\nexport class OfflineOperationQueue extends EventEmitter<OfflineQueueEvents> {\n private static readonly DEFAULT_PERSIST_KEY = 'aeon:offline-queue:v1';\n private queue: Map<string, OfflineOperation> = new Map();\n private syncingIds: Set<string> = new Set();\n private maxQueueSize = 1000;\n private defaultMaxRetries = 3;\n private persistence:\n | (OfflineQueuePersistenceConfig & { key: string })\n | null = null;\n private persistTimer: ReturnType<typeof setTimeout> | null = null;\n private persistInFlight = false;\n private persistPending = false;\n\n constructor(\n maxQueueSizeOrOptions: number | OfflineOperationQueueOptions = 1000,\n defaultMaxRetries = 3\n ) {\n super();\n\n if (typeof maxQueueSizeOrOptions === 'number') {\n this.maxQueueSize = maxQueueSizeOrOptions;\n this.defaultMaxRetries = defaultMaxRetries;\n } else {\n this.maxQueueSize = maxQueueSizeOrOptions.maxQueueSize ?? 1000;\n this.defaultMaxRetries = maxQueueSizeOrOptions.defaultMaxRetries ?? 3;\n\n if (maxQueueSizeOrOptions.persistence) {\n this.persistence = {\n ...maxQueueSizeOrOptions.persistence,\n key:\n maxQueueSizeOrOptions.persistence.key ??\n OfflineOperationQueue.DEFAULT_PERSIST_KEY,\n autoPersist: maxQueueSizeOrOptions.persistence.autoPersist ?? true,\n autoLoad: maxQueueSizeOrOptions.persistence.autoLoad ?? false,\n persistDebounceMs:\n maxQueueSizeOrOptions.persistence.persistDebounceMs ?? 25,\n };\n\n if (this.persistence.autoLoad) {\n void this.loadFromPersistence().catch((error) => {\n logger.error('[OfflineOperationQueue] Failed to load persistence', {\n key: this.persistence?.key,\n error: error instanceof Error ? error.message : String(error),\n });\n });\n }\n }\n }\n\n logger.debug('[OfflineOperationQueue] Initialized', {\n maxQueueSize: this.maxQueueSize,\n defaultMaxRetries: this.defaultMaxRetries,\n persistenceEnabled: this.persistence !== null,\n });\n }\n\n /**\n * Add operation to the queue\n */\n enqueue(\n type: Operation['type'],\n data: Record<string, unknown>,\n sessionId: string,\n priority: OperationPriority = 'normal',\n maxRetries?: number\n ): OfflineOperation {\n if (this.queue.size >= this.maxQueueSize) {\n // Remove oldest low-priority operation\n const oldest = this.findOldestLowPriority();\n if (oldest) {\n this.queue.delete(oldest.id);\n logger.warn('[OfflineOperationQueue] Queue full, removed oldest', {\n removedId: oldest.id,\n });\n }\n }\n\n const operation: OfflineOperation = {\n id: `op-${Date.now()}-${Math.random().toString(36).slice(2)}`,\n type,\n data,\n sessionId,\n priority,\n createdAt: Date.now(),\n retryCount: 0,\n maxRetries: maxRetries ?? this.defaultMaxRetries,\n status: 'pending',\n };\n\n this.queue.set(operation.id, operation);\n this.emit('operation-added', operation);\n this.schedulePersist();\n\n logger.debug('[OfflineOperationQueue] Operation enqueued', {\n id: operation.id,\n type,\n priority,\n queueSize: this.queue.size,\n });\n\n return operation;\n }\n\n /**\n * Get next operations to sync (by priority)\n */\n getNextBatch(batchSize = 10): OfflineOperation[] {\n const pending = Array.from(this.queue.values())\n .filter((op) => op.status === 'pending' && !this.syncingIds.has(op.id))\n .sort((a, b) => {\n // Sort by priority first, then by creation time\n const priorityOrder = { high: 0, normal: 1, low: 2 };\n const priorityDiff =\n priorityOrder[a.priority] - priorityOrder[b.priority];\n if (priorityDiff !== 0) return priorityDiff;\n return a.createdAt - b.createdAt;\n });\n\n return pending.slice(0, batchSize);\n }\n\n /**\n * Mark operations as syncing\n */\n markSyncing(operationIds: string[]): void {\n let changed = false;\n for (const id of operationIds) {\n const op = this.queue.get(id);\n if (op) {\n op.status = 'syncing';\n this.syncingIds.add(id);\n changed = true;\n }\n }\n\n if (changed) {\n this.schedulePersist();\n }\n }\n\n /**\n * Mark operation as synced\n */\n markSynced(operationId: string): void {\n const op = this.queue.get(operationId);\n if (op) {\n op.status = 'synced';\n this.syncingIds.delete(operationId);\n this.emit('operation-synced', op);\n this.schedulePersist();\n\n // Remove synced operations after short delay\n setTimeout(() => {\n this.queue.delete(operationId);\n this.schedulePersist();\n if (this.getPendingCount() === 0) {\n this.emit('queue-empty');\n }\n }, 1000);\n }\n }\n\n /**\n * Mark operation as failed\n */\n markFailed(operationId: string, error: Error): void {\n const op = this.queue.get(operationId);\n if (op) {\n op.retryCount++;\n op.lastError = error.message;\n this.syncingIds.delete(operationId);\n\n if (op.retryCount >= op.maxRetries) {\n op.status = 'failed';\n this.emit('operation-failed', op, error);\n logger.error('[OfflineOperationQueue] Operation permanently failed', {\n id: operationId,\n retries: op.retryCount,\n error: error.message,\n });\n } else {\n op.status = 'pending';\n logger.warn('[OfflineOperationQueue] Operation failed, will retry', {\n id: operationId,\n retryCount: op.retryCount,\n maxRetries: op.maxRetries,\n });\n }\n\n this.schedulePersist();\n }\n }\n\n /**\n * Get operation by ID\n */\n getOperation(operationId: string): OfflineOperation | undefined {\n return this.queue.get(operationId);\n }\n\n /**\n * Get all pending operations\n */\n getPendingOperations(): OfflineOperation[] {\n return Array.from(this.queue.values()).filter(\n (op) => op.status === 'pending'\n );\n }\n\n /**\n * Get pending count\n */\n getPendingCount(): number {\n return Array.from(this.queue.values()).filter(\n (op) => op.status === 'pending'\n ).length;\n }\n\n /**\n * Get queue statistics\n */\n getStats(): OfflineQueueStats {\n const operations = Array.from(this.queue.values());\n\n const pending = operations.filter((op) => op.status === 'pending').length;\n const syncing = operations.filter((op) => op.status === 'syncing').length;\n const failed = operations.filter((op) => op.status === 'failed').length;\n const synced = operations.filter((op) => op.status === 'synced').length;\n\n const pendingOps = operations.filter((op) => op.status === 'pending');\n const oldestPendingMs =\n pendingOps.length > 0\n ? Date.now() - Math.min(...pendingOps.map((op) => op.createdAt))\n : 0;\n\n const averageRetries =\n operations.length > 0\n ? operations.reduce((sum, op) => sum + op.retryCount, 0) /\n operations.length\n : 0;\n\n return {\n pending,\n syncing,\n failed,\n synced,\n totalOperations: operations.length,\n oldestPendingMs,\n averageRetries,\n };\n }\n\n /**\n * Clear all operations\n */\n clear(): void {\n this.queue.clear();\n this.syncingIds.clear();\n this.schedulePersist();\n logger.debug('[OfflineOperationQueue] Queue cleared');\n }\n\n /**\n * Clear failed operations\n */\n clearFailed(): void {\n let changed = false;\n for (const [id, op] of this.queue.entries()) {\n if (op.status === 'failed') {\n this.queue.delete(id);\n changed = true;\n }\n }\n\n if (changed) {\n this.schedulePersist();\n }\n }\n\n /**\n * Retry failed operations\n */\n retryFailed(): void {\n let changed = false;\n for (const op of this.queue.values()) {\n if (op.status === 'failed') {\n op.status = 'pending';\n op.retryCount = 0;\n changed = true;\n }\n }\n\n if (changed) {\n this.schedulePersist();\n }\n }\n\n /**\n * Find oldest low-priority operation\n */\n private findOldestLowPriority(): OfflineOperation | null {\n const lowPriority = Array.from(this.queue.values())\n .filter((op) => op.priority === 'low' && op.status === 'pending')\n .sort((a, b) => a.createdAt - b.createdAt);\n\n return lowPriority[0] ?? null;\n }\n\n /**\n * Export queue for persistence\n */\n export(): OfflineOperation[] {\n return Array.from(this.queue.values());\n }\n\n /**\n * Import queue from persistence\n */\n import(operations: OfflineOperation[]): void {\n this.queue.clear();\n this.syncingIds.clear();\n\n for (const op of operations) {\n if (this.isValidOfflineOperation(op)) {\n this.queue.set(op.id, {\n ...op,\n status: op.status === 'syncing' ? 'pending' : op.status,\n });\n }\n }\n\n this.schedulePersist();\n\n logger.debug('[OfflineOperationQueue] Imported operations', {\n count: this.queue.size,\n });\n }\n\n /**\n * Persist current queue snapshot.\n */\n async saveToPersistence(): Promise<void> {\n if (!this.persistence) {\n return;\n }\n\n const envelope: PersistedEnvelope<OfflineOperation[]> = {\n version: 1,\n updatedAt: Date.now(),\n data: this.export(),\n };\n\n const serialize =\n this.persistence.serializer ??\n ((value: PersistedEnvelope<OfflineOperation[]>) => JSON.stringify(value));\n const raw = serialize(envelope);\n\n await this.persistence.adapter.setItem(this.persistence.key, raw);\n }\n\n /**\n * Load queue snapshot from persistence.\n */\n async loadFromPersistence(): Promise<number> {\n if (!this.persistence) {\n return 0;\n }\n\n const raw = await this.persistence.adapter.getItem(this.persistence.key);\n if (!raw) {\n return 0;\n }\n\n const deserialize =\n this.persistence.deserializer ??\n ((value: string) =>\n JSON.parse(value) as PersistedEnvelope<OfflineOperation[]>);\n\n const envelope = deserialize(raw);\n if (envelope.version !== 1 || !Array.isArray(envelope.data)) {\n throw new Error('Invalid offline queue persistence payload');\n }\n\n this.queue.clear();\n this.syncingIds.clear();\n\n let imported = 0;\n for (const operation of envelope.data) {\n if (this.isValidOfflineOperation(operation)) {\n this.queue.set(operation.id, {\n ...operation,\n status: operation.status === 'syncing' ? 'pending' : operation.status,\n });\n imported++;\n }\n }\n\n logger.debug('[OfflineOperationQueue] Loaded from persistence', {\n key: this.persistence.key,\n imported,\n });\n\n return imported;\n }\n\n /**\n * Remove persisted queue snapshot.\n */\n async clearPersistence(): Promise<void> {\n if (!this.persistence) {\n return;\n }\n await this.persistence.adapter.removeItem(this.persistence.key);\n }\n\n private schedulePersist(): void {\n if (!this.persistence || this.persistence.autoPersist === false) {\n return;\n }\n\n if (this.persistTimer) {\n clearTimeout(this.persistTimer);\n }\n\n this.persistTimer = setTimeout(() => {\n void this.persistSafely();\n }, this.persistence.persistDebounceMs ?? 25);\n }\n\n private async persistSafely(): Promise<void> {\n if (!this.persistence) {\n return;\n }\n\n if (this.persistInFlight) {\n this.persistPending = true;\n return;\n }\n\n this.persistInFlight = true;\n\n try {\n await this.saveToPersistence();\n } catch (error) {\n logger.error('[OfflineOperationQueue] Persistence write failed', {\n key: this.persistence.key,\n error: error instanceof Error ? error.message : String(error),\n });\n } finally {\n this.persistInFlight = false;\n const shouldRunAgain = this.persistPending;\n this.persistPending = false;\n if (shouldRunAgain) {\n void this.persistSafely();\n }\n }\n }\n\n private isValidOfflineOperation(value: unknown): value is OfflineOperation {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const candidate = value as Partial<OfflineOperation>;\n const validType =\n candidate.type === 'create' ||\n candidate.type === 'update' ||\n candidate.type === 'delete' ||\n candidate.type === 'sync' ||\n candidate.type === 'batch';\n const validPriority =\n candidate.priority === 'high' ||\n candidate.priority === 'normal' ||\n candidate.priority === 'low';\n const validStatus =\n candidate.status === 'pending' ||\n candidate.status === 'syncing' ||\n candidate.status === 'failed' ||\n candidate.status === 'synced';\n\n return (\n typeof candidate.id === 'string' &&\n validType &&\n typeof candidate.data === 'object' &&\n candidate.data !== null &&\n !Array.isArray(candidate.data) &&\n typeof candidate.sessionId === 'string' &&\n validPriority &&\n typeof candidate.createdAt === 'number' &&\n typeof candidate.retryCount === 'number' &&\n typeof candidate.maxRetries === 'number' &&\n validStatus\n );\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet offlineQueueInstance: OfflineOperationQueue | null = null;\n\nexport function getOfflineOperationQueue(): OfflineOperationQueue {\n if (!offlineQueueInstance) {\n offlineQueueInstance = new OfflineOperationQueue();\n }\n return offlineQueueInstance;\n}\n\nexport function resetOfflineOperationQueue(): void {\n offlineQueueInstance = null;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/logger.ts","../../src/offline/OfflineOperationQueue.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Aeon Logger Interface\r\n *\r\n * Provides a pluggable logging interface that can be configured\r\n * by consumers to integrate with their preferred logging solution.\r\n */\r\n\r\n/**\r\n * Logger interface that consumers can implement\r\n */\r\nexport interface Logger {\r\n debug: (...args: unknown[]) => void;\r\n info: (...args: unknown[]) => void;\r\n warn: (...args: unknown[]) => void;\r\n error: (...args: unknown[]) => void;\r\n}\r\n\r\n/**\r\n * Default console logger implementation\r\n */\r\nconst consoleLogger: Logger = {\r\n debug: (...args: unknown[]) => {\r\n // eslint-disable-next-line no-console\r\n console.debug('[AEON:DEBUG]', ...args);\r\n },\r\n info: (...args: unknown[]) => {\r\n // eslint-disable-next-line no-console\r\n console.info('[AEON:INFO]', ...args);\r\n },\r\n warn: (...args: unknown[]) => {\r\n // eslint-disable-next-line no-console\r\n console.warn('[AEON:WARN]', ...args);\r\n },\r\n error: (...args: unknown[]) => {\r\n // eslint-disable-next-line no-console\r\n console.error('[AEON:ERROR]', ...args);\r\n },\r\n};\r\n\r\n/**\r\n * No-op logger for production or when logging is disabled\r\n */\r\nconst noopLogger: Logger = {\r\n debug: () => {},\r\n info: () => {},\r\n warn: () => {},\r\n error: () => {},\r\n};\r\n\r\n/**\r\n * Current logger instance\r\n */\r\nlet currentLogger: Logger = consoleLogger;\r\n\r\n/**\r\n * Get the current logger instance\r\n */\r\nexport function getLogger(): Logger {\r\n return currentLogger;\r\n}\r\n\r\n/**\r\n * Set a custom logger implementation\r\n */\r\nexport function setLogger(logger: Logger): void {\r\n currentLogger = logger;\r\n}\r\n\r\n/**\r\n * Reset to the default console logger\r\n */\r\nexport function resetLogger(): void {\r\n currentLogger = consoleLogger;\r\n}\r\n\r\n/**\r\n * Disable all logging\r\n */\r\nexport function disableLogging(): void {\r\n currentLogger = noopLogger;\r\n}\r\n\r\n/**\r\n * Create a namespaced logger\r\n */\r\nexport function createNamespacedLogger(namespace: string): Logger {\r\n const logger = getLogger();\r\n return {\r\n debug: (...args: unknown[]) => logger.debug(`[${namespace}]`, ...args),\r\n info: (...args: unknown[]) => logger.info(`[${namespace}]`, ...args),\r\n warn: (...args: unknown[]) => logger.warn(`[${namespace}]`, ...args),\r\n error: (...args: unknown[]) => logger.error(`[${namespace}]`, ...args),\r\n };\r\n}\r\n\r\n// Export default logger for convenience\r\nexport const logger: Logger = {\r\n debug: (...args: unknown[]) => getLogger().debug(...args),\r\n info: (...args: unknown[]) => getLogger().info(...args),\r\n warn: (...args: unknown[]) => getLogger().warn(...args),\r\n error: (...args: unknown[]) => getLogger().error(...args),\r\n};\r\n","/**\r\n * Offline Operation Queue (Phase 11)\r\n *\r\n * Manages pending operations for offline-first clients.\r\n * Provides priority-based queuing, persistence, and retry logic.\r\n */\r\n\r\nimport { EventEmitter } from 'eventemitter3';\r\nimport { getLogger } from '../utils/logger';\r\nimport type { Operation, OperationPriority } from '../core/types';\r\nimport type {\r\n PersistedEnvelope,\r\n PersistenceDeserializer,\r\n PersistenceSerializer,\r\n StorageAdapter,\r\n} from '../persistence';\r\n\r\nconst logger = getLogger();\r\n\r\n// Re-export OperationPriority from core\r\nexport type { OperationPriority } from '../core/types';\r\n\r\nexport interface OfflineOperation {\r\n id: string;\r\n type: Operation['type'];\r\n data: Record<string, unknown>;\r\n sessionId: string;\r\n priority: OperationPriority;\r\n createdAt: number;\r\n retryCount: number;\r\n maxRetries: number;\r\n lastError?: string;\r\n status: 'pending' | 'syncing' | 'failed' | 'synced';\r\n}\r\n\r\nexport interface OfflineQueueStats {\r\n pending: number;\r\n syncing: number;\r\n failed: number;\r\n synced: number;\r\n totalOperations: number;\r\n oldestPendingMs: number;\r\n averageRetries: number;\r\n}\r\n\r\nexport interface OfflineQueueEvents {\r\n 'operation-added': (operation: OfflineOperation) => void;\r\n 'operation-synced': (operation: OfflineOperation) => void;\r\n 'operation-failed': (operation: OfflineOperation, error: Error) => void;\r\n 'queue-empty': () => void;\r\n 'sync-started': () => void;\r\n 'sync-completed': (stats: { synced: number; failed: number }) => void;\r\n}\r\n\r\nexport interface OfflineQueuePersistenceConfig {\r\n adapter: StorageAdapter;\r\n key?: string;\r\n autoPersist?: boolean;\r\n autoLoad?: boolean;\r\n persistDebounceMs?: number;\r\n serializer?: PersistenceSerializer<OfflineOperation[]>;\r\n deserializer?: PersistenceDeserializer<OfflineOperation[]>;\r\n}\r\n\r\nexport interface OfflineOperationQueueOptions {\r\n maxQueueSize?: number;\r\n defaultMaxRetries?: number;\r\n persistence?: OfflineQueuePersistenceConfig;\r\n}\r\n\r\n// ============================================================================\r\n// Offline Operation Queue\r\n// ============================================================================\r\n\r\nexport class OfflineOperationQueue extends EventEmitter<OfflineQueueEvents> {\r\n private static readonly DEFAULT_PERSIST_KEY = 'aeon:offline-queue:v1';\r\n private queue: Map<string, OfflineOperation> = new Map();\r\n private syncingIds: Set<string> = new Set();\r\n private maxQueueSize = 1000;\r\n private defaultMaxRetries = 3;\r\n private persistence:\r\n | (OfflineQueuePersistenceConfig & { key: string })\r\n | null = null;\r\n private persistTimer: ReturnType<typeof setTimeout> | null = null;\r\n private persistInFlight = false;\r\n private persistPending = false;\r\n\r\n constructor(\r\n maxQueueSizeOrOptions: number | OfflineOperationQueueOptions = 1000,\r\n defaultMaxRetries = 3\r\n ) {\r\n super();\r\n\r\n if (typeof maxQueueSizeOrOptions === 'number') {\r\n this.maxQueueSize = maxQueueSizeOrOptions;\r\n this.defaultMaxRetries = defaultMaxRetries;\r\n } else {\r\n this.maxQueueSize = maxQueueSizeOrOptions.maxQueueSize ?? 1000;\r\n this.defaultMaxRetries = maxQueueSizeOrOptions.defaultMaxRetries ?? 3;\r\n\r\n if (maxQueueSizeOrOptions.persistence) {\r\n this.persistence = {\r\n ...maxQueueSizeOrOptions.persistence,\r\n key:\r\n maxQueueSizeOrOptions.persistence.key ??\r\n OfflineOperationQueue.DEFAULT_PERSIST_KEY,\r\n autoPersist: maxQueueSizeOrOptions.persistence.autoPersist ?? true,\r\n autoLoad: maxQueueSizeOrOptions.persistence.autoLoad ?? false,\r\n persistDebounceMs:\r\n maxQueueSizeOrOptions.persistence.persistDebounceMs ?? 25,\r\n };\r\n\r\n if (this.persistence.autoLoad) {\r\n void this.loadFromPersistence().catch((error) => {\r\n logger.error('[OfflineOperationQueue] Failed to load persistence', {\r\n key: this.persistence?.key,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n });\r\n }\r\n }\r\n }\r\n\r\n logger.debug('[OfflineOperationQueue] Initialized', {\r\n maxQueueSize: this.maxQueueSize,\r\n defaultMaxRetries: this.defaultMaxRetries,\r\n persistenceEnabled: this.persistence !== null,\r\n });\r\n }\r\n\r\n /**\r\n * Add operation to the queue\r\n */\r\n enqueue(\r\n type: Operation['type'],\r\n data: Record<string, unknown>,\r\n sessionId: string,\r\n priority: OperationPriority = 'normal',\r\n maxRetries?: number\r\n ): OfflineOperation {\r\n if (this.queue.size >= this.maxQueueSize) {\r\n // Remove oldest low-priority operation\r\n const oldest = this.findOldestLowPriority();\r\n if (oldest) {\r\n this.queue.delete(oldest.id);\r\n logger.warn('[OfflineOperationQueue] Queue full, removed oldest', {\r\n removedId: oldest.id,\r\n });\r\n }\r\n }\r\n\r\n const operation: OfflineOperation = {\r\n id: `op-${Date.now()}-${Math.random().toString(36).slice(2)}`,\r\n type,\r\n data,\r\n sessionId,\r\n priority,\r\n createdAt: Date.now(),\r\n retryCount: 0,\r\n maxRetries: maxRetries ?? this.defaultMaxRetries,\r\n status: 'pending',\r\n };\r\n\r\n this.queue.set(operation.id, operation);\r\n this.emit('operation-added', operation);\r\n this.schedulePersist();\r\n\r\n logger.debug('[OfflineOperationQueue] Operation enqueued', {\r\n id: operation.id,\r\n type,\r\n priority,\r\n queueSize: this.queue.size,\r\n });\r\n\r\n return operation;\r\n }\r\n\r\n /**\r\n * Get next operations to sync (by priority)\r\n */\r\n getNextBatch(batchSize = 10): OfflineOperation[] {\r\n const pending = Array.from(this.queue.values())\r\n .filter((op) => op.status === 'pending' && !this.syncingIds.has(op.id))\r\n .sort((a, b) => {\r\n // Sort by priority first, then by creation time\r\n const priorityOrder = { high: 0, normal: 1, low: 2 };\r\n const priorityDiff =\r\n priorityOrder[a.priority] - priorityOrder[b.priority];\r\n if (priorityDiff !== 0) return priorityDiff;\r\n return a.createdAt - b.createdAt;\r\n });\r\n\r\n return pending.slice(0, batchSize);\r\n }\r\n\r\n /**\r\n * Mark operations as syncing\r\n */\r\n markSyncing(operationIds: string[]): void {\r\n let changed = false;\r\n for (const id of operationIds) {\r\n const op = this.queue.get(id);\r\n if (op) {\r\n op.status = 'syncing';\r\n this.syncingIds.add(id);\r\n changed = true;\r\n }\r\n }\r\n\r\n if (changed) {\r\n this.schedulePersist();\r\n }\r\n }\r\n\r\n /**\r\n * Mark operation as synced\r\n */\r\n markSynced(operationId: string): void {\r\n const op = this.queue.get(operationId);\r\n if (op) {\r\n op.status = 'synced';\r\n this.syncingIds.delete(operationId);\r\n this.emit('operation-synced', op);\r\n this.schedulePersist();\r\n\r\n // Remove synced operations after short delay\r\n setTimeout(() => {\r\n this.queue.delete(operationId);\r\n this.schedulePersist();\r\n if (this.getPendingCount() === 0) {\r\n this.emit('queue-empty');\r\n }\r\n }, 1000);\r\n }\r\n }\r\n\r\n /**\r\n * Mark operation as failed\r\n */\r\n markFailed(operationId: string, error: Error): void {\r\n const op = this.queue.get(operationId);\r\n if (op) {\r\n op.retryCount++;\r\n op.lastError = error.message;\r\n this.syncingIds.delete(operationId);\r\n\r\n if (op.retryCount >= op.maxRetries) {\r\n op.status = 'failed';\r\n this.emit('operation-failed', op, error);\r\n logger.error('[OfflineOperationQueue] Operation permanently failed', {\r\n id: operationId,\r\n retries: op.retryCount,\r\n error: error.message,\r\n });\r\n } else {\r\n op.status = 'pending';\r\n logger.warn('[OfflineOperationQueue] Operation failed, will retry', {\r\n id: operationId,\r\n retryCount: op.retryCount,\r\n maxRetries: op.maxRetries,\r\n });\r\n }\r\n\r\n this.schedulePersist();\r\n }\r\n }\r\n\r\n /**\r\n * Get operation by ID\r\n */\r\n getOperation(operationId: string): OfflineOperation | undefined {\r\n return this.queue.get(operationId);\r\n }\r\n\r\n /**\r\n * Get all pending operations\r\n */\r\n getPendingOperations(): OfflineOperation[] {\r\n return Array.from(this.queue.values()).filter(\r\n (op) => op.status === 'pending'\r\n );\r\n }\r\n\r\n /**\r\n * Get pending count\r\n */\r\n getPendingCount(): number {\r\n return Array.from(this.queue.values()).filter(\r\n (op) => op.status === 'pending'\r\n ).length;\r\n }\r\n\r\n /**\r\n * Get queue statistics\r\n */\r\n getStats(): OfflineQueueStats {\r\n const operations = Array.from(this.queue.values());\r\n\r\n const pending = operations.filter((op) => op.status === 'pending').length;\r\n const syncing = operations.filter((op) => op.status === 'syncing').length;\r\n const failed = operations.filter((op) => op.status === 'failed').length;\r\n const synced = operations.filter((op) => op.status === 'synced').length;\r\n\r\n const pendingOps = operations.filter((op) => op.status === 'pending');\r\n const oldestPendingMs =\r\n pendingOps.length > 0\r\n ? Date.now() - Math.min(...pendingOps.map((op) => op.createdAt))\r\n : 0;\r\n\r\n const averageRetries =\r\n operations.length > 0\r\n ? operations.reduce((sum, op) => sum + op.retryCount, 0) /\r\n operations.length\r\n : 0;\r\n\r\n return {\r\n pending,\r\n syncing,\r\n failed,\r\n synced,\r\n totalOperations: operations.length,\r\n oldestPendingMs,\r\n averageRetries,\r\n };\r\n }\r\n\r\n /**\r\n * Clear all operations\r\n */\r\n clear(): void {\r\n this.queue.clear();\r\n this.syncingIds.clear();\r\n this.schedulePersist();\r\n logger.debug('[OfflineOperationQueue] Queue cleared');\r\n }\r\n\r\n /**\r\n * Clear failed operations\r\n */\r\n clearFailed(): void {\r\n let changed = false;\r\n for (const [id, op] of this.queue.entries()) {\r\n if (op.status === 'failed') {\r\n this.queue.delete(id);\r\n changed = true;\r\n }\r\n }\r\n\r\n if (changed) {\r\n this.schedulePersist();\r\n }\r\n }\r\n\r\n /**\r\n * Retry failed operations\r\n */\r\n retryFailed(): void {\r\n let changed = false;\r\n for (const op of this.queue.values()) {\r\n if (op.status === 'failed') {\r\n op.status = 'pending';\r\n op.retryCount = 0;\r\n changed = true;\r\n }\r\n }\r\n\r\n if (changed) {\r\n this.schedulePersist();\r\n }\r\n }\r\n\r\n /**\r\n * Find oldest low-priority operation\r\n */\r\n private findOldestLowPriority(): OfflineOperation | null {\r\n const lowPriority = Array.from(this.queue.values())\r\n .filter((op) => op.priority === 'low' && op.status === 'pending')\r\n .sort((a, b) => a.createdAt - b.createdAt);\r\n\r\n return lowPriority[0] ?? null;\r\n }\r\n\r\n /**\r\n * Export queue for persistence\r\n */\r\n export(): OfflineOperation[] {\r\n return Array.from(this.queue.values());\r\n }\r\n\r\n /**\r\n * Import queue from persistence\r\n */\r\n import(operations: OfflineOperation[]): void {\r\n this.queue.clear();\r\n this.syncingIds.clear();\r\n\r\n for (const op of operations) {\r\n if (this.isValidOfflineOperation(op)) {\r\n this.queue.set(op.id, {\r\n ...op,\r\n status: op.status === 'syncing' ? 'pending' : op.status,\r\n });\r\n }\r\n }\r\n\r\n this.schedulePersist();\r\n\r\n logger.debug('[OfflineOperationQueue] Imported operations', {\r\n count: this.queue.size,\r\n });\r\n }\r\n\r\n /**\r\n * Persist current queue snapshot.\r\n */\r\n async saveToPersistence(): Promise<void> {\r\n if (!this.persistence) {\r\n return;\r\n }\r\n\r\n const envelope: PersistedEnvelope<OfflineOperation[]> = {\r\n version: 1,\r\n updatedAt: Date.now(),\r\n data: this.export(),\r\n };\r\n\r\n const serialize =\r\n this.persistence.serializer ??\r\n ((value: PersistedEnvelope<OfflineOperation[]>) => JSON.stringify(value));\r\n const raw = serialize(envelope);\r\n\r\n await this.persistence.adapter.setItem(this.persistence.key, raw);\r\n }\r\n\r\n /**\r\n * Load queue snapshot from persistence.\r\n */\r\n async loadFromPersistence(): Promise<number> {\r\n if (!this.persistence) {\r\n return 0;\r\n }\r\n\r\n const raw = await this.persistence.adapter.getItem(this.persistence.key);\r\n if (!raw) {\r\n return 0;\r\n }\r\n\r\n const deserialize =\r\n this.persistence.deserializer ??\r\n ((value: string) =>\r\n JSON.parse(value) as PersistedEnvelope<OfflineOperation[]>);\r\n\r\n const envelope = deserialize(raw);\r\n if (envelope.version !== 1 || !Array.isArray(envelope.data)) {\r\n throw new Error('Invalid offline queue persistence payload');\r\n }\r\n\r\n this.queue.clear();\r\n this.syncingIds.clear();\r\n\r\n let imported = 0;\r\n for (const operation of envelope.data) {\r\n if (this.isValidOfflineOperation(operation)) {\r\n this.queue.set(operation.id, {\r\n ...operation,\r\n status: operation.status === 'syncing' ? 'pending' : operation.status,\r\n });\r\n imported++;\r\n }\r\n }\r\n\r\n logger.debug('[OfflineOperationQueue] Loaded from persistence', {\r\n key: this.persistence.key,\r\n imported,\r\n });\r\n\r\n return imported;\r\n }\r\n\r\n /**\r\n * Remove persisted queue snapshot.\r\n */\r\n async clearPersistence(): Promise<void> {\r\n if (!this.persistence) {\r\n return;\r\n }\r\n await this.persistence.adapter.removeItem(this.persistence.key);\r\n }\r\n\r\n private schedulePersist(): void {\r\n if (!this.persistence || this.persistence.autoPersist === false) {\r\n return;\r\n }\r\n\r\n if (this.persistTimer) {\r\n clearTimeout(this.persistTimer);\r\n }\r\n\r\n this.persistTimer = setTimeout(() => {\r\n void this.persistSafely();\r\n }, this.persistence.persistDebounceMs ?? 25);\r\n }\r\n\r\n private async persistSafely(): Promise<void> {\r\n if (!this.persistence) {\r\n return;\r\n }\r\n\r\n if (this.persistInFlight) {\r\n this.persistPending = true;\r\n return;\r\n }\r\n\r\n this.persistInFlight = true;\r\n\r\n try {\r\n await this.saveToPersistence();\r\n } catch (error) {\r\n logger.error('[OfflineOperationQueue] Persistence write failed', {\r\n key: this.persistence.key,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n } finally {\r\n this.persistInFlight = false;\r\n const shouldRunAgain = this.persistPending;\r\n this.persistPending = false;\r\n if (shouldRunAgain) {\r\n void this.persistSafely();\r\n }\r\n }\r\n }\r\n\r\n private isValidOfflineOperation(value: unknown): value is OfflineOperation {\r\n if (typeof value !== 'object' || value === null) {\r\n return false;\r\n }\r\n\r\n const candidate = value as Partial<OfflineOperation>;\r\n const validType =\r\n candidate.type === 'create' ||\r\n candidate.type === 'update' ||\r\n candidate.type === 'delete' ||\r\n candidate.type === 'sync' ||\r\n candidate.type === 'batch';\r\n const validPriority =\r\n candidate.priority === 'high' ||\r\n candidate.priority === 'normal' ||\r\n candidate.priority === 'low';\r\n const validStatus =\r\n candidate.status === 'pending' ||\r\n candidate.status === 'syncing' ||\r\n candidate.status === 'failed' ||\r\n candidate.status === 'synced';\r\n\r\n return (\r\n typeof candidate.id === 'string' &&\r\n validType &&\r\n typeof candidate.data === 'object' &&\r\n candidate.data !== null &&\r\n !Array.isArray(candidate.data) &&\r\n typeof candidate.sessionId === 'string' &&\r\n validPriority &&\r\n typeof candidate.createdAt === 'number' &&\r\n typeof candidate.retryCount === 'number' &&\r\n typeof candidate.maxRetries === 'number' &&\r\n validStatus\r\n );\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Singleton Instance\r\n// ============================================================================\r\n\r\nlet offlineQueueInstance: OfflineOperationQueue | null = null;\r\n\r\nexport function getOfflineOperationQueue(): OfflineOperationQueue {\r\n if (!offlineQueueInstance) {\r\n offlineQueueInstance = new OfflineOperationQueue();\r\n }\r\n return offlineQueueInstance;\r\n}\r\n\r\nexport function resetOfflineOperationQueue(): void {\r\n offlineQueueInstance = null;\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/utils/logger.ts","../../src/offline/OfflineOperationQueue.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Aeon Logger Interface\n *\n * Provides a pluggable logging interface that can be configured\n * by consumers to integrate with their preferred logging solution.\n */\n\n/**\n * Logger interface that consumers can implement\n */\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\n/**\n * Default console logger implementation\n */\nconst consoleLogger: Logger = {\n debug: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.debug('[AEON:DEBUG]', ...args);\n },\n info: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.info('[AEON:INFO]', ...args);\n },\n warn: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.warn('[AEON:WARN]', ...args);\n },\n error: (...args: unknown[]) => {\n // eslint-disable-next-line no-console\n console.error('[AEON:ERROR]', ...args);\n },\n};\n\n/**\n * No-op logger for production or when logging is disabled\n */\nconst noopLogger: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\n/**\n * Current logger instance\n */\nlet currentLogger: Logger = consoleLogger;\n\n/**\n * Get the current logger instance\n */\nexport function getLogger(): Logger {\n return currentLogger;\n}\n\n/**\n * Set a custom logger implementation\n */\nexport function setLogger(logger: Logger): void {\n currentLogger = logger;\n}\n\n/**\n * Reset to the default console logger\n */\nexport function resetLogger(): void {\n currentLogger = consoleLogger;\n}\n\n/**\n * Disable all logging\n */\nexport function disableLogging(): void {\n currentLogger = noopLogger;\n}\n\n/**\n * Create a namespaced logger\n */\nexport function createNamespacedLogger(namespace: string): Logger {\n const logger = getLogger();\n return {\n debug: (...args: unknown[]) => logger.debug(`[${namespace}]`, ...args),\n info: (...args: unknown[]) => logger.info(`[${namespace}]`, ...args),\n warn: (...args: unknown[]) => logger.warn(`[${namespace}]`, ...args),\n error: (...args: unknown[]) => logger.error(`[${namespace}]`, ...args),\n };\n}\n\n// Export default logger for convenience\nexport const logger: Logger = {\n debug: (...args: unknown[]) => getLogger().debug(...args),\n info: (...args: unknown[]) => getLogger().info(...args),\n warn: (...args: unknown[]) => getLogger().warn(...args),\n error: (...args: unknown[]) => getLogger().error(...args),\n};\n","/**\n * Offline Operation Queue (Phase 11)\n *\n * Manages pending operations for offline-first clients.\n * Provides priority-based queuing, persistence, and retry logic.\n */\n\nimport { EventEmitter } from 'eventemitter3';\nimport { getLogger } from '../utils/logger';\nimport type { Operation, OperationPriority } from '../core/types';\nimport type {\n PersistedEnvelope,\n PersistenceDeserializer,\n PersistenceSerializer,\n StorageAdapter,\n} from '../persistence';\n\nconst logger = getLogger();\n\n// Re-export OperationPriority from core\nexport type { OperationPriority } from '../core/types';\n\nexport interface OfflineOperation {\n id: string;\n type: Operation['type'];\n data: Record<string, unknown>;\n sessionId: string;\n priority: OperationPriority;\n createdAt: number;\n retryCount: number;\n maxRetries: number;\n lastError?: string;\n status: 'pending' | 'syncing' | 'failed' | 'synced';\n}\n\nexport interface OfflineQueueStats {\n pending: number;\n syncing: number;\n failed: number;\n synced: number;\n totalOperations: number;\n oldestPendingMs: number;\n averageRetries: number;\n}\n\nexport interface OfflineQueueEvents {\n 'operation-added': (operation: OfflineOperation) => void;\n 'operation-synced': (operation: OfflineOperation) => void;\n 'operation-failed': (operation: OfflineOperation, error: Error) => void;\n 'queue-empty': () => void;\n 'sync-started': () => void;\n 'sync-completed': (stats: { synced: number; failed: number }) => void;\n}\n\nexport interface OfflineQueuePersistenceConfig {\n adapter: StorageAdapter;\n key?: string;\n autoPersist?: boolean;\n autoLoad?: boolean;\n persistDebounceMs?: number;\n serializer?: PersistenceSerializer<OfflineOperation[]>;\n deserializer?: PersistenceDeserializer<OfflineOperation[]>;\n}\n\nexport interface OfflineOperationQueueOptions {\n maxQueueSize?: number;\n defaultMaxRetries?: number;\n persistence?: OfflineQueuePersistenceConfig;\n}\n\n// ============================================================================\n// Offline Operation Queue\n// ============================================================================\n\nexport class OfflineOperationQueue extends EventEmitter<OfflineQueueEvents> {\n private static readonly DEFAULT_PERSIST_KEY = 'aeon:offline-queue:v1';\n private queue: Map<string, OfflineOperation> = new Map();\n private syncingIds: Set<string> = new Set();\n private maxQueueSize = 1000;\n private defaultMaxRetries = 3;\n private persistence:\n | (OfflineQueuePersistenceConfig & { key: string })\n | null = null;\n private persistTimer: ReturnType<typeof setTimeout> | null = null;\n private persistInFlight = false;\n private persistPending = false;\n\n constructor(\n maxQueueSizeOrOptions: number | OfflineOperationQueueOptions = 1000,\n defaultMaxRetries = 3\n ) {\n super();\n\n if (typeof maxQueueSizeOrOptions === 'number') {\n this.maxQueueSize = maxQueueSizeOrOptions;\n this.defaultMaxRetries = defaultMaxRetries;\n } else {\n this.maxQueueSize = maxQueueSizeOrOptions.maxQueueSize ?? 1000;\n this.defaultMaxRetries = maxQueueSizeOrOptions.defaultMaxRetries ?? 3;\n\n if (maxQueueSizeOrOptions.persistence) {\n this.persistence = {\n ...maxQueueSizeOrOptions.persistence,\n key:\n maxQueueSizeOrOptions.persistence.key ??\n OfflineOperationQueue.DEFAULT_PERSIST_KEY,\n autoPersist: maxQueueSizeOrOptions.persistence.autoPersist ?? true,\n autoLoad: maxQueueSizeOrOptions.persistence.autoLoad ?? false,\n persistDebounceMs:\n maxQueueSizeOrOptions.persistence.persistDebounceMs ?? 25,\n };\n\n if (this.persistence.autoLoad) {\n void this.loadFromPersistence().catch((error) => {\n logger.error('[OfflineOperationQueue] Failed to load persistence', {\n key: this.persistence?.key,\n error: error instanceof Error ? error.message : String(error),\n });\n });\n }\n }\n }\n\n logger.debug('[OfflineOperationQueue] Initialized', {\n maxQueueSize: this.maxQueueSize,\n defaultMaxRetries: this.defaultMaxRetries,\n persistenceEnabled: this.persistence !== null,\n });\n }\n\n /**\n * Add operation to the queue\n */\n enqueue(\n type: Operation['type'],\n data: Record<string, unknown>,\n sessionId: string,\n priority: OperationPriority = 'normal',\n maxRetries?: number\n ): OfflineOperation {\n if (this.queue.size >= this.maxQueueSize) {\n // Remove oldest low-priority operation\n const oldest = this.findOldestLowPriority();\n if (oldest) {\n this.queue.delete(oldest.id);\n logger.warn('[OfflineOperationQueue] Queue full, removed oldest', {\n removedId: oldest.id,\n });\n }\n }\n\n const operation: OfflineOperation = {\n id: `op-${Date.now()}-${Math.random().toString(36).slice(2)}`,\n type,\n data,\n sessionId,\n priority,\n createdAt: Date.now(),\n retryCount: 0,\n maxRetries: maxRetries ?? this.defaultMaxRetries,\n status: 'pending',\n };\n\n this.queue.set(operation.id, operation);\n this.emit('operation-added', operation);\n this.schedulePersist();\n\n logger.debug('[OfflineOperationQueue] Operation enqueued', {\n id: operation.id,\n type,\n priority,\n queueSize: this.queue.size,\n });\n\n return operation;\n }\n\n /**\n * Get next operations to sync (by priority)\n */\n getNextBatch(batchSize = 10): OfflineOperation[] {\n const pending = Array.from(this.queue.values())\n .filter((op) => op.status === 'pending' && !this.syncingIds.has(op.id))\n .sort((a, b) => {\n // Sort by priority first, then by creation time\n const priorityOrder = { high: 0, normal: 1, low: 2 };\n const priorityDiff =\n priorityOrder[a.priority] - priorityOrder[b.priority];\n if (priorityDiff !== 0) return priorityDiff;\n return a.createdAt - b.createdAt;\n });\n\n return pending.slice(0, batchSize);\n }\n\n /**\n * Mark operations as syncing\n */\n markSyncing(operationIds: string[]): void {\n let changed = false;\n for (const id of operationIds) {\n const op = this.queue.get(id);\n if (op) {\n op.status = 'syncing';\n this.syncingIds.add(id);\n changed = true;\n }\n }\n\n if (changed) {\n this.schedulePersist();\n }\n }\n\n /**\n * Mark operation as synced\n */\n markSynced(operationId: string): void {\n const op = this.queue.get(operationId);\n if (op) {\n op.status = 'synced';\n this.syncingIds.delete(operationId);\n this.emit('operation-synced', op);\n this.schedulePersist();\n\n // Remove synced operations after short delay\n setTimeout(() => {\n this.queue.delete(operationId);\n this.schedulePersist();\n if (this.getPendingCount() === 0) {\n this.emit('queue-empty');\n }\n }, 1000);\n }\n }\n\n /**\n * Mark operation as failed\n */\n markFailed(operationId: string, error: Error): void {\n const op = this.queue.get(operationId);\n if (op) {\n op.retryCount++;\n op.lastError = error.message;\n this.syncingIds.delete(operationId);\n\n if (op.retryCount >= op.maxRetries) {\n op.status = 'failed';\n this.emit('operation-failed', op, error);\n logger.error('[OfflineOperationQueue] Operation permanently failed', {\n id: operationId,\n retries: op.retryCount,\n error: error.message,\n });\n } else {\n op.status = 'pending';\n logger.warn('[OfflineOperationQueue] Operation failed, will retry', {\n id: operationId,\n retryCount: op.retryCount,\n maxRetries: op.maxRetries,\n });\n }\n\n this.schedulePersist();\n }\n }\n\n /**\n * Get operation by ID\n */\n getOperation(operationId: string): OfflineOperation | undefined {\n return this.queue.get(operationId);\n }\n\n /**\n * Get all pending operations\n */\n getPendingOperations(): OfflineOperation[] {\n return Array.from(this.queue.values()).filter(\n (op) => op.status === 'pending'\n );\n }\n\n /**\n * Get pending count\n */\n getPendingCount(): number {\n return Array.from(this.queue.values()).filter(\n (op) => op.status === 'pending'\n ).length;\n }\n\n /**\n * Get queue statistics\n */\n getStats(): OfflineQueueStats {\n const operations = Array.from(this.queue.values());\n\n const pending = operations.filter((op) => op.status === 'pending').length;\n const syncing = operations.filter((op) => op.status === 'syncing').length;\n const failed = operations.filter((op) => op.status === 'failed').length;\n const synced = operations.filter((op) => op.status === 'synced').length;\n\n const pendingOps = operations.filter((op) => op.status === 'pending');\n const oldestPendingMs =\n pendingOps.length > 0\n ? Date.now() - Math.min(...pendingOps.map((op) => op.createdAt))\n : 0;\n\n const averageRetries =\n operations.length > 0\n ? operations.reduce((sum, op) => sum + op.retryCount, 0) /\n operations.length\n : 0;\n\n return {\n pending,\n syncing,\n failed,\n synced,\n totalOperations: operations.length,\n oldestPendingMs,\n averageRetries,\n };\n }\n\n /**\n * Clear all operations\n */\n clear(): void {\n this.queue.clear();\n this.syncingIds.clear();\n this.schedulePersist();\n logger.debug('[OfflineOperationQueue] Queue cleared');\n }\n\n /**\n * Clear failed operations\n */\n clearFailed(): void {\n let changed = false;\n for (const [id, op] of this.queue.entries()) {\n if (op.status === 'failed') {\n this.queue.delete(id);\n changed = true;\n }\n }\n\n if (changed) {\n this.schedulePersist();\n }\n }\n\n /**\n * Retry failed operations\n */\n retryFailed(): void {\n let changed = false;\n for (const op of this.queue.values()) {\n if (op.status === 'failed') {\n op.status = 'pending';\n op.retryCount = 0;\n changed = true;\n }\n }\n\n if (changed) {\n this.schedulePersist();\n }\n }\n\n /**\n * Find oldest low-priority operation\n */\n private findOldestLowPriority(): OfflineOperation | null {\n const lowPriority = Array.from(this.queue.values())\n .filter((op) => op.priority === 'low' && op.status === 'pending')\n .sort((a, b) => a.createdAt - b.createdAt);\n\n return lowPriority[0] ?? null;\n }\n\n /**\n * Export queue for persistence\n */\n export(): OfflineOperation[] {\n return Array.from(this.queue.values());\n }\n\n /**\n * Import queue from persistence\n */\n import(operations: OfflineOperation[]): void {\n this.queue.clear();\n this.syncingIds.clear();\n\n for (const op of operations) {\n if (this.isValidOfflineOperation(op)) {\n this.queue.set(op.id, {\n ...op,\n status: op.status === 'syncing' ? 'pending' : op.status,\n });\n }\n }\n\n this.schedulePersist();\n\n logger.debug('[OfflineOperationQueue] Imported operations', {\n count: this.queue.size,\n });\n }\n\n /**\n * Persist current queue snapshot.\n */\n async saveToPersistence(): Promise<void> {\n if (!this.persistence) {\n return;\n }\n\n const envelope: PersistedEnvelope<OfflineOperation[]> = {\n version: 1,\n updatedAt: Date.now(),\n data: this.export(),\n };\n\n const serialize =\n this.persistence.serializer ??\n ((value: PersistedEnvelope<OfflineOperation[]>) => JSON.stringify(value));\n const raw = serialize(envelope);\n\n await this.persistence.adapter.setItem(this.persistence.key, raw);\n }\n\n /**\n * Load queue snapshot from persistence.\n */\n async loadFromPersistence(): Promise<number> {\n if (!this.persistence) {\n return 0;\n }\n\n const raw = await this.persistence.adapter.getItem(this.persistence.key);\n if (!raw) {\n return 0;\n }\n\n const deserialize =\n this.persistence.deserializer ??\n ((value: string) =>\n JSON.parse(value) as PersistedEnvelope<OfflineOperation[]>);\n\n const envelope = deserialize(raw);\n if (envelope.version !== 1 || !Array.isArray(envelope.data)) {\n throw new Error('Invalid offline queue persistence payload');\n }\n\n this.queue.clear();\n this.syncingIds.clear();\n\n let imported = 0;\n for (const operation of envelope.data) {\n if (this.isValidOfflineOperation(operation)) {\n this.queue.set(operation.id, {\n ...operation,\n status: operation.status === 'syncing' ? 'pending' : operation.status,\n });\n imported++;\n }\n }\n\n logger.debug('[OfflineOperationQueue] Loaded from persistence', {\n key: this.persistence.key,\n imported,\n });\n\n return imported;\n }\n\n /**\n * Remove persisted queue snapshot.\n */\n async clearPersistence(): Promise<void> {\n if (!this.persistence) {\n return;\n }\n await this.persistence.adapter.removeItem(this.persistence.key);\n }\n\n private schedulePersist(): void {\n if (!this.persistence || this.persistence.autoPersist === false) {\n return;\n }\n\n if (this.persistTimer) {\n clearTimeout(this.persistTimer);\n }\n\n this.persistTimer = setTimeout(() => {\n void this.persistSafely();\n }, this.persistence.persistDebounceMs ?? 25);\n }\n\n private async persistSafely(): Promise<void> {\n if (!this.persistence) {\n return;\n }\n\n if (this.persistInFlight) {\n this.persistPending = true;\n return;\n }\n\n this.persistInFlight = true;\n\n try {\n await this.saveToPersistence();\n } catch (error) {\n logger.error('[OfflineOperationQueue] Persistence write failed', {\n key: this.persistence.key,\n error: error instanceof Error ? error.message : String(error),\n });\n } finally {\n this.persistInFlight = false;\n const shouldRunAgain = this.persistPending;\n this.persistPending = false;\n if (shouldRunAgain) {\n void this.persistSafely();\n }\n }\n }\n\n private isValidOfflineOperation(value: unknown): value is OfflineOperation {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const candidate = value as Partial<OfflineOperation>;\n const validType =\n candidate.type === 'create' ||\n candidate.type === 'update' ||\n candidate.type === 'delete' ||\n candidate.type === 'sync' ||\n candidate.type === 'batch';\n const validPriority =\n candidate.priority === 'high' ||\n candidate.priority === 'normal' ||\n candidate.priority === 'low';\n const validStatus =\n candidate.status === 'pending' ||\n candidate.status === 'syncing' ||\n candidate.status === 'failed' ||\n candidate.status === 'synced';\n\n return (\n typeof candidate.id === 'string' &&\n validType &&\n typeof candidate.data === 'object' &&\n candidate.data !== null &&\n !Array.isArray(candidate.data) &&\n typeof candidate.sessionId === 'string' &&\n validPriority &&\n typeof candidate.createdAt === 'number' &&\n typeof candidate.retryCount === 'number' &&\n typeof candidate.maxRetries === 'number' &&\n validStatus\n );\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet offlineQueueInstance: OfflineOperationQueue | null = null;\n\nexport function getOfflineOperationQueue(): OfflineOperationQueue {\n if (!offlineQueueInstance) {\n offlineQueueInstance = new OfflineOperationQueue();\n }\n return offlineQueueInstance;\n}\n\nexport function resetOfflineOperationQueue(): void {\n offlineQueueInstance = null;\n}\n"]}
@@ -122,7 +122,7 @@ var PrefetchingEngine = class {
122
122
  const predictions = [];
123
123
  const recentTypeSequence = recentOperations.slice(-3).map((op) => op.type).join(" \u2192 ");
124
124
  for (const [key, pattern] of this.patterns.entries()) {
125
- if (key.includes(recentTypeSequence)) {
125
+ if (key.includes(recentTypeSequence) && pattern.sequence.length > 0) {
126
126
  const nextType = pattern.sequence[pattern.sequence.length - 1];
127
127
  const prediction = {
128
128
  operationType: nextType,
@@ -639,8 +639,11 @@ var AdaptiveCompressionOptimizer = class {
639
639
  this.compressionHistory.shift();
640
640
  }
641
641
  this.stats.totalBatches++;
642
- this.stats.averageCompressionMs = this.compressionHistory.reduce((sum, h) => sum + h.timeMs, 0) / this.compressionHistory.length;
643
- this.stats.averageRatio = this.compressionHistory.reduce((sum, h) => sum + h.ratio, 0) / this.compressionHistory.length;
642
+ const historyLength = this.compressionHistory.length;
643
+ if (historyLength > 0) {
644
+ this.stats.averageCompressionMs = this.compressionHistory.reduce((sum, h) => sum + h.timeMs, 0) / historyLength;
645
+ this.stats.averageRatio = this.compressionHistory.reduce((sum, h) => sum + h.ratio, 0) / historyLength;
646
+ }
644
647
  }
645
648
  /**
646
649
  * Get compression recommendation based on conditions