@fajarmaulana/komerce-lp-helper 0.1.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.
- package/LICENSE +21 -0
- package/README.md +159 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/hooks/debounce.d.ts +40 -0
- package/dist/hooks/debounce.js +118 -0
- package/dist/hooks/router.d.ts +111 -0
- package/dist/hooks/router.js +182 -0
- package/dist/hooks/slider.d.ts +50 -0
- package/dist/hooks/slider.js +167 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -0
- package/dist/types/enum.d.ts +12 -0
- package/dist/types/enum.js +14 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/api.d.ts +274 -0
- package/dist/utils/api.js +503 -0
- package/dist/utils/cookie.d.ts +50 -0
- package/dist/utils/cookie.js +75 -0
- package/dist/utils/file.d.ts +95 -0
- package/dist/utils/file.js +200 -0
- package/dist/utils/general.d.ts +45 -0
- package/dist/utils/general.js +75 -0
- package/dist/utils/local.d.ts +40 -0
- package/dist/utils/local.js +54 -0
- package/dist/utils/useApi.d.ts +94 -0
- package/dist/utils/useApi.js +488 -0
- package/package.json +34 -0
|
@@ -0,0 +1,488 @@
|
|
|
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
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
74
|
+
import { ApiInstance, buildURL, } from './api';
|
|
75
|
+
var pendingRequests = new Map();
|
|
76
|
+
/**
|
|
77
|
+
* Creates a new API instance with built-in React hooks (`fetch`, `mutation`, `infinite`)
|
|
78
|
+
* for performing typed data fetching and mutations with progress tracking.
|
|
79
|
+
*
|
|
80
|
+
* @param options - Optional configuration for the API instance (e.g. baseURL, default headers).
|
|
81
|
+
* @returns An object containing data hooks (`fetch`, `mutation`, `infinite`), cache manipulation methods, and interceptor registration.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```tsx
|
|
85
|
+
* const api = createApi({ baseURL: '/api' })
|
|
86
|
+
*
|
|
87
|
+
* const { data, isLoading, refetch } = api.fetch<User[]>('/users')
|
|
88
|
+
*
|
|
89
|
+
* const { mutate, isLoading, progress } = api.mutation<User, FormData>('/users', { method: 'POST' })
|
|
90
|
+
*
|
|
91
|
+
* const { data, isLoading, refetch } = api.infinite<User[]>('/users', { initialOffset: 0 })
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export default function createApi(options) {
|
|
95
|
+
if (options === void 0) { options = {}; }
|
|
96
|
+
var instance = new ApiInstance(options);
|
|
97
|
+
/**
|
|
98
|
+
* React hook for data fetching with built-in loading, error, and refetch states.
|
|
99
|
+
*
|
|
100
|
+
* @typeParam T - Expected data type from the API response.
|
|
101
|
+
* @param url - The endpoint URL (relative to instance baseURL).
|
|
102
|
+
* @param config - Optional HTTP configuration (headers, params, cache, etc.).
|
|
103
|
+
* @param enabled - Whether the fetch should run automatically on mount.
|
|
104
|
+
*
|
|
105
|
+
* @returns An object with:
|
|
106
|
+
* - `data`: fetched data or `null`
|
|
107
|
+
* - `error`: any error encountered
|
|
108
|
+
* - `isLoading`: request state
|
|
109
|
+
* - `cacheKey`: identifier for caching this request
|
|
110
|
+
* - `refetch()`: manually trigger a new fetch
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```tsx
|
|
114
|
+
* const { data, isLoading, refetch } = api.fetch<User[]>('/users')
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
function useFetch(url, config, enabled) {
|
|
118
|
+
var _this = this;
|
|
119
|
+
var _a, _b;
|
|
120
|
+
if (enabled === void 0) { enabled = true; }
|
|
121
|
+
var abortControllerRef = useRef(null);
|
|
122
|
+
var _c = __read(useState({
|
|
123
|
+
data: null,
|
|
124
|
+
error: null,
|
|
125
|
+
isLoading: enabled,
|
|
126
|
+
cacheKey: null,
|
|
127
|
+
}), 2), state = _c[0], setState = _c[1];
|
|
128
|
+
var stableConfig = useMemo(function () { return config; }, [
|
|
129
|
+
(_a = config === null || config === void 0 ? void 0 : config.cache) === null || _a === void 0 ? void 0 : _a.enabled,
|
|
130
|
+
(_b = config === null || config === void 0 ? void 0 : config.cache) === null || _b === void 0 ? void 0 : _b.revalidate,
|
|
131
|
+
JSON.stringify(config === null || config === void 0 ? void 0 : config.headers),
|
|
132
|
+
JSON.stringify(config === null || config === void 0 ? void 0 : config.params),
|
|
133
|
+
]);
|
|
134
|
+
var fetchData = useCallback(function () {
|
|
135
|
+
var args_1 = [];
|
|
136
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
137
|
+
args_1[_i] = arguments[_i];
|
|
138
|
+
}
|
|
139
|
+
return __awaiter(_this, __spreadArray([], __read(args_1), false), void 0, function (refetch) {
|
|
140
|
+
var response, newState, err_1, newState;
|
|
141
|
+
var _a;
|
|
142
|
+
if (refetch === void 0) { refetch = false; }
|
|
143
|
+
return __generator(this, function (_b) {
|
|
144
|
+
switch (_b.label) {
|
|
145
|
+
case 0:
|
|
146
|
+
if (!enabled && !refetch) {
|
|
147
|
+
return [2 /*return*/, { data: null, error: null, isLoading: false, cacheKey: null }];
|
|
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
|
+
}
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
}, [enabled, url, stableConfig]);
|
|
184
|
+
useEffect(function () {
|
|
185
|
+
fetchData();
|
|
186
|
+
return function () {
|
|
187
|
+
if (abortControllerRef.current)
|
|
188
|
+
abortControllerRef.current.abort();
|
|
189
|
+
};
|
|
190
|
+
}, [fetchData]);
|
|
191
|
+
return __assign(__assign({}, state), { refetch: function () { return fetchData(true); } });
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* React hook for making data mutations (e.g. POST, PUT, DELETE) with built-in
|
|
195
|
+
* loading state, upload/download progress tracking, and request deduplication.
|
|
196
|
+
*
|
|
197
|
+
* @typeParam TData - Expected data type of the response.
|
|
198
|
+
* @typeParam TRequest - Payload type for the mutation body or query param.
|
|
199
|
+
*
|
|
200
|
+
* @param url - Endpoint URL for the mutation.
|
|
201
|
+
* @param config - Optional mutation config (method, headers, cache, progress, etc.) with queryMutation for bad practice mutate fetching using query while true.
|
|
202
|
+
*
|
|
203
|
+
* @returns An object with:
|
|
204
|
+
* - `mutate(request)`: Function to trigger the mutation.
|
|
205
|
+
* - `isLoading`: Whether the request is currently in progress.
|
|
206
|
+
* - `cacheKey`: Identifier for caching this request.
|
|
207
|
+
* - `progress`: Download or Upload progress info (loaded, total, percentage) - only available when progress is enabled
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```tsx
|
|
211
|
+
*
|
|
212
|
+
* // With upload progress
|
|
213
|
+
* const { mutate, isLoading, progress } = api.mutation<User, FormData>('/upload', {
|
|
214
|
+
* method: 'POST',
|
|
215
|
+
* progress: 'upload'
|
|
216
|
+
* })
|
|
217
|
+
*
|
|
218
|
+
* const handleSubmit = async (form: FormData) => {
|
|
219
|
+
* const { data } = await mutate(form)
|
|
220
|
+
* console.log(data)
|
|
221
|
+
* }
|
|
222
|
+
*
|
|
223
|
+
* // Show progress
|
|
224
|
+
* {progress && <div>Uploaded: {progress.percentage}%</div>}
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
function useMutation(url, config) {
|
|
228
|
+
var _this = this;
|
|
229
|
+
var _a, _b, _c;
|
|
230
|
+
var abortControllerRef = useRef(null);
|
|
231
|
+
var _d = __read(useState({
|
|
232
|
+
isLoading: false,
|
|
233
|
+
cacheKey: null,
|
|
234
|
+
progress: null,
|
|
235
|
+
}), 2), state = _d[0], setState = _d[1];
|
|
236
|
+
var stableConfig = useMemo(function () { return config; }, [
|
|
237
|
+
config === null || config === void 0 ? void 0 : config.method,
|
|
238
|
+
(_a = config === null || config === void 0 ? void 0 : config.cache) === null || _a === void 0 ? void 0 : _a.enabled,
|
|
239
|
+
(_b = config === null || config === void 0 ? void 0 : config.cache) === null || _b === void 0 ? void 0 : _b.revalidate,
|
|
240
|
+
config === null || config === void 0 ? void 0 : config.queryMutation,
|
|
241
|
+
config === null || config === void 0 ? void 0 : config.progress,
|
|
242
|
+
JSON.stringify((_c = config === null || config === void 0 ? void 0 : config.headers) !== null && _c !== void 0 ? _c : {}),
|
|
243
|
+
]);
|
|
244
|
+
var mutate = useCallback(function (request) { return __awaiter(_this, void 0, void 0, function () {
|
|
245
|
+
var requestKey, method, shouldTrackUpload, shouldTrackDownload, requestPromise, response, err_2;
|
|
246
|
+
var _a;
|
|
247
|
+
return __generator(this, function (_b) {
|
|
248
|
+
switch (_b.label) {
|
|
249
|
+
case 0:
|
|
250
|
+
if (abortControllerRef.current)
|
|
251
|
+
abortControllerRef.current.abort();
|
|
252
|
+
abortControllerRef.current = new AbortController();
|
|
253
|
+
setState(function (s) { return (__assign(__assign({}, s), { isLoading: true, progress: null })); });
|
|
254
|
+
requestKey = '';
|
|
255
|
+
_b.label = 1;
|
|
256
|
+
case 1:
|
|
257
|
+
_b.trys.push([1, 3, 4, 5]);
|
|
258
|
+
method = (stableConfig === null || stableConfig === void 0 ? void 0 : stableConfig.method) || 'GET';
|
|
259
|
+
requestKey = JSON.stringify({ url: url, method: method, request: request });
|
|
260
|
+
if (pendingRequests.has(requestKey)) {
|
|
261
|
+
return [2 /*return*/, pendingRequests.get(requestKey)];
|
|
262
|
+
}
|
|
263
|
+
shouldTrackUpload = (stableConfig === null || stableConfig === void 0 ? void 0 : stableConfig.progress) === 'upload';
|
|
264
|
+
shouldTrackDownload = (stableConfig === null || stableConfig === void 0 ? void 0 : stableConfig.progress) === 'download';
|
|
265
|
+
requestPromise = void 0;
|
|
266
|
+
if (method === 'GET') {
|
|
267
|
+
requestPromise = instance.get(url, __assign(__assign({}, stableConfig), { params: request, signal: abortControllerRef.current.signal, onDownload: shouldTrackDownload
|
|
268
|
+
? function (progress) {
|
|
269
|
+
setState(function (s) { return (__assign(__assign({}, s), { progress: progress })); });
|
|
270
|
+
}
|
|
271
|
+
: undefined }));
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
requestPromise = instance.request(__assign(__assign({}, stableConfig), { url: (config === null || config === void 0 ? void 0 : config.queryMutation) ? buildURL(url, request) : url, method: method, body: request ? request : undefined, signal: abortControllerRef.current.signal, onUpload: shouldTrackUpload
|
|
275
|
+
? function (progress) {
|
|
276
|
+
setState(function (s) { return (__assign(__assign({}, s), { progress: progress })); });
|
|
277
|
+
}
|
|
278
|
+
: undefined }));
|
|
279
|
+
}
|
|
280
|
+
pendingRequests.set(requestKey, requestPromise);
|
|
281
|
+
return [4 /*yield*/, requestPromise];
|
|
282
|
+
case 2:
|
|
283
|
+
response = _b.sent();
|
|
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*/];
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
}); }, [url, stableConfig]);
|
|
302
|
+
useEffect(function () {
|
|
303
|
+
return function () {
|
|
304
|
+
if (abortControllerRef.current)
|
|
305
|
+
abortControllerRef.current.abort();
|
|
306
|
+
};
|
|
307
|
+
}, []);
|
|
308
|
+
return __assign({ mutate: mutate }, state);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* React hook for infinite pagination fetching with custom offset logic.
|
|
312
|
+
*
|
|
313
|
+
* @typeParam T - Expected data type from the API response.
|
|
314
|
+
* @param url - Endpoint URL (relative to instance baseURL).
|
|
315
|
+
* @param options - Infinite pagination options.
|
|
316
|
+
* @param config - Optional HTTP configuration (headers, params, etc.).
|
|
317
|
+
* @returns Object containing paginated data, loading states, and pagination controls.
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* ```tsx
|
|
321
|
+
* const { data, isLoading, hasNextPage, isFetchingNextPage, fetchNextPage, refetch } = api.infinite<User[]>('/users', {
|
|
322
|
+
* initialOffset: 0,
|
|
323
|
+
* setOffset: (lastItems, allItems, lastOffset) => {
|
|
324
|
+
* return lastItems.length ? lastOffset + 10 : null
|
|
325
|
+
* },
|
|
326
|
+
* })
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
function useInfiniteFetch(url, options, config) {
|
|
330
|
+
var _this = this;
|
|
331
|
+
var _a, _b;
|
|
332
|
+
var initialOffset = options.initialOffset, offsetKey = options.offsetKey, setOffset = options.setOffset;
|
|
333
|
+
var abortControllerRef = useRef(null);
|
|
334
|
+
var _c = __read(useState([]), 2), items = _c[0], setItems = _c[1];
|
|
335
|
+
var _d = __read(useState(initialOffset), 2), offset = _d[0], setOffsetState = _d[1];
|
|
336
|
+
var _e = __read(useState(false), 2), isLoading = _e[0], setIsLoading = _e[1];
|
|
337
|
+
var _f = __read(useState(false), 2), isFetchingNextPage = _f[0], setIsFetchingNextPage = _f[1];
|
|
338
|
+
var _g = __read(useState(true), 2), hasNextPage = _g[0], setHasNextPage = _g[1];
|
|
339
|
+
var _h = __read(useState(null), 2), error = _h[0], setError = _h[1];
|
|
340
|
+
var stableConfig = useMemo(function () { return config; }, [
|
|
341
|
+
(_a = config === null || config === void 0 ? void 0 : config.cache) === null || _a === void 0 ? void 0 : _a.enabled,
|
|
342
|
+
(_b = config === null || config === void 0 ? void 0 : config.cache) === null || _b === void 0 ? void 0 : _b.revalidate,
|
|
343
|
+
JSON.stringify(config === null || config === void 0 ? void 0 : config.headers),
|
|
344
|
+
JSON.stringify(config === null || config === void 0 ? void 0 : config.params),
|
|
345
|
+
]);
|
|
346
|
+
var fetchPage = useCallback(function (offsetValue_1) {
|
|
347
|
+
var args_1 = [];
|
|
348
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
349
|
+
args_1[_i - 1] = arguments[_i];
|
|
350
|
+
}
|
|
351
|
+
return __awaiter(_this, __spreadArray([offsetValue_1], __read(args_1), false), void 0, function (offsetValue, append) {
|
|
352
|
+
var response, data_1, nextOffset, err_3;
|
|
353
|
+
var _a;
|
|
354
|
+
var _b;
|
|
355
|
+
if (append === void 0) { append = false; }
|
|
356
|
+
return __generator(this, function (_c) {
|
|
357
|
+
switch (_c.label) {
|
|
358
|
+
case 0:
|
|
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
|
+
}
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
}, [url, stableConfig, offsetKey]);
|
|
399
|
+
var fetchNextPage = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
400
|
+
return __generator(this, function (_a) {
|
|
401
|
+
switch (_a.label) {
|
|
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*/];
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
}); }, [offset, hasNextPage, isFetchingNextPage, fetchPage]);
|
|
412
|
+
var refetch = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
413
|
+
return __generator(this, function (_a) {
|
|
414
|
+
switch (_a.label) {
|
|
415
|
+
case 0:
|
|
416
|
+
setItems([]);
|
|
417
|
+
setOffsetState(initialOffset);
|
|
418
|
+
setHasNextPage(true);
|
|
419
|
+
return [4 /*yield*/, fetchPage(initialOffset, false)];
|
|
420
|
+
case 1:
|
|
421
|
+
_a.sent();
|
|
422
|
+
return [2 /*return*/];
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
}); }, [initialOffset, fetchPage]);
|
|
426
|
+
useEffect(function () {
|
|
427
|
+
fetchPage(initialOffset);
|
|
428
|
+
return function () {
|
|
429
|
+
if (abortControllerRef.current)
|
|
430
|
+
abortControllerRef.current.abort();
|
|
431
|
+
};
|
|
432
|
+
}, [fetchPage, initialOffset]);
|
|
433
|
+
return {
|
|
434
|
+
data: items,
|
|
435
|
+
error: error,
|
|
436
|
+
isLoading: isLoading,
|
|
437
|
+
hasNextPage: hasNextPage,
|
|
438
|
+
isFetchingNextPage: isFetchingNextPage,
|
|
439
|
+
fetchNextPage: fetchNextPage,
|
|
440
|
+
refetch: refetch,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
return {
|
|
444
|
+
// ----------- React hooks API -----------
|
|
445
|
+
fetch: useFetch,
|
|
446
|
+
mutation: useMutation,
|
|
447
|
+
infinite: useInfiniteFetch,
|
|
448
|
+
// ----------- cache ops -----------
|
|
449
|
+
/**
|
|
450
|
+
* Retrieves a cached response by its key.
|
|
451
|
+
* @param key - Unique cache key.
|
|
452
|
+
* @returns Cached data or `undefined` if not found.
|
|
453
|
+
*/
|
|
454
|
+
getCache: function (key) { return instance.getCache(key); },
|
|
455
|
+
/**
|
|
456
|
+
* Stores data in cache.
|
|
457
|
+
* @param key - Cache key.
|
|
458
|
+
* @param data - Data to store.
|
|
459
|
+
* @param ttl - Optional time-to-live in milliseconds.
|
|
460
|
+
*/
|
|
461
|
+
setCache: function (key, data, ttl) { return instance.setCache(key, data, ttl); },
|
|
462
|
+
/**
|
|
463
|
+
* Removes a single cached entry.
|
|
464
|
+
* @param key - Cache key to remove.
|
|
465
|
+
*/
|
|
466
|
+
removeCache: function (key) { return instance.removeCache(key); },
|
|
467
|
+
/**
|
|
468
|
+
* Clears all cache entries.
|
|
469
|
+
*/
|
|
470
|
+
clearCache: function () { return instance.clearCache(); },
|
|
471
|
+
// ----------- interceptors -----------
|
|
472
|
+
/**
|
|
473
|
+
* Registers custom request/response interceptors.
|
|
474
|
+
*
|
|
475
|
+
* @param interceptors - Object containing optional `request`, `response`, and `error` interceptors.
|
|
476
|
+
*
|
|
477
|
+
* @example
|
|
478
|
+
* ```ts
|
|
479
|
+
* api.setInterceptors({
|
|
480
|
+
* request: config => config,
|
|
481
|
+
* response: res => res,
|
|
482
|
+
* error: err => Promise.reject(err),
|
|
483
|
+
* })
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
setInterceptors: function (interceptors) { return instance.setInterceptors(interceptors); },
|
|
487
|
+
};
|
|
488
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fajarmaulana/komerce-lp-helper",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Helper functions, hooks and utils for Komerce LP",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc"
|
|
12
|
+
},
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"react": ">=18",
|
|
15
|
+
"react-dom": ">=18",
|
|
16
|
+
"react-router-dom": ">=6"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"typescript": "^5.2.0",
|
|
20
|
+
"@types/react": "^18.2.0",
|
|
21
|
+
"@types/react-dom": "^18.2.0"
|
|
22
|
+
},
|
|
23
|
+
"author": "Fajar Maulana",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"keywords": [
|
|
26
|
+
"react",
|
|
27
|
+
"debounce",
|
|
28
|
+
"slider",
|
|
29
|
+
"router",
|
|
30
|
+
"fetcher",
|
|
31
|
+
"utils",
|
|
32
|
+
"hooks"
|
|
33
|
+
]
|
|
34
|
+
}
|