floppy-disk 1.3.0-beta.2 → 1.4.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -122,6 +122,11 @@ const unsub = useCatStore.subscribe(
122
122
  );
123
123
  ```
124
124
 
125
+ > **Examples:**
126
+ >
127
+ > - [https://codesandbox.io/.../examples/react/basic](https://codesandbox.io/p/sandbox/github/afiiif/floppy-disk/tree/main/examples/react/basic)
128
+ > - [https://codesandbox.io/.../examples/react/custom-reactivity](https://codesandbox.io/p/sandbox/github/afiiif/floppy-disk/tree/main/examples/react/custom-reactivity)
129
+
125
130
  ### Advanced Concept
126
131
 
127
132
  Set the state **silently** (without broadcast the state change to **any subscribers**).
@@ -171,6 +176,11 @@ const useCatStore = createStore(
171
176
  );
172
177
  ```
173
178
 
179
+ > **Examples:**
180
+ >
181
+ > - [https://codesandbox.io/.../examples/react/store-event](https://codesandbox.io/p/sandbox/github/afiiif/floppy-disk/tree/main/examples/react/store-event)
182
+ > - [https://codesandbox.io/.../examples/react/intercept](https://codesandbox.io/p/sandbox/github/afiiif/floppy-disk/tree/main/examples/react/intercept)
183
+
174
184
  Let's go wild using IIFE.
175
185
 
176
186
  ```js
@@ -228,6 +238,10 @@ function CatPageOptimized() {
228
238
  }
229
239
  ```
230
240
 
241
+ > **Examples:**
242
+ >
243
+ > - [https://codesandbox.io/.../examples/react/watch-component](https://codesandbox.io/p/sandbox/github/afiiif/floppy-disk/tree/main/examples/react/watch-component)
244
+
231
245
  Want a local state instead of global state?
232
246
  Or, want to set the initial state inside component?
233
247
 
@@ -103,12 +103,6 @@ export type CreateQueryOptions<TKey extends StoreKey = StoreKey, TResponse = any
103
103
  * Defaults to `3000` (3 seconds).
104
104
  */
105
105
  staleTime?: number;
106
- /**
107
- * Number of maximum error retries.
108
- *
109
- * Defaults to `1`.
110
- */
111
- retry?: number | ((error: TError, key: TKey) => number);
112
106
  /**
113
107
  * Auto call the query when the component is mounted.
114
108
  *
@@ -135,6 +129,18 @@ export type CreateQueryOptions<TKey extends StoreKey = StoreKey, TResponse = any
135
129
  * Defaults to `true`.
136
130
  */
137
131
  enabled?: boolean | ((key: TKey) => boolean);
132
+ /**
133
+ * Number of maximum error retries.
134
+ *
135
+ * Defaults to `1`.
136
+ */
137
+ retry?: number | ((error: TError, key: TKey) => number);
138
+ /**
139
+ * Error retry delay in miliseconds.
140
+ *
141
+ * Defaults to `3000` (3 seconds).
142
+ */
143
+ retryDelay?: number | ((error: TError, key: TKey) => number);
138
144
  /**
139
145
  * If set to `true`, previous `data` will be kept when fetching new data because the query key changed.
140
146
  *
@@ -1,4 +1,4 @@
1
- import { identityFn, noop } from '../utils';
1
+ import { hashStoreKey, identityFn, noop } from '../utils';
2
2
  import { createStores } from './create-stores';
3
3
  const getDecision = (value, param, { ifTrue, ifAlways }) => {
4
4
  if (value === true || (typeof value === 'function' && value(param) === true)) {
@@ -37,7 +37,8 @@ const useQueryDefaultDeps = (state) => [
37
37
  state.hasNextPage,
38
38
  ];
39
39
  export const createQuery = (queryFn, options = {}) => {
40
- const { onFirstSubscribe = noop, onSubscribe = noop, onLastUnsubscribe = noop, onBeforeChangeKey = noop, defaultDeps = useQueryDefaultDeps, select = identityFn, staleTime = DEFAULT_STALE_TIME, retry = 1, fetchOnMount = true, fetchOnWindowFocus = true, enabled = true, keepPreviousData, getNextPageParam = () => undefined, onSuccess = noop, onError = noop, onSettled = noop, ...createStoresOptions } = options;
40
+ const { onFirstSubscribe = noop, onSubscribe = noop, onLastUnsubscribe = noop, onBeforeChangeKey = noop, defaultDeps = useQueryDefaultDeps, select = identityFn, staleTime = DEFAULT_STALE_TIME, fetchOnMount = true, fetchOnWindowFocus = true, enabled = true, retry = 1, retryDelay = 3000, keepPreviousData, getNextPageParam = () => undefined, onSuccess = noop, onError = noop, onSettled = noop, hashKeyFn = hashStoreKey, ...createStoresOptions } = options;
41
+ const retryTimeoutId = new Map();
41
42
  const useQuery = createStores(({ key: _key, get, set }) => {
42
43
  const key = _key;
43
44
  const forceFetch = () => {
@@ -118,8 +119,11 @@ export const createQuery = (queryFn, options = {}) => {
118
119
  });
119
120
  const retryCount = typeof retry === 'function' ? retry(error, key) : retry;
120
121
  if (typeof retryCount === 'number' && prevState.retryCount < retryCount) {
121
- set({ retryCount: prevState.retryCount + 1, isGoingToRetry: true });
122
- callQuery();
122
+ const delay = typeof retryDelay === 'function' ? retryDelay(error, key) : retryDelay;
123
+ retryTimeoutId.set(hashKeyFn(key), window.setTimeout(() => {
124
+ set({ retryCount: prevState.retryCount + 1, isGoingToRetry: true });
125
+ callQuery();
126
+ }, delay));
123
127
  }
124
128
  onError(error, stateBeforeCallQuery);
125
129
  })
@@ -228,6 +232,7 @@ export const createQuery = (queryFn, options = {}) => {
228
232
  return {
229
233
  ...createStoresOptions,
230
234
  defaultDeps,
235
+ hashKeyFn,
231
236
  onFirstSubscribe: (state) => {
232
237
  if (typeof window !== 'undefined' && fetchOnWindowFocus) {
233
238
  window.addEventListener('focus', fetchWindowFocusHandler);
@@ -243,9 +248,10 @@ export const createQuery = (queryFn, options = {}) => {
243
248
  },
244
249
  onLastUnsubscribe: (state) => {
245
250
  if (typeof window !== 'undefined' && fetchOnWindowFocus) {
246
- window.addEventListener('focus', fetchWindowFocusHandler);
251
+ window.removeEventListener('focus', fetchWindowFocusHandler);
247
252
  }
248
253
  resetRetryCount(state.key);
254
+ clearTimeout(retryTimeoutId.get(hashKeyFn(state.key)));
249
255
  onLastUnsubscribe(state);
250
256
  },
251
257
  onBeforeChangeKey: (nextKey, prevKey) => {
@@ -1,7 +1,6 @@
1
1
  import { useEffect, useMemo, useRef, useState } from 'react';
2
- import { noop } from '../utils';
2
+ import { hashStoreKey, noop } from '../utils';
3
3
  import { initStore, } from '../vanilla';
4
- const hashStoreKey = (obj) => JSON.stringify(obj, Object.keys(obj).sort());
5
4
  export const createStores = (initializer, options = {}) => {
6
5
  const { onBeforeChangeKey = noop, defaultDeps, hashKeyFn = hashStoreKey } = options;
7
6
  const stores = new Map();
@@ -1,2 +1,3 @@
1
1
  export declare const noop: () => void;
2
2
  export declare const identityFn: <T>(a: T) => T;
3
+ export declare const hashStoreKey: (obj?: any) => string;
@@ -1,2 +1,3 @@
1
1
  export const noop = () => { };
2
2
  export const identityFn = (a) => a;
3
+ export const hashStoreKey = (obj) => JSON.stringify(obj, Object.keys(obj).sort());
@@ -103,12 +103,6 @@ export type CreateQueryOptions<TKey extends StoreKey = StoreKey, TResponse = any
103
103
  * Defaults to `3000` (3 seconds).
104
104
  */
105
105
  staleTime?: number;
106
- /**
107
- * Number of maximum error retries.
108
- *
109
- * Defaults to `1`.
110
- */
111
- retry?: number | ((error: TError, key: TKey) => number);
112
106
  /**
113
107
  * Auto call the query when the component is mounted.
114
108
  *
@@ -135,6 +129,18 @@ export type CreateQueryOptions<TKey extends StoreKey = StoreKey, TResponse = any
135
129
  * Defaults to `true`.
136
130
  */
137
131
  enabled?: boolean | ((key: TKey) => boolean);
132
+ /**
133
+ * Number of maximum error retries.
134
+ *
135
+ * Defaults to `1`.
136
+ */
137
+ retry?: number | ((error: TError, key: TKey) => number);
138
+ /**
139
+ * Error retry delay in miliseconds.
140
+ *
141
+ * Defaults to `3000` (3 seconds).
142
+ */
143
+ retryDelay?: number | ((error: TError, key: TKey) => number);
138
144
  /**
139
145
  * If set to `true`, previous `data` will be kept when fetching new data because the query key changed.
140
146
  *
@@ -40,7 +40,8 @@ const useQueryDefaultDeps = (state) => [
40
40
  state.hasNextPage,
41
41
  ];
42
42
  const createQuery = (queryFn, options = {}) => {
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 = DEFAULT_STALE_TIME, retry = 1, fetchOnMount = true, fetchOnWindowFocus = true, enabled = true, keepPreviousData, getNextPageParam = () => undefined, onSuccess = utils_1.noop, onError = utils_1.noop, onSettled = utils_1.noop, ...createStoresOptions } = options;
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 = DEFAULT_STALE_TIME, fetchOnMount = true, fetchOnWindowFocus = true, enabled = true, retry = 1, retryDelay = 3000, keepPreviousData, getNextPageParam = () => undefined, onSuccess = utils_1.noop, onError = utils_1.noop, onSettled = utils_1.noop, hashKeyFn = utils_1.hashStoreKey, ...createStoresOptions } = options;
44
+ const retryTimeoutId = new Map();
44
45
  const useQuery = (0, create_stores_1.createStores)(({ key: _key, get, set }) => {
45
46
  const key = _key;
46
47
  const forceFetch = () => {
@@ -121,8 +122,11 @@ const createQuery = (queryFn, options = {}) => {
121
122
  });
122
123
  const retryCount = typeof retry === 'function' ? retry(error, key) : retry;
123
124
  if (typeof retryCount === 'number' && prevState.retryCount < retryCount) {
124
- set({ retryCount: prevState.retryCount + 1, isGoingToRetry: true });
125
- callQuery();
125
+ const delay = typeof retryDelay === 'function' ? retryDelay(error, key) : retryDelay;
126
+ retryTimeoutId.set(hashKeyFn(key), window.setTimeout(() => {
127
+ set({ retryCount: prevState.retryCount + 1, isGoingToRetry: true });
128
+ callQuery();
129
+ }, delay));
126
130
  }
127
131
  onError(error, stateBeforeCallQuery);
128
132
  })
@@ -231,6 +235,7 @@ const createQuery = (queryFn, options = {}) => {
231
235
  return {
232
236
  ...createStoresOptions,
233
237
  defaultDeps,
238
+ hashKeyFn,
234
239
  onFirstSubscribe: (state) => {
235
240
  if (typeof window !== 'undefined' && fetchOnWindowFocus) {
236
241
  window.addEventListener('focus', fetchWindowFocusHandler);
@@ -246,9 +251,10 @@ const createQuery = (queryFn, options = {}) => {
246
251
  },
247
252
  onLastUnsubscribe: (state) => {
248
253
  if (typeof window !== 'undefined' && fetchOnWindowFocus) {
249
- window.addEventListener('focus', fetchWindowFocusHandler);
254
+ window.removeEventListener('focus', fetchWindowFocusHandler);
250
255
  }
251
256
  resetRetryCount(state.key);
257
+ clearTimeout(retryTimeoutId.get(hashKeyFn(state.key)));
252
258
  onLastUnsubscribe(state);
253
259
  },
254
260
  onBeforeChangeKey: (nextKey, prevKey) => {
@@ -4,9 +4,8 @@ exports.createStores = void 0;
4
4
  const react_1 = require("react");
5
5
  const utils_1 = require("../utils");
6
6
  const vanilla_1 = require("../vanilla");
7
- const hashStoreKey = (obj) => JSON.stringify(obj, Object.keys(obj).sort());
8
7
  const createStores = (initializer, options = {}) => {
9
- const { onBeforeChangeKey = utils_1.noop, defaultDeps, hashKeyFn = hashStoreKey } = options;
8
+ const { onBeforeChangeKey = utils_1.noop, defaultDeps, hashKeyFn = utils_1.hashStoreKey } = options;
10
9
  const stores = new Map();
11
10
  const getStore = (_key) => {
12
11
  const key = _key || {};
@@ -1,2 +1,3 @@
1
1
  export declare const noop: () => void;
2
2
  export declare const identityFn: <T>(a: T) => T;
3
+ export declare const hashStoreKey: (obj?: any) => string;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.identityFn = exports.noop = void 0;
3
+ exports.hashStoreKey = exports.identityFn = exports.noop = void 0;
4
4
  const noop = () => { };
5
5
  exports.noop = noop;
6
6
  const identityFn = (a) => a;
7
7
  exports.identityFn = identityFn;
8
+ const hashStoreKey = (obj) => JSON.stringify(obj, Object.keys(obj).sort());
9
+ exports.hashStoreKey = hashStoreKey;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "floppy-disk",
3
- "version": "1.3.0-beta.2",
3
+ "version": "1.4.0-beta.1",
4
4
  "description": "FloppyDisk - lightweight, simple, and powerful state management library",
5
5
  "keywords": [
6
6
  "state",