grab-url 1.0.6 → 1.0.7
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/grab-api.cjs.js +1 -1
- package/dist/grab-api.cjs.js.map +1 -1
- package/dist/grab-api.d.ts +1 -1
- package/dist/grab-api.es.js +166 -192
- package/dist/grab-api.es.js.map +1 -1
- package/dist/icons.cjs.js +0 -0
- package/dist/icons.cjs.js.map +0 -0
- package/dist/icons.d.ts +0 -0
- package/dist/icons.es.js +0 -0
- package/dist/icons.es.js.map +0 -0
- package/package.json +1 -1
- package/readme.md +0 -0
- package/src/grab-api.ts +48 -44
- package/src/grab-url.js +6 -41
- package/src/icons/cli/spinners.json +0 -0
- package/src/icons/svg/index.ts +0 -0
- package/src/icons/svg/loading-bouncy-ball.svg +0 -0
- package/src/icons/svg/loading-double-ring.svg +0 -0
- package/src/icons/svg/loading-eclipse.svg +0 -0
- package/src/icons/svg/loading-ellipsis.svg +0 -0
- package/src/icons/svg/loading-floating-search.svg +0 -0
- package/src/icons/svg/loading-gears.svg +0 -0
- package/src/icons/svg/loading-infinity.svg +0 -0
- package/src/icons/svg/loading-orbital.svg +0 -0
- package/src/icons/svg/loading-pacman.svg +0 -0
- package/src/icons/svg/loading-pulse-bars.svg +0 -0
- package/src/icons/svg/loading-red-blue-ball.svg +0 -0
- package/src/icons/svg/loading-reload-arrow.svg +0 -0
- package/src/icons/svg/loading-ring.svg +0 -0
- package/src/icons/svg/loading-ripple.svg +0 -0
- package/src/icons/svg/loading-spinner-oval.svg +0 -0
- package/src/icons/svg/loading-spinner.svg +0 -0
- package/src/icons/svg/loading-square-blocks.svg +0 -0
- package/src/log.ts +0 -0
package/dist/grab-api.es.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
function log(message = "", options = {}) {
|
|
2
2
|
let {
|
|
3
3
|
color = null,
|
|
4
|
-
style = "color:
|
|
4
|
+
style = "color: #66ccff; font-size: 10pt;",
|
|
5
5
|
hideInProduction = void 0,
|
|
6
6
|
startSpinner = false,
|
|
7
7
|
stopSpinner = false
|
|
@@ -173,7 +173,7 @@ function setupDevTools() {
|
|
|
173
173
|
});
|
|
174
174
|
}
|
|
175
175
|
async function grab$1(path, options) {
|
|
176
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j
|
|
176
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
177
177
|
let {
|
|
178
178
|
headers,
|
|
179
179
|
response = {},
|
|
@@ -239,208 +239,182 @@ async function grab$1(path, options) {
|
|
|
239
239
|
if (s("http:") || s("https:")) baseURL = "";
|
|
240
240
|
else if (!s("/") && !baseURL.endsWith("/")) path = "/" + path;
|
|
241
241
|
else if (s("/") && baseURL.endsWith("/")) path = path.slice(1);
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
await grab$1(path, { ...options, repeat: 0 });
|
|
250
|
-
}
|
|
251
|
-
return response;
|
|
242
|
+
if (debounce > 0)
|
|
243
|
+
return await debouncer(async () => {
|
|
244
|
+
await grab$1(path, { ...options, debounce: 0 });
|
|
245
|
+
}, debounce * 1e3);
|
|
246
|
+
if (repeat > 1) {
|
|
247
|
+
for (let i = 0; i < repeat; i++) {
|
|
248
|
+
await grab$1(path, { ...options, repeat: 0 });
|
|
252
249
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
250
|
+
return response;
|
|
251
|
+
}
|
|
252
|
+
if (repeatEvery) {
|
|
253
|
+
setInterval(async () => {
|
|
254
|
+
await grab$1(path, { ...options, repeat: 0, repeatEvery: null });
|
|
255
|
+
}, repeatEvery * 1e3);
|
|
256
|
+
return response;
|
|
257
|
+
}
|
|
258
|
+
if (options == null ? void 0 : options.setDefaults) {
|
|
259
|
+
if (typeof window !== "undefined")
|
|
260
|
+
window.grab.defaults = { ...options, setDefaults: void 0 };
|
|
261
|
+
else if (typeof (global || globalThis).grab !== "undefined")
|
|
262
|
+
(global || globalThis).grab.defaults = {
|
|
263
|
+
...options,
|
|
264
|
+
setDefaults: void 0
|
|
265
|
+
};
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (typeof window !== void 0) {
|
|
269
|
+
const regrab = async () => await grab$1(path, { ...options, cache: false });
|
|
270
|
+
if (regrabOnStale && cache) setTimeout(regrab, 1e3 * cacheForTime);
|
|
271
|
+
if (regrabOnNetwork) window.addEventListener("online", regrab);
|
|
272
|
+
if (regrabOnFocus) {
|
|
273
|
+
window.addEventListener("focus", regrab);
|
|
274
|
+
document.addEventListener("visibilitychange", async () => {
|
|
275
|
+
if (document.visibilityState === "visible") await regrab();
|
|
276
|
+
});
|
|
258
277
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
278
|
+
}
|
|
279
|
+
let resFunction = typeof response === "function" ? response : null;
|
|
280
|
+
if (!response || resFunction) response = {};
|
|
281
|
+
var [paginateKey, paginateResult, paginateElement] = infiniteScroll || [];
|
|
282
|
+
if ((infiniteScroll == null ? void 0 : infiniteScroll.length) && typeof paginateElement !== "undefined" && typeof window !== "undefined") {
|
|
283
|
+
let paginateDOM = typeof paginateElement === "string" ? document.querySelector(paginateElement) : paginateElement;
|
|
284
|
+
if (!paginateDOM) log("paginateDOM not found", { color: "red" });
|
|
285
|
+
if (window.scrollListener)
|
|
286
|
+
paginateDOM.removeEventListener("scroll", window.scrollListener);
|
|
287
|
+
window.scrollListener = async (event) => {
|
|
288
|
+
const t = event.target;
|
|
289
|
+
localStorage.setItem(
|
|
290
|
+
"scroll",
|
|
291
|
+
JSON.stringify([t.scrollTop, t.scrollLeft, paginateElement])
|
|
292
|
+
);
|
|
293
|
+
if (t.scrollHeight - t.scrollTop <= t.clientHeight + 200) {
|
|
294
|
+
await grab$1(path, {
|
|
264
295
|
...options,
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
if (typeof window !== void 0) {
|
|
270
|
-
const regrab = async () => await grab$1(path, { ...options, cache: false });
|
|
271
|
-
if (regrabOnStale && cache) setTimeout(regrab, 1e3 * cacheForTime);
|
|
272
|
-
if (regrabOnNetwork) window.addEventListener("online", regrab);
|
|
273
|
-
if (regrabOnFocus) {
|
|
274
|
-
window.addEventListener("focus", regrab);
|
|
275
|
-
document.addEventListener("visibilitychange", async () => {
|
|
276
|
-
if (document.visibilityState === "visible") await regrab();
|
|
296
|
+
cache: false,
|
|
297
|
+
[paginateKey]: (priorRequest == null ? void 0 : priorRequest.currentPage) + 1
|
|
277
298
|
});
|
|
278
299
|
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
if (!response || resFunction) response = {};
|
|
282
|
-
var [paginateKey, paginateResult, paginateElement] = infiniteScroll || [];
|
|
283
|
-
if ((infiniteScroll == null ? void 0 : infiniteScroll.length) && typeof window !== "undefined") {
|
|
284
|
-
let paginateDOM = typeof paginateElement === "string" ? document.querySelector(paginateElement) : paginateElement;
|
|
285
|
-
if (window.scrollListener)
|
|
286
|
-
paginateDOM.removeEventListener("scroll", window.scrollListener);
|
|
287
|
-
window.scrollListener = async (event) => {
|
|
288
|
-
const t = event.target;
|
|
289
|
-
localStorage.setItem(
|
|
290
|
-
"scroll",
|
|
291
|
-
JSON.stringify([t.scrollTop, t.scrollLeft, paginateElement])
|
|
292
|
-
);
|
|
293
|
-
if (t.scrollHeight - t.scrollTop <= t.clientHeight + 200) {
|
|
294
|
-
await grab$1(path, {
|
|
295
|
-
...options,
|
|
296
|
-
cache: false,
|
|
297
|
-
[paginateKey]: (priorRequest == null ? void 0 : priorRequest.currentPage) + 1
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
};
|
|
300
|
+
};
|
|
301
|
+
if (paginateDOM)
|
|
301
302
|
paginateDOM.addEventListener("scroll", window.scrollListener);
|
|
303
|
+
}
|
|
304
|
+
let paramsAsText = JSON.stringify(
|
|
305
|
+
paginateKey ? { ...params, [paginateKey]: void 0 } : params
|
|
306
|
+
);
|
|
307
|
+
let priorRequest = (_d = grab$1 == null ? void 0 : grab$1.log) == null ? void 0 : _d.find(
|
|
308
|
+
(e) => e.request == paramsAsText && e.path == path
|
|
309
|
+
);
|
|
310
|
+
if (!paginateKey) {
|
|
311
|
+
for (let key of Object.keys(response)) response[key] = void 0;
|
|
312
|
+
if (cache && (!cacheForTime || (priorRequest == null ? void 0 : priorRequest.lastFetchTime) > Date.now() - 1e3 * cacheForTime)) {
|
|
313
|
+
for (let key of Object.keys(priorRequest.res))
|
|
314
|
+
response[key] = priorRequest.res[key];
|
|
315
|
+
if (resFunction) response = resFunction(response);
|
|
302
316
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
)
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
);
|
|
309
|
-
if (!paginateKey) {
|
|
310
|
-
for (let key of Object.keys(response)) response[key] = void 0;
|
|
311
|
-
if (cache && (!cacheForTime || (priorRequest == null ? void 0 : priorRequest.lastFetchTime) > Date.now() - 1e3 * cacheForTime)) {
|
|
312
|
-
for (let key of Object.keys(priorRequest.res))
|
|
313
|
-
response[key] = priorRequest.res[key];
|
|
314
|
-
if (resFunction) response = resFunction(response);
|
|
315
|
-
}
|
|
316
|
-
} else {
|
|
317
|
-
let pageNumber = (priorRequest == null ? void 0 : priorRequest.currentPage) + 1 || (params == null ? void 0 : params[paginateKey]) || 1;
|
|
318
|
-
if (!priorRequest) {
|
|
319
|
-
response[paginateResult] = [];
|
|
320
|
-
pageNumber = 1;
|
|
321
|
-
}
|
|
322
|
-
if (priorRequest) priorRequest.currentPage = pageNumber;
|
|
323
|
-
params[paginateKey] = pageNumber;
|
|
317
|
+
} else {
|
|
318
|
+
let pageNumber = (priorRequest == null ? void 0 : priorRequest.currentPage) + 1 || (params == null ? void 0 : params[paginateKey]) || 1;
|
|
319
|
+
if (!priorRequest) {
|
|
320
|
+
response[paginateResult] = [];
|
|
321
|
+
pageNumber = 1;
|
|
324
322
|
}
|
|
325
|
-
if (
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
323
|
+
if (priorRequest) priorRequest.currentPage = pageNumber;
|
|
324
|
+
params[paginateKey] = pageNumber;
|
|
325
|
+
}
|
|
326
|
+
if (resFunction) resFunction({ isLoading: true });
|
|
327
|
+
else if (typeof response === "object") response.isLoading = true;
|
|
328
|
+
if (resFunction) response = resFunction(response);
|
|
329
|
+
if (rateLimit > 0 && (priorRequest == null ? void 0 : priorRequest.lastFetchTime) && priorRequest.lastFetchTime > Date.now() - 1e3 * rateLimit)
|
|
330
|
+
throw new Error(`Fetch rate limit exceeded for ${path}.
|
|
330
331
|
Wait ${rateLimit}s between requests.`);
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
332
|
+
if (priorRequest == null ? void 0 : priorRequest.controller) {
|
|
333
|
+
if (cancelOngoingIfNew) priorRequest.controller.abort();
|
|
334
|
+
else if (cancelNewIfOngoing) return { isLoading: true };
|
|
335
|
+
}
|
|
336
|
+
if (typeof grab$1.log != "undefined")
|
|
337
|
+
(_e = grab$1.log) == null ? void 0 : _e.unshift({
|
|
338
|
+
path,
|
|
339
|
+
request: paramsAsText,
|
|
340
|
+
lastFetchTime: Date.now(),
|
|
341
|
+
controller: new AbortController()
|
|
342
|
+
});
|
|
343
|
+
let fetchParams = {
|
|
344
|
+
method,
|
|
345
|
+
headers: {
|
|
346
|
+
"Content-Type": "application/json",
|
|
347
|
+
Accept: "application/json",
|
|
348
|
+
...headers
|
|
349
|
+
},
|
|
350
|
+
body: params.body,
|
|
351
|
+
redirect: "follow",
|
|
352
|
+
cache: cache ? "force-cache" : "no-store",
|
|
353
|
+
signal: cancelOngoingIfNew ? (_g = (_f = grab$1.log[0]) == null ? void 0 : _f.controller) == null ? void 0 : _g.signal : AbortSignal.timeout(timeout * 1e3)
|
|
354
|
+
};
|
|
355
|
+
let paramsGETRequest = "";
|
|
356
|
+
if (["POST", "PUT", "PATCH"].includes(method))
|
|
357
|
+
fetchParams.body = params.body || JSON.stringify(params);
|
|
358
|
+
else
|
|
359
|
+
paramsGETRequest = (Object.keys(params).length ? "?" : "") + new URLSearchParams(params).toString();
|
|
360
|
+
if (typeof onRequest === "function")
|
|
361
|
+
[path, response, params, fetchParams] = onRequest(
|
|
362
|
+
path,
|
|
363
|
+
response,
|
|
364
|
+
params,
|
|
365
|
+
fetchParams
|
|
366
|
+
);
|
|
367
|
+
let res = null, startTime = /* @__PURE__ */ new Date(), mockHandler = (_h = grab$1.mock) == null ? void 0 : _h[path];
|
|
368
|
+
let wait = (s2) => new Promise((res2) => setTimeout(res2, s2 * 1e3 || 0));
|
|
369
|
+
if (mockHandler && (!mockHandler.params || mockHandler.method == method) && (!mockHandler.params || paramsAsText == JSON.stringify(mockHandler.params))) {
|
|
370
|
+
await wait(mockHandler.delay);
|
|
371
|
+
res = typeof mockHandler.response === "function" ? mockHandler.response(params) : mockHandler.response;
|
|
372
|
+
} else {
|
|
373
|
+
res = await fetch(baseURL + path + paramsGETRequest, fetchParams).catch(
|
|
374
|
+
(e) => {
|
|
375
|
+
throw new Error(e);
|
|
376
|
+
}
|
|
377
|
+
);
|
|
378
|
+
if (!res.ok)
|
|
379
|
+
throw new Error(`HTTP error: ${res.status} ${res.statusText}`);
|
|
380
|
+
let type = res.headers.get("content-type");
|
|
381
|
+
if (onStream) await onStream(res.body);
|
|
357
382
|
else
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
[path, response, params, fetchParams] = onRequest(
|
|
361
|
-
path,
|
|
362
|
-
response,
|
|
363
|
-
params,
|
|
364
|
-
fetchParams
|
|
365
|
-
);
|
|
366
|
-
let res = null, startTime = /* @__PURE__ */ new Date(), mockHandler = (_h = grab$1.mock) == null ? void 0 : _h[path];
|
|
367
|
-
let wait = (s2) => new Promise((res2) => setTimeout(res2, s2 * 1e3 || 0));
|
|
368
|
-
if (mockHandler && (!mockHandler.params || mockHandler.method == method) && (!mockHandler.params || paramsAsText == JSON.stringify(mockHandler.params))) {
|
|
369
|
-
await wait(mockHandler.delay);
|
|
370
|
-
res = typeof mockHandler.response === "function" ? mockHandler.response(params) : mockHandler.response;
|
|
371
|
-
} else {
|
|
372
|
-
res = await fetch(baseURL + path + paramsGETRequest, fetchParams).catch(
|
|
373
|
-
(e) => {
|
|
374
|
-
throw new Error(e);
|
|
375
|
-
}
|
|
376
|
-
);
|
|
377
|
-
if (!res.ok)
|
|
378
|
-
throw new Error(`HTTP error: ${res.status} ${res.statusText}`);
|
|
379
|
-
let type = res.headers.get("content-type");
|
|
380
|
-
if (onStream) await onStream(res.body);
|
|
381
|
-
else
|
|
382
|
-
res = await (type ? type.includes("application/json") ? res && res.json() : type.includes("application/pdf") || type.includes("application/octet-stream") ? res.blob() : res.text() : res.json()).catch((e) => {
|
|
383
|
-
throw new Error("Error parsing response: " + e);
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
if (typeof onResponse === "function")
|
|
387
|
-
[path, response, params, fetchParams] = onResponse(
|
|
388
|
-
path,
|
|
389
|
-
response,
|
|
390
|
-
params,
|
|
391
|
-
fetchParams
|
|
392
|
-
);
|
|
393
|
-
if (resFunction) resFunction({ isLoading: void 0 });
|
|
394
|
-
else if (typeof response === "object") response == null ? true : delete response.isLoading;
|
|
395
|
-
priorRequest == null ? true : delete priorRequest.controller;
|
|
396
|
-
const elapsedTime = ((Number(/* @__PURE__ */ new Date()) - Number(startTime)) / 1e3).toFixed(1);
|
|
397
|
-
if (debug) {
|
|
398
|
-
logger(
|
|
399
|
-
"Path:" + baseURL + path + paramsGETRequest + "\n" + JSON.stringify(options, null, 2) + "\nTime: " + elapsedTime + "s\nResponse: " + printJSONStructure(res)
|
|
400
|
-
);
|
|
401
|
-
}
|
|
402
|
-
if (typeof res === "object") {
|
|
403
|
-
for (let key of Object.keys(res))
|
|
404
|
-
response[key] = paginateResult == key && ((_i = response[key]) == null ? void 0 : _i.length) ? [...response[key], ...res[key]] : res[key];
|
|
405
|
-
if (typeof response !== "undefined") response.data = res;
|
|
406
|
-
} else if (resFunction) resFunction({ data: res, ...res });
|
|
407
|
-
else if (typeof response === "object") response.data = res;
|
|
408
|
-
if (typeof grab$1.log != "undefined")
|
|
409
|
-
(_j = grab$1.log) == null ? void 0 : _j.unshift({
|
|
410
|
-
path,
|
|
411
|
-
request: JSON.stringify({ ...params, paginateKey: void 0 }),
|
|
412
|
-
response,
|
|
413
|
-
lastFetchTime: Date.now()
|
|
414
|
-
});
|
|
415
|
-
if (resFunction) response = resFunction(response);
|
|
416
|
-
return response;
|
|
417
|
-
} catch (error) {
|
|
418
|
-
let errorMessage = "Error: " + error.message + "\nPath:" + baseURL + path + "\n";
|
|
419
|
-
JSON.stringify(params);
|
|
420
|
-
if (typeof onError === "function")
|
|
421
|
-
onError(error.message, baseURL + path, params);
|
|
422
|
-
if (options.retryAttempts > 0)
|
|
423
|
-
return await grab$1(path, {
|
|
424
|
-
...options,
|
|
425
|
-
retryAttempts: --options.retryAttempts
|
|
426
|
-
});
|
|
427
|
-
if (!error.message.includes("signal") && options.debug) {
|
|
428
|
-
logger(errorMessage, { color: "red" });
|
|
429
|
-
if (debug && typeof document !== void 0) showAlert(errorMessage);
|
|
430
|
-
}
|
|
431
|
-
response.error = error.message;
|
|
432
|
-
if (typeof response === "function") {
|
|
433
|
-
response.data = response({ isLoading: void 0, error: error.message });
|
|
434
|
-
response = response.data;
|
|
435
|
-
} else response == null ? true : delete response.isLoading;
|
|
436
|
-
if (typeof grab$1.log != "undefined")
|
|
437
|
-
(_k = grab$1.log) == null ? void 0 : _k.unshift({
|
|
438
|
-
path,
|
|
439
|
-
request: JSON.stringify(params),
|
|
440
|
-
error: error.message
|
|
383
|
+
res = await (type ? type.includes("application/json") ? res && res.json() : type.includes("application/pdf") || type.includes("application/octet-stream") ? res.blob() : res.text() : res.json()).catch((e) => {
|
|
384
|
+
throw new Error("Error parsing response: " + e);
|
|
441
385
|
});
|
|
442
|
-
return response;
|
|
443
386
|
}
|
|
387
|
+
if (typeof onResponse === "function")
|
|
388
|
+
[path, response, params, fetchParams] = onResponse(
|
|
389
|
+
path,
|
|
390
|
+
response,
|
|
391
|
+
params,
|
|
392
|
+
fetchParams
|
|
393
|
+
);
|
|
394
|
+
if (resFunction) resFunction({ isLoading: void 0 });
|
|
395
|
+
else if (typeof response === "object") response == null ? true : delete response.isLoading;
|
|
396
|
+
priorRequest == null ? true : delete priorRequest.controller;
|
|
397
|
+
const elapsedTime = ((Number(/* @__PURE__ */ new Date()) - Number(startTime)) / 1e3).toFixed(1);
|
|
398
|
+
if (debug) {
|
|
399
|
+
logger(
|
|
400
|
+
"Path:" + baseURL + path + paramsGETRequest + "\n" + JSON.stringify(options, null, 2) + "\nTime: " + elapsedTime + "s\nResponse: " + printJSONStructure(res)
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
if (typeof res === "object") {
|
|
404
|
+
for (let key of Object.keys(res))
|
|
405
|
+
response[key] = paginateResult == key && ((_i = response[key]) == null ? void 0 : _i.length) ? [...response[key], ...res[key]] : res[key];
|
|
406
|
+
if (typeof response !== "undefined") response.data = res;
|
|
407
|
+
} else if (resFunction) resFunction({ data: res, ...res });
|
|
408
|
+
else if (typeof response === "object") response.data = res;
|
|
409
|
+
if (typeof grab$1.log != "undefined")
|
|
410
|
+
(_j = grab$1.log) == null ? void 0 : _j.unshift({
|
|
411
|
+
path,
|
|
412
|
+
request: JSON.stringify({ ...params, paginateKey: void 0 }),
|
|
413
|
+
response,
|
|
414
|
+
lastFetchTime: Date.now()
|
|
415
|
+
});
|
|
416
|
+
if (resFunction) response = resFunction(response);
|
|
417
|
+
return response;
|
|
444
418
|
}
|
|
445
419
|
grab$1.instance = (defaults = {}) => (path, options = {}) => grab$1(path, { ...defaults, ...options });
|
|
446
420
|
const debouncer = async (func, wait) => {
|