@terreno/rtk 0.13.3 → 0.14.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.
Files changed (163) hide show
  1. package/dist/authSlice.d.ts +4 -4
  2. package/dist/authSlice.d.ts.map +1 -1
  3. package/dist/authSlice.js +7 -7
  4. package/dist/authSlice.js.map +1 -1
  5. package/dist/authSlice.test.js +2 -10
  6. package/dist/authSlice.test.js.map +1 -1
  7. package/dist/authSliceNative.test.js +11 -3
  8. package/dist/authSliceNative.test.js.map +1 -1
  9. package/dist/betterAuthSlice.d.ts.map +1 -1
  10. package/dist/betterAuthSlice.js +3 -2
  11. package/dist/betterAuthSlice.js.map +1 -1
  12. package/dist/betterAuthSlice.test.js +1 -25
  13. package/dist/betterAuthSlice.test.js.map +1 -1
  14. package/dist/constants.d.ts +3 -0
  15. package/dist/constants.d.ts.map +1 -1
  16. package/dist/constants.js +11 -3
  17. package/dist/constants.js.map +1 -1
  18. package/dist/constants.test.js +85 -2
  19. package/dist/constants.test.js.map +1 -1
  20. package/dist/emptyApi.d.ts +3 -1
  21. package/dist/emptyApi.d.ts.map +1 -1
  22. package/dist/emptyApi.js +7 -2
  23. package/dist/emptyApi.js.map +1 -1
  24. package/dist/index.d.ts +8 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +8 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/isolated/constants.isolated.js +7 -1
  29. package/dist/isolated/constants.isolated.js.map +1 -1
  30. package/dist/isolated/offlineMiddleware.isolated.d.ts +2 -0
  31. package/dist/isolated/offlineMiddleware.isolated.d.ts.map +1 -0
  32. package/dist/isolated/offlineMiddleware.isolated.js +516 -0
  33. package/dist/isolated/offlineMiddleware.isolated.js.map +1 -0
  34. package/dist/isolated/offlineMiddleware.native.isolated.d.ts +2 -0
  35. package/dist/isolated/offlineMiddleware.native.isolated.d.ts.map +1 -0
  36. package/dist/isolated/offlineMiddleware.native.isolated.js +70 -0
  37. package/dist/isolated/offlineMiddleware.native.isolated.js.map +1 -0
  38. package/dist/isolated/useUpgradeCheck.mobile.isolated.d.ts +2 -0
  39. package/dist/isolated/useUpgradeCheck.mobile.isolated.d.ts.map +1 -0
  40. package/dist/{useUpgradeCheck.mobile.test.js → isolated/useUpgradeCheck.mobile.isolated.js} +13 -5
  41. package/dist/isolated/useUpgradeCheck.mobile.isolated.js.map +1 -0
  42. package/dist/isolated/useUpgradeCheck.web.isolated.d.ts +2 -0
  43. package/dist/isolated/useUpgradeCheck.web.isolated.d.ts.map +1 -0
  44. package/dist/{useUpgradeCheck.test.js → isolated/useUpgradeCheck.web.isolated.js} +37 -7
  45. package/dist/isolated/useUpgradeCheck.web.isolated.js.map +1 -0
  46. package/dist/mongooseSlice.d.ts +3 -2
  47. package/dist/mongooseSlice.d.ts.map +1 -1
  48. package/dist/mongooseSlice.js +3 -4
  49. package/dist/mongooseSlice.js.map +1 -1
  50. package/dist/mongooseSlice.test.js +1 -1
  51. package/dist/mongooseSlice.test.js.map +1 -1
  52. package/dist/offlineGate.d.ts +8 -0
  53. package/dist/offlineGate.d.ts.map +1 -0
  54. package/dist/offlineGate.js +20 -0
  55. package/dist/offlineGate.js.map +1 -0
  56. package/dist/offlineGate.test.d.ts +2 -0
  57. package/dist/offlineGate.test.d.ts.map +1 -0
  58. package/dist/offlineGate.test.js +46 -0
  59. package/dist/offlineGate.test.js.map +1 -0
  60. package/dist/offlineMiddleware.d.ts +46 -0
  61. package/dist/offlineMiddleware.d.ts.map +1 -0
  62. package/dist/offlineMiddleware.js +589 -0
  63. package/dist/offlineMiddleware.js.map +1 -0
  64. package/dist/offlineMiddleware.test.d.ts +2 -0
  65. package/dist/offlineMiddleware.test.d.ts.map +1 -0
  66. package/dist/offlineMiddleware.test.js +145 -0
  67. package/dist/offlineMiddleware.test.js.map +1 -0
  68. package/dist/offlineSlice.d.ts +232 -0
  69. package/dist/offlineSlice.d.ts.map +1 -0
  70. package/dist/offlineSlice.js +65 -0
  71. package/dist/offlineSlice.js.map +1 -0
  72. package/dist/offlineSlice.test.d.ts +2 -0
  73. package/dist/offlineSlice.test.d.ts.map +1 -0
  74. package/dist/offlineSlice.test.js +153 -0
  75. package/dist/offlineSlice.test.js.map +1 -0
  76. package/dist/realtime.d.ts +123 -0
  77. package/dist/realtime.d.ts.map +1 -0
  78. package/dist/realtime.js +299 -0
  79. package/dist/realtime.js.map +1 -0
  80. package/dist/realtime.test.d.ts +2 -0
  81. package/dist/realtime.test.d.ts.map +1 -0
  82. package/dist/realtime.test.js +339 -0
  83. package/dist/realtime.test.js.map +1 -0
  84. package/dist/socket.d.ts.map +1 -1
  85. package/dist/socket.js +29 -28
  86. package/dist/socket.js.map +1 -1
  87. package/dist/sync.d.ts +35 -0
  88. package/dist/sync.d.ts.map +1 -0
  89. package/dist/sync.js +205 -0
  90. package/dist/sync.js.map +1 -0
  91. package/dist/tagGenerator.d.ts +20 -1
  92. package/dist/tagGenerator.d.ts.map +1 -1
  93. package/dist/tagGenerator.js +4 -12
  94. package/dist/tagGenerator.js.map +1 -1
  95. package/dist/useFeatureFlags.d.ts +4 -2
  96. package/dist/useFeatureFlags.d.ts.map +1 -1
  97. package/dist/useFeatureFlags.js +3 -5
  98. package/dist/useFeatureFlags.js.map +1 -1
  99. package/dist/useOfflineStatus.d.ts +33 -0
  100. package/dist/useOfflineStatus.d.ts.map +1 -0
  101. package/dist/useOfflineStatus.js +43 -0
  102. package/dist/useOfflineStatus.js.map +1 -0
  103. package/dist/useOfflineStatus.test.d.ts +2 -0
  104. package/dist/useOfflineStatus.test.d.ts.map +1 -0
  105. package/dist/useOfflineStatus.test.js +119 -0
  106. package/dist/useOfflineStatus.test.js.map +1 -0
  107. package/dist/useRealtimeDebug.d.ts +6 -0
  108. package/dist/useRealtimeDebug.d.ts.map +1 -0
  109. package/dist/useRealtimeDebug.js +41 -0
  110. package/dist/useRealtimeDebug.js.map +1 -0
  111. package/dist/useServerStatus.d.ts +29 -0
  112. package/dist/useServerStatus.d.ts.map +1 -0
  113. package/dist/useServerStatus.js +89 -0
  114. package/dist/useServerStatus.js.map +1 -0
  115. package/dist/useUpgradeCheck.d.ts +7 -3
  116. package/dist/useUpgradeCheck.d.ts.map +1 -1
  117. package/dist/useUpgradeCheck.js +27 -13
  118. package/dist/useUpgradeCheck.js.map +1 -1
  119. package/package.json +2 -2
  120. package/src/authSlice.test.ts +2 -11
  121. package/src/authSlice.ts +9 -9
  122. package/src/authSliceNative.test.ts +11 -4
  123. package/src/betterAuthSlice.test.ts +1 -25
  124. package/src/betterAuthSlice.ts +3 -2
  125. package/src/constants.test.ts +99 -1
  126. package/src/constants.ts +14 -3
  127. package/src/emptyApi.ts +11 -3
  128. package/src/index.ts +8 -0
  129. package/src/isolated/constants.isolated.ts +7 -3
  130. package/src/isolated/offlineMiddleware.isolated.ts +696 -0
  131. package/src/isolated/offlineMiddleware.native.isolated.ts +80 -0
  132. package/src/{useUpgradeCheck.mobile.test.ts → isolated/useUpgradeCheck.mobile.isolated.ts} +13 -4
  133. package/src/{useUpgradeCheck.test.ts → isolated/useUpgradeCheck.web.isolated.ts} +48 -6
  134. package/src/mongooseSlice.test.ts +1 -1
  135. package/src/mongooseSlice.ts +4 -5
  136. package/src/offlineGate.test.ts +55 -0
  137. package/src/offlineGate.ts +25 -0
  138. package/src/offlineMiddleware.test.ts +187 -0
  139. package/src/offlineMiddleware.ts +716 -0
  140. package/src/offlineSlice.test.ts +204 -0
  141. package/src/offlineSlice.ts +130 -0
  142. package/src/realtime.test.ts +404 -0
  143. package/src/realtime.ts +408 -0
  144. package/src/socket.ts +33 -32
  145. package/src/sync.ts +310 -0
  146. package/src/tagGenerator.ts +30 -18
  147. package/src/useFeatureFlags.ts +6 -6
  148. package/src/useOfflineStatus.test.ts +157 -0
  149. package/src/useOfflineStatus.ts +82 -0
  150. package/src/useRealtimeDebug.ts +51 -0
  151. package/src/useServerStatus.ts +122 -0
  152. package/src/useUpgradeCheck.ts +35 -13
  153. package/dist/isolated/useUpgradeCheck.isolated.d.ts +0 -2
  154. package/dist/isolated/useUpgradeCheck.isolated.d.ts.map +0 -1
  155. package/dist/isolated/useUpgradeCheck.isolated.js +0 -153
  156. package/dist/isolated/useUpgradeCheck.isolated.js.map +0 -1
  157. package/dist/useUpgradeCheck.mobile.test.d.ts +0 -2
  158. package/dist/useUpgradeCheck.mobile.test.d.ts.map +0 -1
  159. package/dist/useUpgradeCheck.mobile.test.js.map +0 -1
  160. package/dist/useUpgradeCheck.test.d.ts +0 -2
  161. package/dist/useUpgradeCheck.test.d.ts.map +0 -1
  162. package/dist/useUpgradeCheck.test.js.map +0 -1
  163. package/src/isolated/useUpgradeCheck.isolated.ts +0 -201
@@ -0,0 +1,589 @@
1
+ import { createListenerMiddleware } from "@reduxjs/toolkit";
2
+ import { DateTime } from "luxon";
3
+ import { getAuthToken, selectCurrentUserId } from "./authSlice";
4
+ import { baseUrl, LOGOUT_ACTION_TYPE } from "./constants";
5
+ import { configureOfflineMutationEndpoints } from "./offlineGate";
6
+ import { addConflict, clearConflicts, clearQueue, dequeue, enqueue, offlineReducer, offlineSlice, selectIsOnline, selectIsSyncing, selectOfflineQueue, setOnlineStatus, setSyncing, } from "./offlineSlice";
7
+ import { IsWeb } from "./platform";
8
+ /**
9
+ * Infer the CRUD operation type from an RTK Query endpoint name.
10
+ * Convention: postX = create, patchX = update, deleteX = delete.
11
+ */
12
+ const inferMutationType = (endpointName) => {
13
+ if (endpointName.startsWith("post")) {
14
+ return "create";
15
+ }
16
+ if (endpointName.startsWith("patch")) {
17
+ return "update";
18
+ }
19
+ if (endpointName.startsWith("delete")) {
20
+ return "delete";
21
+ }
22
+ return "update";
23
+ };
24
+ /**
25
+ * True when a rejected RTK Query action failed due to a network/transport error,
26
+ * not an auth or application-level FETCH_ERROR from emptyApi.
27
+ */
28
+ export const isNetworkFetchError = (
29
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query error shapes vary by source
30
+ source) => {
31
+ if (source?.error?.name === "TypeError") {
32
+ return true;
33
+ }
34
+ const NETWORK_PATTERNS = [
35
+ "failed to fetch",
36
+ "fetch failed",
37
+ "network error",
38
+ "network unavailable",
39
+ "load failed",
40
+ ];
41
+ const candidates = [];
42
+ if (typeof source?.error?.message === "string") {
43
+ candidates.push(source.error.message);
44
+ }
45
+ if (typeof source?.error === "string") {
46
+ candidates.push(source.error);
47
+ }
48
+ if (typeof source?.payload?.error === "string") {
49
+ candidates.push(source.payload.error);
50
+ }
51
+ if (typeof source?.status === "string" && source.status === "FETCH_ERROR") {
52
+ if (typeof source?.error === "string") {
53
+ candidates.push(source.error);
54
+ }
55
+ }
56
+ const combined = candidates.join(" ").toLowerCase();
57
+ return NETWORK_PATTERNS.some((p) => combined.includes(p));
58
+ };
59
+ /**
60
+ * Whether a queued mutation may be replayed for the currently signed-in user.
61
+ * Legacy entries without userId are discarded to avoid cross-account replay after account switch.
62
+ */
63
+ export const shouldReplayQueuedMutation = (mutation, currentUserId) => {
64
+ if (!currentUserId) {
65
+ return false;
66
+ }
67
+ if (mutation.userId === undefined) {
68
+ return false;
69
+ }
70
+ return mutation.userId === currentUserId;
71
+ };
72
+ /** Optimistic list item for a queued create; temp IDs are applied after body spread. */
73
+ export const buildOptimisticCreateItem = (mutation, body) => {
74
+ const tempId = `temp-${mutation.id}`;
75
+ return {
76
+ ...(body ?? {}),
77
+ _id: tempId,
78
+ created: mutation.timestamp,
79
+ id: tempId,
80
+ updated: mutation.timestamp,
81
+ };
82
+ };
83
+ /** Derives the collection tag from an endpoint name (e.g. "patchTodosById" → "todos"). */
84
+ const inferTagType = (endpointName) => {
85
+ let name = endpointName.replace(/^(post|patch|delete)/, "").replace(/ById$/, "");
86
+ name = name.charAt(0).toLowerCase() + name.slice(1);
87
+ return name;
88
+ };
89
+ const inferGetByIdEndpointName = (endpointName) => {
90
+ const tagType = inferTagType(endpointName);
91
+ const capitalized = tagType.charAt(0).toUpperCase() + tagType.slice(1);
92
+ return `get${capitalized}ById`;
93
+ };
94
+ /**
95
+ * Last-seen document `updated` timestamp for conflict headers on replay.
96
+ * Prefer the patch body's `_updatedAt`, then a cached get-by-id entry.
97
+ */
98
+ const extractBaseUpdatedAt = (endpointName, originalArgs,
99
+ // biome-ignore lint/suspicious/noExplicitAny: Generic getState
100
+ getState,
101
+ // biome-ignore lint/suspicious/noExplicitAny: Generic API type
102
+ api) => {
103
+ if (inferMutationType(endpointName) !== "update") {
104
+ return undefined;
105
+ }
106
+ const args = originalArgs;
107
+ const bodyUpdatedAt = args?.body?._updatedAt;
108
+ if (typeof bodyUpdatedAt === "string") {
109
+ return bodyUpdatedAt;
110
+ }
111
+ if (!args?.id) {
112
+ return undefined;
113
+ }
114
+ const getByIdEndpoint = inferGetByIdEndpointName(endpointName);
115
+ const state = getState();
116
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query internal state shape
117
+ const queries = state[api.reducerPath]?.queries ?? {};
118
+ for (const key of Object.keys(queries)) {
119
+ if (!key.startsWith(`${getByIdEndpoint}(`)) {
120
+ continue;
121
+ }
122
+ const queryEntry = queries[key];
123
+ if (queryEntry?.originalArgs?.id !== args.id) {
124
+ continue;
125
+ }
126
+ const data = queryEntry?.data;
127
+ const updated = data?.data?.updated;
128
+ if (typeof updated === "string") {
129
+ return updated;
130
+ }
131
+ }
132
+ return undefined;
133
+ };
134
+ /**
135
+ * Collect all cached query args for a given list endpoint so optimistic
136
+ * updates are applied to every active cache entry (regardless of the
137
+ * args the consumer passed to the query hook, e.g. `{}` vs `undefined`).
138
+ */
139
+ const getCachedQueryArgs = (
140
+ // biome-ignore lint/suspicious/noExplicitAny: Generic API state shape
141
+ getState,
142
+ // biome-ignore lint/suspicious/noExplicitAny: Generic API type
143
+ api, listEndpointName) => {
144
+ const state = getState();
145
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query internal state shape
146
+ const queries = state[api.reducerPath]?.queries ?? {};
147
+ const cachedArgs = [];
148
+ for (const key of Object.keys(queries)) {
149
+ if (key.startsWith(`${listEndpointName}(`)) {
150
+ cachedArgs.push(queries[key]?.originalArgs);
151
+ }
152
+ }
153
+ if (cachedArgs.length === 0) {
154
+ cachedArgs.push(undefined);
155
+ }
156
+ return cachedArgs;
157
+ };
158
+ /**
159
+ * Apply an optimistic update to the RTK Query cache for a queued mutation.
160
+ */
161
+ const applyOptimisticUpdate = (
162
+ // biome-ignore lint/suspicious/noExplicitAny: Generic API type
163
+ api,
164
+ // biome-ignore lint/suspicious/noExplicitAny: Generic dispatch
165
+ dispatch,
166
+ // biome-ignore lint/suspicious/noExplicitAny: Generic getState
167
+ getState, mutation) => {
168
+ const tagType = inferTagType(mutation.endpointName);
169
+ const listEndpointName = `get${tagType.charAt(0).toUpperCase() + tagType.slice(1)}`;
170
+ const cachedArgs = getCachedQueryArgs(getState, api, listEndpointName);
171
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query cache shape varies by endpoint
172
+ const updateAllCacheEntries = (updater) => {
173
+ for (const queryArg of cachedArgs) {
174
+ dispatch(
175
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query cache shape varies by endpoint
176
+ api.util.updateQueryData(listEndpointName, queryArg, updater));
177
+ }
178
+ };
179
+ if (mutation.type === "create") {
180
+ const args = mutation.args;
181
+ const tempItem = buildOptimisticCreateItem(mutation, args?.body);
182
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query cache shape varies by endpoint
183
+ updateAllCacheEntries((draft) => {
184
+ if (draft?.data && Array.isArray(draft.data)) {
185
+ draft.data.unshift(tempItem);
186
+ }
187
+ });
188
+ }
189
+ else if (mutation.type === "update") {
190
+ const args = mutation.args;
191
+ if (args?.id && args?.body) {
192
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query cache shape varies by endpoint
193
+ updateAllCacheEntries((draft) => {
194
+ if (draft?.data && Array.isArray(draft.data)) {
195
+ const item = draft.data.find((d) => d._id === args.id || d.id === args.id);
196
+ if (item) {
197
+ Object.assign(item, args.body);
198
+ }
199
+ }
200
+ });
201
+ }
202
+ }
203
+ else if (mutation.type === "delete") {
204
+ const args = mutation.args;
205
+ if (args?.id) {
206
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query cache shape varies by endpoint
207
+ updateAllCacheEntries((draft) => {
208
+ if (draft?.data && Array.isArray(draft.data)) {
209
+ draft.data = draft.data.filter((d) => d._id !== args.id && d.id !== args.id);
210
+ }
211
+ });
212
+ }
213
+ }
214
+ };
215
+ /**
216
+ * Remove optimistic temp items from the cache after they've been replayed.
217
+ */
218
+ const removeTempItems = (
219
+ // biome-ignore lint/suspicious/noExplicitAny: Generic API type
220
+ api,
221
+ // biome-ignore lint/suspicious/noExplicitAny: Generic dispatch
222
+ dispatch,
223
+ // biome-ignore lint/suspicious/noExplicitAny: Generic getState
224
+ getState, mutations) => {
225
+ const tempIds = new Set(mutations.map((m) => `temp-${m.id}`));
226
+ const tagTypes = [...new Set(mutations.map((m) => inferTagType(m.endpointName)))];
227
+ for (const tagType of tagTypes) {
228
+ const listEndpointName = `get${tagType.charAt(0).toUpperCase() + tagType.slice(1)}`;
229
+ const cachedArgs = getCachedQueryArgs(getState, api, listEndpointName);
230
+ for (const queryArg of cachedArgs) {
231
+ dispatch(
232
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query cache shape varies by endpoint
233
+ api.util.updateQueryData(listEndpointName, queryArg, (draft) => {
234
+ if (draft?.data && Array.isArray(draft.data)) {
235
+ draft.data = draft.data.filter((d) => !tempIds.has(d._id) && !tempIds.has(d.id));
236
+ }
237
+ }));
238
+ }
239
+ }
240
+ };
241
+ /**
242
+ * Replay a single queued mutation by making a direct API call.
243
+ * Returns the response status and data for conflict handling.
244
+ */
245
+ const replayMutation = async (mutation) => {
246
+ const token = await getAuthToken();
247
+ const headers = {
248
+ "Content-Type": "application/json",
249
+ };
250
+ if (token) {
251
+ headers.authorization = `Bearer ${token}`;
252
+ }
253
+ // For update operations, include If-Unmodified-Since from the document version at queue time
254
+ if (mutation.type === "update" && mutation.baseUpdatedAt) {
255
+ const timestamp = DateTime.fromISO(mutation.baseUpdatedAt);
256
+ if (timestamp.isValid) {
257
+ headers["If-Unmodified-Since"] = timestamp.toHTTP();
258
+ headers["X-Unmodified-Since-ISO"] = mutation.baseUpdatedAt;
259
+ }
260
+ }
261
+ const args = mutation.args;
262
+ const tagType = inferTagType(mutation.endpointName);
263
+ const basePath = `/${tagType}`;
264
+ let url;
265
+ let method;
266
+ let body;
267
+ if (mutation.type === "create") {
268
+ url = `${baseUrl}${basePath}`;
269
+ method = "POST";
270
+ body = JSON.stringify(args?.body);
271
+ }
272
+ else if (mutation.type === "update") {
273
+ url = `${baseUrl}${basePath}/${args?.id}`;
274
+ method = "PATCH";
275
+ body = JSON.stringify(args?.body);
276
+ }
277
+ else {
278
+ url = `${baseUrl}${basePath}/${args?.id}`;
279
+ method = "DELETE";
280
+ }
281
+ const response = await fetch(url, { body, headers, method });
282
+ if (response.status === 204) {
283
+ return { status: 204 };
284
+ }
285
+ const data = await response.json();
286
+ return { data, status: response.status };
287
+ };
288
+ /**
289
+ * Set up native-only network monitoring (expo-network).
290
+ * Web apps should use `useServerStatus` for server-level health checking.
291
+ */
292
+ const setupNativeNetworkMonitoring = (
293
+ // biome-ignore lint/suspicious/noExplicitAny: Generic dispatch
294
+ dispatch) => {
295
+ if (IsWeb) {
296
+ return () => { };
297
+ }
298
+ let cleanup = () => { };
299
+ void import("expo-network").then((Network) => {
300
+ Network.getNetworkStateAsync().then((state) => {
301
+ dispatch(setOnlineStatus(state.isConnected ?? true));
302
+ });
303
+ const subscription = Network.addNetworkStateListener((state) => {
304
+ dispatch(setOnlineStatus(state.isConnected ?? true));
305
+ });
306
+ cleanup = () => subscription.remove();
307
+ });
308
+ return () => cleanup();
309
+ };
310
+ /**
311
+ * Creates an offline middleware system for RTK Query mutations.
312
+ *
313
+ * When the device is offline, configured mutation endpoints are queued instead of
314
+ * failing. When connectivity returns, queued mutations are replayed in order with
315
+ * LWW (Last-Writer-Wins) conflict detection via If-Unmodified-Since headers.
316
+ *
317
+ * Usage:
318
+ * ```typescript
319
+ * const offline = createOfflineMiddleware({
320
+ * endpoints: ["postTodos", "patchTodosById", "deleteTodosById"],
321
+ * api: terrenoApi,
322
+ * });
323
+ *
324
+ * // Add to store:
325
+ * // reducer: { offline: offline.offlineReducer }
326
+ * // middleware: [..., offline.middleware]
327
+ * ```
328
+ */
329
+ export const createOfflineMiddleware = (config) => {
330
+ const { endpoints, api } = config;
331
+ const endpointSet = new Set(endpoints);
332
+ configureOfflineMutationEndpoints(endpoints);
333
+ const listenerMiddleware = createListenerMiddleware();
334
+ let _networkCleanup;
335
+ let isReplayInProgress = false;
336
+ // Listener 1: Set up native network monitoring on first action (lazy init)
337
+ let networkInitialized = false;
338
+ listenerMiddleware.startListening({
339
+ effect: (_action, listenerApi) => {
340
+ networkInitialized = true;
341
+ _networkCleanup = setupNativeNetworkMonitoring(listenerApi.dispatch);
342
+ },
343
+ predicate: () => !networkInitialized,
344
+ });
345
+ // Listener 2: Intercept failed mutations on network errors (offline or server unreachable)
346
+ // RTK Query dispatches actions with type "terreno-rtk/executeMutation/rejected"
347
+ // when a mutation fails. Queue the mutation and apply an optimistic cache update.
348
+ listenerMiddleware.startListening({
349
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query action types are complex
350
+ effect: async (action, listenerApi) => {
351
+ const state = listenerApi.getState();
352
+ const isOnline = selectIsOnline(state);
353
+ if (!isNetworkFetchError(action)) {
354
+ return;
355
+ }
356
+ const endpointName = action.meta.arg.endpointName;
357
+ const originalArgs = action.meta.arg.originalArgs;
358
+ const mutationType = inferMutationType(endpointName);
359
+ // For updates, use the document's last-known `updated` timestamp from cache
360
+ // rather than the current time. This ensures conflict detection compares against
361
+ // when the document was last fetched, not when the mutation was queued.
362
+ let timestamp = DateTime.now().toISO();
363
+ let listCacheBaseUpdatedAt;
364
+ if (mutationType === "update") {
365
+ const args = originalArgs;
366
+ if (args?.id) {
367
+ const tagType = inferTagType(endpointName);
368
+ const listEndpointName = `get${tagType.charAt(0).toUpperCase() + tagType.slice(1)}`;
369
+ const cachedArgs = getCachedQueryArgs(listenerApi.getState, api, listEndpointName);
370
+ for (const queryArg of cachedArgs) {
371
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query cache shape and endpoint types vary
372
+ const endpoint = api.endpoints[listEndpointName];
373
+ if (!endpoint?.select) {
374
+ continue;
375
+ }
376
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query cache shape varies
377
+ const cacheEntry = endpoint.select(queryArg)(listenerApi.getState());
378
+ const items = cacheEntry?.data?.data;
379
+ if (Array.isArray(items)) {
380
+ const doc = items.find((d) => d._id === args.id || d.id === args.id);
381
+ if (doc?.updated) {
382
+ timestamp =
383
+ typeof doc.updated === "string"
384
+ ? doc.updated
385
+ : DateTime.fromJSDate(doc.updated).toISO();
386
+ listCacheBaseUpdatedAt = timestamp ?? undefined;
387
+ break;
388
+ }
389
+ }
390
+ }
391
+ }
392
+ }
393
+ const baseUpdatedAt = extractBaseUpdatedAt(endpointName, originalArgs, listenerApi.getState, api) ??
394
+ listCacheBaseUpdatedAt;
395
+ const currentUserId = selectCurrentUserId(listenerApi.getState());
396
+ const mutation = {
397
+ args: originalArgs,
398
+ baseUpdatedAt,
399
+ endpointName,
400
+ id: `${endpointName}-${DateTime.now().toMillis()}-${Math.random().toString(36).slice(2, 8)}`,
401
+ timestamp,
402
+ type: mutationType,
403
+ userId: currentUserId,
404
+ };
405
+ listenerApi.dispatch(enqueue(mutation));
406
+ applyOptimisticUpdate(api, listenerApi.dispatch, listenerApi.getState, mutation);
407
+ // Browser may still report online when the API server is unreachable
408
+ if (isOnline) {
409
+ listenerApi.dispatch(setOnlineStatus(false));
410
+ }
411
+ },
412
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query internal action shape
413
+ predicate: (action) => {
414
+ if (typeof action?.type !== "string") {
415
+ return false;
416
+ }
417
+ // Match RTK Query mutation rejected actions
418
+ return (action.type.includes("/executeMutation/rejected") &&
419
+ action?.meta?.arg?.endpointName &&
420
+ endpointSet.has(action.meta.arg.endpointName));
421
+ },
422
+ });
423
+ // Listener 3: Mark offline when any API request fails with a network error
424
+ listenerMiddleware.startListening({
425
+ effect: (_action, listenerApi) => {
426
+ const state = listenerApi.getState();
427
+ if (selectIsOnline(state)) {
428
+ listenerApi.dispatch(setOnlineStatus(false));
429
+ }
430
+ },
431
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query internal action shape
432
+ predicate: (action) => {
433
+ if (typeof action?.type !== "string") {
434
+ return false;
435
+ }
436
+ return (action.type.startsWith(`${api.reducerPath}/`) &&
437
+ (action.type.includes("/executeQuery/rejected") ||
438
+ action.type.includes("/executeMutation/rejected")) &&
439
+ isNetworkFetchError(action));
440
+ },
441
+ });
442
+ // Listener 4: Mark online when any API request succeeds (server reachable again)
443
+ listenerMiddleware.startListening({
444
+ effect: (_action, listenerApi) => {
445
+ const state = listenerApi.getState();
446
+ if (!selectIsOnline(state)) {
447
+ listenerApi.dispatch(setOnlineStatus(true));
448
+ }
449
+ },
450
+ // biome-ignore lint/suspicious/noExplicitAny: RTK Query internal action shape
451
+ predicate: (action) => {
452
+ if (typeof action?.type !== "string") {
453
+ return false;
454
+ }
455
+ return (action.type.startsWith(`${api.reducerPath}/`) &&
456
+ action.type.endsWith("/fulfilled") &&
457
+ (action.type.includes("/executeQuery/") || action.type.includes("/executeMutation/")));
458
+ },
459
+ });
460
+ // Listener 5: Sync queue when coming back online
461
+ listenerMiddleware.startListening({
462
+ actionCreator: setOnlineStatus,
463
+ effect: async (action, listenerApi) => {
464
+ if (!action.payload) {
465
+ // Going offline, nothing to do
466
+ return;
467
+ }
468
+ if (isReplayInProgress) {
469
+ return;
470
+ }
471
+ listenerApi.cancelActiveListeners();
472
+ const state = listenerApi.getState();
473
+ const queue = selectOfflineQueue(state);
474
+ const currentUserId = selectCurrentUserId(listenerApi.getState());
475
+ if (queue.length === 0) {
476
+ // Reset isSyncing if it was stuck from a crash/reload during sync
477
+ if (selectIsSyncing(state)) {
478
+ listenerApi.dispatch(setSyncing(false));
479
+ }
480
+ return;
481
+ }
482
+ isReplayInProgress = true;
483
+ listenerApi.dispatch(setSyncing(true));
484
+ const replayedCreates = [];
485
+ try {
486
+ // Replay mutations in FIFO order
487
+ for (const mutation of queue) {
488
+ if (!shouldReplayQueuedMutation(mutation, currentUserId)) {
489
+ console.warn(`[offline] Dropping queued mutation ${mutation.endpointName} — not owned by current user`);
490
+ listenerApi.dispatch(dequeue(mutation.id));
491
+ continue;
492
+ }
493
+ try {
494
+ const result = await replayMutation(mutation);
495
+ if (result.status === 409) {
496
+ const conflict = {
497
+ args: mutation.args,
498
+ dismissed: false,
499
+ endpointName: mutation.endpointName,
500
+ id: mutation.id,
501
+ serverDocument: result.data?.data ?? result.data,
502
+ timestamp: DateTime.now().toISO(),
503
+ };
504
+ listenerApi.dispatch(addConflict(conflict));
505
+ listenerApi.dispatch(dequeue(mutation.id));
506
+ if (mutation.type === "create") {
507
+ replayedCreates.push(mutation);
508
+ }
509
+ }
510
+ else if (result.status >= 200 && result.status < 300) {
511
+ listenerApi.dispatch(dequeue(mutation.id));
512
+ if (mutation.type === "create") {
513
+ replayedCreates.push(mutation);
514
+ }
515
+ }
516
+ else {
517
+ console.warn(`[offline] Replay failed for ${mutation.endpointName}: status ${result.status}`);
518
+ if (result.status >= 400 && result.status < 500 && result.status !== 409) {
519
+ listenerApi.dispatch(dequeue(mutation.id));
520
+ if (mutation.type === "create") {
521
+ replayedCreates.push(mutation);
522
+ }
523
+ }
524
+ }
525
+ }
526
+ catch (_error) {
527
+ console.warn(`[offline] Replay network error for ${mutation.endpointName}`);
528
+ break;
529
+ }
530
+ }
531
+ // Remove optimistic temp items for creates that were replayed
532
+ if (replayedCreates.length > 0) {
533
+ removeTempItems(api, listenerApi.dispatch, listenerApi.getState, replayedCreates);
534
+ }
535
+ // Invalidate tags to refresh cache with server state
536
+ const tagTypes = [...new Set(queue.map((m) => inferTagType(m.endpointName)))];
537
+ for (const tagType of tagTypes) {
538
+ listenerApi.dispatch(api.util.invalidateTags([tagType]));
539
+ }
540
+ }
541
+ finally {
542
+ isReplayInProgress = false;
543
+ listenerApi.dispatch(setSyncing(false));
544
+ }
545
+ },
546
+ });
547
+ // Listener 6: Clear persisted queue on logout so mutations are not replayed for the next user
548
+ listenerMiddleware.startListening({
549
+ effect: (_action, listenerApi) => {
550
+ listenerApi.dispatch(clearQueue());
551
+ listenerApi.dispatch(clearConflicts());
552
+ },
553
+ type: LOGOUT_ACTION_TYPE,
554
+ });
555
+ // Listener 7: On startup, if the persisted queue has items and we're online,
556
+ // trigger a replay. This handles the case where the app reloads while online
557
+ // with a non-empty queue (rehydrated state already has isOnline: true, so no
558
+ // offline→online transition would otherwise occur).
559
+ let startupReplayTriggered = false;
560
+ listenerMiddleware.startListening({
561
+ effect: (_action, listenerApi) => {
562
+ startupReplayTriggered = true;
563
+ const state = listenerApi.getState();
564
+ const queue = selectOfflineQueue(state);
565
+ const isOnline = selectIsOnline(state);
566
+ // Reset stuck isSyncing from a crash during prior sync
567
+ if (selectIsSyncing(state) && !isReplayInProgress) {
568
+ listenerApi.dispatch(setSyncing(false));
569
+ }
570
+ if (queue.length > 0 && isOnline && !isReplayInProgress) {
571
+ // Re-dispatch setOnlineStatus(true) to trigger the sync listener
572
+ listenerApi.dispatch(setOnlineStatus(true));
573
+ }
574
+ },
575
+ predicate: (action) => {
576
+ if (startupReplayTriggered) {
577
+ return false;
578
+ }
579
+ // redux-persist dispatches "persist/REHYDRATE" after loading stored state
580
+ return typeof action?.type === "string" && action.type === "persist/REHYDRATE";
581
+ },
582
+ });
583
+ return {
584
+ middleware: listenerMiddleware.middleware,
585
+ offlineReducer,
586
+ offlineSlice,
587
+ };
588
+ };
589
+ //# sourceMappingURL=offlineMiddleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offlineMiddleware.js","sourceRoot":"","sources":["../src/offlineMiddleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=offlineMiddleware.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offlineMiddleware.test.d.ts","sourceRoot":"","sources":["../src/offlineMiddleware.test.ts"],"names":[],"mappings":""}