@teincfood/core 0.7.9 → 0.8.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.
Files changed (191) hide show
  1. package/README.md +26 -21
  2. package/dist/adapters/auth.d.ts +8 -0
  3. package/dist/adapters/auth.js +36 -0
  4. package/dist/adapters/devices.d.ts +3 -1
  5. package/dist/adapters/devices.js +187 -3
  6. package/dist/adapters/filesystem.d.ts +4 -0
  7. package/dist/adapters/kv.d.ts +10 -0
  8. package/dist/adapters/kv.js +23 -7
  9. package/dist/adapters/local-node.d.ts +4 -6
  10. package/dist/adapters/local-node.js +9 -32
  11. package/dist/adapters/notify.d.ts +12 -0
  12. package/dist/adapters/notify.js +33 -0
  13. package/dist/adapters/query-keys.d.ts +4 -0
  14. package/dist/adapters/query-keys.js +4 -0
  15. package/dist/adapters/services.d.ts +96 -15
  16. package/dist/adapters/services.js +241 -4
  17. package/dist/auth/session.d.ts +66 -0
  18. package/dist/auth/session.js +172 -0
  19. package/dist/catalog/hooks.d.ts +10 -0
  20. package/dist/catalog/hooks.js +82 -11
  21. package/dist/db/migrations.js +274 -0
  22. package/dist/db/operations.d.ts +53 -2
  23. package/dist/db/operations.js +177 -8
  24. package/dist/domain/business/index.d.ts +5 -0
  25. package/dist/domain/business/index.js +5 -0
  26. package/dist/domain/orders/lifecycle.d.ts +6 -0
  27. package/dist/domain/orders/lifecycle.js +6 -0
  28. package/dist/domain/orders/service.d.ts +24 -0
  29. package/dist/domain/orders/service.js +242 -0
  30. package/dist/domain/payments/index.d.ts +6 -0
  31. package/dist/domain/payments/index.js +5 -0
  32. package/dist/domain/reference/index.d.ts +8 -0
  33. package/dist/domain/reference/index.js +8 -0
  34. package/dist/e2e/harness.d.ts +1 -0
  35. package/dist/e2e/harness.js +61 -0
  36. package/dist/hooks/analytics.hooks.d.ts +25 -0
  37. package/dist/hooks/analytics.hooks.js +214 -0
  38. package/dist/hooks/business-hours.hooks.d.ts +8 -0
  39. package/dist/hooks/business-hours.hooks.js +45 -0
  40. package/dist/hooks/dashboard.hooks.d.ts +30 -0
  41. package/dist/hooks/dashboard.hooks.js +132 -0
  42. package/dist/hooks/delivery.hooks.d.ts +225 -0
  43. package/dist/hooks/delivery.hooks.js +80 -0
  44. package/dist/hooks/fleet.hooks.d.ts +37 -0
  45. package/dist/hooks/fleet.hooks.js +229 -0
  46. package/dist/hooks/image.hooks.d.ts +20 -0
  47. package/dist/hooks/image.hooks.js +62 -0
  48. package/dist/hooks/kiosk.hooks.d.ts +22 -5
  49. package/dist/hooks/kiosk.hooks.js +74 -5
  50. package/dist/hooks/members.hooks.d.ts +48 -0
  51. package/dist/hooks/members.hooks.js +302 -0
  52. package/dist/hooks/offline-orders.hooks.d.ts +9 -0
  53. package/dist/hooks/offline-orders.hooks.js +51 -0
  54. package/dist/hooks/orders.hooks.d.ts +18 -39
  55. package/dist/hooks/orders.hooks.js +124 -343
  56. package/dist/hooks/places.hooks.d.ts +21 -0
  57. package/dist/hooks/places.hooks.js +112 -0
  58. package/dist/hooks/realtime-stubs.d.ts +28 -0
  59. package/dist/hooks/realtime-stubs.js +85 -0
  60. package/dist/hooks/rider.hooks.d.ts +470 -0
  61. package/dist/hooks/rider.hooks.js +373 -0
  62. package/dist/hooks/use-infinite-list.d.ts +243 -0
  63. package/dist/hooks/use-infinite-list.js +58 -0
  64. package/dist/hooks/wallet.hooks.d.ts +219 -0
  65. package/dist/hooks/wallet.hooks.js +56 -0
  66. package/dist/image-cache/service.d.ts +8 -0
  67. package/dist/image-cache/service.js +15 -3
  68. package/dist/index.d.ts +56 -6
  69. package/dist/index.js +73 -6
  70. package/dist/local-node/adapters.d.ts +87 -0
  71. package/dist/local-node/adapters.js +4 -0
  72. package/dist/local-node/index.d.ts +5 -0
  73. package/dist/local-node/index.js +5 -0
  74. package/dist/local-node/security.d.ts +25 -0
  75. package/dist/local-node/security.js +149 -0
  76. package/dist/local-node/service.d.ts +83 -0
  77. package/dist/local-node/service.js +706 -0
  78. package/dist/local-node/store.d.ts +50 -0
  79. package/dist/local-node/store.js +284 -0
  80. package/dist/local-node/types.d.ts +92 -0
  81. package/dist/local-node/types.js +4 -0
  82. package/dist/printer/receipt.d.ts +4 -0
  83. package/dist/printer/receipt.js +75 -0
  84. package/dist/printer/service.js +1 -1
  85. package/dist/providers/query-client.d.ts +13 -0
  86. package/dist/providers/query-client.js +58 -0
  87. package/dist/realtime/phoenix-socket.js +30 -1
  88. package/dist/realtime/useEventsConnection.js +11 -2
  89. package/dist/reference/api.d.ts +2 -0
  90. package/dist/reference/api.js +2 -0
  91. package/dist/reference/capabilities.d.ts +12 -7
  92. package/dist/reference/capabilities.js +27 -13
  93. package/dist/reference/hooks.d.ts +34 -0
  94. package/dist/reference/hooks.js +124 -0
  95. package/dist/reference/menu-apply.d.ts +29 -0
  96. package/dist/reference/menu-apply.js +289 -0
  97. package/dist/reference/menu-record.d.ts +69 -0
  98. package/dist/reference/menu-record.js +163 -0
  99. package/dist/reference/operations.d.ts +3 -0
  100. package/dist/reference/operations.js +35 -1
  101. package/dist/reference/service.js +36 -9
  102. package/dist/reference/types.d.ts +1 -1
  103. package/dist/repositories/order.repository.d.ts +7 -0
  104. package/dist/repositories/order.repository.js +15 -2
  105. package/dist/repositories/pos.repository.d.ts +4 -0
  106. package/dist/repositories/pos.repository.js +4 -0
  107. package/dist/sync/backoff.d.ts +21 -0
  108. package/dist/sync/backoff.js +42 -0
  109. package/dist/sync/command-builder.js +10 -2
  110. package/dist/sync/command-queue.service.d.ts +12 -0
  111. package/dist/sync/command-queue.service.js +81 -16
  112. package/dist/sync/device-lease.service.d.ts +3 -3
  113. package/dist/sync/device-lease.service.js +80 -20
  114. package/dist/sync/engine.d.ts +3 -1
  115. package/dist/sync/engine.js +44 -4
  116. package/dist/sync/full-sync.d.ts +6 -0
  117. package/dist/sync/full-sync.js +72 -0
  118. package/dist/sync/health-probe.d.ts +24 -0
  119. package/dist/sync/health-probe.js +138 -0
  120. package/dist/sync/offline-capable.js +25 -0
  121. package/dist/sync/online-gates.d.ts +17 -0
  122. package/dist/sync/online-gates.js +55 -0
  123. package/dist/sync/order-number.d.ts +4 -4
  124. package/dist/sync/order-number.js +33 -13
  125. package/dist/sync/order-snapshots.service.js +18 -3
  126. package/dist/sync/pending-orders.service.d.ts +18 -0
  127. package/dist/sync/pending-orders.service.js +67 -1
  128. package/dist/sync/reconciliation/index.d.ts +5 -0
  129. package/dist/sync/reconciliation/index.js +5 -0
  130. package/dist/sync/snapshots/entity.d.ts +6 -0
  131. package/dist/sync/snapshots/entity.js +6 -0
  132. package/dist/sync/sync-jobs.service.d.ts +18 -0
  133. package/dist/sync/sync-jobs.service.js +539 -0
  134. package/dist/sync/transition-endpoints.d.ts +11 -0
  135. package/dist/sync/transition-endpoints.js +30 -0
  136. package/dist/sync/transport-local-node.js +3 -2
  137. package/dist/sync/transport-rest.d.ts +7 -0
  138. package/dist/sync/transport-rest.js +84 -26
  139. package/dist/sync/use-sync-reconciliation.js +15 -1
  140. package/dist/test-helpers/memory-driver.js +182 -4
  141. package/dist/test-helpers/seed-hours.d.ts +1 -0
  142. package/dist/test-helpers/seed-hours.js +23 -0
  143. package/dist/types/api/business.api.d.ts +42 -0
  144. package/dist/types/api/menu.api.d.ts +15 -0
  145. package/dist/types/api/seller.api.d.ts +20 -0
  146. package/dist/types/places.d.ts +19 -0
  147. package/dist/types/places.js +2 -0
  148. package/dist/types/rider.d.ts +67 -0
  149. package/dist/types/rider.js +2 -0
  150. package/dist/utils/attempt-stats.d.ts +23 -0
  151. package/dist/utils/attempt-stats.js +61 -0
  152. package/dist/utils/business-hours.d.ts +37 -0
  153. package/dist/utils/business-hours.js +96 -0
  154. package/dist/utils/debug-log.d.ts +23 -0
  155. package/dist/utils/debug-log.js +153 -0
  156. package/dist/utils/order-filter.d.ts +1 -1
  157. package/dist/utils/order-filter.js +1 -1
  158. package/dist/utils/order-transitions.d.ts +30 -0
  159. package/dist/utils/order-transitions.js +185 -0
  160. package/dist/utils/sync-logger.js +5 -4
  161. package/dist/validation/offline.d.ts +46 -0
  162. package/dist/validation/offline.js +79 -0
  163. package/package.json +6 -1
  164. package/dist/pricing/engine.test.d.ts +0 -1
  165. package/dist/pricing/engine.test.js +0 -142
  166. package/dist/reference/lww.test.d.ts +0 -1
  167. package/dist/reference/lww.test.js +0 -23
  168. package/dist/reference/operations.test.d.ts +0 -1
  169. package/dist/reference/operations.test.js +0 -66
  170. package/dist/standalone.integration.test.d.ts +0 -1
  171. package/dist/standalone.integration.test.js +0 -235
  172. package/dist/sync/device-lease.test.d.ts +0 -1
  173. package/dist/sync/device-lease.test.js +0 -38
  174. package/dist/sync/offline-integration.test.d.ts +0 -1
  175. package/dist/sync/offline-integration.test.js +0 -52
  176. package/dist/sync/order-number.test.d.ts +0 -1
  177. package/dist/sync/order-number.test.js +0 -51
  178. package/dist/sync/perms.test.d.ts +0 -1
  179. package/dist/sync/perms.test.js +0 -15
  180. package/dist/utils/currency.test.d.ts +0 -1
  181. package/dist/utils/currency.test.js +0 -17
  182. package/dist/utils/hlc.test.d.ts +0 -1
  183. package/dist/utils/hlc.test.js +0 -29
  184. package/dist/utils/phone.test.d.ts +0 -1
  185. package/dist/utils/phone.test.js +0 -19
  186. package/dist/utils/responsive.d.ts +0 -13
  187. package/dist/utils/responsive.js +0 -18
  188. package/dist/utils/uuid.test.d.ts +0 -1
  189. package/dist/utils/uuid.test.js +0 -13
  190. package/dist/utils/validation.test.d.ts +0 -1
  191. 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,14 @@ 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;
17
25
  export declare function cacheRemoteImage(url: string | null | undefined, opts?: {
18
26
  skipIfCached?: boolean;
19
27
  removeOnFailure?: boolean;
@@ -49,6 +49,17 @@ 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
+ }
52
63
  export async function cacheRemoteImage(url, opts = {}) {
53
64
  if (!url)
54
65
  return null;
@@ -58,9 +69,12 @@ export async function cacheRemoteImage(url, opts = {}) {
58
69
  await ensureImageCacheDir();
59
70
  const localPath = getCachedImagePath(url);
60
71
  const existing = await fs.getInfoAsync(localPath);
61
- if (opts.skipIfCached && existing.exists && !existing.isDirectory) {
72
+ if (existing.exists && !existing.isDirectory) {
62
73
  return { remoteUrl: url, localUri: localPath, etag: null, lastModified: null, cachedAt: new Date().toISOString() };
63
74
  }
75
+ if (!isDownloadableImageUrl(url)) {
76
+ return { remoteUrl: url, localUri: null, etag: null, lastModified: null, cachedAt: null };
77
+ }
64
78
  try {
65
79
  const res = await fs.downloadAsync(url, localPath);
66
80
  if (res.uri)
@@ -71,8 +85,6 @@ export async function cacheRemoteImage(url, opts = {}) {
71
85
  }
72
86
  if (opts.removeOnFailure)
73
87
  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
88
  return { remoteUrl: url, localUri: null, etag: null, lastModified: null, cachedAt: null };
77
89
  }
78
90
  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 "./utils/responsive";
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 "./adapters/local-node";
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 { KIOSK_KEYS, SELLER_ORDERS_KEYS, BUSINESS_DELIVERIES_KEYS, MENU_KEYS, REFERENCE_KEYS } from "./adapters/query-keys";
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";
package/dist/index.js CHANGED
@@ -7,6 +7,9 @@
7
7
  // ── Types ──
8
8
  export * from "./types/api";
9
9
  export * from "./types/pos.types";
10
+ export * from "./types/rider";
11
+ export * from "./types/places";
12
+ export * from "./adapters/notify";
10
13
  // ── Pricing (server-parity) ──
11
14
  export { calculatePricing, calculateTaxLines, calculateExclusiveTax, calculateInclusiveTaxShare, } from "./pricing/engine";
12
15
  // ── Utils ──
@@ -15,14 +18,29 @@ export * from "./utils/currency";
15
18
  export * from "./utils/error";
16
19
  export * from "./utils/uuid";
17
20
  export * from "./utils/sync-logger";
21
+ export * from "./utils/debug-log";
22
+ export * from "./utils/attempt-stats";
18
23
  export { PHONE_COUNTRIES, getDialCodeFromCountry, getCountryOption, normalizePhoneForCountry, isLikelyE164 } from "./utils/phone";
19
24
  export * from "./utils/formatCurrency";
20
25
  export { formatDate, formatRelativeTime } from "./utils/formatDate";
21
26
  export * from "./utils/validation";
22
- export * from "./utils/responsive";
27
+ export * from "./validation/offline";
23
28
  export * from "./utils/copyToClipBoard";
24
29
  export * from "./utils/customer-display";
25
30
  export * from "./utils/order-filter";
31
+ export { useReferenceData } from "./reference/hooks";
32
+ export { setNotifyHandlers } from "./adapters/notify";
33
+ export { walletService, riderService, fleetService, deliveryService, dashboardService, analyticsService, placesService } from "./adapters/services";
34
+ export { buildMenuItemEnvelope, buildMenuCategoryEnvelope } from "./reference/menu-record";
35
+ export { validateMenuItemInput, validateMenuCategoryInput, validateOrderCreateInput, validateInviteInput } from "./validation/offline";
36
+ export { useBusinessDeliveriesQuery } from "./hooks/delivery.hooks";
37
+ export { useBusinessReferenceDataSync } from "./reference/hooks";
38
+ export { createAppQueryClient, createQueryPersister } from "./providers/query-client";
39
+ export { useSellerAnalyticsQuery } from "./hooks/analytics.hooks";
40
+ export { useSellerDashboardQuery } from "./hooks/dashboard.hooks";
41
+ export { useRealtimeInvalidation, useOrderRealtimeUpdates } from "./hooks/realtime-stubs";
42
+ export { useAcceptFleetInvitationMutation, useAcceptBusinessInvitationMutation, useUserInvitationsQuery, } from "./hooks/members.hooks";
43
+ export { useJoinRequestsQuery } from "./hooks/fleet.hooks";
26
44
  // ── DB ──
27
45
  export * from "./db/migrations";
28
46
  export * from "./db/operations";
@@ -30,10 +48,10 @@ export * as dbOps from "./db/operations";
30
48
  export { openSyncDatabase, getSyncDatabase, closeSyncDatabase } from "./db/connection";
31
49
  // ── Sync ──
32
50
  export * from "./sync/types";
51
+ export * from "./sync/online-gates";
33
52
  export * from "./sync/use-sync-reconciliation";
34
53
  export { SyncEngine, syncEngine } from "./sync/engine";
35
54
  export * from "./sync/command-builder";
36
- export * from "./sync/command-queue.service";
37
55
  export { commandQueueService } from "./sync/command-queue.service";
38
56
  export { buildCommand } from "./sync/command-builder";
39
57
  export { generateLocalOrderNumber, generateLocalCalloutNumber, isLocalOrderNumber, generateOrderNumber, generateOrderNumberForBusiness, isOfflineOrderNumber, parseOrderNumber, resetCalloutForTests, } from "./sync/order-number";
@@ -55,30 +73,54 @@ export { orderRepository } from "./repositories/order.repository";
55
73
  export { posRepository } from "./repositories/pos.repository";
56
74
  // ── Order lifecycle hooks (offline-first, device-owned outbox) ──
57
75
  export * from "./hooks/orders.hooks";
76
+ export * from "./hooks/use-infinite-list";
77
+ export * from "./hooks/wallet.hooks";
78
+ export * from "./hooks/rider.hooks";
79
+ export * from "./hooks/fleet.hooks";
80
+ export * from "./hooks/delivery.hooks";
81
+ export * from "./hooks/dashboard.hooks";
82
+ export * from "./hooks/analytics.hooks";
83
+ export * from "./hooks/members.hooks";
84
+ export * from "./hooks/places.hooks";
85
+ export * from "./hooks/offline-orders.hooks";
86
+ export * from "./hooks/image.hooks";
87
+ export * from "./hooks/realtime-stubs";
88
+ export * from "./providers/query-client";
89
+ export { KIOSK_KEYS, useKioskOrdersQuery, useAvailableRidersQuery, useAcceptKioskOrderMutation, useRejectKioskOrderMutation, useStartPreparingKioskOrderMutation, useMarkKioskOrderReadyMutation, } from "./hooks/kiosk.hooks";
58
90
  // ── Reference ──
59
91
  export * from "./reference/types";
60
92
  export * from "./reference/operations";
61
- export { fetchReferenceVersions, fetchReferenceData, fetchReferenceChanges, setReferenceLocalNodeFetcher } from "./reference/api";
93
+ export { fetchReferenceVersions, fetchReferenceData, fetchReferenceChanges, setReferenceLocalNodeFetcher, setReferenceData, mergeReferenceData, setOperatingHoursLocal, setBusinessProfileLocal } from "./reference/api";
62
94
  export { emitReferenceChanged, applyReferenceChangeEvent, syncReferenceDataOnReconnect, registerReferenceEventEngine, registerReferenceInvalidator } from "./reference/events";
63
95
  export * from "./reference/events";
64
96
  export * from "./reference/service";
97
+ export * from "./reference/hooks";
65
98
  export { referenceSyncService } from "./reference/service";
99
+ export * from "./reference/menu-record";
100
+ export * from "./reference/menu-apply";
66
101
  export * from "./reference/capabilities";
67
102
  // ── Adapters (for host apps to supply) ──
68
103
  export * from "./adapters/sqlite";
69
104
  export { setKVDriver, getKVDriver, kvGetItem, kvSetItem, kvRemoveItem, getItem, setItem, removeItem, getItemSync, setItemSync } from "./adapters/kv";
70
105
  export * from "./adapters/connectivity";
71
106
  export * from "./adapters/http";
72
- export * from "./adapters/local-node";
107
+ export * from "./local-node/types";
108
+ export * from "./local-node/store";
109
+ export * from "./local-node/security";
110
+ export * from "./local-node/adapters";
111
+ export * from "./local-node/service";
112
+ // adapters/local-node is compat shim — export only non-conflicting
113
+ export { setLocalNodeState } from "./adapters/local-node";
73
114
  export * from "./adapters/services";
74
115
  export * from "./adapters/devices";
75
- export { setAuthProvider, getAuthToken } from "./adapters/auth";
116
+ export { setAuthProvider, getAuthToken, setAuthRefreshProvider, getRefreshToken, setAuthTokensProvider, setAuthTokens, setAuthClearProvider, clearAuth } from "./adapters/auth";
76
117
  export { imageCacheService } from "./adapters/image-cache";
77
118
  export * from "./adapters/business";
78
119
  export * from "./adapters/pending-orders";
79
120
  export * from "./adapters/print";
80
121
  export * from "./adapters/filesystem";
81
- export { KIOSK_KEYS, SELLER_ORDERS_KEYS, BUSINESS_DELIVERIES_KEYS, MENU_KEYS, REFERENCE_KEYS } from "./adapters/query-keys";
122
+ export { SELLER_ORDERS_KEYS, BUSINESS_DELIVERIES_KEYS, MENU_KEYS, REFERENCE_KEYS } from "./adapters/query-keys";
123
+ // KIOSK_KEYS exported from hooks/kiosk.hooks (single source)
82
124
  // POS_KEYS / SELLER_KEYS are exported from hooks/orders.hooks (offline-first source of truth)
83
125
  // ── Printer (backend-identical template) ──
84
126
  export * from "./printer/types";
@@ -91,11 +133,26 @@ export * from "./cart/store";
91
133
  export * from "./cart/hooks";
92
134
  // ── Catalog ──
93
135
  export * from "./catalog/hooks";
136
+ // ── Order transitions (shared business logic — single source) ──
137
+ export * from "./utils/order-transitions";
138
+ // ── Business hours gate (single source — mirrors backend is_open?) ──
139
+ export * from "./utils/business-hours";
140
+ export * from "./hooks/business-hours.hooks";
141
+ // components/OrderStatusCard was folded into order-transitions (compat re-export lives in apps)
142
+ // ── Domain (offline-first primary DB) ──
143
+ export * from "./domain/orders/service";
94
144
  // ── Realtime (single source — PHX WebSocket + business:{id}) ──
95
145
  export { phoenixSocket } from "./realtime/phoenix-socket";
96
146
  export { eventsService } from "./realtime/events.service";
97
147
  export { orderEventsService } from "./realtime/order-events.service";
98
148
  export { useEventsConnection } from "./realtime/useEventsConnection";
149
+ // ── Sync jobs (POS primary sync) — debug helpers for DiagnosticsScreen
150
+ export { getSyncJobsPendingCount, debugDumpSyncJobs, drainPending } from "./sync/sync-jobs.service";
151
+ export { performFullSync } from "./sync/full-sync";
152
+ export { stopHealthProbe } from "./sync/health-probe";
153
+ export { notifyAuthChanged, subscribeAuth } from "./adapters/auth";
154
+ // ── Session lifecycle (access-expired → refresh → refresh-expired → logout)
155
+ export { ACCESS_EXPIRED_CODE, SESSION_DEAD_CODES, SKIP_AUTH_RETRY, extractAuthFailure, isAccessExpired, isSessionDead, hasAuthRetrySkip, refreshSession, withAuthRetry, } from "./auth/session";
99
156
  // ── Image cache (durable) ──
100
157
  export { getCachedImagePath, ensureImageCacheDir, getCachedImageInfo, cacheRemoteImage, cacheImageBatch, clearImageCache, pruneImageCache, resolveImageSource, stableCacheUrl } from "./image-cache/service";
101
158
  // ── Init helper ──
@@ -109,6 +166,8 @@ import { API_BASE_URL, WS_BASE_URL, setApiBaseUrl, setWsBaseUrl } from "./utils/
109
166
  import { SyncEngine } from "./sync/engine";
110
167
  import { restTransport } from "./sync/transport-rest";
111
168
  import { localNodeTransport } from "./sync/transport-local-node";
169
+ import { setupSyncJobsDrain } from "./sync/sync-jobs.service";
170
+ import { startHealthProbe } from "./sync/health-probe";
112
171
  let engine = null;
113
172
  export function createTeincCore(config = {}) {
114
173
  try {
@@ -154,6 +213,14 @@ export function createTeincCore(config = {}) {
154
213
  }
155
214
  if (config.initialConnectivity)
156
215
  setConnectivityState(config.initialConnectivity);
216
+ try {
217
+ setupSyncJobsDrain();
218
+ }
219
+ catch { }
220
+ try {
221
+ startHealthProbe();
222
+ }
223
+ catch { }
157
224
  // Debug: confirm env vars as seen by core after injection
158
225
  try {
159
226
  console.debug("[core] final URLs", { API_BASE_URL, WS_BASE_URL });