@framers/sql-storage-adapter 0.4.2 → 0.5.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 (135) hide show
  1. package/README.md +94 -2
  2. package/dist/adapters/electron/electronMainAdapter.d.ts +241 -0
  3. package/dist/adapters/electron/electronMainAdapter.d.ts.map +1 -0
  4. package/dist/adapters/electron/electronMainAdapter.js +442 -0
  5. package/dist/adapters/electron/electronMainAdapter.js.map +1 -0
  6. package/dist/adapters/electron/electronRendererAdapter.d.ts +177 -0
  7. package/dist/adapters/electron/electronRendererAdapter.d.ts.map +1 -0
  8. package/dist/adapters/electron/electronRendererAdapter.js +339 -0
  9. package/dist/adapters/electron/electronRendererAdapter.js.map +1 -0
  10. package/dist/adapters/electron/index.d.ts +74 -0
  11. package/dist/adapters/electron/index.d.ts.map +1 -0
  12. package/dist/adapters/electron/index.js +96 -0
  13. package/dist/adapters/electron/index.js.map +1 -0
  14. package/dist/adapters/electron/ipc/channels.d.ts +196 -0
  15. package/dist/adapters/electron/ipc/channels.d.ts.map +1 -0
  16. package/dist/adapters/electron/ipc/channels.js +121 -0
  17. package/dist/adapters/electron/ipc/channels.js.map +1 -0
  18. package/dist/adapters/electron/ipc/index.d.ts +11 -0
  19. package/dist/adapters/electron/ipc/index.d.ts.map +1 -0
  20. package/dist/adapters/electron/ipc/index.js +11 -0
  21. package/dist/adapters/electron/ipc/index.js.map +1 -0
  22. package/dist/adapters/electron/ipc/protocol.d.ts +78 -0
  23. package/dist/adapters/electron/ipc/protocol.d.ts.map +1 -0
  24. package/dist/adapters/electron/ipc/protocol.js +347 -0
  25. package/dist/adapters/electron/ipc/protocol.js.map +1 -0
  26. package/dist/adapters/electron/ipc/types.d.ts +248 -0
  27. package/dist/adapters/electron/ipc/types.d.ts.map +1 -0
  28. package/dist/adapters/electron/ipc/types.js +8 -0
  29. package/dist/adapters/electron/ipc/types.js.map +1 -0
  30. package/dist/adapters/electron/migration/autoMigrator.d.ts +184 -0
  31. package/dist/adapters/electron/migration/autoMigrator.d.ts.map +1 -0
  32. package/dist/adapters/electron/migration/autoMigrator.js +478 -0
  33. package/dist/adapters/electron/migration/autoMigrator.js.map +1 -0
  34. package/dist/adapters/electron/migration/index.d.ts +9 -0
  35. package/dist/adapters/electron/migration/index.d.ts.map +1 -0
  36. package/dist/adapters/electron/migration/index.js +9 -0
  37. package/dist/adapters/electron/migration/index.js.map +1 -0
  38. package/dist/adapters/electron/preload.d.ts +126 -0
  39. package/dist/adapters/electron/preload.d.ts.map +1 -0
  40. package/dist/adapters/electron/preload.js +254 -0
  41. package/dist/adapters/electron/preload.js.map +1 -0
  42. package/dist/adapters/electron/recovery/corruptionDetector.d.ts +214 -0
  43. package/dist/adapters/electron/recovery/corruptionDetector.d.ts.map +1 -0
  44. package/dist/adapters/electron/recovery/corruptionDetector.js +410 -0
  45. package/dist/adapters/electron/recovery/corruptionDetector.js.map +1 -0
  46. package/dist/adapters/electron/recovery/index.d.ts +11 -0
  47. package/dist/adapters/electron/recovery/index.d.ts.map +1 -0
  48. package/dist/adapters/electron/recovery/index.js +11 -0
  49. package/dist/adapters/electron/recovery/index.js.map +1 -0
  50. package/dist/adapters/electron/recovery/walCheckpoint.d.ts +186 -0
  51. package/dist/adapters/electron/recovery/walCheckpoint.d.ts.map +1 -0
  52. package/dist/adapters/electron/recovery/walCheckpoint.js +302 -0
  53. package/dist/adapters/electron/recovery/walCheckpoint.js.map +1 -0
  54. package/dist/adapters/electron/window/index.d.ts +9 -0
  55. package/dist/adapters/electron/window/index.d.ts.map +1 -0
  56. package/dist/adapters/electron/window/index.js +9 -0
  57. package/dist/adapters/electron/window/index.js.map +1 -0
  58. package/dist/adapters/electron/window/windowManager.d.ts +190 -0
  59. package/dist/adapters/electron/window/windowManager.d.ts.map +1 -0
  60. package/dist/adapters/electron/window/windowManager.js +358 -0
  61. package/dist/adapters/electron/window/windowManager.js.map +1 -0
  62. package/dist/core/contracts/context.d.ts +2 -2
  63. package/dist/core/contracts/context.d.ts.map +1 -1
  64. package/dist/core/database.d.ts +19 -0
  65. package/dist/core/database.d.ts.map +1 -1
  66. package/dist/core/database.js +4 -0
  67. package/dist/core/database.js.map +1 -1
  68. package/dist/core/resolver.d.ts +3 -0
  69. package/dist/core/resolver.d.ts.map +1 -1
  70. package/dist/core/resolver.js +39 -3
  71. package/dist/core/resolver.js.map +1 -1
  72. package/dist/features/sync/conflicts/conflictResolver.d.ts +222 -0
  73. package/dist/features/sync/conflicts/conflictResolver.d.ts.map +1 -0
  74. package/dist/features/sync/conflicts/conflictResolver.js +396 -0
  75. package/dist/features/sync/conflicts/conflictResolver.js.map +1 -0
  76. package/dist/features/sync/conflicts/index.d.ts +9 -0
  77. package/dist/features/sync/conflicts/index.d.ts.map +1 -0
  78. package/dist/features/sync/conflicts/index.js +9 -0
  79. package/dist/features/sync/conflicts/index.js.map +1 -0
  80. package/dist/features/sync/crossPlatformSync.d.ts +281 -0
  81. package/dist/features/sync/crossPlatformSync.d.ts.map +1 -0
  82. package/dist/features/sync/crossPlatformSync.js +623 -0
  83. package/dist/features/sync/crossPlatformSync.js.map +1 -0
  84. package/dist/features/sync/devices/deviceManager.d.ts +243 -0
  85. package/dist/features/sync/devices/deviceManager.d.ts.map +1 -0
  86. package/dist/features/sync/devices/deviceManager.js +494 -0
  87. package/dist/features/sync/devices/deviceManager.js.map +1 -0
  88. package/dist/features/sync/devices/index.d.ts +10 -0
  89. package/dist/features/sync/devices/index.d.ts.map +1 -0
  90. package/dist/features/sync/devices/index.js +10 -0
  91. package/dist/features/sync/devices/index.js.map +1 -0
  92. package/dist/features/sync/index.d.ts +37 -0
  93. package/dist/features/sync/index.d.ts.map +1 -0
  94. package/dist/features/sync/index.js +47 -0
  95. package/dist/features/sync/index.js.map +1 -0
  96. package/dist/features/sync/protocol/index.d.ts +11 -0
  97. package/dist/features/sync/protocol/index.d.ts.map +1 -0
  98. package/dist/features/sync/protocol/index.js +11 -0
  99. package/dist/features/sync/protocol/index.js.map +1 -0
  100. package/dist/features/sync/protocol/messages.d.ts +348 -0
  101. package/dist/features/sync/protocol/messages.d.ts.map +1 -0
  102. package/dist/features/sync/protocol/messages.js +216 -0
  103. package/dist/features/sync/protocol/messages.js.map +1 -0
  104. package/dist/features/sync/protocol/vectorClock.d.ts +164 -0
  105. package/dist/features/sync/protocol/vectorClock.d.ts.map +1 -0
  106. package/dist/features/sync/protocol/vectorClock.js +286 -0
  107. package/dist/features/sync/protocol/vectorClock.js.map +1 -0
  108. package/dist/features/sync/tables/index.d.ts +10 -0
  109. package/dist/features/sync/tables/index.d.ts.map +1 -0
  110. package/dist/features/sync/tables/index.js +10 -0
  111. package/dist/features/sync/tables/index.js.map +1 -0
  112. package/dist/features/sync/tables/syncLogManager.d.ts +216 -0
  113. package/dist/features/sync/tables/syncLogManager.d.ts.map +1 -0
  114. package/dist/features/sync/tables/syncLogManager.js +456 -0
  115. package/dist/features/sync/tables/syncLogManager.js.map +1 -0
  116. package/dist/features/sync/transport/httpTransport.d.ts +123 -0
  117. package/dist/features/sync/transport/httpTransport.d.ts.map +1 -0
  118. package/dist/features/sync/transport/httpTransport.js +380 -0
  119. package/dist/features/sync/transport/httpTransport.js.map +1 -0
  120. package/dist/features/sync/transport/index.d.ts +12 -0
  121. package/dist/features/sync/transport/index.d.ts.map +1 -0
  122. package/dist/features/sync/transport/index.js +12 -0
  123. package/dist/features/sync/transport/index.js.map +1 -0
  124. package/dist/features/sync/transport/transport.d.ts +259 -0
  125. package/dist/features/sync/transport/transport.d.ts.map +1 -0
  126. package/dist/features/sync/transport/transport.js +153 -0
  127. package/dist/features/sync/transport/transport.js.map +1 -0
  128. package/dist/features/sync/transport/websocketTransport.d.ts +126 -0
  129. package/dist/features/sync/transport/websocketTransport.d.ts.map +1 -0
  130. package/dist/features/sync/transport/websocketTransport.js +374 -0
  131. package/dist/features/sync/transport/websocketTransport.js.map +1 -0
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +6 -0
  134. package/dist/index.js.map +1 -1
  135. package/package.json +21 -1
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Conflict Detection and Resolution.
3
+ *
4
+ * Provides conflict detection using vector clocks and
5
+ * configurable resolution strategies with UI hooks.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import type { VectorClockData } from '../protocol/vectorClock';
10
+ /**
11
+ * Conflict resolution strategy.
12
+ */
13
+ export type ConflictStrategy = 'last-write-wins' | 'local-wins' | 'remote-wins' | 'merge' | 'manual';
14
+ /**
15
+ * Resolution decision for a conflict.
16
+ */
17
+ export type ResolutionDecision = 'use_local' | 'use_remote' | 'use_merged' | 'keep_both' | 'defer';
18
+ /**
19
+ * Represents a sync conflict between local and remote data.
20
+ */
21
+ export interface SyncConflict {
22
+ /** Unique conflict identifier */
23
+ conflictId: string;
24
+ /** Table where conflict occurred */
25
+ tableName: string;
26
+ /** Primary key of the conflicting record */
27
+ recordId: string;
28
+ /** Local version of the data */
29
+ localData: Record<string, unknown>;
30
+ /** Remote version of the data */
31
+ remoteData: Record<string, unknown>;
32
+ /** Local vector clock */
33
+ localClock: VectorClockData;
34
+ /** Remote vector clock */
35
+ remoteClock: VectorClockData;
36
+ /** Local device ID */
37
+ localDeviceId: string;
38
+ /** Remote device ID */
39
+ remoteDeviceId: string;
40
+ /** When the conflict was detected */
41
+ detectedAt: number;
42
+ /** Fields that differ between versions */
43
+ conflictingFields: string[];
44
+ /** Conflict status */
45
+ status: 'pending' | 'resolved' | 'deferred';
46
+ }
47
+ /**
48
+ * Resolution result after conflict is resolved.
49
+ */
50
+ export interface ConflictResolution {
51
+ /** How the conflict was resolved */
52
+ decision: ResolutionDecision;
53
+ /** Merged data if decision is 'use_merged' */
54
+ mergedData?: Record<string, unknown>;
55
+ /** Merged vector clock */
56
+ mergedClock: VectorClockData;
57
+ /** Who/what resolved the conflict */
58
+ resolvedBy: 'auto' | 'user' | 'strategy';
59
+ /** Resolution timestamp */
60
+ resolvedAt: number;
61
+ /** Optional reason for the resolution */
62
+ reason?: string;
63
+ }
64
+ /**
65
+ * UI hooks for conflict resolution.
66
+ */
67
+ export interface ConflictUIHooks {
68
+ /**
69
+ * Called when a conflict requires manual resolution.
70
+ * Return the resolution decision from the UI.
71
+ */
72
+ onConflictNeedsResolution?: (conflict: SyncConflict) => Promise<ConflictResolution>;
73
+ /**
74
+ * Called when a conflict is detected (before auto-resolution).
75
+ */
76
+ onConflictDetected?: (conflict: SyncConflict) => void;
77
+ /**
78
+ * Called after a conflict is resolved.
79
+ */
80
+ onConflictResolved?: (conflict: SyncConflict, resolution: ConflictResolution) => void;
81
+ /**
82
+ * Called when auto-merge fails and manual intervention is needed.
83
+ */
84
+ onMergeFailed?: (conflict: SyncConflict, error: Error) => void;
85
+ }
86
+ /**
87
+ * Configuration for the conflict resolver.
88
+ */
89
+ export interface ConflictResolverOptions {
90
+ /** Default resolution strategy */
91
+ defaultStrategy: ConflictStrategy;
92
+ /** Per-table strategy overrides */
93
+ tableStrategies?: Record<string, ConflictStrategy>;
94
+ /** Per-field merge functions for 'merge' strategy */
95
+ fieldMergers?: Record<string, FieldMerger>;
96
+ /** UI hooks for manual resolution */
97
+ hooks?: ConflictUIHooks;
98
+ /** Maximum time to wait for manual resolution (ms) */
99
+ manualResolutionTimeout?: number;
100
+ /** Auto-resolve conflicts older than this (ms) */
101
+ autoResolveAfter?: number;
102
+ }
103
+ /**
104
+ * Function to merge a single field.
105
+ */
106
+ export type FieldMerger = (fieldName: string, localValue: unknown, remoteValue: unknown, localTimestamp: number, remoteTimestamp: number) => unknown;
107
+ /**
108
+ * Built-in field mergers.
109
+ */
110
+ export declare const FieldMergers: {
111
+ /**
112
+ * Use the most recent value based on timestamp.
113
+ */
114
+ lastWriteWins: FieldMerger;
115
+ /**
116
+ * For numeric fields, take the maximum value.
117
+ */
118
+ max: FieldMerger;
119
+ /**
120
+ * For numeric fields, sum the values.
121
+ */
122
+ sum: FieldMerger;
123
+ /**
124
+ * For arrays, union the values.
125
+ */
126
+ union: FieldMerger;
127
+ /**
128
+ * For strings, concatenate with separator.
129
+ */
130
+ concat: FieldMerger;
131
+ };
132
+ /**
133
+ * Conflict resolver for cross-platform sync.
134
+ *
135
+ * Detects conflicts using vector clock comparison and resolves
136
+ * them using configurable strategies or UI hooks.
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * const resolver = new ConflictResolver({
141
+ * defaultStrategy: 'last-write-wins',
142
+ * tableStrategies: {
143
+ * notes: 'merge',
144
+ * settings: 'local-wins',
145
+ * },
146
+ * hooks: {
147
+ * onConflictNeedsResolution: async (conflict) => {
148
+ * return showConflictDialog(conflict);
149
+ * },
150
+ * },
151
+ * });
152
+ *
153
+ * const resolution = await resolver.resolve(conflict);
154
+ * ```
155
+ */
156
+ export declare class ConflictResolver {
157
+ private _options;
158
+ private _pendingConflicts;
159
+ private _resolvedConflicts;
160
+ constructor(options: ConflictResolverOptions);
161
+ /**
162
+ * Detect if there is a conflict between local and remote data.
163
+ */
164
+ detectConflict(tableName: string, recordId: string, localData: Record<string, unknown>, remoteData: Record<string, unknown>, localClock: VectorClockData, remoteClock: VectorClockData, localDeviceId: string, remoteDeviceId: string): SyncConflict | null;
165
+ /**
166
+ * Resolve a conflict using the configured strategy.
167
+ */
168
+ resolve(conflict: SyncConflict): Promise<ConflictResolution>;
169
+ /**
170
+ * Get pending conflicts.
171
+ */
172
+ getPendingConflicts(): SyncConflict[];
173
+ /**
174
+ * Get a specific pending conflict.
175
+ */
176
+ getConflict(conflictId: string): SyncConflict | undefined;
177
+ /**
178
+ * Manually resolve a conflict with a user decision.
179
+ */
180
+ resolveManually(conflictId: string, decision: ResolutionDecision, mergedData?: Record<string, unknown>): Promise<ConflictResolution>;
181
+ /**
182
+ * Auto-resolve old conflicts that have been pending too long.
183
+ */
184
+ autoResolveStale(): ConflictResolution[];
185
+ /**
186
+ * Get the resolution strategy for a table.
187
+ */
188
+ private _getStrategy;
189
+ /**
190
+ * Find fields that differ between local and remote data.
191
+ */
192
+ private _findConflictingFields;
193
+ /**
194
+ * Check if two values are equal (deep comparison for objects/arrays).
195
+ */
196
+ private _valuesEqual;
197
+ /**
198
+ * Resolve using last-write-wins strategy.
199
+ */
200
+ private _resolveLastWriteWins;
201
+ /**
202
+ * Resolve using local-wins strategy.
203
+ */
204
+ private _resolveLocalWins;
205
+ /**
206
+ * Resolve using remote-wins strategy.
207
+ */
208
+ private _resolveRemoteWins;
209
+ /**
210
+ * Resolve using field-level merge strategy.
211
+ */
212
+ private _resolveMerge;
213
+ /**
214
+ * Resolve using manual/UI strategy.
215
+ */
216
+ private _resolveManual;
217
+ }
218
+ /**
219
+ * Create a conflict resolver instance.
220
+ */
221
+ export declare const createConflictResolver: (options: ConflictResolverOptions) => ConflictResolver;
222
+ //# sourceMappingURL=conflictResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflictResolver.d.ts","sourceRoot":"","sources":["../../../../src/features/sync/conflicts/conflictResolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,396 @@
1
+ /**
2
+ * Conflict Detection and Resolution.
3
+ *
4
+ * Provides conflict detection using vector clocks and
5
+ * configurable resolution strategies with UI hooks.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import { compareClocks } from '../protocol/vectorClock.js';
10
+ /**
11
+ * Built-in field mergers.
12
+ */
13
+ export const FieldMergers = {
14
+ /**
15
+ * Use the most recent value based on timestamp.
16
+ */
17
+ lastWriteWins: ((_fieldName, localValue, remoteValue, localTimestamp, remoteTimestamp) => {
18
+ return localTimestamp >= remoteTimestamp ? localValue : remoteValue;
19
+ }),
20
+ /**
21
+ * For numeric fields, take the maximum value.
22
+ */
23
+ max: ((_fieldName, localValue, remoteValue) => {
24
+ const local = Number(localValue) || 0;
25
+ const remote = Number(remoteValue) || 0;
26
+ return Math.max(local, remote);
27
+ }),
28
+ /**
29
+ * For numeric fields, sum the values.
30
+ */
31
+ sum: ((_fieldName, localValue, remoteValue) => {
32
+ const local = Number(localValue) || 0;
33
+ const remote = Number(remoteValue) || 0;
34
+ return local + remote;
35
+ }),
36
+ /**
37
+ * For arrays, union the values.
38
+ */
39
+ union: ((_fieldName, localValue, remoteValue) => {
40
+ const local = Array.isArray(localValue) ? localValue : [];
41
+ const remote = Array.isArray(remoteValue) ? remoteValue : [];
42
+ return [...new Set([...local, ...remote])];
43
+ }),
44
+ /**
45
+ * For strings, concatenate with separator.
46
+ */
47
+ concat: ((_fieldName, localValue, remoteValue) => {
48
+ const local = String(localValue ?? '');
49
+ const remote = String(remoteValue ?? '');
50
+ if (!local)
51
+ return remote;
52
+ if (!remote)
53
+ return local;
54
+ if (local === remote)
55
+ return local;
56
+ return `${local}\n---\n${remote}`;
57
+ }),
58
+ };
59
+ /**
60
+ * Merge two vector clocks by taking max of each device's counter.
61
+ */
62
+ function mergeVectorClocks(a, b) {
63
+ const merged = { ...a };
64
+ for (const [deviceId, value] of Object.entries(b)) {
65
+ merged[deviceId] = Math.max(merged[deviceId] ?? 0, value);
66
+ }
67
+ return merged;
68
+ }
69
+ /**
70
+ * Get total tick count from a vector clock.
71
+ */
72
+ function getTotalTicks(clock) {
73
+ return Object.values(clock).reduce((sum, val) => sum + val, 0);
74
+ }
75
+ /**
76
+ * Conflict resolver for cross-platform sync.
77
+ *
78
+ * Detects conflicts using vector clock comparison and resolves
79
+ * them using configurable strategies or UI hooks.
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const resolver = new ConflictResolver({
84
+ * defaultStrategy: 'last-write-wins',
85
+ * tableStrategies: {
86
+ * notes: 'merge',
87
+ * settings: 'local-wins',
88
+ * },
89
+ * hooks: {
90
+ * onConflictNeedsResolution: async (conflict) => {
91
+ * return showConflictDialog(conflict);
92
+ * },
93
+ * },
94
+ * });
95
+ *
96
+ * const resolution = await resolver.resolve(conflict);
97
+ * ```
98
+ */
99
+ export class ConflictResolver {
100
+ constructor(options) {
101
+ this._pendingConflicts = new Map();
102
+ this._resolvedConflicts = new Map();
103
+ this._options = {
104
+ defaultStrategy: options.defaultStrategy,
105
+ tableStrategies: options.tableStrategies ?? {},
106
+ fieldMergers: options.fieldMergers ?? {},
107
+ hooks: options.hooks ?? {},
108
+ manualResolutionTimeout: options.manualResolutionTimeout ?? 300000, // 5 minutes
109
+ autoResolveAfter: options.autoResolveAfter ?? 0, // Disabled by default
110
+ };
111
+ }
112
+ /**
113
+ * Detect if there is a conflict between local and remote data.
114
+ */
115
+ detectConflict(tableName, recordId, localData, remoteData, localClock, remoteClock, localDeviceId, remoteDeviceId) {
116
+ // Compare vector clocks
117
+ const comparison = compareClocks(localClock, remoteClock);
118
+ // No conflict if one is clearly before the other
119
+ if (comparison === 'before' || comparison === 'after') {
120
+ return null;
121
+ }
122
+ // Concurrent changes - potential conflict
123
+ // Check if data actually differs
124
+ const conflictingFields = this._findConflictingFields(localData, remoteData);
125
+ if (conflictingFields.length === 0) {
126
+ // Same data, no conflict
127
+ return null;
128
+ }
129
+ const conflict = {
130
+ conflictId: `${tableName}:${recordId}:${Date.now()}`,
131
+ tableName,
132
+ recordId,
133
+ localData,
134
+ remoteData,
135
+ localClock,
136
+ remoteClock,
137
+ localDeviceId,
138
+ remoteDeviceId,
139
+ detectedAt: Date.now(),
140
+ conflictingFields,
141
+ status: 'pending',
142
+ };
143
+ this._pendingConflicts.set(conflict.conflictId, conflict);
144
+ this._options.hooks.onConflictDetected?.(conflict);
145
+ return conflict;
146
+ }
147
+ /**
148
+ * Resolve a conflict using the configured strategy.
149
+ */
150
+ async resolve(conflict) {
151
+ const strategy = this._getStrategy(conflict.tableName);
152
+ let resolution;
153
+ switch (strategy) {
154
+ case 'last-write-wins':
155
+ resolution = this._resolveLastWriteWins(conflict);
156
+ break;
157
+ case 'local-wins':
158
+ resolution = this._resolveLocalWins(conflict);
159
+ break;
160
+ case 'remote-wins':
161
+ resolution = this._resolveRemoteWins(conflict);
162
+ break;
163
+ case 'merge':
164
+ resolution = this._resolveMerge(conflict);
165
+ break;
166
+ case 'manual':
167
+ resolution = await this._resolveManual(conflict);
168
+ break;
169
+ default:
170
+ resolution = this._resolveLastWriteWins(conflict);
171
+ }
172
+ // Update conflict status
173
+ conflict.status = resolution.decision === 'defer' ? 'deferred' : 'resolved';
174
+ // Store resolution
175
+ this._resolvedConflicts.set(conflict.conflictId, resolution);
176
+ this._pendingConflicts.delete(conflict.conflictId);
177
+ // Notify hooks
178
+ this._options.hooks.onConflictResolved?.(conflict, resolution);
179
+ return resolution;
180
+ }
181
+ /**
182
+ * Get pending conflicts.
183
+ */
184
+ getPendingConflicts() {
185
+ return Array.from(this._pendingConflicts.values());
186
+ }
187
+ /**
188
+ * Get a specific pending conflict.
189
+ */
190
+ getConflict(conflictId) {
191
+ return this._pendingConflicts.get(conflictId);
192
+ }
193
+ /**
194
+ * Manually resolve a conflict with a user decision.
195
+ */
196
+ async resolveManually(conflictId, decision, mergedData) {
197
+ const conflict = this._pendingConflicts.get(conflictId);
198
+ if (!conflict) {
199
+ throw new Error(`Conflict not found: ${conflictId}`);
200
+ }
201
+ const resolution = {
202
+ decision,
203
+ mergedData,
204
+ mergedClock: mergeVectorClocks(conflict.localClock, conflict.remoteClock),
205
+ resolvedBy: 'user',
206
+ resolvedAt: Date.now(),
207
+ };
208
+ conflict.status = 'resolved';
209
+ this._resolvedConflicts.set(conflictId, resolution);
210
+ this._pendingConflicts.delete(conflictId);
211
+ this._options.hooks.onConflictResolved?.(conflict, resolution);
212
+ return resolution;
213
+ }
214
+ /**
215
+ * Auto-resolve old conflicts that have been pending too long.
216
+ */
217
+ autoResolveStale() {
218
+ if (this._options.autoResolveAfter <= 0) {
219
+ return [];
220
+ }
221
+ const now = Date.now();
222
+ const staleThreshold = now - this._options.autoResolveAfter;
223
+ const resolutions = [];
224
+ for (const conflict of this._pendingConflicts.values()) {
225
+ if (conflict.detectedAt < staleThreshold) {
226
+ // Auto-resolve with last-write-wins
227
+ const resolution = this._resolveLastWriteWins(conflict);
228
+ resolution.reason = 'Auto-resolved due to timeout';
229
+ conflict.status = 'resolved';
230
+ this._resolvedConflicts.set(conflict.conflictId, resolution);
231
+ this._pendingConflicts.delete(conflict.conflictId);
232
+ resolutions.push(resolution);
233
+ this._options.hooks.onConflictResolved?.(conflict, resolution);
234
+ }
235
+ }
236
+ return resolutions;
237
+ }
238
+ /**
239
+ * Get the resolution strategy for a table.
240
+ */
241
+ _getStrategy(tableName) {
242
+ return this._options.tableStrategies[tableName] ?? this._options.defaultStrategy;
243
+ }
244
+ /**
245
+ * Find fields that differ between local and remote data.
246
+ */
247
+ _findConflictingFields(localData, remoteData) {
248
+ const allKeys = new Set([
249
+ ...Object.keys(localData),
250
+ ...Object.keys(remoteData),
251
+ ]);
252
+ const conflicting = [];
253
+ for (const key of allKeys) {
254
+ // Skip metadata fields
255
+ if (key.startsWith('_'))
256
+ continue;
257
+ const localValue = localData[key];
258
+ const remoteValue = remoteData[key];
259
+ if (!this._valuesEqual(localValue, remoteValue)) {
260
+ conflicting.push(key);
261
+ }
262
+ }
263
+ return conflicting;
264
+ }
265
+ /**
266
+ * Check if two values are equal (deep comparison for objects/arrays).
267
+ */
268
+ _valuesEqual(a, b) {
269
+ if (a === b)
270
+ return true;
271
+ if (a === null || b === null)
272
+ return false;
273
+ if (typeof a !== typeof b)
274
+ return false;
275
+ if (typeof a === 'object') {
276
+ return JSON.stringify(a) === JSON.stringify(b);
277
+ }
278
+ return false;
279
+ }
280
+ /**
281
+ * Resolve using last-write-wins strategy.
282
+ */
283
+ _resolveLastWriteWins(conflict) {
284
+ // Use the clock's total ticks as a proxy for recency
285
+ const localTicks = getTotalTicks(conflict.localClock);
286
+ const remoteTicks = getTotalTicks(conflict.remoteClock);
287
+ // If clocks are equal, prefer remote (server-side typically more authoritative)
288
+ const useLocal = localTicks > remoteTicks;
289
+ return {
290
+ decision: useLocal ? 'use_local' : 'use_remote',
291
+ mergedClock: mergeVectorClocks(conflict.localClock, conflict.remoteClock),
292
+ resolvedBy: 'strategy',
293
+ resolvedAt: Date.now(),
294
+ reason: `Last-write-wins: ${useLocal ? 'local' : 'remote'} had higher clock (${useLocal ? localTicks : remoteTicks} ticks)`,
295
+ };
296
+ }
297
+ /**
298
+ * Resolve using local-wins strategy.
299
+ */
300
+ _resolveLocalWins(conflict) {
301
+ return {
302
+ decision: 'use_local',
303
+ mergedClock: mergeVectorClocks(conflict.localClock, conflict.remoteClock),
304
+ resolvedBy: 'strategy',
305
+ resolvedAt: Date.now(),
306
+ reason: 'Local-wins strategy',
307
+ };
308
+ }
309
+ /**
310
+ * Resolve using remote-wins strategy.
311
+ */
312
+ _resolveRemoteWins(conflict) {
313
+ return {
314
+ decision: 'use_remote',
315
+ mergedClock: mergeVectorClocks(conflict.localClock, conflict.remoteClock),
316
+ resolvedBy: 'strategy',
317
+ resolvedAt: Date.now(),
318
+ reason: 'Remote-wins strategy',
319
+ };
320
+ }
321
+ /**
322
+ * Resolve using field-level merge strategy.
323
+ */
324
+ _resolveMerge(conflict) {
325
+ try {
326
+ const mergedData = { ...conflict.localData };
327
+ // Use current timestamp for LWW fallback
328
+ const now = Date.now();
329
+ for (const field of conflict.conflictingFields) {
330
+ const merger = this._options.fieldMergers[field] ?? FieldMergers.lastWriteWins;
331
+ mergedData[field] = merger(field, conflict.localData[field], conflict.remoteData[field], now, now);
332
+ }
333
+ return {
334
+ decision: 'use_merged',
335
+ mergedData,
336
+ mergedClock: mergeVectorClocks(conflict.localClock, conflict.remoteClock),
337
+ resolvedBy: 'strategy',
338
+ resolvedAt: Date.now(),
339
+ reason: `Merged ${conflict.conflictingFields.length} conflicting fields`,
340
+ };
341
+ }
342
+ catch (error) {
343
+ this._options.hooks.onMergeFailed?.(conflict, error);
344
+ // Fallback to last-write-wins
345
+ return this._resolveLastWriteWins(conflict);
346
+ }
347
+ }
348
+ /**
349
+ * Resolve using manual/UI strategy.
350
+ */
351
+ async _resolveManual(conflict) {
352
+ const hook = this._options.hooks.onConflictNeedsResolution;
353
+ if (!hook) {
354
+ // No UI hook, fall back to last-write-wins
355
+ console.warn('[ConflictResolver] No UI hook for manual resolution, falling back to LWW');
356
+ return this._resolveLastWriteWins(conflict);
357
+ }
358
+ // Create a timeout promise
359
+ const timeout = new Promise((_, reject) => {
360
+ setTimeout(() => {
361
+ reject(new Error('Manual resolution timed out'));
362
+ }, this._options.manualResolutionTimeout);
363
+ });
364
+ try {
365
+ // Race between user resolution and timeout
366
+ const resolution = await Promise.race([
367
+ hook(conflict),
368
+ timeout,
369
+ ]);
370
+ return {
371
+ ...resolution,
372
+ mergedClock: mergeVectorClocks(conflict.localClock, conflict.remoteClock),
373
+ resolvedBy: 'user',
374
+ resolvedAt: Date.now(),
375
+ };
376
+ }
377
+ catch (error) {
378
+ console.warn('[ConflictResolver] Manual resolution failed:', error);
379
+ // Defer the conflict for later
380
+ return {
381
+ decision: 'defer',
382
+ mergedClock: conflict.localClock, // Keep local for now
383
+ resolvedBy: 'auto',
384
+ resolvedAt: Date.now(),
385
+ reason: `Manual resolution failed: ${error.message}`,
386
+ };
387
+ }
388
+ }
389
+ }
390
+ /**
391
+ * Create a conflict resolver instance.
392
+ */
393
+ export const createConflictResolver = (options) => {
394
+ return new ConflictResolver(options);
395
+ };
396
+ //# sourceMappingURL=conflictResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflictResolver.js","sourceRoot":"","sources":["../../../../src/features/sync/conflicts/conflictResolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Conflict Resolution Module.
3
+ *
4
+ * Provides conflict detection and resolution for cross-platform sync.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ export * from './conflictResolver';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/features/sync/conflicts/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Conflict Resolution Module.
3
+ *
4
+ * Provides conflict detection and resolution for cross-platform sync.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ export * from './conflictResolver.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/features/sync/conflicts/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,oBAAoB,CAAC"}