Phase 4 - synch engine complete
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
import 'sync_status.dart';
|
||||
|
||||
/// Represents a sync operation in the queue.
|
||||
class SyncOperation {
|
||||
/// Unique identifier for the operation.
|
||||
final String id;
|
||||
|
||||
/// Type of sync operation.
|
||||
final SyncOperationType type;
|
||||
|
||||
/// Item ID being synced.
|
||||
final String itemId;
|
||||
|
||||
/// Source of the sync (local, immich, nostr).
|
||||
final String source;
|
||||
|
||||
/// Target of the sync (local, immich, nostr).
|
||||
final String target;
|
||||
|
||||
/// Current status of the operation.
|
||||
SyncStatus status;
|
||||
|
||||
/// Priority of the operation.
|
||||
final SyncPriority priority;
|
||||
|
||||
/// Number of retry attempts.
|
||||
int retryCount;
|
||||
|
||||
/// Maximum number of retries allowed.
|
||||
final int maxRetries;
|
||||
|
||||
/// Error message if operation failed.
|
||||
String? error;
|
||||
|
||||
/// Timestamp when operation was created.
|
||||
final int createdAt;
|
||||
|
||||
/// Timestamp when operation was last updated.
|
||||
int updatedAt;
|
||||
|
||||
/// Creates a [SyncOperation] instance.
|
||||
SyncOperation({
|
||||
required this.id,
|
||||
required this.type,
|
||||
required this.itemId,
|
||||
required this.source,
|
||||
required this.target,
|
||||
this.status = SyncStatus.pending,
|
||||
this.priority = SyncPriority.normal,
|
||||
this.retryCount = 0,
|
||||
this.maxRetries = 3,
|
||||
this.error,
|
||||
int? createdAt,
|
||||
int? updatedAt,
|
||||
}) : createdAt = createdAt ?? DateTime.now().millisecondsSinceEpoch,
|
||||
updatedAt = updatedAt ?? DateTime.now().millisecondsSinceEpoch;
|
||||
|
||||
/// Creates a [SyncOperation] from JSON.
|
||||
factory SyncOperation.fromJson(Map<String, dynamic> json) {
|
||||
return SyncOperation(
|
||||
id: json['id'] as String,
|
||||
type: SyncOperationType.values.firstWhere(
|
||||
(e) => e.toString() == json['type'],
|
||||
orElse: () => SyncOperationType.upload,
|
||||
),
|
||||
itemId: json['itemId'] as String,
|
||||
source: json['source'] as String,
|
||||
target: json['target'] as String,
|
||||
status: SyncStatus.values.firstWhere(
|
||||
(e) => e.toString() == json['status'],
|
||||
orElse: () => SyncStatus.pending,
|
||||
),
|
||||
priority: SyncPriority.values.firstWhere(
|
||||
(e) => e.toString() == json['priority'],
|
||||
orElse: () => SyncPriority.normal,
|
||||
),
|
||||
retryCount: json['retryCount'] as int? ?? 0,
|
||||
maxRetries: json['maxRetries'] as int? ?? 3,
|
||||
error: json['error'] as String?,
|
||||
createdAt: json['createdAt'] as int,
|
||||
updatedAt: json['updatedAt'] as int,
|
||||
);
|
||||
}
|
||||
|
||||
/// Converts [SyncOperation] to JSON.
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'type': type.toString(),
|
||||
'itemId': itemId,
|
||||
'source': source,
|
||||
'target': target,
|
||||
'status': status.toString(),
|
||||
'priority': priority.toString(),
|
||||
'retryCount': retryCount,
|
||||
'maxRetries': maxRetries,
|
||||
'error': error,
|
||||
'createdAt': createdAt,
|
||||
'updatedAt': updatedAt,
|
||||
};
|
||||
}
|
||||
|
||||
/// Marks the operation as failed with an error.
|
||||
void markFailed(String errorMessage) {
|
||||
status = SyncStatus.failed;
|
||||
error = errorMessage;
|
||||
updatedAt = DateTime.now().millisecondsSinceEpoch;
|
||||
}
|
||||
|
||||
/// Marks the operation as successful.
|
||||
void markSuccess() {
|
||||
status = SyncStatus.success;
|
||||
error = null;
|
||||
updatedAt = DateTime.now().millisecondsSinceEpoch;
|
||||
}
|
||||
|
||||
/// Increments retry count and updates status.
|
||||
void incrementRetry() {
|
||||
retryCount++;
|
||||
status = SyncStatus.pending;
|
||||
updatedAt = DateTime.now().millisecondsSinceEpoch;
|
||||
}
|
||||
|
||||
/// Checks if the operation can be retried.
|
||||
bool canRetry() {
|
||||
return retryCount < maxRetries && status == SyncStatus.failed;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SyncOperation(id: $id, type: $type, itemId: $itemId, status: $status, retries: $retryCount/$maxRetries)';
|
||||
}
|
||||
}
|
||||
|
||||
/// Type of sync operation.
|
||||
enum SyncOperationType {
|
||||
/// Upload operation (local to remote).
|
||||
upload,
|
||||
|
||||
/// Download operation (remote to local).
|
||||
download,
|
||||
|
||||
/// Bidirectional sync (merge).
|
||||
sync,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/// Status of a sync operation.
|
||||
enum SyncStatus {
|
||||
/// Sync operation is pending (queued).
|
||||
pending,
|
||||
|
||||
/// Sync operation is in progress.
|
||||
syncing,
|
||||
|
||||
/// Sync operation completed successfully.
|
||||
success,
|
||||
|
||||
/// Sync operation failed.
|
||||
failed,
|
||||
}
|
||||
|
||||
/// Priority level for sync operations.
|
||||
enum SyncPriority {
|
||||
/// Low priority (background sync).
|
||||
low,
|
||||
|
||||
/// Normal priority.
|
||||
normal,
|
||||
|
||||
/// High priority (user-initiated).
|
||||
high,
|
||||
}
|
||||
|
||||
/// Resolution strategy for conflicts.
|
||||
enum ConflictResolution {
|
||||
/// Use local version (prefer local data).
|
||||
useLocal,
|
||||
|
||||
/// Use remote version (prefer remote data).
|
||||
useRemote,
|
||||
|
||||
/// Merge both versions.
|
||||
merge,
|
||||
|
||||
/// Keep the most recent version based on timestamp.
|
||||
useLatest,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user