@tanstack/react-query-persist-client 4.0.11-beta.0 → 4.2.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 (68) hide show
  1. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +33 -0
  2. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -0
  3. package/build/cjs/query-core/build/esm/index.js +314 -0
  4. package/build/cjs/query-core/build/esm/index.js.map +1 -0
  5. package/build/cjs/react-query-persist-client/src/PersistQueryClientProvider.js +83 -0
  6. package/build/cjs/react-query-persist-client/src/PersistQueryClientProvider.js.map +1 -0
  7. package/build/cjs/react-query-persist-client/src/index.js +27 -0
  8. package/build/cjs/react-query-persist-client/src/index.js.map +1 -0
  9. package/build/{lib/index.mjs → cjs/react-query-persist-client/src/persist.js} +12 -89
  10. package/build/cjs/react-query-persist-client/src/persist.js.map +1 -0
  11. package/build/cjs/react-query-persist-client/src/retryStrategies.js +39 -0
  12. package/build/cjs/react-query-persist-client/src/retryStrategies.js.map +1 -0
  13. package/build/esm/index.js +492 -0
  14. package/build/esm/index.js.map +1 -0
  15. package/build/stats-html.html +2689 -0
  16. package/build/stats.json +217 -0
  17. package/build/types/packages/query-core/src/focusManager.d.ts +16 -0
  18. package/build/types/packages/query-core/src/hydration.d.ts +34 -0
  19. package/build/types/packages/query-core/src/index.d.ts +20 -0
  20. package/build/types/packages/query-core/src/infiniteQueryBehavior.d.ts +15 -0
  21. package/build/types/packages/query-core/src/infiniteQueryObserver.d.ts +18 -0
  22. package/build/types/packages/query-core/src/logger.d.ts +8 -0
  23. package/build/types/packages/query-core/src/mutation.d.ts +70 -0
  24. package/build/types/packages/query-core/src/mutationCache.d.ts +57 -0
  25. package/build/types/packages/query-core/src/mutationObserver.d.ts +23 -0
  26. package/build/types/packages/query-core/src/notifyManager.d.ts +18 -0
  27. package/build/types/packages/query-core/src/onlineManager.d.ts +16 -0
  28. package/build/types/packages/query-core/src/queriesObserver.d.ts +23 -0
  29. package/build/types/packages/query-core/src/query.d.ts +119 -0
  30. package/build/types/packages/query-core/src/queryCache.d.ts +64 -0
  31. package/build/types/packages/query-core/src/queryClient.d.ts +65 -0
  32. package/build/types/packages/query-core/src/queryObserver.d.ts +61 -0
  33. package/build/types/packages/query-core/src/removable.d.ts +9 -0
  34. package/build/types/packages/query-core/src/retryer.d.ts +33 -0
  35. package/build/types/packages/query-core/src/subscribable.d.ts +10 -0
  36. package/build/types/packages/query-core/src/types.d.ts +419 -0
  37. package/build/types/packages/query-core/src/utils.d.ts +99 -0
  38. package/build/types/packages/react-query/src/Hydrate.d.ts +10 -0
  39. package/build/types/packages/react-query/src/QueryClientProvider.d.ts +24 -0
  40. package/build/types/packages/react-query/src/QueryErrorResetBoundary.d.ts +12 -0
  41. package/build/types/packages/react-query/src/index.d.ts +17 -0
  42. package/build/types/packages/react-query/src/isRestoring.d.ts +3 -0
  43. package/build/types/packages/react-query/src/reactBatchedUpdates.d.ts +2 -0
  44. package/build/types/packages/react-query/src/setBatchUpdatesFn.d.ts +1 -0
  45. package/build/types/packages/react-query/src/types.d.ts +34 -0
  46. package/build/types/packages/react-query/src/useBaseQuery.d.ts +3 -0
  47. package/build/types/packages/react-query/src/useInfiniteQuery.d.ts +5 -0
  48. package/build/types/packages/react-query/src/useIsFetching.d.ts +7 -0
  49. package/build/types/packages/react-query/src/useIsMutating.d.ts +7 -0
  50. package/build/types/packages/react-query/src/useMutation.d.ts +6 -0
  51. package/build/types/packages/react-query/src/useQueries.d.ts +49 -0
  52. package/build/types/packages/react-query/src/useQuery.d.ts +23 -0
  53. package/build/types/packages/react-query/src/utils.d.ts +1 -0
  54. package/build/{lib → types/packages/react-query-persist-client/src}/PersistQueryClientProvider.d.ts +0 -0
  55. package/build/types/packages/react-query-persist-client/src/__tests__/PersistQueryClientProvider.test.d.ts +1 -0
  56. package/build/types/packages/react-query-persist-client/src/__tests__/persist.test.d.ts +1 -0
  57. package/build/{lib → types/packages/react-query-persist-client/src}/index.d.ts +0 -0
  58. package/build/{lib → types/packages/react-query-persist-client/src}/persist.d.ts +0 -0
  59. package/build/{lib → types/packages/react-query-persist-client/src}/retryStrategies.d.ts +0 -0
  60. package/build/types/tests/utils.d.ts +24 -0
  61. package/build/umd/index.development.js +303 -6
  62. package/build/umd/index.development.js.map +1 -1
  63. package/build/umd/index.production.js +11 -1
  64. package/build/umd/index.production.js.map +1 -1
  65. package/package.json +7 -20
  66. package/build/lib/index.js +0 -225
  67. package/build/lib/index.js.map +0 -1
  68. package/build/lib/index.mjs.map +0 -1
@@ -0,0 +1,492 @@
1
+ /**
2
+ * react-query-persist-client
3
+ *
4
+ * Copyright (c) TanStack
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import * as React from 'react';
12
+ import { QueryClientProvider, IsRestoringProvider } from '@tanstack/react-query';
13
+
14
+ /**
15
+ * query-core
16
+ *
17
+ * Copyright (c) TanStack
18
+ *
19
+ * This source code is licensed under the MIT license found in the
20
+ * LICENSE.md file in the root directory of this source tree.
21
+ *
22
+ * @license MIT
23
+ */
24
+ class Subscribable {
25
+ constructor() {
26
+ this.listeners = [];
27
+ this.subscribe = this.subscribe.bind(this);
28
+ }
29
+
30
+ subscribe(listener) {
31
+ this.listeners.push(listener);
32
+ this.onSubscribe();
33
+ return () => {
34
+ this.listeners = this.listeners.filter(x => x !== listener);
35
+ this.onUnsubscribe();
36
+ };
37
+ }
38
+
39
+ hasListeners() {
40
+ return this.listeners.length > 0;
41
+ }
42
+
43
+ onSubscribe() {// Do nothing
44
+ }
45
+
46
+ onUnsubscribe() {// Do nothing
47
+ }
48
+
49
+ }
50
+
51
+ // TYPES
52
+ // UTILS
53
+ const isServer = typeof window === 'undefined';
54
+
55
+ class FocusManager extends Subscribable {
56
+ constructor() {
57
+ super();
58
+
59
+ this.setup = onFocus => {
60
+ // addEventListener does not exist in React Native, but window does
61
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
62
+ if (!isServer && window.addEventListener) {
63
+ const listener = () => onFocus(); // Listen to visibillitychange and focus
64
+
65
+
66
+ window.addEventListener('visibilitychange', listener, false);
67
+ window.addEventListener('focus', listener, false);
68
+ return () => {
69
+ // Be sure to unsubscribe if a new handler is set
70
+ window.removeEventListener('visibilitychange', listener);
71
+ window.removeEventListener('focus', listener);
72
+ };
73
+ }
74
+ };
75
+ }
76
+
77
+ onSubscribe() {
78
+ if (!this.cleanup) {
79
+ this.setEventListener(this.setup);
80
+ }
81
+ }
82
+
83
+ onUnsubscribe() {
84
+ if (!this.hasListeners()) {
85
+ var _this$cleanup;
86
+
87
+ (_this$cleanup = this.cleanup) == null ? void 0 : _this$cleanup.call(this);
88
+ this.cleanup = undefined;
89
+ }
90
+ }
91
+
92
+ setEventListener(setup) {
93
+ var _this$cleanup2;
94
+
95
+ this.setup = setup;
96
+ (_this$cleanup2 = this.cleanup) == null ? void 0 : _this$cleanup2.call(this);
97
+ this.cleanup = setup(focused => {
98
+ if (typeof focused === 'boolean') {
99
+ this.setFocused(focused);
100
+ } else {
101
+ this.onFocus();
102
+ }
103
+ });
104
+ }
105
+
106
+ setFocused(focused) {
107
+ this.focused = focused;
108
+
109
+ if (focused) {
110
+ this.onFocus();
111
+ }
112
+ }
113
+
114
+ onFocus() {
115
+ this.listeners.forEach(listener => {
116
+ listener();
117
+ });
118
+ }
119
+
120
+ isFocused() {
121
+ if (typeof this.focused === 'boolean') {
122
+ return this.focused;
123
+ } // document global can be unavailable in react native
124
+
125
+
126
+ if (typeof document === 'undefined') {
127
+ return true;
128
+ }
129
+
130
+ return [undefined, 'visible', 'prerender'].includes(document.visibilityState);
131
+ }
132
+
133
+ }
134
+ new FocusManager();
135
+
136
+ class OnlineManager extends Subscribable {
137
+ constructor() {
138
+ super();
139
+
140
+ this.setup = onOnline => {
141
+ // addEventListener does not exist in React Native, but window does
142
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
143
+ if (!isServer && window.addEventListener) {
144
+ const listener = () => onOnline(); // Listen to online
145
+
146
+
147
+ window.addEventListener('online', listener, false);
148
+ window.addEventListener('offline', listener, false);
149
+ return () => {
150
+ // Be sure to unsubscribe if a new handler is set
151
+ window.removeEventListener('online', listener);
152
+ window.removeEventListener('offline', listener);
153
+ };
154
+ }
155
+ };
156
+ }
157
+
158
+ onSubscribe() {
159
+ if (!this.cleanup) {
160
+ this.setEventListener(this.setup);
161
+ }
162
+ }
163
+
164
+ onUnsubscribe() {
165
+ if (!this.hasListeners()) {
166
+ var _this$cleanup;
167
+
168
+ (_this$cleanup = this.cleanup) == null ? void 0 : _this$cleanup.call(this);
169
+ this.cleanup = undefined;
170
+ }
171
+ }
172
+
173
+ setEventListener(setup) {
174
+ var _this$cleanup2;
175
+
176
+ this.setup = setup;
177
+ (_this$cleanup2 = this.cleanup) == null ? void 0 : _this$cleanup2.call(this);
178
+ this.cleanup = setup(online => {
179
+ if (typeof online === 'boolean') {
180
+ this.setOnline(online);
181
+ } else {
182
+ this.onOnline();
183
+ }
184
+ });
185
+ }
186
+
187
+ setOnline(online) {
188
+ this.online = online;
189
+
190
+ if (online) {
191
+ this.onOnline();
192
+ }
193
+ }
194
+
195
+ onOnline() {
196
+ this.listeners.forEach(listener => {
197
+ listener();
198
+ });
199
+ }
200
+
201
+ isOnline() {
202
+ if (typeof this.online === 'boolean') {
203
+ return this.online;
204
+ }
205
+
206
+ if (typeof navigator === 'undefined' || typeof navigator.onLine === 'undefined') {
207
+ return true;
208
+ }
209
+
210
+ return navigator.onLine;
211
+ }
212
+
213
+ }
214
+ new OnlineManager();
215
+
216
+ // TYPES
217
+ // FUNCTIONS
218
+ function dehydrateMutation(mutation) {
219
+ return {
220
+ mutationKey: mutation.options.mutationKey,
221
+ state: mutation.state
222
+ };
223
+ } // Most config is not dehydrated but instead meant to configure again when
224
+ // consuming the de/rehydrated data, typically with useQuery on the client.
225
+ // Sometimes it might make sense to prefetch data on the server and include
226
+ // in the html-payload, but not consume it on the initial render.
227
+
228
+
229
+ function dehydrateQuery(query) {
230
+ return {
231
+ state: query.state,
232
+ queryKey: query.queryKey,
233
+ queryHash: query.queryHash
234
+ };
235
+ }
236
+
237
+ function defaultShouldDehydrateMutation(mutation) {
238
+ return mutation.state.isPaused;
239
+ }
240
+
241
+ function defaultShouldDehydrateQuery(query) {
242
+ return query.state.status === 'success';
243
+ }
244
+
245
+ function dehydrate(client, options = {}) {
246
+ const mutations = [];
247
+ const queries = [];
248
+
249
+ if (options.dehydrateMutations !== false) {
250
+ const shouldDehydrateMutation = options.shouldDehydrateMutation || defaultShouldDehydrateMutation;
251
+ client.getMutationCache().getAll().forEach(mutation => {
252
+ if (shouldDehydrateMutation(mutation)) {
253
+ mutations.push(dehydrateMutation(mutation));
254
+ }
255
+ });
256
+ }
257
+
258
+ if (options.dehydrateQueries !== false) {
259
+ const shouldDehydrateQuery = options.shouldDehydrateQuery || defaultShouldDehydrateQuery;
260
+ client.getQueryCache().getAll().forEach(query => {
261
+ if (shouldDehydrateQuery(query)) {
262
+ queries.push(dehydrateQuery(query));
263
+ }
264
+ });
265
+ }
266
+
267
+ return {
268
+ mutations,
269
+ queries
270
+ };
271
+ }
272
+ function hydrate(client, dehydratedState, options) {
273
+ if (typeof dehydratedState !== 'object' || dehydratedState === null) {
274
+ return;
275
+ }
276
+
277
+ const mutationCache = client.getMutationCache();
278
+ const queryCache = client.getQueryCache(); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
279
+
280
+ const mutations = dehydratedState.mutations || []; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
281
+
282
+ const queries = dehydratedState.queries || [];
283
+ mutations.forEach(dehydratedMutation => {
284
+ var _options$defaultOptio;
285
+
286
+ mutationCache.build(client, { ...(options == null ? void 0 : (_options$defaultOptio = options.defaultOptions) == null ? void 0 : _options$defaultOptio.mutations),
287
+ mutationKey: dehydratedMutation.mutationKey
288
+ }, dehydratedMutation.state);
289
+ });
290
+ queries.forEach(dehydratedQuery => {
291
+ var _options$defaultOptio2;
292
+
293
+ const query = queryCache.get(dehydratedQuery.queryHash); // Do not hydrate if an existing query exists with newer data
294
+
295
+ if (query) {
296
+ if (query.state.dataUpdatedAt < dehydratedQuery.state.dataUpdatedAt) {
297
+ query.setState(dehydratedQuery.state);
298
+ }
299
+
300
+ return;
301
+ } // Restore query
302
+
303
+
304
+ queryCache.build(client, { ...(options == null ? void 0 : (_options$defaultOptio2 = options.defaultOptions) == null ? void 0 : _options$defaultOptio2.queries),
305
+ queryKey: dehydratedQuery.queryKey,
306
+ queryHash: dehydratedQuery.queryHash
307
+ }, dehydratedQuery.state);
308
+ });
309
+ }
310
+
311
+ /**
312
+ * Restores persisted data to the QueryCache
313
+ * - data obtained from persister.restoreClient
314
+ * - data is hydrated using hydrateOptions
315
+ * If data is expired, busted, empty, or throws, it runs persister.removeClient
316
+ */
317
+ async function persistQueryClientRestore({
318
+ queryClient,
319
+ persister,
320
+ maxAge = 1000 * 60 * 60 * 24,
321
+ buster = '',
322
+ hydrateOptions
323
+ }) {
324
+ try {
325
+ const persistedClient = await persister.restoreClient();
326
+
327
+ if (persistedClient) {
328
+ if (persistedClient.timestamp) {
329
+ const expired = Date.now() - persistedClient.timestamp > maxAge;
330
+ const busted = persistedClient.buster !== buster;
331
+
332
+ if (expired || busted) {
333
+ persister.removeClient();
334
+ } else {
335
+ hydrate(queryClient, persistedClient.clientState, hydrateOptions);
336
+ }
337
+ } else {
338
+ persister.removeClient();
339
+ }
340
+ }
341
+ } catch (err) {
342
+ if (process.env.NODE_ENV !== 'production') {
343
+ queryClient.getLogger().error(err);
344
+ queryClient.getLogger().warn('Encountered an error attempting to restore client cache from persisted location. As a precaution, the persisted cache will be discarded.');
345
+ }
346
+
347
+ persister.removeClient();
348
+ }
349
+ }
350
+ /**
351
+ * Persists data from the QueryCache
352
+ * - data dehydrated using dehydrateOptions
353
+ * - data is persisted using persister.persistClient
354
+ */
355
+
356
+ async function persistQueryClientSave({
357
+ queryClient,
358
+ persister,
359
+ buster = '',
360
+ dehydrateOptions
361
+ }) {
362
+ const persistClient = {
363
+ buster,
364
+ timestamp: Date.now(),
365
+ clientState: dehydrate(queryClient, dehydrateOptions)
366
+ };
367
+ await persister.persistClient(persistClient);
368
+ }
369
+ /**
370
+ * Subscribe to QueryCache and MutationCache updates (for persisting)
371
+ * @returns an unsubscribe function (to discontinue monitoring)
372
+ */
373
+
374
+ function persistQueryClientSubscribe(props) {
375
+ const unsubscribeQueryCache = props.queryClient.getQueryCache().subscribe(() => {
376
+ persistQueryClientSave(props);
377
+ });
378
+ const unusbscribeMutationCache = props.queryClient.getMutationCache().subscribe(() => {
379
+ persistQueryClientSave(props);
380
+ });
381
+ return () => {
382
+ unsubscribeQueryCache();
383
+ unusbscribeMutationCache();
384
+ };
385
+ }
386
+ /**
387
+ * Restores persisted data to QueryCache and persists further changes.
388
+ */
389
+
390
+ function persistQueryClient(props) {
391
+ let hasUnsubscribed = false;
392
+ let persistQueryClientUnsubscribe;
393
+
394
+ const unsubscribe = () => {
395
+ hasUnsubscribed = true;
396
+ persistQueryClientUnsubscribe == null ? void 0 : persistQueryClientUnsubscribe();
397
+ }; // Attempt restore
398
+
399
+
400
+ const restorePromise = persistQueryClientRestore(props).then(() => {
401
+ if (!hasUnsubscribed) {
402
+ // Subscribe to changes in the query cache to trigger the save
403
+ persistQueryClientUnsubscribe = persistQueryClientSubscribe(props);
404
+ }
405
+ });
406
+ return [unsubscribe, restorePromise];
407
+ }
408
+
409
+ function _extends() {
410
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
411
+ for (var i = 1; i < arguments.length; i++) {
412
+ var source = arguments[i];
413
+
414
+ for (var key in source) {
415
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
416
+ target[key] = source[key];
417
+ }
418
+ }
419
+ }
420
+
421
+ return target;
422
+ };
423
+ return _extends.apply(this, arguments);
424
+ }
425
+
426
+ const PersistQueryClientProvider = ({
427
+ client,
428
+ children,
429
+ persistOptions,
430
+ onSuccess,
431
+ ...props
432
+ }) => {
433
+ const [isRestoring, setIsRestoring] = React.useState(true);
434
+ const refs = React.useRef({
435
+ persistOptions,
436
+ onSuccess
437
+ });
438
+ React.useEffect(() => {
439
+ refs.current = {
440
+ persistOptions,
441
+ onSuccess
442
+ };
443
+ });
444
+ React.useEffect(() => {
445
+ let isStale = false;
446
+ setIsRestoring(true);
447
+ const [unsubscribe, promise] = persistQueryClient({ ...refs.current.persistOptions,
448
+ queryClient: client
449
+ });
450
+ promise.then(() => {
451
+ if (!isStale) {
452
+ refs.current.onSuccess == null ? void 0 : refs.current.onSuccess();
453
+ setIsRestoring(false);
454
+ }
455
+ });
456
+ return () => {
457
+ isStale = true;
458
+ unsubscribe();
459
+ };
460
+ }, [client]);
461
+ return /*#__PURE__*/React.createElement(QueryClientProvider, _extends({
462
+ client: client
463
+ }, props), /*#__PURE__*/React.createElement(IsRestoringProvider, {
464
+ value: isRestoring
465
+ }, children));
466
+ };
467
+
468
+ const removeOldestQuery = ({
469
+ persistedClient
470
+ }) => {
471
+ const mutations = [...persistedClient.clientState.mutations];
472
+ const queries = [...persistedClient.clientState.queries];
473
+ const client = { ...persistedClient,
474
+ clientState: {
475
+ mutations,
476
+ queries
477
+ }
478
+ }; // sort queries by dataUpdatedAt (oldest first)
479
+
480
+ const sortedQueries = [...queries].sort((a, b) => a.state.dataUpdatedAt - b.state.dataUpdatedAt); // clean oldest query
481
+
482
+ if (sortedQueries.length > 0) {
483
+ const oldestData = sortedQueries.shift();
484
+ client.clientState.queries = queries.filter(q => q !== oldestData);
485
+ return client;
486
+ }
487
+
488
+ return undefined;
489
+ };
490
+
491
+ export { PersistQueryClientProvider, persistQueryClient, persistQueryClientRestore, persistQueryClientSave, persistQueryClientSubscribe, removeOldestQuery };
492
+ //# sourceMappingURL=index.js.map