floppy-disk 2.6.0 → 2.7.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.
@@ -158,6 +158,17 @@ export type CreateQueryOptions<TKey extends StoreKey = StoreKey, TResponse = any
158
158
  * - If set to `"always"`, the query will be called on window focus.
159
159
  */
160
160
  fetchOnWindowFocus?: boolean | 'always' | ((key: TKey) => boolean | 'always');
161
+ /**
162
+ * Defaults to follow the value of `fetchOnMount`.
163
+ *
164
+ * `fetchOnMount` and `fetchOnReconnect` can be set to different values.
165
+ * However, if `fetchOnReconnect` is not explicitly set, it will mimic the value of `fetchOnMount`.
166
+ *
167
+ * - If set to `true`, the query will be called on window focus **if the data is stale**.
168
+ * - If set to `false`, the query won't be called on window focus.
169
+ * - If set to `"always"`, the query will be called on window focus.
170
+ */
171
+ fetchOnReconnect?: boolean | 'always' | ((key: TKey) => boolean | 'always');
161
172
  /**
162
173
  * If set to `false` or return `false`, the query won't be called in any condition.
163
174
  * Auto fetch on mount will be disabled.
@@ -1,6 +1,6 @@
1
1
  import { h as createElement } from 'preact';
2
2
  import { useState } from 'preact/hooks';
3
- import { getValueOrComputedValue, hasValue, identityFn, noop } from '../utils';
3
+ import { getValueOrComputedValue, hasValue, identityFn, isClient, noop } from '../utils';
4
4
  import { createStores } from './create-stores';
5
5
  const INITIAL_QUERY_STATE = {
6
6
  isWaiting: false,
@@ -37,8 +37,9 @@ const useQueryDefaultDeps = (state) => [
37
37
  */
38
38
  export const createQuery = (queryFn, options = {}) => {
39
39
  const defaultFetchOnWindowFocus = options.fetchOnMount ?? true;
40
+ const defaultFetchOnReconnect = options.fetchOnMount ?? true;
40
41
  const { onFirstSubscribe = noop, onSubscribe = noop, onLastUnsubscribe = noop, onBeforeChangeKey = noop, defaultDeps = useQueryDefaultDeps, select = identityFn, staleTime = 3000, // 3 seconds
41
- fetchOnMount = true, fetchOnWindowFocus = defaultFetchOnWindowFocus, enabled = true, retry = 1, retryDelay = 2000, // 2 seconds
42
+ fetchOnMount = true, fetchOnWindowFocus = defaultFetchOnWindowFocus, fetchOnReconnect = defaultFetchOnReconnect, enabled = true, retry = 1, retryDelay = 2000, // 2 seconds
42
43
  keepPreviousData, getNextPageParam = () => undefined, onBeforeFetch = noop, onSuccess = noop, onError = noop, onSettled = noop, cacheTime = 5 * 60 * 1000, refetchInterval = false, ...createStoresOptions } = options;
43
44
  const retryTimeoutId = new Map();
44
45
  const retryNextPageTimeoutId = new Map();
@@ -119,8 +120,7 @@ export const createQuery = (queryFn, options = {}) => {
119
120
  pageParams: newPageParams,
120
121
  hasNextPage: hasValue(newPageParam),
121
122
  };
122
- const refetchIntervalValue = typeof window !== 'undefined' &&
123
- getValueOrComputedValue(refetchInterval, { ...get(), ...nextState });
123
+ const refetchIntervalValue = isClient && getValueOrComputedValue(refetchInterval, { ...get(), ...nextState });
124
124
  if (refetchIntervalValue) {
125
125
  refetchIntervalTimeoutId.set(keyHash, window.setTimeout(() => {
126
126
  forceFetch();
@@ -161,7 +161,7 @@ export const createQuery = (queryFn, options = {}) => {
161
161
  pageParam,
162
162
  hasNextPage: hasValue(pageParam),
163
163
  });
164
- if (shouldRetry && typeof window !== 'undefined') {
164
+ if (shouldRetry && isClient) {
165
165
  retryTimeoutId.set(keyHash, window.setTimeout(() => {
166
166
  set({ retryCount: prevState.retryCount + 1 });
167
167
  callQuery();
@@ -252,7 +252,7 @@ export const createQuery = (queryFn, options = {}) => {
252
252
  optimisticUpdate: (response) => useQuery.optimisticUpdate({ key, response }),
253
253
  };
254
254
  }, (() => {
255
- const fetchWindowFocusHandler = () => {
255
+ const windowFocusHandler = () => {
256
256
  useQuery.getAllWithSubscriber().forEach((state) => {
257
257
  const result = getValueOrComputedValue(fetchOnWindowFocus, state.key);
258
258
  if (result === 'always')
@@ -261,20 +261,32 @@ export const createQuery = (queryFn, options = {}) => {
261
261
  state.fetch();
262
262
  });
263
263
  };
264
+ const reconnectHandler = () => {
265
+ useQuery.getAllWithSubscriber().forEach((state) => {
266
+ const result = getValueOrComputedValue(fetchOnReconnect, state.key);
267
+ if (result === 'always')
268
+ state.forceFetch();
269
+ else if (result)
270
+ state.fetch();
271
+ });
272
+ };
264
273
  return {
265
274
  ...createStoresOptions,
266
275
  defaultDeps,
267
276
  onFirstSubscribe: (state) => {
268
277
  if (state.isSuccess) {
269
- const refetchIntervalValue = typeof window !== 'undefined' && getValueOrComputedValue(refetchInterval, state);
278
+ const refetchIntervalValue = isClient && getValueOrComputedValue(refetchInterval, state);
270
279
  if (refetchIntervalValue) {
271
280
  refetchIntervalTimeoutId.set(state.keyHash, window.setTimeout(() => {
272
281
  state.forceFetch();
273
282
  }, refetchIntervalValue));
274
283
  }
275
284
  }
276
- if (typeof window !== 'undefined' && fetchOnWindowFocus) {
277
- window.addEventListener('focus', fetchWindowFocusHandler);
285
+ if (isClient) {
286
+ if (fetchOnWindowFocus)
287
+ window.addEventListener('focus', windowFocusHandler);
288
+ if (fetchOnReconnect)
289
+ window.addEventListener('online', reconnectHandler);
278
290
  }
279
291
  clearTimeout(resetTimeoutId.get(state.keyHash));
280
292
  onFirstSubscribe(state);
@@ -288,14 +300,18 @@ export const createQuery = (queryFn, options = {}) => {
288
300
  onSubscribe(state);
289
301
  },
290
302
  onLastUnsubscribe: (state) => {
291
- if (typeof window !== 'undefined' && fetchOnWindowFocus) {
292
- window.removeEventListener('focus', fetchWindowFocusHandler);
303
+ const totalSubs = useQuery.getAllWithSubscriber().length;
304
+ if (isClient && totalSubs === 0) {
305
+ if (fetchOnWindowFocus)
306
+ window.removeEventListener('focus', windowFocusHandler);
307
+ if (fetchOnReconnect)
308
+ window.removeEventListener('online', reconnectHandler);
293
309
  }
294
310
  useQuery.set(state.key, { retryCount: 0, retryNextPageCount: 0 }, true);
295
311
  clearTimeout(retryTimeoutId.get(state.keyHash));
296
312
  clearTimeout(retryNextPageTimeoutId.get(state.keyHash));
297
313
  clearTimeout(refetchIntervalTimeoutId.get(state.keyHash));
298
- if (typeof window !== 'undefined' && cacheTime !== Infinity) {
314
+ if (isClient && cacheTime !== Infinity) {
299
315
  resetTimeoutId.set(state.keyHash, window.setTimeout(() => {
300
316
  useQuery.set(state.key, INITIAL_QUERY_STATE);
301
317
  }, cacheTime));
@@ -157,6 +157,17 @@ export type CreateQueryOptions<TKey extends StoreKey = StoreKey, TResponse = any
157
157
  * - If set to `"always"`, the query will be called on window focus.
158
158
  */
159
159
  fetchOnWindowFocus?: boolean | 'always' | ((key: TKey) => boolean | 'always');
160
+ /**
161
+ * Defaults to follow the value of `fetchOnMount`.
162
+ *
163
+ * `fetchOnMount` and `fetchOnReconnect` can be set to different values.
164
+ * However, if `fetchOnReconnect` is not explicitly set, it will mimic the value of `fetchOnMount`.
165
+ *
166
+ * - If set to `true`, the query will be called on window focus **if the data is stale**.
167
+ * - If set to `false`, the query won't be called on window focus.
168
+ * - If set to `"always"`, the query will be called on window focus.
169
+ */
170
+ fetchOnReconnect?: boolean | 'always' | ((key: TKey) => boolean | 'always');
160
171
  /**
161
172
  * If set to `false` or return `false`, the query won't be called in any condition.
162
173
  * Auto fetch on mount will be disabled.
@@ -1,5 +1,5 @@
1
1
  import { createElement, useState } from 'react';
2
- import { getValueOrComputedValue, hasValue, identityFn, noop } from '../utils';
2
+ import { getValueOrComputedValue, hasValue, identityFn, isClient, noop } from '../utils';
3
3
  import { createStores } from './create-stores';
4
4
  const INITIAL_QUERY_STATE = {
5
5
  isWaiting: false,
@@ -36,8 +36,9 @@ const useQueryDefaultDeps = (state) => [
36
36
  */
37
37
  export const createQuery = (queryFn, options = {}) => {
38
38
  const defaultFetchOnWindowFocus = options.fetchOnMount ?? true;
39
+ const defaultFetchOnReconnect = options.fetchOnMount ?? true;
39
40
  const { onFirstSubscribe = noop, onSubscribe = noop, onLastUnsubscribe = noop, onBeforeChangeKey = noop, defaultDeps = useQueryDefaultDeps, select = identityFn, staleTime = 3000, // 3 seconds
40
- fetchOnMount = true, fetchOnWindowFocus = defaultFetchOnWindowFocus, enabled = true, retry = 1, retryDelay = 2000, // 2 seconds
41
+ fetchOnMount = true, fetchOnWindowFocus = defaultFetchOnWindowFocus, fetchOnReconnect = defaultFetchOnReconnect, enabled = true, retry = 1, retryDelay = 2000, // 2 seconds
41
42
  keepPreviousData, getNextPageParam = () => undefined, onBeforeFetch = noop, onSuccess = noop, onError = noop, onSettled = noop, cacheTime = 5 * 60 * 1000, refetchInterval = false, ...createStoresOptions } = options;
42
43
  const retryTimeoutId = new Map();
43
44
  const retryNextPageTimeoutId = new Map();
@@ -118,8 +119,7 @@ export const createQuery = (queryFn, options = {}) => {
118
119
  pageParams: newPageParams,
119
120
  hasNextPage: hasValue(newPageParam),
120
121
  };
121
- const refetchIntervalValue = typeof window !== 'undefined' &&
122
- getValueOrComputedValue(refetchInterval, { ...get(), ...nextState });
122
+ const refetchIntervalValue = isClient && getValueOrComputedValue(refetchInterval, { ...get(), ...nextState });
123
123
  if (refetchIntervalValue) {
124
124
  refetchIntervalTimeoutId.set(keyHash, window.setTimeout(() => {
125
125
  forceFetch();
@@ -160,7 +160,7 @@ export const createQuery = (queryFn, options = {}) => {
160
160
  pageParam,
161
161
  hasNextPage: hasValue(pageParam),
162
162
  });
163
- if (shouldRetry && typeof window !== 'undefined') {
163
+ if (shouldRetry && isClient) {
164
164
  retryTimeoutId.set(keyHash, window.setTimeout(() => {
165
165
  set({ retryCount: prevState.retryCount + 1 });
166
166
  callQuery();
@@ -251,7 +251,7 @@ export const createQuery = (queryFn, options = {}) => {
251
251
  optimisticUpdate: (response) => useQuery.optimisticUpdate({ key, response }),
252
252
  };
253
253
  }, (() => {
254
- const fetchWindowFocusHandler = () => {
254
+ const windowFocusHandler = () => {
255
255
  useQuery.getAllWithSubscriber().forEach((state) => {
256
256
  const result = getValueOrComputedValue(fetchOnWindowFocus, state.key);
257
257
  if (result === 'always')
@@ -260,20 +260,32 @@ export const createQuery = (queryFn, options = {}) => {
260
260
  state.fetch();
261
261
  });
262
262
  };
263
+ const reconnectHandler = () => {
264
+ useQuery.getAllWithSubscriber().forEach((state) => {
265
+ const result = getValueOrComputedValue(fetchOnReconnect, state.key);
266
+ if (result === 'always')
267
+ state.forceFetch();
268
+ else if (result)
269
+ state.fetch();
270
+ });
271
+ };
263
272
  return {
264
273
  ...createStoresOptions,
265
274
  defaultDeps,
266
275
  onFirstSubscribe: (state) => {
267
276
  if (state.isSuccess) {
268
- const refetchIntervalValue = typeof window !== 'undefined' && getValueOrComputedValue(refetchInterval, state);
277
+ const refetchIntervalValue = isClient && getValueOrComputedValue(refetchInterval, state);
269
278
  if (refetchIntervalValue) {
270
279
  refetchIntervalTimeoutId.set(state.keyHash, window.setTimeout(() => {
271
280
  state.forceFetch();
272
281
  }, refetchIntervalValue));
273
282
  }
274
283
  }
275
- if (typeof window !== 'undefined' && fetchOnWindowFocus) {
276
- window.addEventListener('focus', fetchWindowFocusHandler);
284
+ if (isClient) {
285
+ if (fetchOnWindowFocus)
286
+ window.addEventListener('focus', windowFocusHandler);
287
+ if (fetchOnReconnect)
288
+ window.addEventListener('online', reconnectHandler);
277
289
  }
278
290
  clearTimeout(resetTimeoutId.get(state.keyHash));
279
291
  onFirstSubscribe(state);
@@ -287,14 +299,18 @@ export const createQuery = (queryFn, options = {}) => {
287
299
  onSubscribe(state);
288
300
  },
289
301
  onLastUnsubscribe: (state) => {
290
- if (typeof window !== 'undefined' && fetchOnWindowFocus) {
291
- window.removeEventListener('focus', fetchWindowFocusHandler);
302
+ const totalSubs = useQuery.getAllWithSubscriber().length;
303
+ if (isClient && totalSubs === 0) {
304
+ if (fetchOnWindowFocus)
305
+ window.removeEventListener('focus', windowFocusHandler);
306
+ if (fetchOnReconnect)
307
+ window.removeEventListener('online', reconnectHandler);
292
308
  }
293
309
  useQuery.set(state.key, { retryCount: 0, retryNextPageCount: 0 }, true);
294
310
  clearTimeout(retryTimeoutId.get(state.keyHash));
295
311
  clearTimeout(retryNextPageTimeoutId.get(state.keyHash));
296
312
  clearTimeout(refetchIntervalTimeoutId.get(state.keyHash));
297
- if (typeof window !== 'undefined' && cacheTime !== Infinity) {
313
+ if (isClient && cacheTime !== Infinity) {
298
314
  resetTimeoutId.set(state.keyHash, window.setTimeout(() => {
299
315
  useQuery.set(state.key, INITIAL_QUERY_STATE);
300
316
  }, cacheTime));
@@ -4,3 +4,4 @@ export declare const hasValue: (value: any) => boolean;
4
4
  export declare const hashStoreKey: (obj?: any) => string;
5
5
  export declare const getValueOrComputedValue: <T, P extends any[]>(valueOrComputeValueFn: T | ((...params: P) => T), ...params: P) => T;
6
6
  export type Maybe<T> = T | null | undefined;
7
+ export declare const isClient: boolean;
@@ -8,3 +8,4 @@ export const getValueOrComputedValue = (valueOrComputeValueFn, ...params) => {
8
8
  }
9
9
  return valueOrComputeValueFn;
10
10
  };
11
+ export const isClient = typeof window !== 'undefined' && !('Deno' in window);
@@ -158,6 +158,17 @@ export type CreateQueryOptions<TKey extends StoreKey = StoreKey, TResponse = any
158
158
  * - If set to `"always"`, the query will be called on window focus.
159
159
  */
160
160
  fetchOnWindowFocus?: boolean | 'always' | ((key: TKey) => boolean | 'always');
161
+ /**
162
+ * Defaults to follow the value of `fetchOnMount`.
163
+ *
164
+ * `fetchOnMount` and `fetchOnReconnect` can be set to different values.
165
+ * However, if `fetchOnReconnect` is not explicitly set, it will mimic the value of `fetchOnMount`.
166
+ *
167
+ * - If set to `true`, the query will be called on window focus **if the data is stale**.
168
+ * - If set to `false`, the query won't be called on window focus.
169
+ * - If set to `"always"`, the query will be called on window focus.
170
+ */
171
+ fetchOnReconnect?: boolean | 'always' | ((key: TKey) => boolean | 'always');
161
172
  /**
162
173
  * If set to `false` or return `false`, the query won't be called in any condition.
163
174
  * Auto fetch on mount will be disabled.
@@ -40,8 +40,9 @@ const useQueryDefaultDeps = (state) => [
40
40
  */
41
41
  const createQuery = (queryFn, options = {}) => {
42
42
  const defaultFetchOnWindowFocus = options.fetchOnMount ?? true;
43
+ const defaultFetchOnReconnect = options.fetchOnMount ?? true;
43
44
  const { onFirstSubscribe = utils_1.noop, onSubscribe = utils_1.noop, onLastUnsubscribe = utils_1.noop, onBeforeChangeKey = utils_1.noop, defaultDeps = useQueryDefaultDeps, select = utils_1.identityFn, staleTime = 3000, // 3 seconds
44
- fetchOnMount = true, fetchOnWindowFocus = defaultFetchOnWindowFocus, enabled = true, retry = 1, retryDelay = 2000, // 2 seconds
45
+ fetchOnMount = true, fetchOnWindowFocus = defaultFetchOnWindowFocus, fetchOnReconnect = defaultFetchOnReconnect, enabled = true, retry = 1, retryDelay = 2000, // 2 seconds
45
46
  keepPreviousData, getNextPageParam = () => undefined, onBeforeFetch = utils_1.noop, onSuccess = utils_1.noop, onError = utils_1.noop, onSettled = utils_1.noop, cacheTime = 5 * 60 * 1000, refetchInterval = false, ...createStoresOptions } = options;
46
47
  const retryTimeoutId = new Map();
47
48
  const retryNextPageTimeoutId = new Map();
@@ -122,8 +123,7 @@ const createQuery = (queryFn, options = {}) => {
122
123
  pageParams: newPageParams,
123
124
  hasNextPage: (0, utils_1.hasValue)(newPageParam),
124
125
  };
125
- const refetchIntervalValue = typeof window !== 'undefined' &&
126
- (0, utils_1.getValueOrComputedValue)(refetchInterval, { ...get(), ...nextState });
126
+ const refetchIntervalValue = utils_1.isClient && (0, utils_1.getValueOrComputedValue)(refetchInterval, { ...get(), ...nextState });
127
127
  if (refetchIntervalValue) {
128
128
  refetchIntervalTimeoutId.set(keyHash, window.setTimeout(() => {
129
129
  forceFetch();
@@ -164,7 +164,7 @@ const createQuery = (queryFn, options = {}) => {
164
164
  pageParam,
165
165
  hasNextPage: (0, utils_1.hasValue)(pageParam),
166
166
  });
167
- if (shouldRetry && typeof window !== 'undefined') {
167
+ if (shouldRetry && utils_1.isClient) {
168
168
  retryTimeoutId.set(keyHash, window.setTimeout(() => {
169
169
  set({ retryCount: prevState.retryCount + 1 });
170
170
  callQuery();
@@ -255,7 +255,7 @@ const createQuery = (queryFn, options = {}) => {
255
255
  optimisticUpdate: (response) => useQuery.optimisticUpdate({ key, response }),
256
256
  };
257
257
  }, (() => {
258
- const fetchWindowFocusHandler = () => {
258
+ const windowFocusHandler = () => {
259
259
  useQuery.getAllWithSubscriber().forEach((state) => {
260
260
  const result = (0, utils_1.getValueOrComputedValue)(fetchOnWindowFocus, state.key);
261
261
  if (result === 'always')
@@ -264,20 +264,32 @@ const createQuery = (queryFn, options = {}) => {
264
264
  state.fetch();
265
265
  });
266
266
  };
267
+ const reconnectHandler = () => {
268
+ useQuery.getAllWithSubscriber().forEach((state) => {
269
+ const result = (0, utils_1.getValueOrComputedValue)(fetchOnReconnect, state.key);
270
+ if (result === 'always')
271
+ state.forceFetch();
272
+ else if (result)
273
+ state.fetch();
274
+ });
275
+ };
267
276
  return {
268
277
  ...createStoresOptions,
269
278
  defaultDeps,
270
279
  onFirstSubscribe: (state) => {
271
280
  if (state.isSuccess) {
272
- const refetchIntervalValue = typeof window !== 'undefined' && (0, utils_1.getValueOrComputedValue)(refetchInterval, state);
281
+ const refetchIntervalValue = utils_1.isClient && (0, utils_1.getValueOrComputedValue)(refetchInterval, state);
273
282
  if (refetchIntervalValue) {
274
283
  refetchIntervalTimeoutId.set(state.keyHash, window.setTimeout(() => {
275
284
  state.forceFetch();
276
285
  }, refetchIntervalValue));
277
286
  }
278
287
  }
279
- if (typeof window !== 'undefined' && fetchOnWindowFocus) {
280
- window.addEventListener('focus', fetchWindowFocusHandler);
288
+ if (utils_1.isClient) {
289
+ if (fetchOnWindowFocus)
290
+ window.addEventListener('focus', windowFocusHandler);
291
+ if (fetchOnReconnect)
292
+ window.addEventListener('online', reconnectHandler);
281
293
  }
282
294
  clearTimeout(resetTimeoutId.get(state.keyHash));
283
295
  onFirstSubscribe(state);
@@ -291,14 +303,18 @@ const createQuery = (queryFn, options = {}) => {
291
303
  onSubscribe(state);
292
304
  },
293
305
  onLastUnsubscribe: (state) => {
294
- if (typeof window !== 'undefined' && fetchOnWindowFocus) {
295
- window.removeEventListener('focus', fetchWindowFocusHandler);
306
+ const totalSubs = useQuery.getAllWithSubscriber().length;
307
+ if (utils_1.isClient && totalSubs === 0) {
308
+ if (fetchOnWindowFocus)
309
+ window.removeEventListener('focus', windowFocusHandler);
310
+ if (fetchOnReconnect)
311
+ window.removeEventListener('online', reconnectHandler);
296
312
  }
297
313
  useQuery.set(state.key, { retryCount: 0, retryNextPageCount: 0 }, true);
298
314
  clearTimeout(retryTimeoutId.get(state.keyHash));
299
315
  clearTimeout(retryNextPageTimeoutId.get(state.keyHash));
300
316
  clearTimeout(refetchIntervalTimeoutId.get(state.keyHash));
301
- if (typeof window !== 'undefined' && cacheTime !== Infinity) {
317
+ if (utils_1.isClient && cacheTime !== Infinity) {
302
318
  resetTimeoutId.set(state.keyHash, window.setTimeout(() => {
303
319
  useQuery.set(state.key, INITIAL_QUERY_STATE);
304
320
  }, cacheTime));
@@ -157,6 +157,17 @@ export type CreateQueryOptions<TKey extends StoreKey = StoreKey, TResponse = any
157
157
  * - If set to `"always"`, the query will be called on window focus.
158
158
  */
159
159
  fetchOnWindowFocus?: boolean | 'always' | ((key: TKey) => boolean | 'always');
160
+ /**
161
+ * Defaults to follow the value of `fetchOnMount`.
162
+ *
163
+ * `fetchOnMount` and `fetchOnReconnect` can be set to different values.
164
+ * However, if `fetchOnReconnect` is not explicitly set, it will mimic the value of `fetchOnMount`.
165
+ *
166
+ * - If set to `true`, the query will be called on window focus **if the data is stale**.
167
+ * - If set to `false`, the query won't be called on window focus.
168
+ * - If set to `"always"`, the query will be called on window focus.
169
+ */
170
+ fetchOnReconnect?: boolean | 'always' | ((key: TKey) => boolean | 'always');
160
171
  /**
161
172
  * If set to `false` or return `false`, the query won't be called in any condition.
162
173
  * Auto fetch on mount will be disabled.
@@ -39,8 +39,9 @@ const useQueryDefaultDeps = (state) => [
39
39
  */
40
40
  const createQuery = (queryFn, options = {}) => {
41
41
  const defaultFetchOnWindowFocus = options.fetchOnMount ?? true;
42
+ const defaultFetchOnReconnect = options.fetchOnMount ?? true;
42
43
  const { onFirstSubscribe = utils_1.noop, onSubscribe = utils_1.noop, onLastUnsubscribe = utils_1.noop, onBeforeChangeKey = utils_1.noop, defaultDeps = useQueryDefaultDeps, select = utils_1.identityFn, staleTime = 3000, // 3 seconds
43
- fetchOnMount = true, fetchOnWindowFocus = defaultFetchOnWindowFocus, enabled = true, retry = 1, retryDelay = 2000, // 2 seconds
44
+ fetchOnMount = true, fetchOnWindowFocus = defaultFetchOnWindowFocus, fetchOnReconnect = defaultFetchOnReconnect, enabled = true, retry = 1, retryDelay = 2000, // 2 seconds
44
45
  keepPreviousData, getNextPageParam = () => undefined, onBeforeFetch = utils_1.noop, onSuccess = utils_1.noop, onError = utils_1.noop, onSettled = utils_1.noop, cacheTime = 5 * 60 * 1000, refetchInterval = false, ...createStoresOptions } = options;
45
46
  const retryTimeoutId = new Map();
46
47
  const retryNextPageTimeoutId = new Map();
@@ -121,8 +122,7 @@ const createQuery = (queryFn, options = {}) => {
121
122
  pageParams: newPageParams,
122
123
  hasNextPage: (0, utils_1.hasValue)(newPageParam),
123
124
  };
124
- const refetchIntervalValue = typeof window !== 'undefined' &&
125
- (0, utils_1.getValueOrComputedValue)(refetchInterval, { ...get(), ...nextState });
125
+ const refetchIntervalValue = utils_1.isClient && (0, utils_1.getValueOrComputedValue)(refetchInterval, { ...get(), ...nextState });
126
126
  if (refetchIntervalValue) {
127
127
  refetchIntervalTimeoutId.set(keyHash, window.setTimeout(() => {
128
128
  forceFetch();
@@ -163,7 +163,7 @@ const createQuery = (queryFn, options = {}) => {
163
163
  pageParam,
164
164
  hasNextPage: (0, utils_1.hasValue)(pageParam),
165
165
  });
166
- if (shouldRetry && typeof window !== 'undefined') {
166
+ if (shouldRetry && utils_1.isClient) {
167
167
  retryTimeoutId.set(keyHash, window.setTimeout(() => {
168
168
  set({ retryCount: prevState.retryCount + 1 });
169
169
  callQuery();
@@ -254,7 +254,7 @@ const createQuery = (queryFn, options = {}) => {
254
254
  optimisticUpdate: (response) => useQuery.optimisticUpdate({ key, response }),
255
255
  };
256
256
  }, (() => {
257
- const fetchWindowFocusHandler = () => {
257
+ const windowFocusHandler = () => {
258
258
  useQuery.getAllWithSubscriber().forEach((state) => {
259
259
  const result = (0, utils_1.getValueOrComputedValue)(fetchOnWindowFocus, state.key);
260
260
  if (result === 'always')
@@ -263,20 +263,32 @@ const createQuery = (queryFn, options = {}) => {
263
263
  state.fetch();
264
264
  });
265
265
  };
266
+ const reconnectHandler = () => {
267
+ useQuery.getAllWithSubscriber().forEach((state) => {
268
+ const result = (0, utils_1.getValueOrComputedValue)(fetchOnReconnect, state.key);
269
+ if (result === 'always')
270
+ state.forceFetch();
271
+ else if (result)
272
+ state.fetch();
273
+ });
274
+ };
266
275
  return {
267
276
  ...createStoresOptions,
268
277
  defaultDeps,
269
278
  onFirstSubscribe: (state) => {
270
279
  if (state.isSuccess) {
271
- const refetchIntervalValue = typeof window !== 'undefined' && (0, utils_1.getValueOrComputedValue)(refetchInterval, state);
280
+ const refetchIntervalValue = utils_1.isClient && (0, utils_1.getValueOrComputedValue)(refetchInterval, state);
272
281
  if (refetchIntervalValue) {
273
282
  refetchIntervalTimeoutId.set(state.keyHash, window.setTimeout(() => {
274
283
  state.forceFetch();
275
284
  }, refetchIntervalValue));
276
285
  }
277
286
  }
278
- if (typeof window !== 'undefined' && fetchOnWindowFocus) {
279
- window.addEventListener('focus', fetchWindowFocusHandler);
287
+ if (utils_1.isClient) {
288
+ if (fetchOnWindowFocus)
289
+ window.addEventListener('focus', windowFocusHandler);
290
+ if (fetchOnReconnect)
291
+ window.addEventListener('online', reconnectHandler);
280
292
  }
281
293
  clearTimeout(resetTimeoutId.get(state.keyHash));
282
294
  onFirstSubscribe(state);
@@ -290,14 +302,18 @@ const createQuery = (queryFn, options = {}) => {
290
302
  onSubscribe(state);
291
303
  },
292
304
  onLastUnsubscribe: (state) => {
293
- if (typeof window !== 'undefined' && fetchOnWindowFocus) {
294
- window.removeEventListener('focus', fetchWindowFocusHandler);
305
+ const totalSubs = useQuery.getAllWithSubscriber().length;
306
+ if (utils_1.isClient && totalSubs === 0) {
307
+ if (fetchOnWindowFocus)
308
+ window.removeEventListener('focus', windowFocusHandler);
309
+ if (fetchOnReconnect)
310
+ window.removeEventListener('online', reconnectHandler);
295
311
  }
296
312
  useQuery.set(state.key, { retryCount: 0, retryNextPageCount: 0 }, true);
297
313
  clearTimeout(retryTimeoutId.get(state.keyHash));
298
314
  clearTimeout(retryNextPageTimeoutId.get(state.keyHash));
299
315
  clearTimeout(refetchIntervalTimeoutId.get(state.keyHash));
300
- if (typeof window !== 'undefined' && cacheTime !== Infinity) {
316
+ if (utils_1.isClient && cacheTime !== Infinity) {
301
317
  resetTimeoutId.set(state.keyHash, window.setTimeout(() => {
302
318
  useQuery.set(state.key, INITIAL_QUERY_STATE);
303
319
  }, cacheTime));
@@ -4,3 +4,4 @@ export declare const hasValue: (value: any) => boolean;
4
4
  export declare const hashStoreKey: (obj?: any) => string;
5
5
  export declare const getValueOrComputedValue: <T, P extends any[]>(valueOrComputeValueFn: T | ((...params: P) => T), ...params: P) => T;
6
6
  export type Maybe<T> = T | null | undefined;
7
+ export declare const isClient: boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getValueOrComputedValue = exports.hashStoreKey = exports.hasValue = exports.identityFn = exports.noop = void 0;
3
+ exports.isClient = exports.getValueOrComputedValue = exports.hashStoreKey = exports.hasValue = exports.identityFn = exports.noop = void 0;
4
4
  const noop = () => { };
5
5
  exports.noop = noop;
6
6
  const identityFn = (value) => value;
@@ -16,3 +16,4 @@ const getValueOrComputedValue = (valueOrComputeValueFn, ...params) => {
16
16
  return valueOrComputeValueFn;
17
17
  };
18
18
  exports.getValueOrComputedValue = getValueOrComputedValue;
19
+ exports.isClient = typeof window !== 'undefined' && !('Deno' in window);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "floppy-disk",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "FloppyDisk - lightweight, simple, and powerful state management library",
5
5
  "keywords": [
6
6
  "state",