@nahisaho/yata-local 1.6.6 → 1.7.0
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.
- package/dist/index-optimizer.d.ts +254 -0
- package/dist/index-optimizer.d.ts.map +1 -0
- package/dist/index-optimizer.js +525 -0
- package/dist/index-optimizer.js.map +1 -0
- package/dist/index.d.ts +35 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -1
- package/dist/index.js.map +1 -1
- package/dist/io.d.ts +143 -0
- package/dist/io.d.ts.map +1 -1
- package/dist/io.js +553 -0
- package/dist/io.js.map +1 -1
- package/dist/sync.d.ts +221 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +404 -0
- package/dist/sync.js.map +1 -0
- package/package.json +1 -1
package/dist/sync.d.ts
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YATA Global Sync Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages synchronization between YATA Local and YATA Global.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
* @module @nahisaho/yata-local/sync
|
|
8
|
+
*
|
|
9
|
+
* @see REQ-YI-GLB-001 - Global Synchronization
|
|
10
|
+
* @see REQ-YI-GLB-002 - Sync State Management
|
|
11
|
+
* @see REQ-YI-GLB-003 - Conflict Resolution
|
|
12
|
+
* @see DES-YATA-IMPROVEMENTS-001 - Design Document
|
|
13
|
+
*/
|
|
14
|
+
import type { Entity, Relationship } from './types.js';
|
|
15
|
+
import type { YataDatabase } from './database.js';
|
|
16
|
+
/**
|
|
17
|
+
* Synchronization configuration
|
|
18
|
+
*/
|
|
19
|
+
export interface SyncConfig {
|
|
20
|
+
/** YATA Global endpoint URL */
|
|
21
|
+
globalEndpoint: string;
|
|
22
|
+
/** Authentication token (optional) */
|
|
23
|
+
authToken?: string;
|
|
24
|
+
/** Namespace to sync */
|
|
25
|
+
namespace: string;
|
|
26
|
+
/** Sync direction */
|
|
27
|
+
syncDirection: 'push' | 'pull' | 'bidirectional';
|
|
28
|
+
/** Conflict resolution strategy */
|
|
29
|
+
conflictStrategy: 'local-wins' | 'remote-wins' | 'manual';
|
|
30
|
+
/** Request timeout in milliseconds */
|
|
31
|
+
timeoutMs?: number;
|
|
32
|
+
/** Batch size for sync operations */
|
|
33
|
+
batchSize?: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Sync state
|
|
37
|
+
*/
|
|
38
|
+
export type SyncState = 'idle' | 'preparing' | 'uploading' | 'downloading' | 'conflict' | 'finalizing' | 'error';
|
|
39
|
+
/**
|
|
40
|
+
* Sync status
|
|
41
|
+
*/
|
|
42
|
+
export interface SyncStatus {
|
|
43
|
+
/** Current sync state */
|
|
44
|
+
state: SyncState;
|
|
45
|
+
/** Progress percentage (0-100) */
|
|
46
|
+
progress: number;
|
|
47
|
+
/** Last successful sync timestamp */
|
|
48
|
+
lastSyncAt?: Date;
|
|
49
|
+
/** Number of pending local changes */
|
|
50
|
+
pendingChanges: number;
|
|
51
|
+
/** Active conflicts */
|
|
52
|
+
conflicts: SyncConflict[];
|
|
53
|
+
/** Error message if in error state */
|
|
54
|
+
errorMessage?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Sync conflict
|
|
58
|
+
*/
|
|
59
|
+
export interface SyncConflict {
|
|
60
|
+
/** Entity ID */
|
|
61
|
+
entityId: string;
|
|
62
|
+
/** Local version */
|
|
63
|
+
localVersion: Entity;
|
|
64
|
+
/** Remote version */
|
|
65
|
+
remoteVersion: Entity;
|
|
66
|
+
/** Conflict type */
|
|
67
|
+
conflictType: 'update-update' | 'delete-update' | 'create-create';
|
|
68
|
+
/** Resolution status */
|
|
69
|
+
resolved: boolean;
|
|
70
|
+
/** Chosen resolution */
|
|
71
|
+
resolution?: 'local' | 'remote' | 'merged';
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Sync result
|
|
75
|
+
*/
|
|
76
|
+
export interface SyncResult {
|
|
77
|
+
/** Whether sync completed successfully */
|
|
78
|
+
success: boolean;
|
|
79
|
+
/** Number of entities uploaded */
|
|
80
|
+
uploaded: number;
|
|
81
|
+
/** Number of entities downloaded */
|
|
82
|
+
downloaded: number;
|
|
83
|
+
/** Conflicts encountered */
|
|
84
|
+
conflicts: SyncConflict[];
|
|
85
|
+
/** Conflicts auto-resolved */
|
|
86
|
+
conflictsResolved: number;
|
|
87
|
+
/** Sync duration in milliseconds */
|
|
88
|
+
syncTimeMs: number;
|
|
89
|
+
/** Error message if failed */
|
|
90
|
+
errorMessage?: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Change set for sync
|
|
94
|
+
*/
|
|
95
|
+
export interface ChangeSet {
|
|
96
|
+
/** New or modified entities */
|
|
97
|
+
entities: Entity[];
|
|
98
|
+
/** New or modified relationships */
|
|
99
|
+
relationships: Relationship[];
|
|
100
|
+
/** Deleted entity IDs */
|
|
101
|
+
deletedEntityIds: string[];
|
|
102
|
+
/** Deleted relationship IDs */
|
|
103
|
+
deletedRelationshipIds: string[];
|
|
104
|
+
/** Last sync ID for continuation */
|
|
105
|
+
lastSyncId?: string;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Sync response from Global
|
|
109
|
+
*/
|
|
110
|
+
export interface SyncResponse {
|
|
111
|
+
/** Changes from remote */
|
|
112
|
+
changes: ChangeSet;
|
|
113
|
+
/** Detected conflicts */
|
|
114
|
+
conflicts: SyncConflict[];
|
|
115
|
+
/** New sync ID */
|
|
116
|
+
syncId: string;
|
|
117
|
+
/** Server timestamp */
|
|
118
|
+
serverTimestamp: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Default sync configuration
|
|
122
|
+
*/
|
|
123
|
+
export declare const DEFAULT_SYNC_CONFIG: Partial<SyncConfig>;
|
|
124
|
+
/**
|
|
125
|
+
* Manages synchronization with YATA Global
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const syncManager = new GlobalSyncManager(db, {
|
|
130
|
+
* globalEndpoint: 'https://yata.global/api',
|
|
131
|
+
* namespace: 'my-project',
|
|
132
|
+
* syncDirection: 'bidirectional',
|
|
133
|
+
* conflictStrategy: 'local-wins',
|
|
134
|
+
* });
|
|
135
|
+
*
|
|
136
|
+
* const result = await syncManager.sync();
|
|
137
|
+
* console.log(`Uploaded: ${result.uploaded}, Downloaded: ${result.downloaded}`);
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* @see REQ-YI-GLB-001
|
|
141
|
+
* @see REQ-YI-GLB-002
|
|
142
|
+
* @see REQ-YI-GLB-003
|
|
143
|
+
*/
|
|
144
|
+
export declare class GlobalSyncManager {
|
|
145
|
+
private db;
|
|
146
|
+
private config;
|
|
147
|
+
private status;
|
|
148
|
+
private lastSyncId?;
|
|
149
|
+
constructor(db: YataDatabase, config: SyncConfig);
|
|
150
|
+
/**
|
|
151
|
+
* Get current sync status
|
|
152
|
+
* @see REQ-YI-GLB-002
|
|
153
|
+
*/
|
|
154
|
+
getStatus(): SyncStatus;
|
|
155
|
+
/**
|
|
156
|
+
* Perform full synchronization
|
|
157
|
+
* Performance target: 60 seconds for up to 1,000 changed entities
|
|
158
|
+
*
|
|
159
|
+
* @returns Sync result
|
|
160
|
+
* @see REQ-YI-GLB-001
|
|
161
|
+
*/
|
|
162
|
+
sync(): Promise<SyncResult>;
|
|
163
|
+
/**
|
|
164
|
+
* Push local changes to Global
|
|
165
|
+
* @see REQ-YI-GLB-001
|
|
166
|
+
*/
|
|
167
|
+
push(): Promise<SyncResult>;
|
|
168
|
+
/**
|
|
169
|
+
* Pull remote changes from Global
|
|
170
|
+
* @see REQ-YI-GLB-001
|
|
171
|
+
*/
|
|
172
|
+
pull(): Promise<SyncResult>;
|
|
173
|
+
/**
|
|
174
|
+
* Manually resolve a conflict
|
|
175
|
+
* @see REQ-YI-GLB-003
|
|
176
|
+
*/
|
|
177
|
+
resolveConflict(entityId: string, resolution: 'local' | 'remote' | 'merged', mergedEntity?: Entity): Promise<boolean>;
|
|
178
|
+
/**
|
|
179
|
+
* Reset sync state
|
|
180
|
+
*/
|
|
181
|
+
reset(): void;
|
|
182
|
+
/**
|
|
183
|
+
* Update sync status
|
|
184
|
+
*/
|
|
185
|
+
private updateStatus;
|
|
186
|
+
/**
|
|
187
|
+
* Get local changes since last sync
|
|
188
|
+
*/
|
|
189
|
+
private getLocalChanges;
|
|
190
|
+
/**
|
|
191
|
+
* Upload changes to Global
|
|
192
|
+
*/
|
|
193
|
+
private uploadChanges;
|
|
194
|
+
/**
|
|
195
|
+
* Download changes from Global
|
|
196
|
+
*/
|
|
197
|
+
private downloadChanges;
|
|
198
|
+
/**
|
|
199
|
+
* Check if there's a conflict between local and remote versions
|
|
200
|
+
*/
|
|
201
|
+
private hasConflict;
|
|
202
|
+
/**
|
|
203
|
+
* Auto-resolve conflicts based on strategy
|
|
204
|
+
* @see REQ-YI-GLB-003
|
|
205
|
+
*/
|
|
206
|
+
private resolveConflicts;
|
|
207
|
+
/**
|
|
208
|
+
* Finalize sync
|
|
209
|
+
*/
|
|
210
|
+
private finalize;
|
|
211
|
+
/**
|
|
212
|
+
* Simulate YATA Global API call
|
|
213
|
+
* This is a placeholder for actual HTTP requests
|
|
214
|
+
*/
|
|
215
|
+
private simulateGlobalApiCall;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Factory function to create GlobalSyncManager
|
|
219
|
+
*/
|
|
220
|
+
export declare function createGlobalSyncManager(db: YataDatabase, config: SyncConfig): GlobalSyncManager;
|
|
221
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
|
package/dist/sync.js
ADDED
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YATA Global Sync Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages synchronization between YATA Local and YATA Global.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
* @module @nahisaho/yata-local/sync
|
|
8
|
+
*
|
|
9
|
+
* @see REQ-YI-GLB-001 - Global Synchronization
|
|
10
|
+
* @see REQ-YI-GLB-002 - Sync State Management
|
|
11
|
+
* @see REQ-YI-GLB-003 - Conflict Resolution
|
|
12
|
+
* @see DES-YATA-IMPROVEMENTS-001 - Design Document
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Default sync configuration
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_SYNC_CONFIG = {
|
|
18
|
+
syncDirection: 'bidirectional',
|
|
19
|
+
conflictStrategy: 'local-wins',
|
|
20
|
+
timeoutMs: 60000,
|
|
21
|
+
batchSize: 100,
|
|
22
|
+
};
|
|
23
|
+
// ============================================================
|
|
24
|
+
// GlobalSyncManager Class
|
|
25
|
+
// ============================================================
|
|
26
|
+
/**
|
|
27
|
+
* Manages synchronization with YATA Global
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const syncManager = new GlobalSyncManager(db, {
|
|
32
|
+
* globalEndpoint: 'https://yata.global/api',
|
|
33
|
+
* namespace: 'my-project',
|
|
34
|
+
* syncDirection: 'bidirectional',
|
|
35
|
+
* conflictStrategy: 'local-wins',
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* const result = await syncManager.sync();
|
|
39
|
+
* console.log(`Uploaded: ${result.uploaded}, Downloaded: ${result.downloaded}`);
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @see REQ-YI-GLB-001
|
|
43
|
+
* @see REQ-YI-GLB-002
|
|
44
|
+
* @see REQ-YI-GLB-003
|
|
45
|
+
*/
|
|
46
|
+
export class GlobalSyncManager {
|
|
47
|
+
db;
|
|
48
|
+
config;
|
|
49
|
+
status;
|
|
50
|
+
lastSyncId;
|
|
51
|
+
constructor(db, config) {
|
|
52
|
+
this.db = db;
|
|
53
|
+
this.config = { ...DEFAULT_SYNC_CONFIG, ...config };
|
|
54
|
+
this.status = {
|
|
55
|
+
state: 'idle',
|
|
56
|
+
progress: 0,
|
|
57
|
+
pendingChanges: 0,
|
|
58
|
+
conflicts: [],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// ============================================================
|
|
62
|
+
// Public API
|
|
63
|
+
// ============================================================
|
|
64
|
+
/**
|
|
65
|
+
* Get current sync status
|
|
66
|
+
* @see REQ-YI-GLB-002
|
|
67
|
+
*/
|
|
68
|
+
getStatus() {
|
|
69
|
+
return { ...this.status };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Perform full synchronization
|
|
73
|
+
* Performance target: 60 seconds for up to 1,000 changed entities
|
|
74
|
+
*
|
|
75
|
+
* @returns Sync result
|
|
76
|
+
* @see REQ-YI-GLB-001
|
|
77
|
+
*/
|
|
78
|
+
async sync() {
|
|
79
|
+
const startTime = Date.now();
|
|
80
|
+
const result = {
|
|
81
|
+
success: false,
|
|
82
|
+
uploaded: 0,
|
|
83
|
+
downloaded: 0,
|
|
84
|
+
conflicts: [],
|
|
85
|
+
conflictsResolved: 0,
|
|
86
|
+
syncTimeMs: 0,
|
|
87
|
+
};
|
|
88
|
+
try {
|
|
89
|
+
// Phase 1: Preparing
|
|
90
|
+
this.updateStatus('preparing', 0);
|
|
91
|
+
const localChanges = await this.getLocalChanges();
|
|
92
|
+
this.status.pendingChanges = localChanges.entities.length + localChanges.deletedEntityIds.length;
|
|
93
|
+
// Phase 2: Upload local changes
|
|
94
|
+
if (this.config.syncDirection !== 'pull') {
|
|
95
|
+
this.updateStatus('uploading', 20);
|
|
96
|
+
const uploadResult = await this.uploadChanges(localChanges);
|
|
97
|
+
result.uploaded = uploadResult.uploaded;
|
|
98
|
+
result.conflicts.push(...uploadResult.conflicts);
|
|
99
|
+
}
|
|
100
|
+
// Phase 3: Download remote changes
|
|
101
|
+
if (this.config.syncDirection !== 'push') {
|
|
102
|
+
this.updateStatus('downloading', 50);
|
|
103
|
+
const downloadResult = await this.downloadChanges();
|
|
104
|
+
result.downloaded = downloadResult.downloaded;
|
|
105
|
+
result.conflicts.push(...downloadResult.conflicts);
|
|
106
|
+
}
|
|
107
|
+
// Phase 4: Resolve conflicts
|
|
108
|
+
if (result.conflicts.length > 0) {
|
|
109
|
+
this.updateStatus('conflict', 70);
|
|
110
|
+
const resolved = await this.resolveConflicts(result.conflicts);
|
|
111
|
+
result.conflictsResolved = resolved;
|
|
112
|
+
}
|
|
113
|
+
// Phase 5: Finalize
|
|
114
|
+
this.updateStatus('finalizing', 90);
|
|
115
|
+
await this.finalize();
|
|
116
|
+
result.success = true;
|
|
117
|
+
this.status.lastSyncAt = new Date();
|
|
118
|
+
this.updateStatus('idle', 100);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
result.success = false;
|
|
122
|
+
result.errorMessage = error instanceof Error ? error.message : String(error);
|
|
123
|
+
this.status.errorMessage = result.errorMessage;
|
|
124
|
+
this.updateStatus('error', 0);
|
|
125
|
+
}
|
|
126
|
+
result.syncTimeMs = Date.now() - startTime;
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Push local changes to Global
|
|
131
|
+
* @see REQ-YI-GLB-001
|
|
132
|
+
*/
|
|
133
|
+
async push() {
|
|
134
|
+
const originalDirection = this.config.syncDirection;
|
|
135
|
+
this.config.syncDirection = 'push';
|
|
136
|
+
try {
|
|
137
|
+
return await this.sync();
|
|
138
|
+
}
|
|
139
|
+
finally {
|
|
140
|
+
this.config.syncDirection = originalDirection;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Pull remote changes from Global
|
|
145
|
+
* @see REQ-YI-GLB-001
|
|
146
|
+
*/
|
|
147
|
+
async pull() {
|
|
148
|
+
const originalDirection = this.config.syncDirection;
|
|
149
|
+
this.config.syncDirection = 'pull';
|
|
150
|
+
try {
|
|
151
|
+
return await this.sync();
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
this.config.syncDirection = originalDirection;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Manually resolve a conflict
|
|
159
|
+
* @see REQ-YI-GLB-003
|
|
160
|
+
*/
|
|
161
|
+
async resolveConflict(entityId, resolution, mergedEntity) {
|
|
162
|
+
const conflict = this.status.conflicts.find(c => c.entityId === entityId);
|
|
163
|
+
if (!conflict) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
switch (resolution) {
|
|
167
|
+
case 'local':
|
|
168
|
+
// Keep local version - no action needed
|
|
169
|
+
conflict.resolution = 'local';
|
|
170
|
+
break;
|
|
171
|
+
case 'remote':
|
|
172
|
+
// Apply remote version
|
|
173
|
+
this.db.updateEntity(entityId, conflict.remoteVersion);
|
|
174
|
+
conflict.resolution = 'remote';
|
|
175
|
+
break;
|
|
176
|
+
case 'merged':
|
|
177
|
+
if (!mergedEntity) {
|
|
178
|
+
throw new Error('Merged entity required for merge resolution');
|
|
179
|
+
}
|
|
180
|
+
this.db.updateEntity(entityId, mergedEntity);
|
|
181
|
+
conflict.resolution = 'merged';
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
conflict.resolved = true;
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Reset sync state
|
|
189
|
+
*/
|
|
190
|
+
reset() {
|
|
191
|
+
this.status = {
|
|
192
|
+
state: 'idle',
|
|
193
|
+
progress: 0,
|
|
194
|
+
pendingChanges: 0,
|
|
195
|
+
conflicts: [],
|
|
196
|
+
};
|
|
197
|
+
this.lastSyncId = undefined;
|
|
198
|
+
}
|
|
199
|
+
// ============================================================
|
|
200
|
+
// Internal Methods
|
|
201
|
+
// ============================================================
|
|
202
|
+
/**
|
|
203
|
+
* Update sync status
|
|
204
|
+
*/
|
|
205
|
+
updateStatus(state, progress) {
|
|
206
|
+
this.status.state = state;
|
|
207
|
+
this.status.progress = progress;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get local changes since last sync
|
|
211
|
+
*/
|
|
212
|
+
async getLocalChanges() {
|
|
213
|
+
const since = this.status.lastSyncAt ?? new Date(0);
|
|
214
|
+
const changes = this.db.getChangesSince(since);
|
|
215
|
+
return {
|
|
216
|
+
entities: [...changes.entities.added, ...changes.entities.updated],
|
|
217
|
+
relationships: [...changes.relationships.added],
|
|
218
|
+
deletedEntityIds: changes.entities.deleted,
|
|
219
|
+
deletedRelationshipIds: changes.relationships.deleted,
|
|
220
|
+
lastSyncId: this.lastSyncId,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Upload changes to Global
|
|
225
|
+
*/
|
|
226
|
+
async uploadChanges(changes) {
|
|
227
|
+
// In a real implementation, this would make HTTP requests to YATA Global
|
|
228
|
+
// For now, we simulate the behavior
|
|
229
|
+
const result = {
|
|
230
|
+
uploaded: 0,
|
|
231
|
+
conflicts: [],
|
|
232
|
+
};
|
|
233
|
+
// Simulate batched upload
|
|
234
|
+
const batchSize = this.config.batchSize ?? 100;
|
|
235
|
+
for (let i = 0; i < changes.entities.length; i += batchSize) {
|
|
236
|
+
const batch = changes.entities.slice(i, i + batchSize);
|
|
237
|
+
try {
|
|
238
|
+
// Simulated API call
|
|
239
|
+
const response = await this.simulateGlobalApiCall('push', {
|
|
240
|
+
entities: batch,
|
|
241
|
+
namespace: this.config.namespace,
|
|
242
|
+
});
|
|
243
|
+
result.uploaded += batch.length;
|
|
244
|
+
if (response.conflicts) {
|
|
245
|
+
result.conflicts.push(...response.conflicts);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
throw new Error(`Failed to upload batch: ${error instanceof Error ? error.message : String(error)}`);
|
|
250
|
+
}
|
|
251
|
+
// Update progress
|
|
252
|
+
const progress = 20 + (30 * (i + batch.length) / changes.entities.length);
|
|
253
|
+
this.updateStatus('uploading', progress);
|
|
254
|
+
}
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Download changes from Global
|
|
259
|
+
*/
|
|
260
|
+
async downloadChanges() {
|
|
261
|
+
const result = {
|
|
262
|
+
downloaded: 0,
|
|
263
|
+
conflicts: [],
|
|
264
|
+
};
|
|
265
|
+
try {
|
|
266
|
+
// Simulated API call to get remote changes
|
|
267
|
+
const response = await this.simulateGlobalApiCall('pull', {
|
|
268
|
+
namespace: this.config.namespace,
|
|
269
|
+
since: this.lastSyncId,
|
|
270
|
+
});
|
|
271
|
+
// Apply remote changes
|
|
272
|
+
for (const entity of response.changes?.entities ?? []) {
|
|
273
|
+
const local = this.db.getEntity(entity.id);
|
|
274
|
+
if (local) {
|
|
275
|
+
// Potential conflict
|
|
276
|
+
if (this.hasConflict(local, entity)) {
|
|
277
|
+
result.conflicts.push({
|
|
278
|
+
entityId: entity.id,
|
|
279
|
+
localVersion: local,
|
|
280
|
+
remoteVersion: entity,
|
|
281
|
+
conflictType: 'update-update',
|
|
282
|
+
resolved: false,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
this.db.updateEntity(entity.id, entity);
|
|
287
|
+
result.downloaded++;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
this.db.insertEntity(entity);
|
|
292
|
+
result.downloaded++;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
// Handle deleted entities
|
|
296
|
+
for (const entityId of response.changes?.deletedEntityIds ?? []) {
|
|
297
|
+
const local = this.db.getEntity(entityId);
|
|
298
|
+
if (local) {
|
|
299
|
+
// Check if local was modified after remote deletion
|
|
300
|
+
const localChanges = this.db.getChangesSince(this.status.lastSyncAt ?? new Date(0));
|
|
301
|
+
const wasModified = localChanges.entities.updated.some(e => e.id === entityId);
|
|
302
|
+
if (wasModified) {
|
|
303
|
+
result.conflicts.push({
|
|
304
|
+
entityId,
|
|
305
|
+
localVersion: local,
|
|
306
|
+
remoteVersion: { ...local, id: entityId }, // Marker for deleted
|
|
307
|
+
conflictType: 'delete-update',
|
|
308
|
+
resolved: false,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
this.db.deleteEntity(entityId);
|
|
313
|
+
result.downloaded++;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// Update sync ID
|
|
318
|
+
if (response.syncId) {
|
|
319
|
+
this.lastSyncId = response.syncId;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
catch (error) {
|
|
323
|
+
throw new Error(`Failed to download changes: ${error instanceof Error ? error.message : String(error)}`);
|
|
324
|
+
}
|
|
325
|
+
return result;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Check if there's a conflict between local and remote versions
|
|
329
|
+
*/
|
|
330
|
+
hasConflict(local, remote) {
|
|
331
|
+
// Simple conflict detection: both modified after last sync
|
|
332
|
+
const lastSync = this.status.lastSyncAt ?? new Date(0);
|
|
333
|
+
return local.updatedAt > lastSync && remote.updatedAt > lastSync;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Auto-resolve conflicts based on strategy
|
|
337
|
+
* @see REQ-YI-GLB-003
|
|
338
|
+
*/
|
|
339
|
+
async resolveConflicts(conflicts) {
|
|
340
|
+
let resolved = 0;
|
|
341
|
+
for (const conflict of conflicts) {
|
|
342
|
+
if (this.config.conflictStrategy === 'manual') {
|
|
343
|
+
// Skip - wait for manual resolution
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
const resolution = this.config.conflictStrategy === 'local-wins' ? 'local' : 'remote';
|
|
347
|
+
if (resolution === 'remote') {
|
|
348
|
+
this.db.updateEntity(conflict.entityId, conflict.remoteVersion);
|
|
349
|
+
}
|
|
350
|
+
// local-wins: keep local, no action needed
|
|
351
|
+
conflict.resolved = true;
|
|
352
|
+
conflict.resolution = resolution;
|
|
353
|
+
resolved++;
|
|
354
|
+
}
|
|
355
|
+
// Update status conflicts (only unresolved)
|
|
356
|
+
this.status.conflicts = conflicts.filter(c => !c.resolved);
|
|
357
|
+
return resolved;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Finalize sync
|
|
361
|
+
*/
|
|
362
|
+
async finalize() {
|
|
363
|
+
// Commit any pending changes
|
|
364
|
+
// In a real implementation, this might involve committing a transaction
|
|
365
|
+
// or updating sync metadata
|
|
366
|
+
// Clear pending changes count
|
|
367
|
+
this.status.pendingChanges = 0;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Simulate YATA Global API call
|
|
371
|
+
* This is a placeholder for actual HTTP requests
|
|
372
|
+
*/
|
|
373
|
+
async simulateGlobalApiCall(_operation, _payload) {
|
|
374
|
+
// Simulate network delay
|
|
375
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
376
|
+
// In production, this would be:
|
|
377
|
+
// const response = await fetch(`${this.config.globalEndpoint}/sync/${operation}`, {
|
|
378
|
+
// method: 'POST',
|
|
379
|
+
// headers: {
|
|
380
|
+
// 'Content-Type': 'application/json',
|
|
381
|
+
// 'Authorization': `Bearer ${this.config.authToken}`,
|
|
382
|
+
// },
|
|
383
|
+
// body: JSON.stringify(payload),
|
|
384
|
+
// });
|
|
385
|
+
return {
|
|
386
|
+
changes: {
|
|
387
|
+
entities: [],
|
|
388
|
+
relationships: [],
|
|
389
|
+
deletedEntityIds: [],
|
|
390
|
+
deletedRelationshipIds: [],
|
|
391
|
+
},
|
|
392
|
+
conflicts: [],
|
|
393
|
+
syncId: `sync-${Date.now()}`,
|
|
394
|
+
serverTimestamp: new Date().toISOString(),
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Factory function to create GlobalSyncManager
|
|
400
|
+
*/
|
|
401
|
+
export function createGlobalSyncManager(db, config) {
|
|
402
|
+
return new GlobalSyncManager(db, config);
|
|
403
|
+
}
|
|
404
|
+
//# sourceMappingURL=sync.js.map
|
package/dist/sync.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
|