-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsync-engine.ts
More file actions
64 lines (55 loc) · 2.02 KB
/
sync-engine.ts
File metadata and controls
64 lines (55 loc) · 2.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// src/infra/offline/sync-engine.ts
/**
* FILE: sync-engine.ts
* LAYER: infra/offline
* ---------------------------------------------------------------------
* PURPOSE:
* Orchestrate offline → online synchronization process.
* Handles replaying queued write operations (mutations/uploads)
* once connectivity is restored.
*
* RESPONSIBILITIES:
* - Read queued offline mutations from offlineQueue.
* - Re-run them (FIFO) using transport.mutate().
* - Remove successfully replayed entries.
* - Stop on first failure to avoid destructive cascading errors.
* - Provide the main entry point: onConnected().
* - (ADDED) After successful replay, invalidate React Query caches by tags.
* ---------------------------------------------------------------------
*/
import { QueryClient } from '@tanstack/react-query'
import { invalidateByTags } from '@/shared/services/api/query/helpers/invalidate-by-tags'
import type { TagMap } from '@/shared/services/api/query/tags'
import { transport } from '@/shared/services/api/transport/transport'
import { offlineQueue } from './offline-queue'
// Wired once at app startup
let qc: QueryClient | null = null
let tagMaps: TagMap[] = []
/** Provide QueryClient so sync-engine can invalidate caches after replay. */
export function setQueryClientForSync(client: QueryClient) {
qc = client
}
/** Provide feature tag maps (e.g., authKeys.tagMap, userKeys.tagMap). */
export function setTagMapsForSync(maps: TagMap[]) {
tagMaps = maps
}
export const syncEngine = {
async replayOfflineMutations() {
const items = offlineQueue.getAll()
for (const item of items) {
try {
await transport.mutate(item.operation, item.variables)
// targeted invalidation after successful replay (if wired)
if (qc && item.tags?.length && tagMaps.length) {
await invalidateByTags(qc, item.tags, tagMaps)
}
offlineQueue.remove(item.id)
} catch {
return
}
}
},
async onConnected() {
await this.replayOfflineMutations()
},
}