-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathtransport.ts
More file actions
80 lines (70 loc) · 2.51 KB
/
transport.ts
File metadata and controls
80 lines (70 loc) · 2.51 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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// src/infra/transport/transport.ts
/**
* FILE: transport.ts
* LAYER: infra/transport
* ---------------------------------------------------------------------
* PURPOSE:
* Provide a single, offline-aware Transport instance for the app.
* All services must use this, never concrete adapters directly.
*
* RESPONSIBILITIES:
* - Hold active low-level adapter (REST/GraphQL/Firebase/WebSocket/...).
* - Expose setTransport() to swap adapters at runtime/config.
* - Track offlineMode flag (setOfflineMode()).
* - Wrap adapter calls to:
* - queue mutations/uploads when offline,
* - block queries/subscriptions when offline.
* ---------------------------------------------------------------------
*/
import { offlineQueue } from '@/shared/services/api/offline/offline-queue'
import type { Tag } from '@/shared/services/api/query/tags'
import { restAdapter } from './adapters/rest.adapter'
// src/infra/transport/transport.ts
import type { Transport } from './transport.types'
let activeTransport: Transport = restAdapter
let offline = false
export function setTransport(adapter: Transport) {
activeTransport = adapter
}
export function setOfflineMode(enabled: boolean) {
offline = enabled
}
export function isOfflineMode(): boolean {
return offline
}
function normalizeTags(tags?: Tag | readonly Tag[]): Tag[] | undefined {
if (!tags) return undefined
if (typeof tags === 'string') return [tags]
if (Array.isArray(tags)) return [...tags] // ✅ make mutable copy
return undefined
}
export const transport: Transport = {
async query(operation, variables, meta) {
if (offline) {
const err: any = new Error('Offline: query is not available')
err.code = 'NETWORK_OFFLINE'
throw err
}
return activeTransport.query(operation, variables, meta)
},
async mutate(operation, variables, meta) {
if (offline) {
const tags = normalizeTags(meta?.tags)
offlineQueue.push(operation, variables, tags)
return Promise.resolve({ offline: true, queued: true } as any)
}
return activeTransport.mutate(operation, variables, meta)
},
subscribe(channel, handler, meta) {
if (offline) return () => {}
return activeTransport.subscribe(channel, handler, meta)
},
async upload(operation, payload, meta) {
if (offline) {
const tags = normalizeTags(meta?.tags)
offlineQueue.push(operation, payload, tags)
return Promise.resolve({ offline: true, queued: true } as any)
}
return activeTransport.upload(operation, payload, meta)
},
}