@teincfood/core 0.7.9 → 0.8.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.
- package/README.md +26 -21
- package/dist/adapters/auth.d.ts +8 -0
- package/dist/adapters/auth.js +36 -0
- package/dist/adapters/devices.d.ts +3 -1
- package/dist/adapters/devices.js +187 -3
- package/dist/adapters/filesystem.d.ts +4 -0
- package/dist/adapters/kv.d.ts +10 -0
- package/dist/adapters/kv.js +23 -7
- package/dist/adapters/local-node.d.ts +4 -6
- package/dist/adapters/local-node.js +9 -32
- package/dist/adapters/notify.d.ts +12 -0
- package/dist/adapters/notify.js +33 -0
- package/dist/adapters/query-keys.d.ts +4 -0
- package/dist/adapters/query-keys.js +4 -0
- package/dist/adapters/services.d.ts +96 -15
- package/dist/adapters/services.js +241 -4
- package/dist/auth/session.d.ts +66 -0
- package/dist/auth/session.js +172 -0
- package/dist/catalog/hooks.d.ts +10 -0
- package/dist/catalog/hooks.js +82 -11
- package/dist/db/migrations.js +274 -0
- package/dist/db/operations.d.ts +53 -2
- package/dist/db/operations.js +177 -8
- package/dist/domain/business/index.d.ts +5 -0
- package/dist/domain/business/index.js +5 -0
- package/dist/domain/orders/lifecycle.d.ts +6 -0
- package/dist/domain/orders/lifecycle.js +6 -0
- package/dist/domain/orders/service.d.ts +24 -0
- package/dist/domain/orders/service.js +242 -0
- package/dist/domain/payments/index.d.ts +6 -0
- package/dist/domain/payments/index.js +5 -0
- package/dist/domain/reference/index.d.ts +8 -0
- package/dist/domain/reference/index.js +8 -0
- package/dist/e2e/harness.d.ts +1 -0
- package/dist/e2e/harness.js +61 -0
- package/dist/hooks/analytics.hooks.d.ts +25 -0
- package/dist/hooks/analytics.hooks.js +214 -0
- package/dist/hooks/business-hours.hooks.d.ts +8 -0
- package/dist/hooks/business-hours.hooks.js +45 -0
- package/dist/hooks/dashboard.hooks.d.ts +30 -0
- package/dist/hooks/dashboard.hooks.js +132 -0
- package/dist/hooks/delivery.hooks.d.ts +225 -0
- package/dist/hooks/delivery.hooks.js +80 -0
- package/dist/hooks/fleet.hooks.d.ts +37 -0
- package/dist/hooks/fleet.hooks.js +229 -0
- package/dist/hooks/image.hooks.d.ts +24 -0
- package/dist/hooks/image.hooks.js +66 -0
- package/dist/hooks/kiosk.hooks.d.ts +22 -5
- package/dist/hooks/kiosk.hooks.js +74 -5
- package/dist/hooks/members.hooks.d.ts +48 -0
- package/dist/hooks/members.hooks.js +302 -0
- package/dist/hooks/offline-orders.hooks.d.ts +9 -0
- package/dist/hooks/offline-orders.hooks.js +51 -0
- package/dist/hooks/orders.hooks.d.ts +18 -39
- package/dist/hooks/orders.hooks.js +124 -343
- package/dist/hooks/places.hooks.d.ts +21 -0
- package/dist/hooks/places.hooks.js +112 -0
- package/dist/hooks/realtime-stubs.d.ts +28 -0
- package/dist/hooks/realtime-stubs.js +85 -0
- package/dist/hooks/rider.hooks.d.ts +470 -0
- package/dist/hooks/rider.hooks.js +373 -0
- package/dist/hooks/use-infinite-list.d.ts +243 -0
- package/dist/hooks/use-infinite-list.js +58 -0
- package/dist/hooks/wallet.hooks.d.ts +219 -0
- package/dist/hooks/wallet.hooks.js +56 -0
- package/dist/image-cache/service.d.ts +28 -0
- package/dist/image-cache/service.js +51 -3
- package/dist/index.d.ts +56 -6
- package/dist/index.js +73 -6
- package/dist/local-node/adapters.d.ts +87 -0
- package/dist/local-node/adapters.js +4 -0
- package/dist/local-node/index.d.ts +5 -0
- package/dist/local-node/index.js +5 -0
- package/dist/local-node/security.d.ts +25 -0
- package/dist/local-node/security.js +149 -0
- package/dist/local-node/service.d.ts +83 -0
- package/dist/local-node/service.js +706 -0
- package/dist/local-node/store.d.ts +50 -0
- package/dist/local-node/store.js +284 -0
- package/dist/local-node/types.d.ts +92 -0
- package/dist/local-node/types.js +4 -0
- package/dist/printer/receipt.d.ts +4 -0
- package/dist/printer/receipt.js +75 -0
- package/dist/printer/service.js +1 -1
- package/dist/providers/query-client.d.ts +13 -0
- package/dist/providers/query-client.js +58 -0
- package/dist/realtime/phoenix-socket.js +30 -1
- package/dist/realtime/useEventsConnection.js +11 -2
- package/dist/reference/api.d.ts +2 -0
- package/dist/reference/api.js +2 -0
- package/dist/reference/capabilities.d.ts +12 -7
- package/dist/reference/capabilities.js +27 -13
- package/dist/reference/hooks.d.ts +34 -0
- package/dist/reference/hooks.js +124 -0
- package/dist/reference/menu-apply.d.ts +29 -0
- package/dist/reference/menu-apply.js +289 -0
- package/dist/reference/menu-record.d.ts +69 -0
- package/dist/reference/menu-record.js +168 -0
- package/dist/reference/operations.d.ts +3 -0
- package/dist/reference/operations.js +35 -1
- package/dist/reference/service.js +36 -9
- package/dist/reference/types.d.ts +1 -1
- package/dist/repositories/order.repository.d.ts +7 -0
- package/dist/repositories/order.repository.js +15 -2
- package/dist/repositories/pos.repository.d.ts +4 -0
- package/dist/repositories/pos.repository.js +4 -0
- package/dist/sync/backoff.d.ts +21 -0
- package/dist/sync/backoff.js +42 -0
- package/dist/sync/command-builder.js +10 -2
- package/dist/sync/command-queue.service.d.ts +12 -0
- package/dist/sync/command-queue.service.js +81 -16
- package/dist/sync/device-lease.service.d.ts +3 -3
- package/dist/sync/device-lease.service.js +80 -20
- package/dist/sync/engine.d.ts +3 -1
- package/dist/sync/engine.js +44 -4
- package/dist/sync/full-sync.d.ts +6 -0
- package/dist/sync/full-sync.js +72 -0
- package/dist/sync/health-probe.d.ts +24 -0
- package/dist/sync/health-probe.js +138 -0
- package/dist/sync/offline-capable.js +25 -0
- package/dist/sync/online-gates.d.ts +17 -0
- package/dist/sync/online-gates.js +55 -0
- package/dist/sync/order-number.d.ts +4 -4
- package/dist/sync/order-number.js +33 -13
- package/dist/sync/order-snapshots.service.js +18 -3
- package/dist/sync/pending-orders.service.d.ts +18 -0
- package/dist/sync/pending-orders.service.js +67 -1
- package/dist/sync/reconciliation/index.d.ts +5 -0
- package/dist/sync/reconciliation/index.js +5 -0
- package/dist/sync/snapshots/entity.d.ts +6 -0
- package/dist/sync/snapshots/entity.js +6 -0
- package/dist/sync/sync-jobs.service.d.ts +18 -0
- package/dist/sync/sync-jobs.service.js +539 -0
- package/dist/sync/transition-endpoints.d.ts +11 -0
- package/dist/sync/transition-endpoints.js +30 -0
- package/dist/sync/transport-local-node.js +3 -2
- package/dist/sync/transport-rest.d.ts +7 -0
- package/dist/sync/transport-rest.js +84 -26
- package/dist/sync/use-sync-reconciliation.js +15 -1
- package/dist/test-helpers/memory-driver.js +182 -4
- package/dist/test-helpers/seed-hours.d.ts +1 -0
- package/dist/test-helpers/seed-hours.js +23 -0
- package/dist/types/api/business.api.d.ts +42 -0
- package/dist/types/api/menu.api.d.ts +15 -0
- package/dist/types/api/seller.api.d.ts +20 -0
- package/dist/types/places.d.ts +19 -0
- package/dist/types/places.js +2 -0
- package/dist/types/rider.d.ts +67 -0
- package/dist/types/rider.js +2 -0
- package/dist/utils/attempt-stats.d.ts +23 -0
- package/dist/utils/attempt-stats.js +61 -0
- package/dist/utils/business-hours.d.ts +37 -0
- package/dist/utils/business-hours.js +96 -0
- package/dist/utils/debug-log.d.ts +23 -0
- package/dist/utils/debug-log.js +153 -0
- package/dist/utils/order-filter.d.ts +1 -1
- package/dist/utils/order-filter.js +1 -1
- package/dist/utils/order-transitions.d.ts +30 -0
- package/dist/utils/order-transitions.js +185 -0
- package/dist/utils/sync-logger.js +5 -4
- package/dist/validation/offline.d.ts +46 -0
- package/dist/validation/offline.js +79 -0
- package/package.json +6 -1
- package/dist/pricing/engine.test.d.ts +0 -1
- package/dist/pricing/engine.test.js +0 -142
- package/dist/reference/lww.test.d.ts +0 -1
- package/dist/reference/lww.test.js +0 -23
- package/dist/reference/operations.test.d.ts +0 -1
- package/dist/reference/operations.test.js +0 -66
- package/dist/standalone.integration.test.d.ts +0 -1
- package/dist/standalone.integration.test.js +0 -235
- package/dist/sync/device-lease.test.d.ts +0 -1
- package/dist/sync/device-lease.test.js +0 -38
- package/dist/sync/offline-integration.test.d.ts +0 -1
- package/dist/sync/offline-integration.test.js +0 -52
- package/dist/sync/order-number.test.d.ts +0 -1
- package/dist/sync/order-number.test.js +0 -51
- package/dist/sync/perms.test.d.ts +0 -1
- package/dist/sync/perms.test.js +0 -15
- package/dist/utils/currency.test.d.ts +0 -1
- package/dist/utils/currency.test.js +0 -17
- package/dist/utils/hlc.test.d.ts +0 -1
- package/dist/utils/hlc.test.js +0 -29
- package/dist/utils/phone.test.d.ts +0 -1
- package/dist/utils/phone.test.js +0 -19
- package/dist/utils/responsive.d.ts +0 -13
- package/dist/utils/responsive.js +0 -18
- package/dist/utils/uuid.test.d.ts +0 -1
- package/dist/utils/uuid.test.js +0 -13
- package/dist/utils/validation.test.d.ts +0 -1
- package/dist/utils/validation.test.js +0 -23
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wallet hooks — offline-first. Balances and history serve the persisted
|
|
3
|
+
* query cache instantly offline; the network refreshes silently when online.
|
|
4
|
+
* (No SQLite wallet cache — the persisted TanStack cache is the offline
|
|
5
|
+
* source; both apps persist it.)
|
|
6
|
+
*/
|
|
7
|
+
import type { WalletBalanceResponse, WalletEntry } from "../types/api/wallet.api";
|
|
8
|
+
export declare const WALLET_KEYS: {
|
|
9
|
+
all: readonly ["wallet"];
|
|
10
|
+
balance: (scope?: string) => readonly ["wallet", "balance", string | undefined];
|
|
11
|
+
history: (scope?: string) => readonly ["wallet", "history", string | undefined];
|
|
12
|
+
};
|
|
13
|
+
export declare function useAllBalancesQuery(enabled?: boolean): import("@tanstack/react-query").UseQueryResult<WalletBalanceResponse, Error>;
|
|
14
|
+
export declare function useBusinessWalletBalanceQuery(enabled?: boolean): import("@tanstack/react-query").UseQueryResult<WalletBalanceResponse, Error>;
|
|
15
|
+
export declare function useWalletHistoryQuery(enabled?: boolean): {
|
|
16
|
+
dataUpdatedAt: number;
|
|
17
|
+
errorUpdatedAt: number;
|
|
18
|
+
failureCount: number;
|
|
19
|
+
failureReason: Error | null;
|
|
20
|
+
errorUpdateCount: number;
|
|
21
|
+
isFetched: boolean;
|
|
22
|
+
isFetchedAfterMount: boolean;
|
|
23
|
+
isFetching: boolean;
|
|
24
|
+
isInitialLoading: boolean;
|
|
25
|
+
isPaused: boolean;
|
|
26
|
+
isRefetching: boolean;
|
|
27
|
+
isStale: boolean;
|
|
28
|
+
isEnabled: boolean;
|
|
29
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
30
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
31
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
32
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
33
|
+
hasNextPage: boolean;
|
|
34
|
+
hasPreviousPage: boolean;
|
|
35
|
+
isFetchingNextPage: boolean;
|
|
36
|
+
isFetchingPreviousPage: boolean;
|
|
37
|
+
error: Error;
|
|
38
|
+
isError: true;
|
|
39
|
+
isPending: false;
|
|
40
|
+
isLoading: false;
|
|
41
|
+
isLoadingError: true;
|
|
42
|
+
isRefetchError: false;
|
|
43
|
+
isFetchNextPageError: false;
|
|
44
|
+
isFetchPreviousPageError: false;
|
|
45
|
+
isSuccess: false;
|
|
46
|
+
isPlaceholderData: false;
|
|
47
|
+
status: 'error';
|
|
48
|
+
data: WalletEntry[] | undefined;
|
|
49
|
+
} | {
|
|
50
|
+
dataUpdatedAt: number;
|
|
51
|
+
errorUpdatedAt: number;
|
|
52
|
+
failureCount: number;
|
|
53
|
+
failureReason: Error | null;
|
|
54
|
+
errorUpdateCount: number;
|
|
55
|
+
isFetched: boolean;
|
|
56
|
+
isFetchedAfterMount: boolean;
|
|
57
|
+
isFetching: boolean;
|
|
58
|
+
isInitialLoading: boolean;
|
|
59
|
+
isPaused: boolean;
|
|
60
|
+
isRefetching: boolean;
|
|
61
|
+
isStale: boolean;
|
|
62
|
+
isEnabled: boolean;
|
|
63
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
64
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
65
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
66
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
67
|
+
hasNextPage: boolean;
|
|
68
|
+
hasPreviousPage: boolean;
|
|
69
|
+
isFetchingNextPage: boolean;
|
|
70
|
+
isFetchingPreviousPage: boolean;
|
|
71
|
+
error: null;
|
|
72
|
+
isError: false;
|
|
73
|
+
isPending: true;
|
|
74
|
+
isLoading: true;
|
|
75
|
+
isLoadingError: false;
|
|
76
|
+
isRefetchError: false;
|
|
77
|
+
isFetchNextPageError: false;
|
|
78
|
+
isFetchPreviousPageError: false;
|
|
79
|
+
isSuccess: false;
|
|
80
|
+
isPlaceholderData: false;
|
|
81
|
+
status: 'pending';
|
|
82
|
+
data: WalletEntry[] | undefined;
|
|
83
|
+
} | {
|
|
84
|
+
dataUpdatedAt: number;
|
|
85
|
+
errorUpdatedAt: number;
|
|
86
|
+
failureCount: number;
|
|
87
|
+
failureReason: Error | null;
|
|
88
|
+
errorUpdateCount: number;
|
|
89
|
+
isFetched: boolean;
|
|
90
|
+
isFetchedAfterMount: boolean;
|
|
91
|
+
isFetching: boolean;
|
|
92
|
+
isLoading: boolean;
|
|
93
|
+
isInitialLoading: boolean;
|
|
94
|
+
isPaused: boolean;
|
|
95
|
+
isRefetching: boolean;
|
|
96
|
+
isStale: boolean;
|
|
97
|
+
isEnabled: boolean;
|
|
98
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
99
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
100
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
101
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
102
|
+
hasNextPage: boolean;
|
|
103
|
+
hasPreviousPage: boolean;
|
|
104
|
+
isFetchingNextPage: boolean;
|
|
105
|
+
isFetchingPreviousPage: boolean;
|
|
106
|
+
error: null;
|
|
107
|
+
isError: false;
|
|
108
|
+
isPending: true;
|
|
109
|
+
isLoadingError: false;
|
|
110
|
+
isRefetchError: false;
|
|
111
|
+
isFetchNextPageError: false;
|
|
112
|
+
isFetchPreviousPageError: false;
|
|
113
|
+
isSuccess: false;
|
|
114
|
+
isPlaceholderData: false;
|
|
115
|
+
status: 'pending';
|
|
116
|
+
data: WalletEntry[] | undefined;
|
|
117
|
+
} | {
|
|
118
|
+
dataUpdatedAt: number;
|
|
119
|
+
errorUpdatedAt: number;
|
|
120
|
+
failureCount: number;
|
|
121
|
+
failureReason: Error | null;
|
|
122
|
+
errorUpdateCount: number;
|
|
123
|
+
isFetched: boolean;
|
|
124
|
+
isFetchedAfterMount: boolean;
|
|
125
|
+
isFetching: boolean;
|
|
126
|
+
isInitialLoading: boolean;
|
|
127
|
+
isPaused: boolean;
|
|
128
|
+
isRefetching: boolean;
|
|
129
|
+
isStale: boolean;
|
|
130
|
+
isEnabled: boolean;
|
|
131
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
132
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
133
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
134
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
135
|
+
hasNextPage: boolean;
|
|
136
|
+
hasPreviousPage: boolean;
|
|
137
|
+
isFetchingNextPage: boolean;
|
|
138
|
+
isFetchingPreviousPage: boolean;
|
|
139
|
+
isError: false;
|
|
140
|
+
error: null;
|
|
141
|
+
isPending: false;
|
|
142
|
+
isLoading: false;
|
|
143
|
+
isLoadingError: false;
|
|
144
|
+
isRefetchError: false;
|
|
145
|
+
isSuccess: true;
|
|
146
|
+
isPlaceholderData: true;
|
|
147
|
+
isFetchNextPageError: false;
|
|
148
|
+
isFetchPreviousPageError: false;
|
|
149
|
+
status: 'success';
|
|
150
|
+
data: WalletEntry[] | undefined;
|
|
151
|
+
} | {
|
|
152
|
+
dataUpdatedAt: number;
|
|
153
|
+
errorUpdatedAt: number;
|
|
154
|
+
failureCount: number;
|
|
155
|
+
failureReason: Error | null;
|
|
156
|
+
errorUpdateCount: number;
|
|
157
|
+
isFetched: boolean;
|
|
158
|
+
isFetchedAfterMount: boolean;
|
|
159
|
+
isFetching: boolean;
|
|
160
|
+
isInitialLoading: boolean;
|
|
161
|
+
isPaused: boolean;
|
|
162
|
+
isRefetching: boolean;
|
|
163
|
+
isStale: boolean;
|
|
164
|
+
isEnabled: boolean;
|
|
165
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
166
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
167
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
168
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
169
|
+
hasNextPage: boolean;
|
|
170
|
+
hasPreviousPage: boolean;
|
|
171
|
+
isFetchNextPageError: boolean;
|
|
172
|
+
isFetchingNextPage: boolean;
|
|
173
|
+
isFetchPreviousPageError: boolean;
|
|
174
|
+
isFetchingPreviousPage: boolean;
|
|
175
|
+
error: Error;
|
|
176
|
+
isError: true;
|
|
177
|
+
isPending: false;
|
|
178
|
+
isLoading: false;
|
|
179
|
+
isLoadingError: false;
|
|
180
|
+
isRefetchError: true;
|
|
181
|
+
isSuccess: false;
|
|
182
|
+
isPlaceholderData: false;
|
|
183
|
+
status: 'error';
|
|
184
|
+
data: WalletEntry[] | undefined;
|
|
185
|
+
} | {
|
|
186
|
+
dataUpdatedAt: number;
|
|
187
|
+
errorUpdatedAt: number;
|
|
188
|
+
failureCount: number;
|
|
189
|
+
failureReason: Error | null;
|
|
190
|
+
errorUpdateCount: number;
|
|
191
|
+
isFetched: boolean;
|
|
192
|
+
isFetchedAfterMount: boolean;
|
|
193
|
+
isFetching: boolean;
|
|
194
|
+
isInitialLoading: boolean;
|
|
195
|
+
isPaused: boolean;
|
|
196
|
+
isRefetching: boolean;
|
|
197
|
+
isStale: boolean;
|
|
198
|
+
isEnabled: boolean;
|
|
199
|
+
refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
200
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
201
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
202
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<import("@tanstack/react-query").InfiniteData<import("./use-infinite-list").ListPage<WalletEntry>, unknown>, Error>>;
|
|
203
|
+
hasNextPage: boolean;
|
|
204
|
+
hasPreviousPage: boolean;
|
|
205
|
+
isFetchingNextPage: boolean;
|
|
206
|
+
isFetchingPreviousPage: boolean;
|
|
207
|
+
error: null;
|
|
208
|
+
isError: false;
|
|
209
|
+
isPending: false;
|
|
210
|
+
isLoading: false;
|
|
211
|
+
isLoadingError: false;
|
|
212
|
+
isRefetchError: false;
|
|
213
|
+
isFetchNextPageError: false;
|
|
214
|
+
isFetchPreviousPageError: false;
|
|
215
|
+
isSuccess: true;
|
|
216
|
+
isPlaceholderData: false;
|
|
217
|
+
status: 'success';
|
|
218
|
+
data: WalletEntry[] | undefined;
|
|
219
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wallet hooks — offline-first. Balances and history serve the persisted
|
|
3
|
+
* query cache instantly offline; the network refreshes silently when online.
|
|
4
|
+
* (No SQLite wallet cache — the persisted TanStack cache is the offline
|
|
5
|
+
* source; both apps persist it.)
|
|
6
|
+
*/
|
|
7
|
+
import { useQuery } from "@tanstack/react-query";
|
|
8
|
+
import { useSyncExternalStore } from "react";
|
|
9
|
+
import { getActiveBusiness, subscribeBusiness } from "../adapters/business";
|
|
10
|
+
import { walletService } from "../adapters/services";
|
|
11
|
+
import { useInfiniteList } from "./use-infinite-list";
|
|
12
|
+
export const WALLET_KEYS = {
|
|
13
|
+
all: ["wallet"],
|
|
14
|
+
balance: (scope) => [...WALLET_KEYS.all, "balance", scope],
|
|
15
|
+
history: (scope) => [...WALLET_KEYS.all, "history", scope],
|
|
16
|
+
};
|
|
17
|
+
function useBusinessId() {
|
|
18
|
+
const id = useSyncExternalStore(subscribeBusiness, () => getActiveBusiness()?.id ?? null, () => null);
|
|
19
|
+
return id ?? undefined;
|
|
20
|
+
}
|
|
21
|
+
export function useAllBalancesQuery(enabled = true) {
|
|
22
|
+
return useQuery({
|
|
23
|
+
queryKey: WALLET_KEYS.balance("all"),
|
|
24
|
+
queryFn: () => walletService.fetchAllBalances(),
|
|
25
|
+
enabled,
|
|
26
|
+
placeholderData: (prev) => prev,
|
|
27
|
+
staleTime: 30000,
|
|
28
|
+
retry: false,
|
|
29
|
+
networkMode: "offlineFirst",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export function useBusinessWalletBalanceQuery(enabled = true) {
|
|
33
|
+
const businessId = useBusinessId();
|
|
34
|
+
return useQuery({
|
|
35
|
+
queryKey: WALLET_KEYS.balance(businessId),
|
|
36
|
+
queryFn: () => walletService.fetchBusinessWalletBalance(businessId),
|
|
37
|
+
enabled: enabled && Boolean(businessId),
|
|
38
|
+
placeholderData: (prev) => prev,
|
|
39
|
+
staleTime: 30000,
|
|
40
|
+
retry: false,
|
|
41
|
+
networkMode: "offlineFirst",
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export function useWalletHistoryQuery(enabled = true) {
|
|
45
|
+
const businessId = useBusinessId();
|
|
46
|
+
return useInfiniteList({
|
|
47
|
+
key: [...WALLET_KEYS.history(businessId)],
|
|
48
|
+
enabled: enabled && Boolean(businessId),
|
|
49
|
+
pageSize: 20,
|
|
50
|
+
staleTime: 30000,
|
|
51
|
+
onlineFetch: async (page, pageSize) => {
|
|
52
|
+
const res = (await walletService.fetchWalletHistory({ businessId, page, pageSize }));
|
|
53
|
+
return { data: res.data.entries, pagination: res.pagination };
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
@@ -14,6 +14,34 @@ export declare function stableCacheUrl(url: string): string;
|
|
|
14
14
|
export declare function getCachedImagePath(url: string): string;
|
|
15
15
|
export declare function ensureImageCacheDir(): Promise<string>;
|
|
16
16
|
export declare function getCachedImageInfo(url: string): Promise<ImageCacheEntry>;
|
|
17
|
+
/**
|
|
18
|
+
* Only http(s) URLs can be fetched by the host downloader. Anything else
|
|
19
|
+
* (tfimg:// disk URIs leaked from another device, data:, blob:, file:)
|
|
20
|
+
* is either already local or unfetchable — attempting a download throws
|
|
21
|
+
* per-attempt errors (e.g. iOS NSURLError -1002) and, worse, feeds the
|
|
22
|
+
* hook's warm-then-invalidate cycle into an unbounded retry storm.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isDownloadableImageUrl(url: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* URI schemes React Native's `<Image>` can actually load on device. Anything
|
|
27
|
+
* else has no RCTImageURLLoader on iOS ("No suitable image URL loader
|
|
28
|
+
* found") and crashes the screen — notably `tfimg://` disk URIs leaked from
|
|
29
|
+
* desktop rows, bare S3 keys (`menus/biz/img.jpg`), and `blob:` preview
|
|
30
|
+
* URLs. The hook maps these to null so callers render their placeholder
|
|
31
|
+
* branch instead of feeding a fatal URI to the native loader.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isLoadableImageUri(uri: string): boolean;
|
|
34
|
+
/** Map a resolved URI to one RN `<Image>` can load, else null (placeholder). */
|
|
35
|
+
export declare function toRenderableUri(uri: string | null | undefined): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Values safe to persist as a menu image reference: S3 keys, http(s) URLs,
|
|
38
|
+
* null. Preview URIs (tfimg:, blob:, file:, data:) must never be stored —
|
|
39
|
+
* the backend keeps non-http values verbatim and they poison every other
|
|
40
|
+
* device (mobile has no native loader for tfimg:// and crashes). Returns
|
|
41
|
+
* null for un-storable values, so re-saving a poisoned row self-heals it
|
|
42
|
+
* (caller re-uploads to restore the image).
|
|
43
|
+
*/
|
|
44
|
+
export declare function toStorableImageUrl(value: string | null | undefined): string | null;
|
|
17
45
|
export declare function cacheRemoteImage(url: string | null | undefined, opts?: {
|
|
18
46
|
skipIfCached?: boolean;
|
|
19
47
|
removeOnFailure?: boolean;
|
|
@@ -49,6 +49,53 @@ export async function getCachedImageInfo(url) {
|
|
|
49
49
|
const info = await fs.getInfoAsync(localPath);
|
|
50
50
|
return { remoteUrl: url, localUri: info.exists && !info.isDirectory ? localPath : null, etag: null, lastModified: null, cachedAt: info.exists ? new Date().toISOString() : null };
|
|
51
51
|
}
|
|
52
|
+
const DOWNLOADABLE_RE = /^https?:\/\//i;
|
|
53
|
+
/**
|
|
54
|
+
* Only http(s) URLs can be fetched by the host downloader. Anything else
|
|
55
|
+
* (tfimg:// disk URIs leaked from another device, data:, blob:, file:)
|
|
56
|
+
* is either already local or unfetchable — attempting a download throws
|
|
57
|
+
* per-attempt errors (e.g. iOS NSURLError -1002) and, worse, feeds the
|
|
58
|
+
* hook's warm-then-invalidate cycle into an unbounded retry storm.
|
|
59
|
+
*/
|
|
60
|
+
export function isDownloadableImageUrl(url) {
|
|
61
|
+
return DOWNLOADABLE_RE.test(url);
|
|
62
|
+
}
|
|
63
|
+
const LOADABLE_RE = /^(https?|file|data|asset|content):/i;
|
|
64
|
+
/**
|
|
65
|
+
* URI schemes React Native's `<Image>` can actually load on device. Anything
|
|
66
|
+
* else has no RCTImageURLLoader on iOS ("No suitable image URL loader
|
|
67
|
+
* found") and crashes the screen — notably `tfimg://` disk URIs leaked from
|
|
68
|
+
* desktop rows, bare S3 keys (`menus/biz/img.jpg`), and `blob:` preview
|
|
69
|
+
* URLs. The hook maps these to null so callers render their placeholder
|
|
70
|
+
* branch instead of feeding a fatal URI to the native loader.
|
|
71
|
+
*/
|
|
72
|
+
export function isLoadableImageUri(uri) {
|
|
73
|
+
return LOADABLE_RE.test(uri);
|
|
74
|
+
}
|
|
75
|
+
/** Map a resolved URI to one RN `<Image>` can load, else null (placeholder). */
|
|
76
|
+
export function toRenderableUri(uri) {
|
|
77
|
+
if (!uri)
|
|
78
|
+
return null;
|
|
79
|
+
return isLoadableImageUri(uri) ? uri : null;
|
|
80
|
+
}
|
|
81
|
+
const URI_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;
|
|
82
|
+
/**
|
|
83
|
+
* Values safe to persist as a menu image reference: S3 keys, http(s) URLs,
|
|
84
|
+
* null. Preview URIs (tfimg:, blob:, file:, data:) must never be stored —
|
|
85
|
+
* the backend keeps non-http values verbatim and they poison every other
|
|
86
|
+
* device (mobile has no native loader for tfimg:// and crashes). Returns
|
|
87
|
+
* null for un-storable values, so re-saving a poisoned row self-heals it
|
|
88
|
+
* (caller re-uploads to restore the image).
|
|
89
|
+
*/
|
|
90
|
+
export function toStorableImageUrl(value) {
|
|
91
|
+
if (!value)
|
|
92
|
+
return null;
|
|
93
|
+
if (URI_SCHEME_RE.test(value) && !DOWNLOADABLE_RE.test(value)) {
|
|
94
|
+
syncLogger.warn("ImageCache", "Dropping un-storable image URL", { value: value.slice(0, 32) });
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
52
99
|
export async function cacheRemoteImage(url, opts = {}) {
|
|
53
100
|
if (!url)
|
|
54
101
|
return null;
|
|
@@ -58,9 +105,12 @@ export async function cacheRemoteImage(url, opts = {}) {
|
|
|
58
105
|
await ensureImageCacheDir();
|
|
59
106
|
const localPath = getCachedImagePath(url);
|
|
60
107
|
const existing = await fs.getInfoAsync(localPath);
|
|
61
|
-
if (
|
|
108
|
+
if (existing.exists && !existing.isDirectory) {
|
|
62
109
|
return { remoteUrl: url, localUri: localPath, etag: null, lastModified: null, cachedAt: new Date().toISOString() };
|
|
63
110
|
}
|
|
111
|
+
if (!isDownloadableImageUrl(url)) {
|
|
112
|
+
return { remoteUrl: url, localUri: null, etag: null, lastModified: null, cachedAt: null };
|
|
113
|
+
}
|
|
64
114
|
try {
|
|
65
115
|
const res = await fs.downloadAsync(url, localPath);
|
|
66
116
|
if (res.uri)
|
|
@@ -71,8 +121,6 @@ export async function cacheRemoteImage(url, opts = {}) {
|
|
|
71
121
|
}
|
|
72
122
|
if (opts.removeOnFailure)
|
|
73
123
|
await fs.deleteAsync(localPath, { idempotent: true }).catch(() => { });
|
|
74
|
-
if (existing.exists && !existing.isDirectory)
|
|
75
|
-
return { remoteUrl: url, localUri: localPath, etag: null, lastModified: null, cachedAt: new Date().toISOString() };
|
|
76
124
|
return { remoteUrl: url, localUri: null, etag: null, lastModified: null, cachedAt: null };
|
|
77
125
|
}
|
|
78
126
|
export async function cacheImageBatch(urls, opts = {}) {
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export * from "./types/api";
|
|
8
8
|
export * from "./types/pos.types";
|
|
9
|
+
export * from "./types/rider";
|
|
10
|
+
export * from "./types/places";
|
|
11
|
+
export * from "./adapters/notify";
|
|
9
12
|
export { calculatePricing, calculateTaxLines, calculateExclusiveTax, calculateInclusiveTaxShare, } from "./pricing/engine";
|
|
10
13
|
export type { PricingInput, PricingResult } from "./pricing/engine";
|
|
11
14
|
export * from "./utils/constants";
|
|
@@ -13,24 +16,39 @@ export * from "./utils/currency";
|
|
|
13
16
|
export * from "./utils/error";
|
|
14
17
|
export * from "./utils/uuid";
|
|
15
18
|
export * from "./utils/sync-logger";
|
|
19
|
+
export * from "./utils/debug-log";
|
|
20
|
+
export * from "./utils/attempt-stats";
|
|
16
21
|
export { PHONE_COUNTRIES, getDialCodeFromCountry, getCountryOption, normalizePhoneForCountry, isLikelyE164 } from "./utils/phone";
|
|
17
22
|
export type { PhoneCountryOption } from "./utils/phone";
|
|
18
23
|
export * from "./utils/formatCurrency";
|
|
19
24
|
export { formatDate, formatRelativeTime } from "./utils/formatDate";
|
|
20
25
|
export * from "./utils/validation";
|
|
21
|
-
export * from "./
|
|
26
|
+
export * from "./validation/offline";
|
|
22
27
|
export * from "./utils/copyToClipBoard";
|
|
23
28
|
export * from "./utils/customer-display";
|
|
24
29
|
export * from "./utils/order-filter";
|
|
30
|
+
export { useReferenceData } from "./reference/hooks";
|
|
31
|
+
export { setNotifyHandlers } from "./adapters/notify";
|
|
32
|
+
export { walletService, riderService, fleetService, deliveryService, dashboardService, analyticsService, placesService } from "./adapters/services";
|
|
33
|
+
export { buildMenuItemEnvelope, buildMenuCategoryEnvelope } from "./reference/menu-record";
|
|
34
|
+
export { validateMenuItemInput, validateMenuCategoryInput, validateOrderCreateInput, validateInviteInput } from "./validation/offline";
|
|
35
|
+
export { useBusinessDeliveriesQuery } from "./hooks/delivery.hooks";
|
|
36
|
+
export { useBusinessReferenceDataSync } from "./reference/hooks";
|
|
37
|
+
export { createAppQueryClient, createQueryPersister } from "./providers/query-client";
|
|
38
|
+
export { useSellerAnalyticsQuery } from "./hooks/analytics.hooks";
|
|
39
|
+
export { useSellerDashboardQuery } from "./hooks/dashboard.hooks";
|
|
40
|
+
export { useRealtimeInvalidation, useOrderRealtimeUpdates } from "./hooks/realtime-stubs";
|
|
41
|
+
export { useAcceptFleetInvitationMutation, useAcceptBusinessInvitationMutation, useUserInvitationsQuery, } from "./hooks/members.hooks";
|
|
42
|
+
export { useJoinRequestsQuery } from "./hooks/fleet.hooks";
|
|
25
43
|
export * from "./db/migrations";
|
|
26
44
|
export * from "./db/operations";
|
|
27
45
|
export * as dbOps from "./db/operations";
|
|
28
46
|
export { openSyncDatabase, getSyncDatabase, closeSyncDatabase } from "./db/connection";
|
|
29
47
|
export * from "./sync/types";
|
|
48
|
+
export * from "./sync/online-gates";
|
|
30
49
|
export * from "./sync/use-sync-reconciliation";
|
|
31
50
|
export { SyncEngine, syncEngine } from "./sync/engine";
|
|
32
51
|
export * from "./sync/command-builder";
|
|
33
|
-
export * from "./sync/command-queue.service";
|
|
34
52
|
export { commandQueueService } from "./sync/command-queue.service";
|
|
35
53
|
export { buildCommand } from "./sync/command-builder";
|
|
36
54
|
export { generateLocalOrderNumber, generateLocalCalloutNumber, isLocalOrderNumber, generateOrderNumber, generateOrderNumberForBusiness, isOfflineOrderNumber, parseOrderNumber, resetCalloutForTests, } from "./sync/order-number";
|
|
@@ -53,29 +71,51 @@ export type { CreateOrderInput, AssignRiderInput, OrderActionInput } from "./rep
|
|
|
53
71
|
export { posRepository } from "./repositories/pos.repository";
|
|
54
72
|
export type { POSOrderPreviewInput } from "./repositories/pos.repository";
|
|
55
73
|
export * from "./hooks/orders.hooks";
|
|
74
|
+
export * from "./hooks/use-infinite-list";
|
|
75
|
+
export * from "./hooks/wallet.hooks";
|
|
76
|
+
export * from "./hooks/rider.hooks";
|
|
77
|
+
export * from "./hooks/fleet.hooks";
|
|
78
|
+
export * from "./hooks/delivery.hooks";
|
|
79
|
+
export * from "./hooks/dashboard.hooks";
|
|
80
|
+
export * from "./hooks/analytics.hooks";
|
|
81
|
+
export * from "./hooks/members.hooks";
|
|
82
|
+
export * from "./hooks/places.hooks";
|
|
83
|
+
export * from "./hooks/offline-orders.hooks";
|
|
84
|
+
export * from "./hooks/image.hooks";
|
|
85
|
+
export * from "./hooks/realtime-stubs";
|
|
86
|
+
export * from "./providers/query-client";
|
|
87
|
+
export { KIOSK_KEYS, useKioskOrdersQuery, useAvailableRidersQuery, type AvailableRider, useAcceptKioskOrderMutation, useRejectKioskOrderMutation, useStartPreparingKioskOrderMutation, useMarkKioskOrderReadyMutation, } from "./hooks/kiosk.hooks";
|
|
56
88
|
export * from "./reference/types";
|
|
57
89
|
export * from "./reference/operations";
|
|
58
|
-
export { fetchReferenceVersions, fetchReferenceData, fetchReferenceChanges, setReferenceLocalNodeFetcher } from "./reference/api";
|
|
90
|
+
export { fetchReferenceVersions, fetchReferenceData, fetchReferenceChanges, setReferenceLocalNodeFetcher, setReferenceData, mergeReferenceData, setOperatingHoursLocal, setBusinessProfileLocal } from "./reference/api";
|
|
59
91
|
export type { ReferenceLocalNodeFetcher } from "./reference/api";
|
|
60
92
|
export { emitReferenceChanged, applyReferenceChangeEvent, syncReferenceDataOnReconnect, registerReferenceEventEngine, registerReferenceInvalidator } from "./reference/events";
|
|
61
93
|
export * from "./reference/events";
|
|
62
94
|
export * from "./reference/service";
|
|
95
|
+
export * from "./reference/hooks";
|
|
63
96
|
export { referenceSyncService } from "./reference/service";
|
|
97
|
+
export * from "./reference/menu-record";
|
|
98
|
+
export * from "./reference/menu-apply";
|
|
64
99
|
export * from "./reference/capabilities";
|
|
65
100
|
export * from "./adapters/sqlite";
|
|
66
101
|
export { KVDriver, setKVDriver, getKVDriver, kvGetItem, kvSetItem, kvRemoveItem, getItem, setItem, removeItem, getItemSync, setItemSync } from "./adapters/kv";
|
|
67
102
|
export * from "./adapters/connectivity";
|
|
68
103
|
export * from "./adapters/http";
|
|
69
|
-
export * from "./
|
|
104
|
+
export * from "./local-node/types";
|
|
105
|
+
export * from "./local-node/store";
|
|
106
|
+
export * from "./local-node/security";
|
|
107
|
+
export * from "./local-node/adapters";
|
|
108
|
+
export * from "./local-node/service";
|
|
109
|
+
export { setLocalNodeState } from "./adapters/local-node";
|
|
70
110
|
export * from "./adapters/services";
|
|
71
111
|
export * from "./adapters/devices";
|
|
72
|
-
export { setAuthProvider, getAuthToken } from "./adapters/auth";
|
|
112
|
+
export { setAuthProvider, getAuthToken, setAuthRefreshProvider, getRefreshToken, setAuthTokensProvider, setAuthTokens, setAuthClearProvider, clearAuth } from "./adapters/auth";
|
|
73
113
|
export { imageCacheService } from "./adapters/image-cache";
|
|
74
114
|
export * from "./adapters/business";
|
|
75
115
|
export * from "./adapters/pending-orders";
|
|
76
116
|
export * from "./adapters/print";
|
|
77
117
|
export * from "./adapters/filesystem";
|
|
78
|
-
export {
|
|
118
|
+
export { SELLER_ORDERS_KEYS, BUSINESS_DELIVERIES_KEYS, MENU_KEYS, REFERENCE_KEYS } from "./adapters/query-keys";
|
|
79
119
|
export * from "./printer/types";
|
|
80
120
|
export * from "./printer/store";
|
|
81
121
|
export * from "./printer/receipt";
|
|
@@ -84,10 +124,20 @@ export * from "./printer/hooks";
|
|
|
84
124
|
export * from "./cart/store";
|
|
85
125
|
export * from "./cart/hooks";
|
|
86
126
|
export * from "./catalog/hooks";
|
|
127
|
+
export * from "./utils/order-transitions";
|
|
128
|
+
export * from "./utils/business-hours";
|
|
129
|
+
export * from "./hooks/business-hours.hooks";
|
|
130
|
+
export * from "./domain/orders/service";
|
|
87
131
|
export { phoenixSocket } from "./realtime/phoenix-socket";
|
|
88
132
|
export { eventsService } from "./realtime/events.service";
|
|
89
133
|
export { orderEventsService } from "./realtime/order-events.service";
|
|
90
134
|
export { useEventsConnection } from "./realtime/useEventsConnection";
|
|
135
|
+
export { getSyncJobsPendingCount, debugDumpSyncJobs, drainPending } from "./sync/sync-jobs.service";
|
|
136
|
+
export { performFullSync } from "./sync/full-sync";
|
|
137
|
+
export { stopHealthProbe } from "./sync/health-probe";
|
|
138
|
+
export { notifyAuthChanged, subscribeAuth } from "./adapters/auth";
|
|
139
|
+
export { ACCESS_EXPIRED_CODE, SESSION_DEAD_CODES, SKIP_AUTH_RETRY, extractAuthFailure, isAccessExpired, isSessionDead, hasAuthRetrySkip, refreshSession, withAuthRetry, } from "./auth/session";
|
|
140
|
+
export type { AuthFailure, SessionTokens } from "./auth/session";
|
|
91
141
|
export { getCachedImagePath, ensureImageCacheDir, getCachedImageInfo, cacheRemoteImage, cacheImageBatch, clearImageCache, pruneImageCache, resolveImageSource, stableCacheUrl } from "./image-cache/service";
|
|
92
142
|
import { type SqliteDriver } from "./adapters/sqlite";
|
|
93
143
|
import { type KVDriver } from "./adapters/kv";
|