@fajarmaulana/komerce-lp-helper 0.2.2 → 0.3.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/dist/components/Form.js +7 -30
- package/dist/components/LazyBackground.js +2 -3
- package/dist/components/hooks/useLazyBackground.js +8 -26
- package/dist/constants/index.js +1 -1
- package/dist/constants/regex.js +10 -10
- package/dist/hooks/debounce.js +16 -47
- package/dist/hooks/form.js +26 -65
- package/dist/hooks/router.js +49 -89
- package/dist/hooks/sectionObserver.js +7 -25
- package/dist/hooks/slider.js +36 -55
- package/dist/utils/api.js +261 -434
- package/dist/utils/cookie.js +18 -19
- package/dist/utils/error-provider.js +30 -55
- package/dist/utils/file.js +27 -31
- package/dist/utils/general.d.ts +10 -0
- package/dist/utils/general.js +24 -11
- package/dist/utils/local.js +10 -10
- package/dist/utils/useApi.js +188 -315
- package/package.json +11 -1
package/dist/utils/useApi.js
CHANGED
|
@@ -1,78 +1,6 @@
|
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
|
2
|
-
__assign = Object.assign || function(t) {
|
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
-
s = arguments[i];
|
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
-
t[p] = s[p];
|
|
7
|
-
}
|
|
8
|
-
return t;
|
|
9
|
-
};
|
|
10
|
-
return __assign.apply(this, arguments);
|
|
11
|
-
};
|
|
12
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
23
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
-
function step(op) {
|
|
26
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
-
switch (op[0]) {
|
|
31
|
-
case 0: case 1: t = op; break;
|
|
32
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
-
default:
|
|
36
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
-
if (t[2]) _.ops.pop();
|
|
41
|
-
_.trys.pop(); continue;
|
|
42
|
-
}
|
|
43
|
-
op = body.call(thisArg, _);
|
|
44
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
49
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
50
|
-
if (!m) return o;
|
|
51
|
-
var i = m.call(o), r, ar = [], e;
|
|
52
|
-
try {
|
|
53
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
54
|
-
}
|
|
55
|
-
catch (error) { e = { error: error }; }
|
|
56
|
-
finally {
|
|
57
|
-
try {
|
|
58
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
59
|
-
}
|
|
60
|
-
finally { if (e) throw e.error; }
|
|
61
|
-
}
|
|
62
|
-
return ar;
|
|
63
|
-
};
|
|
64
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
65
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
66
|
-
if (ar || !(i in from)) {
|
|
67
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
68
|
-
ar[i] = from[i];
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
72
|
-
};
|
|
73
1
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
74
2
|
import { ApiInstance, buildURL, } from './api';
|
|
75
|
-
|
|
3
|
+
const pendingRequests = new Map();
|
|
76
4
|
/**
|
|
77
5
|
* Creates a new API instance with built-in React hooks (`fetch`, `mutation`, `infinite`)
|
|
78
6
|
* for performing typed data fetching and mutations with progress tracking.
|
|
@@ -91,9 +19,8 @@ var pendingRequests = new Map();
|
|
|
91
19
|
* const { data, isLoading, refetch } = api.infinite<User[]>('/users', { initialOffset: 0 })
|
|
92
20
|
* ```
|
|
93
21
|
*/
|
|
94
|
-
export default function createApi(options) {
|
|
95
|
-
|
|
96
|
-
var instance = new ApiInstance(options);
|
|
22
|
+
export default function createApi(options = {}) {
|
|
23
|
+
const instance = new ApiInstance(options);
|
|
97
24
|
/**
|
|
98
25
|
* React hook for data fetching with built-in loading, error, and refetch states.
|
|
99
26
|
*
|
|
@@ -114,81 +41,63 @@ export default function createApi(options) {
|
|
|
114
41
|
* const { data, isLoading, refetch } = api.fetch<User[]>('/users')
|
|
115
42
|
* ```
|
|
116
43
|
*/
|
|
117
|
-
function useFetch(url, config, enabled) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (enabled === void 0) { enabled = true; }
|
|
121
|
-
var abortControllerRef = useRef(null);
|
|
122
|
-
var _c = __read(useState({
|
|
44
|
+
function useFetch(url, config, enabled = true) {
|
|
45
|
+
const abortControllerRef = useRef(null);
|
|
46
|
+
const [state, setState] = useState({
|
|
123
47
|
data: null,
|
|
124
48
|
error: null,
|
|
125
49
|
isLoading: enabled,
|
|
126
50
|
cacheKey: null,
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
JSON.stringify(config
|
|
132
|
-
JSON.stringify(config
|
|
51
|
+
});
|
|
52
|
+
const stableConfig = useMemo(() => config, [
|
|
53
|
+
config?.cache?.enabled,
|
|
54
|
+
config?.cache?.revalidate,
|
|
55
|
+
JSON.stringify(config?.headers),
|
|
56
|
+
JSON.stringify(config?.params),
|
|
133
57
|
]);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
args_1[_i] = arguments[_i];
|
|
58
|
+
const fetchData = useCallback(async (refetch = false) => {
|
|
59
|
+
if (!enabled && !refetch) {
|
|
60
|
+
return { data: null, error: null, isLoading: false, cacheKey: null };
|
|
138
61
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (abortControllerRef.current)
|
|
150
|
-
abortControllerRef.current.abort();
|
|
151
|
-
abortControllerRef.current = new AbortController();
|
|
152
|
-
if (!state.isLoading) {
|
|
153
|
-
setState(function (s) { return (__assign(__assign({}, s), { isLoading: true })); });
|
|
154
|
-
}
|
|
155
|
-
_b.label = 1;
|
|
156
|
-
case 1:
|
|
157
|
-
_b.trys.push([1, 3, , 4]);
|
|
158
|
-
return [4 /*yield*/, instance.get(url, __assign(__assign({}, stableConfig), { signal: abortControllerRef.current.signal }))];
|
|
159
|
-
case 2:
|
|
160
|
-
response = _b.sent();
|
|
161
|
-
newState = {
|
|
162
|
-
data: response.data,
|
|
163
|
-
error: null,
|
|
164
|
-
isLoading: false,
|
|
165
|
-
cacheKey: (_a = response.cacheKey) !== null && _a !== void 0 ? _a : null,
|
|
166
|
-
};
|
|
167
|
-
setState(newState);
|
|
168
|
-
return [2 /*return*/, newState];
|
|
169
|
-
case 3:
|
|
170
|
-
err_1 = _b.sent();
|
|
171
|
-
newState = {
|
|
172
|
-
data: null,
|
|
173
|
-
error: err_1 instanceof Error && err_1.name === 'AbortError' ? null : err_1,
|
|
174
|
-
isLoading: false,
|
|
175
|
-
cacheKey: null,
|
|
176
|
-
};
|
|
177
|
-
setState(newState);
|
|
178
|
-
return [2 /*return*/, newState];
|
|
179
|
-
case 4: return [2 /*return*/];
|
|
180
|
-
}
|
|
62
|
+
if (abortControllerRef.current)
|
|
63
|
+
abortControllerRef.current.abort();
|
|
64
|
+
abortControllerRef.current = new AbortController();
|
|
65
|
+
if (!state.isLoading) {
|
|
66
|
+
setState(s => ({ ...s, isLoading: true }));
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const response = await instance.get(url, {
|
|
70
|
+
...stableConfig,
|
|
71
|
+
signal: abortControllerRef.current.signal,
|
|
181
72
|
});
|
|
182
|
-
|
|
73
|
+
const newState = {
|
|
74
|
+
data: response.data,
|
|
75
|
+
error: null,
|
|
76
|
+
isLoading: false,
|
|
77
|
+
cacheKey: response.cacheKey ?? null,
|
|
78
|
+
};
|
|
79
|
+
setState(newState);
|
|
80
|
+
return newState;
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
const newState = {
|
|
84
|
+
data: null,
|
|
85
|
+
error: err instanceof Error && err.name === 'AbortError' ? null : err,
|
|
86
|
+
isLoading: false,
|
|
87
|
+
cacheKey: null,
|
|
88
|
+
};
|
|
89
|
+
setState(newState);
|
|
90
|
+
return newState;
|
|
91
|
+
}
|
|
183
92
|
}, [enabled, url, stableConfig]);
|
|
184
|
-
useEffect(
|
|
93
|
+
useEffect(() => {
|
|
185
94
|
fetchData();
|
|
186
|
-
return
|
|
95
|
+
return () => {
|
|
187
96
|
if (abortControllerRef.current)
|
|
188
97
|
abortControllerRef.current.abort();
|
|
189
98
|
};
|
|
190
99
|
}, [fetchData]);
|
|
191
|
-
return
|
|
100
|
+
return { ...state, refetch: () => fetchData(true) };
|
|
192
101
|
}
|
|
193
102
|
/**
|
|
194
103
|
* React hook for making data mutations (e.g. POST, PUT, DELETE) with built-in
|
|
@@ -225,87 +134,86 @@ export default function createApi(options) {
|
|
|
225
134
|
* ```
|
|
226
135
|
*/
|
|
227
136
|
function useMutation(url, config) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
var abortControllerRef = useRef(null);
|
|
231
|
-
var _d = __read(useState({
|
|
137
|
+
const abortControllerRef = useRef(null);
|
|
138
|
+
const [state, setState] = useState({
|
|
232
139
|
isLoading: false,
|
|
233
140
|
cacheKey: null,
|
|
234
141
|
progress: null,
|
|
235
|
-
})
|
|
236
|
-
|
|
237
|
-
config
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
config
|
|
241
|
-
config
|
|
242
|
-
JSON.stringify(
|
|
142
|
+
});
|
|
143
|
+
const stableConfig = useMemo(() => config, [
|
|
144
|
+
config?.method,
|
|
145
|
+
config?.cache?.enabled,
|
|
146
|
+
config?.cache?.revalidate,
|
|
147
|
+
config?.queryMutation,
|
|
148
|
+
config?.progress,
|
|
149
|
+
JSON.stringify(config?.headers ?? {}),
|
|
243
150
|
]);
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
setState({
|
|
285
|
-
isLoading: false,
|
|
286
|
-
cacheKey: (_a = response.cacheKey) !== null && _a !== void 0 ? _a : null,
|
|
287
|
-
progress: null,
|
|
288
|
-
});
|
|
289
|
-
return [2 /*return*/, response];
|
|
290
|
-
case 3:
|
|
291
|
-
err_2 = _b.sent();
|
|
292
|
-
setState({ isLoading: false, cacheKey: null, progress: null });
|
|
293
|
-
throw err_2;
|
|
294
|
-
case 4:
|
|
295
|
-
if (pendingRequests.has(requestKey))
|
|
296
|
-
pendingRequests.delete(requestKey);
|
|
297
|
-
return [7 /*endfinally*/];
|
|
298
|
-
case 5: return [2 /*return*/];
|
|
151
|
+
const mutate = useCallback(async (request) => {
|
|
152
|
+
if (abortControllerRef.current)
|
|
153
|
+
abortControllerRef.current.abort();
|
|
154
|
+
abortControllerRef.current = new AbortController();
|
|
155
|
+
setState(s => ({ ...s, isLoading: true, progress: null }));
|
|
156
|
+
let requestKey = '';
|
|
157
|
+
try {
|
|
158
|
+
const method = stableConfig?.method || 'GET';
|
|
159
|
+
requestKey = JSON.stringify({ url, method, request });
|
|
160
|
+
if (pendingRequests.has(requestKey)) {
|
|
161
|
+
return pendingRequests.get(requestKey);
|
|
162
|
+
}
|
|
163
|
+
const shouldTrackUpload = stableConfig?.progress === 'upload';
|
|
164
|
+
const shouldTrackDownload = stableConfig?.progress === 'download';
|
|
165
|
+
let requestPromise;
|
|
166
|
+
if (method === 'GET') {
|
|
167
|
+
requestPromise = instance.get(url, {
|
|
168
|
+
...stableConfig,
|
|
169
|
+
params: request,
|
|
170
|
+
signal: abortControllerRef.current.signal,
|
|
171
|
+
onDownload: shouldTrackDownload
|
|
172
|
+
? progress => {
|
|
173
|
+
setState(s => ({ ...s, progress: progress }));
|
|
174
|
+
}
|
|
175
|
+
: undefined,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
requestPromise = instance.request({
|
|
180
|
+
...stableConfig,
|
|
181
|
+
url: config?.queryMutation ? buildURL(url, request) : url,
|
|
182
|
+
method,
|
|
183
|
+
body: request ? request : undefined,
|
|
184
|
+
signal: abortControllerRef.current.signal,
|
|
185
|
+
onUpload: shouldTrackUpload
|
|
186
|
+
? progress => {
|
|
187
|
+
setState(s => ({ ...s, progress }));
|
|
188
|
+
}
|
|
189
|
+
: undefined,
|
|
190
|
+
});
|
|
299
191
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
192
|
+
pendingRequests.set(requestKey, requestPromise);
|
|
193
|
+
const response = await requestPromise;
|
|
194
|
+
setState({
|
|
195
|
+
isLoading: false,
|
|
196
|
+
cacheKey: response.cacheKey ?? null,
|
|
197
|
+
progress: null,
|
|
198
|
+
});
|
|
199
|
+
return response;
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
setState({ isLoading: false, cacheKey: null, progress: null });
|
|
203
|
+
throw err;
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
if (pendingRequests.has(requestKey))
|
|
207
|
+
pendingRequests.delete(requestKey);
|
|
208
|
+
}
|
|
209
|
+
}, [url, stableConfig]);
|
|
210
|
+
useEffect(() => {
|
|
211
|
+
return () => {
|
|
304
212
|
if (abortControllerRef.current)
|
|
305
213
|
abortControllerRef.current.abort();
|
|
306
214
|
};
|
|
307
215
|
}, []);
|
|
308
|
-
return
|
|
216
|
+
return { mutate, ...state };
|
|
309
217
|
}
|
|
310
218
|
/**
|
|
311
219
|
* React hook for infinite pagination fetching with custom offset logic.
|
|
@@ -327,117 +235,82 @@ export default function createApi(options) {
|
|
|
327
235
|
* ```
|
|
328
236
|
*/
|
|
329
237
|
function useInfiniteFetch(url, options, config) {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
(
|
|
342
|
-
(
|
|
343
|
-
JSON.stringify(config === null || config === void 0 ? void 0 : config.headers),
|
|
344
|
-
JSON.stringify(config === null || config === void 0 ? void 0 : config.params),
|
|
238
|
+
const { initialOffset, offsetKey, setOffset } = options;
|
|
239
|
+
const abortControllerRef = useRef(null);
|
|
240
|
+
const [items, setItems] = useState([]);
|
|
241
|
+
const [offset, setOffsetState] = useState(initialOffset);
|
|
242
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
243
|
+
const [isFetchingNextPage, setIsFetchingNextPage] = useState(false);
|
|
244
|
+
const [hasNextPage, setHasNextPage] = useState(true);
|
|
245
|
+
const [error, setError] = useState(null);
|
|
246
|
+
const stableConfig = useMemo(() => config, [
|
|
247
|
+
config?.cache?.enabled,
|
|
248
|
+
config?.cache?.revalidate,
|
|
249
|
+
JSON.stringify(config?.headers),
|
|
250
|
+
JSON.stringify(config?.params),
|
|
345
251
|
]);
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
if (abortControllerRef.current)
|
|
360
|
-
abortControllerRef.current.abort();
|
|
361
|
-
abortControllerRef.current = new AbortController();
|
|
362
|
-
if (!append)
|
|
363
|
-
setIsLoading(true);
|
|
364
|
-
else
|
|
365
|
-
setIsFetchingNextPage(true);
|
|
366
|
-
_c.label = 1;
|
|
367
|
-
case 1:
|
|
368
|
-
_c.trys.push([1, 3, 4, 5]);
|
|
369
|
-
return [4 /*yield*/, instance.get(url, __assign(__assign({}, config), { params: __assign(__assign({}, ((_b = config === null || config === void 0 ? void 0 : config.params) !== null && _b !== void 0 ? _b : {})), (_a = {}, _a[offsetKey !== null && offsetKey !== void 0 ? offsetKey : 'offset'] = offsetValue, _a)), signal: abortControllerRef.current.signal }))];
|
|
370
|
-
case 2:
|
|
371
|
-
response = _c.sent();
|
|
372
|
-
data_1 = response.data;
|
|
373
|
-
setItems(function (prev) { return (append ? __spreadArray(__spreadArray([], __read(prev), false), [data_1], false) : [data_1]); });
|
|
374
|
-
nextOffset = setOffset(data_1, append ? __spreadArray(__spreadArray([], __read(items), false), [data_1], false) : [data_1], offsetValue);
|
|
375
|
-
if (nextOffset === null || nextOffset === undefined) {
|
|
376
|
-
setHasNextPage(false);
|
|
377
|
-
}
|
|
378
|
-
else {
|
|
379
|
-
setHasNextPage(true);
|
|
380
|
-
setOffsetState(nextOffset);
|
|
381
|
-
}
|
|
382
|
-
setError(null);
|
|
383
|
-
return [3 /*break*/, 5];
|
|
384
|
-
case 3:
|
|
385
|
-
err_3 = _c.sent();
|
|
386
|
-
if (!(err_3 instanceof Error && err_3.name === 'AbortError')) {
|
|
387
|
-
setError(err_3);
|
|
388
|
-
}
|
|
389
|
-
return [3 /*break*/, 5];
|
|
390
|
-
case 4:
|
|
391
|
-
setIsLoading(false);
|
|
392
|
-
setIsFetchingNextPage(false);
|
|
393
|
-
return [7 /*endfinally*/];
|
|
394
|
-
case 5: return [2 /*return*/];
|
|
395
|
-
}
|
|
252
|
+
const fetchPage = useCallback(async (offsetValue, append = false) => {
|
|
253
|
+
if (abortControllerRef.current)
|
|
254
|
+
abortControllerRef.current.abort();
|
|
255
|
+
abortControllerRef.current = new AbortController();
|
|
256
|
+
if (!append)
|
|
257
|
+
setIsLoading(true);
|
|
258
|
+
else
|
|
259
|
+
setIsFetchingNextPage(true);
|
|
260
|
+
try {
|
|
261
|
+
const response = await instance.get(url, {
|
|
262
|
+
...config,
|
|
263
|
+
params: { ...(config?.params ?? {}), [offsetKey ?? 'offset']: offsetValue },
|
|
264
|
+
signal: abortControllerRef.current.signal,
|
|
396
265
|
});
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
case 0:
|
|
403
|
-
if (!hasNextPage || isFetchingNextPage)
|
|
404
|
-
return [2 /*return*/];
|
|
405
|
-
return [4 /*yield*/, fetchPage(offset, true)];
|
|
406
|
-
case 1:
|
|
407
|
-
_a.sent();
|
|
408
|
-
return [2 /*return*/];
|
|
266
|
+
const { data } = response;
|
|
267
|
+
setItems(prev => (append ? [...prev, data] : [data]));
|
|
268
|
+
const nextOffset = setOffset(data, append ? [...items, data] : [data], offsetValue);
|
|
269
|
+
if (nextOffset === null || nextOffset === undefined) {
|
|
270
|
+
setHasNextPage(false);
|
|
409
271
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
return [4 /*yield*/, fetchPage(initialOffset, false)];
|
|
420
|
-
case 1:
|
|
421
|
-
_a.sent();
|
|
422
|
-
return [2 /*return*/];
|
|
272
|
+
else {
|
|
273
|
+
setHasNextPage(true);
|
|
274
|
+
setOffsetState(nextOffset);
|
|
275
|
+
}
|
|
276
|
+
setError(null);
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
if (!(err instanceof Error && err.name === 'AbortError')) {
|
|
280
|
+
setError(err);
|
|
423
281
|
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
|
|
282
|
+
}
|
|
283
|
+
finally {
|
|
284
|
+
setIsLoading(false);
|
|
285
|
+
setIsFetchingNextPage(false);
|
|
286
|
+
}
|
|
287
|
+
}, [url, stableConfig, offsetKey]);
|
|
288
|
+
const fetchNextPage = useCallback(async () => {
|
|
289
|
+
if (!hasNextPage || isFetchingNextPage)
|
|
290
|
+
return;
|
|
291
|
+
await fetchPage(offset, true);
|
|
292
|
+
}, [offset, hasNextPage, isFetchingNextPage, fetchPage]);
|
|
293
|
+
const refetch = useCallback(async () => {
|
|
294
|
+
setItems([]);
|
|
295
|
+
setOffsetState(initialOffset);
|
|
296
|
+
setHasNextPage(true);
|
|
297
|
+
await fetchPage(initialOffset, false);
|
|
298
|
+
}, [initialOffset, fetchPage]);
|
|
299
|
+
useEffect(() => {
|
|
427
300
|
fetchPage(initialOffset);
|
|
428
|
-
return
|
|
301
|
+
return () => {
|
|
429
302
|
if (abortControllerRef.current)
|
|
430
303
|
abortControllerRef.current.abort();
|
|
431
304
|
};
|
|
432
305
|
}, [fetchPage, initialOffset]);
|
|
433
306
|
return {
|
|
434
307
|
data: items,
|
|
435
|
-
error
|
|
436
|
-
isLoading
|
|
437
|
-
hasNextPage
|
|
438
|
-
isFetchingNextPage
|
|
439
|
-
fetchNextPage
|
|
440
|
-
refetch
|
|
308
|
+
error,
|
|
309
|
+
isLoading,
|
|
310
|
+
hasNextPage,
|
|
311
|
+
isFetchingNextPage,
|
|
312
|
+
fetchNextPage,
|
|
313
|
+
refetch,
|
|
441
314
|
};
|
|
442
315
|
}
|
|
443
316
|
return {
|
|
@@ -451,23 +324,23 @@ export default function createApi(options) {
|
|
|
451
324
|
* @param key - Unique cache key.
|
|
452
325
|
* @returns Cached data or `undefined` if not found.
|
|
453
326
|
*/
|
|
454
|
-
getCache:
|
|
327
|
+
getCache: (key) => instance.getCache(key),
|
|
455
328
|
/**
|
|
456
329
|
* Stores data in cache.
|
|
457
330
|
* @param key - Cache key.
|
|
458
331
|
* @param data - Data to store.
|
|
459
332
|
* @param ttl - Optional time-to-live in milliseconds.
|
|
460
333
|
*/
|
|
461
|
-
setCache:
|
|
334
|
+
setCache: (key, data, ttl) => instance.setCache(key, data, ttl),
|
|
462
335
|
/**
|
|
463
336
|
* Removes a single cached entry.
|
|
464
337
|
* @param key - Cache key to remove.
|
|
465
338
|
*/
|
|
466
|
-
removeCache:
|
|
339
|
+
removeCache: (key) => instance.removeCache(key),
|
|
467
340
|
/**
|
|
468
341
|
* Clears all cache entries.
|
|
469
342
|
*/
|
|
470
|
-
clearCache:
|
|
343
|
+
clearCache: () => instance.clearCache(),
|
|
471
344
|
// ----------- interceptors -----------
|
|
472
345
|
/**
|
|
473
346
|
* Registers custom request/response interceptors.
|
|
@@ -483,6 +356,6 @@ export default function createApi(options) {
|
|
|
483
356
|
* })
|
|
484
357
|
* ```
|
|
485
358
|
*/
|
|
486
|
-
setInterceptors:
|
|
359
|
+
setInterceptors: (interceptors) => instance.setInterceptors(interceptors),
|
|
487
360
|
};
|
|
488
361
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fajarmaulana/komerce-lp-helper",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Helper functions, hooks, and utils for Komerce LP",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
6
8
|
"types": "dist/index.d.ts",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
7
17
|
"files": [
|
|
8
18
|
"dist"
|
|
9
19
|
],
|