floppy-disk 1.4.0-beta.1 → 1.4.0-beta.2
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.
|
@@ -94,6 +94,8 @@ export type QueryState<TKey extends StoreKey = StoreKey, TResponse = any, TData
|
|
|
94
94
|
pageParam: any;
|
|
95
95
|
pageParams: any[];
|
|
96
96
|
hasNextPage: boolean;
|
|
97
|
+
retryNextPageCount: number;
|
|
98
|
+
isGoingToRetryNextPage: boolean;
|
|
97
99
|
};
|
|
98
100
|
export type CreateQueryOptions<TKey extends StoreKey = StoreKey, TResponse = any, TData = TResponse, TError = unknown> = CreateStoresOptions<TKey, QueryState<TKey, TResponse, TData, TError>> & {
|
|
99
101
|
select?: (response: TResponse, state: Pick<QueryState<TKey, TResponse, TData, TError>, 'data' | 'key'>) => TData;
|
|
@@ -29,6 +29,8 @@ const INITIAL_QUERY_STATE = {
|
|
|
29
29
|
pageParam: undefined,
|
|
30
30
|
pageParams: [undefined],
|
|
31
31
|
hasNextPage: false,
|
|
32
|
+
retryNextPageCount: 0,
|
|
33
|
+
isGoingToRetryNextPage: false,
|
|
32
34
|
};
|
|
33
35
|
const useQueryDefaultDeps = (state) => [
|
|
34
36
|
state.data,
|
|
@@ -39,13 +41,20 @@ const useQueryDefaultDeps = (state) => [
|
|
|
39
41
|
export const createQuery = (queryFn, options = {}) => {
|
|
40
42
|
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
43
|
const retryTimeoutId = new Map();
|
|
44
|
+
const retryNextPageTimeoutId = new Map();
|
|
42
45
|
const useQuery = createStores(({ key: _key, get, set }) => {
|
|
43
46
|
const key = _key;
|
|
47
|
+
const getRetryProps = (error, retryCount) => {
|
|
48
|
+
const maxRetryCount = (typeof retry === 'function' ? retry(error, key) : retry) || 0;
|
|
49
|
+
const shouldRetry = retryCount < maxRetryCount;
|
|
50
|
+
const delay = (typeof retryDelay === 'function' ? retryDelay(error, key) : retryDelay) || 0;
|
|
51
|
+
return { shouldRetry, delay };
|
|
52
|
+
};
|
|
44
53
|
const forceFetch = () => {
|
|
45
54
|
const responseAllPages = [];
|
|
46
55
|
const newPageParams = [undefined];
|
|
47
56
|
let pageParam = undefined;
|
|
48
|
-
const { isWaiting, isLoading,
|
|
57
|
+
const { isWaiting, isLoading, pageParams } = get();
|
|
49
58
|
if (isWaiting || enabled === false || (typeof enabled === 'function' && !enabled(key)))
|
|
50
59
|
return;
|
|
51
60
|
if (isLoading)
|
|
@@ -53,11 +62,12 @@ export const createQuery = (queryFn, options = {}) => {
|
|
|
53
62
|
else
|
|
54
63
|
set({ isWaiting: true, isRefetching: true });
|
|
55
64
|
const callQuery = () => {
|
|
56
|
-
if (isGoingToRetry) {
|
|
65
|
+
if (get().isGoingToRetry) {
|
|
57
66
|
if (isLoading)
|
|
58
67
|
set({ isGoingToRetry: false, isWaiting: true });
|
|
59
68
|
else
|
|
60
69
|
set({ isGoingToRetry: false, isWaiting: true, isRefetching: true });
|
|
70
|
+
clearTimeout(retryTimeoutId.get(hashKeyFn(key)));
|
|
61
71
|
}
|
|
62
72
|
const stateBeforeCallQuery = { ...get(), pageParam };
|
|
63
73
|
queryFn(key, stateBeforeCallQuery)
|
|
@@ -96,6 +106,7 @@ export const createQuery = (queryFn, options = {}) => {
|
|
|
96
106
|
.catch((error) => {
|
|
97
107
|
const prevState = get();
|
|
98
108
|
const errorUpdatedAt = Date.now();
|
|
109
|
+
const { shouldRetry, delay } = getRetryProps(error, prevState.retryCount);
|
|
99
110
|
set(prevState.isSuccess
|
|
100
111
|
? {
|
|
101
112
|
isWaiting: false,
|
|
@@ -106,6 +117,7 @@ export const createQuery = (queryFn, options = {}) => {
|
|
|
106
117
|
}, null),
|
|
107
118
|
error,
|
|
108
119
|
errorUpdatedAt,
|
|
120
|
+
isGoingToRetry: shouldRetry,
|
|
109
121
|
pageParam,
|
|
110
122
|
hasNextPage: pageParam !== undefined,
|
|
111
123
|
}
|
|
@@ -114,14 +126,13 @@ export const createQuery = (queryFn, options = {}) => {
|
|
|
114
126
|
isError: true,
|
|
115
127
|
error,
|
|
116
128
|
errorUpdatedAt,
|
|
129
|
+
isGoingToRetry: shouldRetry,
|
|
117
130
|
pageParam,
|
|
118
131
|
hasNextPage: pageParam !== undefined,
|
|
119
132
|
});
|
|
120
|
-
|
|
121
|
-
if (typeof retryCount === 'number' && prevState.retryCount < retryCount) {
|
|
122
|
-
const delay = typeof retryDelay === 'function' ? retryDelay(error, key) : retryDelay;
|
|
133
|
+
if (shouldRetry) {
|
|
123
134
|
retryTimeoutId.set(hashKeyFn(key), window.setTimeout(() => {
|
|
124
|
-
set({ retryCount: prevState.retryCount + 1
|
|
135
|
+
set({ retryCount: prevState.retryCount + 1 });
|
|
125
136
|
callQuery();
|
|
126
137
|
}, delay));
|
|
127
138
|
}
|
|
@@ -147,7 +158,8 @@ export const createQuery = (queryFn, options = {}) => {
|
|
|
147
158
|
return forceFetch();
|
|
148
159
|
if (isWaitingNextPage || !hasNextPage)
|
|
149
160
|
return;
|
|
150
|
-
set({ isWaitingNextPage: true });
|
|
161
|
+
set({ isWaitingNextPage: true, isGoingToRetryNextPage: false });
|
|
162
|
+
clearTimeout(retryNextPageTimeoutId.get(hashKeyFn(key)));
|
|
151
163
|
queryFn(key, { ...state, pageParam })
|
|
152
164
|
.then((response) => {
|
|
153
165
|
const newPageParam = getNextPageParam(response, pageParams.length);
|
|
@@ -162,12 +174,21 @@ export const createQuery = (queryFn, options = {}) => {
|
|
|
162
174
|
});
|
|
163
175
|
})
|
|
164
176
|
.catch((error) => {
|
|
177
|
+
const prevState = get();
|
|
178
|
+
const { shouldRetry, delay } = getRetryProps(error, prevState.retryNextPageCount);
|
|
165
179
|
set({
|
|
166
180
|
isWaitingNextPage: false,
|
|
167
181
|
isError: true,
|
|
168
182
|
error,
|
|
169
183
|
errorUpdatedAt: Date.now(),
|
|
184
|
+
isGoingToRetryNextPage: shouldRetry,
|
|
170
185
|
});
|
|
186
|
+
if (shouldRetry) {
|
|
187
|
+
retryNextPageTimeoutId.set(hashKeyFn(key), window.setTimeout(() => {
|
|
188
|
+
set({ retryNextPageCount: prevState.retryNextPageCount + 1 });
|
|
189
|
+
fetchNextPage();
|
|
190
|
+
}, delay));
|
|
191
|
+
}
|
|
171
192
|
});
|
|
172
193
|
};
|
|
173
194
|
const setResponse = (responseSetter) => {
|
|
@@ -218,9 +239,6 @@ export const createQuery = (queryFn, options = {}) => {
|
|
|
218
239
|
},
|
|
219
240
|
};
|
|
220
241
|
}, (() => {
|
|
221
|
-
const resetRetryCount = (key) => {
|
|
222
|
-
useQuery.set(key, { retryCount: 0 }, true);
|
|
223
|
-
};
|
|
224
242
|
const fetchWindowFocusHandler = () => {
|
|
225
243
|
useQuery.getAllWithSubscriber().forEach((state) => {
|
|
226
244
|
getDecision(fetchOnWindowFocus, state.key, {
|
|
@@ -250,8 +268,9 @@ export const createQuery = (queryFn, options = {}) => {
|
|
|
250
268
|
if (typeof window !== 'undefined' && fetchOnWindowFocus) {
|
|
251
269
|
window.removeEventListener('focus', fetchWindowFocusHandler);
|
|
252
270
|
}
|
|
253
|
-
|
|
271
|
+
useQuery.set(state.key, { retryCount: 0, retryNextPageCount: 0 }, true);
|
|
254
272
|
clearTimeout(retryTimeoutId.get(hashKeyFn(state.key)));
|
|
273
|
+
clearTimeout(retryNextPageTimeoutId.get(hashKeyFn(state.key)));
|
|
255
274
|
onLastUnsubscribe(state);
|
|
256
275
|
},
|
|
257
276
|
onBeforeChangeKey: (nextKey, prevKey) => {
|
|
@@ -94,6 +94,8 @@ export type QueryState<TKey extends StoreKey = StoreKey, TResponse = any, TData
|
|
|
94
94
|
pageParam: any;
|
|
95
95
|
pageParams: any[];
|
|
96
96
|
hasNextPage: boolean;
|
|
97
|
+
retryNextPageCount: number;
|
|
98
|
+
isGoingToRetryNextPage: boolean;
|
|
97
99
|
};
|
|
98
100
|
export type CreateQueryOptions<TKey extends StoreKey = StoreKey, TResponse = any, TData = TResponse, TError = unknown> = CreateStoresOptions<TKey, QueryState<TKey, TResponse, TData, TError>> & {
|
|
99
101
|
select?: (response: TResponse, state: Pick<QueryState<TKey, TResponse, TData, TError>, 'data' | 'key'>) => TData;
|
|
@@ -32,6 +32,8 @@ const INITIAL_QUERY_STATE = {
|
|
|
32
32
|
pageParam: undefined,
|
|
33
33
|
pageParams: [undefined],
|
|
34
34
|
hasNextPage: false,
|
|
35
|
+
retryNextPageCount: 0,
|
|
36
|
+
isGoingToRetryNextPage: false,
|
|
35
37
|
};
|
|
36
38
|
const useQueryDefaultDeps = (state) => [
|
|
37
39
|
state.data,
|
|
@@ -42,13 +44,20 @@ const useQueryDefaultDeps = (state) => [
|
|
|
42
44
|
const createQuery = (queryFn, options = {}) => {
|
|
43
45
|
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
46
|
const retryTimeoutId = new Map();
|
|
47
|
+
const retryNextPageTimeoutId = new Map();
|
|
45
48
|
const useQuery = (0, create_stores_1.createStores)(({ key: _key, get, set }) => {
|
|
46
49
|
const key = _key;
|
|
50
|
+
const getRetryProps = (error, retryCount) => {
|
|
51
|
+
const maxRetryCount = (typeof retry === 'function' ? retry(error, key) : retry) || 0;
|
|
52
|
+
const shouldRetry = retryCount < maxRetryCount;
|
|
53
|
+
const delay = (typeof retryDelay === 'function' ? retryDelay(error, key) : retryDelay) || 0;
|
|
54
|
+
return { shouldRetry, delay };
|
|
55
|
+
};
|
|
47
56
|
const forceFetch = () => {
|
|
48
57
|
const responseAllPages = [];
|
|
49
58
|
const newPageParams = [undefined];
|
|
50
59
|
let pageParam = undefined;
|
|
51
|
-
const { isWaiting, isLoading,
|
|
60
|
+
const { isWaiting, isLoading, pageParams } = get();
|
|
52
61
|
if (isWaiting || enabled === false || (typeof enabled === 'function' && !enabled(key)))
|
|
53
62
|
return;
|
|
54
63
|
if (isLoading)
|
|
@@ -56,11 +65,12 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
56
65
|
else
|
|
57
66
|
set({ isWaiting: true, isRefetching: true });
|
|
58
67
|
const callQuery = () => {
|
|
59
|
-
if (isGoingToRetry) {
|
|
68
|
+
if (get().isGoingToRetry) {
|
|
60
69
|
if (isLoading)
|
|
61
70
|
set({ isGoingToRetry: false, isWaiting: true });
|
|
62
71
|
else
|
|
63
72
|
set({ isGoingToRetry: false, isWaiting: true, isRefetching: true });
|
|
73
|
+
clearTimeout(retryTimeoutId.get(hashKeyFn(key)));
|
|
64
74
|
}
|
|
65
75
|
const stateBeforeCallQuery = { ...get(), pageParam };
|
|
66
76
|
queryFn(key, stateBeforeCallQuery)
|
|
@@ -99,6 +109,7 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
99
109
|
.catch((error) => {
|
|
100
110
|
const prevState = get();
|
|
101
111
|
const errorUpdatedAt = Date.now();
|
|
112
|
+
const { shouldRetry, delay } = getRetryProps(error, prevState.retryCount);
|
|
102
113
|
set(prevState.isSuccess
|
|
103
114
|
? {
|
|
104
115
|
isWaiting: false,
|
|
@@ -109,6 +120,7 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
109
120
|
}, null),
|
|
110
121
|
error,
|
|
111
122
|
errorUpdatedAt,
|
|
123
|
+
isGoingToRetry: shouldRetry,
|
|
112
124
|
pageParam,
|
|
113
125
|
hasNextPage: pageParam !== undefined,
|
|
114
126
|
}
|
|
@@ -117,14 +129,13 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
117
129
|
isError: true,
|
|
118
130
|
error,
|
|
119
131
|
errorUpdatedAt,
|
|
132
|
+
isGoingToRetry: shouldRetry,
|
|
120
133
|
pageParam,
|
|
121
134
|
hasNextPage: pageParam !== undefined,
|
|
122
135
|
});
|
|
123
|
-
|
|
124
|
-
if (typeof retryCount === 'number' && prevState.retryCount < retryCount) {
|
|
125
|
-
const delay = typeof retryDelay === 'function' ? retryDelay(error, key) : retryDelay;
|
|
136
|
+
if (shouldRetry) {
|
|
126
137
|
retryTimeoutId.set(hashKeyFn(key), window.setTimeout(() => {
|
|
127
|
-
set({ retryCount: prevState.retryCount + 1
|
|
138
|
+
set({ retryCount: prevState.retryCount + 1 });
|
|
128
139
|
callQuery();
|
|
129
140
|
}, delay));
|
|
130
141
|
}
|
|
@@ -150,7 +161,8 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
150
161
|
return forceFetch();
|
|
151
162
|
if (isWaitingNextPage || !hasNextPage)
|
|
152
163
|
return;
|
|
153
|
-
set({ isWaitingNextPage: true });
|
|
164
|
+
set({ isWaitingNextPage: true, isGoingToRetryNextPage: false });
|
|
165
|
+
clearTimeout(retryNextPageTimeoutId.get(hashKeyFn(key)));
|
|
154
166
|
queryFn(key, { ...state, pageParam })
|
|
155
167
|
.then((response) => {
|
|
156
168
|
const newPageParam = getNextPageParam(response, pageParams.length);
|
|
@@ -165,12 +177,21 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
165
177
|
});
|
|
166
178
|
})
|
|
167
179
|
.catch((error) => {
|
|
180
|
+
const prevState = get();
|
|
181
|
+
const { shouldRetry, delay } = getRetryProps(error, prevState.retryNextPageCount);
|
|
168
182
|
set({
|
|
169
183
|
isWaitingNextPage: false,
|
|
170
184
|
isError: true,
|
|
171
185
|
error,
|
|
172
186
|
errorUpdatedAt: Date.now(),
|
|
187
|
+
isGoingToRetryNextPage: shouldRetry,
|
|
173
188
|
});
|
|
189
|
+
if (shouldRetry) {
|
|
190
|
+
retryNextPageTimeoutId.set(hashKeyFn(key), window.setTimeout(() => {
|
|
191
|
+
set({ retryNextPageCount: prevState.retryNextPageCount + 1 });
|
|
192
|
+
fetchNextPage();
|
|
193
|
+
}, delay));
|
|
194
|
+
}
|
|
174
195
|
});
|
|
175
196
|
};
|
|
176
197
|
const setResponse = (responseSetter) => {
|
|
@@ -221,9 +242,6 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
221
242
|
},
|
|
222
243
|
};
|
|
223
244
|
}, (() => {
|
|
224
|
-
const resetRetryCount = (key) => {
|
|
225
|
-
useQuery.set(key, { retryCount: 0 }, true);
|
|
226
|
-
};
|
|
227
245
|
const fetchWindowFocusHandler = () => {
|
|
228
246
|
useQuery.getAllWithSubscriber().forEach((state) => {
|
|
229
247
|
getDecision(fetchOnWindowFocus, state.key, {
|
|
@@ -253,8 +271,9 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
253
271
|
if (typeof window !== 'undefined' && fetchOnWindowFocus) {
|
|
254
272
|
window.removeEventListener('focus', fetchWindowFocusHandler);
|
|
255
273
|
}
|
|
256
|
-
|
|
274
|
+
useQuery.set(state.key, { retryCount: 0, retryNextPageCount: 0 }, true);
|
|
257
275
|
clearTimeout(retryTimeoutId.get(hashKeyFn(state.key)));
|
|
276
|
+
clearTimeout(retryNextPageTimeoutId.get(hashKeyFn(state.key)));
|
|
258
277
|
onLastUnsubscribe(state);
|
|
259
278
|
},
|
|
260
279
|
onBeforeChangeKey: (nextKey, prevKey) => {
|