@alwatr/fetch 0.29.0 → 0.31.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/CHANGELOG.md CHANGED
@@ -3,6 +3,37 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [0.31.0](https://github.com/AliMD/alwatr/compare/v0.30.0...v0.31.0) (2023-05-08)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **fetch.ts:** compatible with node ([c3acb53](https://github.com/AliMD/alwatr/commit/c3acb53effd4a79e389bc4de1567b0285c03d71d))
11
+ - **fetch:** bodyJson type ([5740467](https://github.com/AliMD/alwatr/commit/57404673e7f031a73d1cf23501e6fa8d89759769))
12
+ - **fetch:** check node_mode before use navigator.online ([a688f48](https://github.com/AliMD/alwatr/commit/a688f48e9ce4b103c25ffd50f1b8c96e89c205d1))
13
+ - **fetch:** serviceRequest generic type ([074ef38](https://github.com/AliMD/alwatr/commit/074ef3876086f93486753559d8e3db0b60c52a0e))
14
+ - **fetch:** suppress fetch_cache_not_found extra error ([c04f609](https://github.com/AliMD/alwatr/commit/c04f60944106dbd8d1bf2fb5ce0e7be644c3abc6))
15
+ - new logger api ([9d83a7d](https://github.com/AliMD/alwatr/commit/9d83a7dc5c103bc3bb4282dacfd85fa998915300))
16
+
17
+ ### Features
18
+
19
+ - **fetch:** add user auth ([811fbc0](https://github.com/AliMD/alwatr/commit/811fbc018c2b4e3b808704e8623bd5dff2b2f3f7))
20
+ - **fetch:** StringifyableFetchOptions type ([e13fdb2](https://github.com/AliMD/alwatr/commit/e13fdb2550cf3a2102c331aa7980234ca6f86e08))
21
+
22
+ # [0.30.0](https://github.com/AliMD/alwatr/compare/v0.29.0...v0.30.0) (2023-03-06)
23
+
24
+ ### Bug Fixes
25
+
26
+ - **fetch:** fetchContext duplicate setSignalValue ([8aa9b00](https://github.com/AliMD/alwatr/commit/8aa9b003a2d7b7ffc8243ff7092d9560763d7273))
27
+ - **fetch:** getClientId in nodejs ([c99e41c](https://github.com/AliMD/alwatr/commit/c99e41c9e9a979ca50cc01aeb5371a3487d9da2e))
28
+
29
+ ### Features
30
+
31
+ - **fetch:** enhance fetchContext with dispatchOptions and only cache_only request in first time ([1f6b575](https://github.com/AliMD/alwatr/commit/1f6b575437104d64ede8a2c23d141160360d2cd5))
32
+ - **fetch:** fetchContext ([d63d17e](https://github.com/AliMD/alwatr/commit/d63d17ecb58221159dc45a473fdd1c992d306d2b))
33
+ - **fetch:** fetchContext skip online request when offline ([7c2b649](https://github.com/AliMD/alwatr/commit/7c2b6491f78acb961cdc0583112e3c709a177b79))
34
+ - **fetch:** fetchContext work on background ([2e12bfd](https://github.com/AliMD/alwatr/commit/2e12bfde0a0636c30e60906c4812ec66b2d36742))
35
+ - **fetch:** handle offline for all requests ([6a8d7b7](https://github.com/AliMD/alwatr/commit/6a8d7b7159732d834be052191935580331e36962))
36
+
6
37
  # [0.29.0](https://github.com/AliMD/alwatr/compare/v0.28.0...v0.29.0) (2023-02-10)
7
38
 
8
39
  ### Bug Fixes
package/fetch.d.ts CHANGED
@@ -1,10 +1,12 @@
1
- import type { FetchOptions, CacheDuplicate, CacheStrategy } from './type.js';
2
- import type { AlwatrServiceResponse, AlwatrServiceResponseSuccessWithMeta, AlwatrServiceResponseSuccess, StringifyableRecord } from '@alwatr/type';
3
- export type { FetchOptions, CacheDuplicate, CacheStrategy, AlwatrServiceResponse, AlwatrServiceResponseSuccessWithMeta, AlwatrServiceResponseSuccess, };
1
+ import { type DispatchOptions } from '@alwatr/signal';
2
+ import type { FetchOptions } from './type.js';
3
+ import type { AlwatrServiceResponseSuccessWithMeta } from '@alwatr/type';
4
+ export type * from './type.js';
5
+ export declare function fetchContext(contextName: string, fetchOption: FetchOptions, dispatchOptions?: Partial<DispatchOptions>): Promise<void>;
4
6
  /**
5
7
  * Fetch from alwatr services and return standard response.
6
8
  */
7
- export declare function serviceRequest<TData extends StringifyableRecord = StringifyableRecord, TMeta extends StringifyableRecord = StringifyableRecord>(options: FetchOptions): Promise<AlwatrServiceResponseSuccess<TData> | AlwatrServiceResponseSuccessWithMeta<TData, TMeta>>;
9
+ export declare function serviceRequest<T extends AlwatrServiceResponseSuccessWithMeta = AlwatrServiceResponseSuccessWithMeta>(options: FetchOptions): Promise<T>;
8
10
  /**
9
11
  * It's a wrapper around the browser's `fetch` function that adds retry pattern, timeout, cacheStrategy,
10
12
  * remove duplicates, etc.
package/fetch.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["src/fetch.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAC,MAAM,WAAW,CAAC;AAC3E,OAAO,KAAK,EACV,qBAAqB,EACrB,oCAAoC,EACpC,4BAA4B,EAC5B,mBAAmB,EACpB,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,YAAY,EACZ,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,oCAAoC,EACpC,4BAA4B,GAC7B,CAAC;AAcF;;GAEG;AACH,wBAAsB,cAAc,CAClC,KAAK,SAAS,mBAAmB,GAAG,mBAAmB,EACvD,KAAK,SAAS,mBAAmB,GAAG,mBAAmB,EAErD,OAAO,EAAE,YAAY,GACtB,OAAO,CAAC,4BAA4B,CAAC,KAAK,CAAC,GAAG,oCAAoC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAmDnG;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAI9D"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["src/fetch.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,eAAe,EAAC,MAAM,gBAAgB,CAAC;AAGrE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAC,oCAAoC,EAAC,MAAM,cAAc,CAAC;AAEvE,mBAAmB,WAAW,CAAC;AAc/B,wBAAsB,YAAY,CAC9B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,YAAY,EACzB,eAAe,GAAE,OAAO,CAAC,eAAe,CAAyB,GAClE,OAAO,CAAC,IAAI,CAAC,CAuCf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,CAAC,SAAS,oCAAoC,GAAG,oCAAoC,EACrF,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAwDnC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAI9D"}
package/fetch.js CHANGED
@@ -1,5 +1,6 @@
1
- import { createLogger, globalAlwatr } from '@alwatr/logger';
2
- import { getClientId } from '@alwatr/math';
1
+ import { createLogger, globalAlwatr, NODE_MODE } from '@alwatr/logger';
2
+ import { contextProvider } from '@alwatr/signal';
3
+ import { getClientId } from '@alwatr/util';
3
4
  const logger = createLogger('alwatr/fetch');
4
5
  globalAlwatr.registeredList.push({
5
6
  name: '@alwatr/fetch',
@@ -8,22 +9,65 @@ globalAlwatr.registeredList.push({
8
9
  let alwatrCacheStorage;
9
10
  const cacheSupported = 'caches' in globalThis;
10
11
  const duplicateRequestStorage = {};
12
+ export async function fetchContext(contextName, fetchOption, dispatchOptions = { debounce: 'Timeout' }) {
13
+ var _a, _b, _c, _d, _e, _f, _g, _h;
14
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'fetchContext', { contextName });
15
+ if (cacheSupported && contextProvider.getValue(contextName) == null) {
16
+ try {
17
+ fetchOption.cacheStrategy = 'cache_only';
18
+ const response = await serviceRequest(fetchOption);
19
+ contextProvider.setValue(contextName, response, dispatchOptions);
20
+ if (navigator.onLine === false) {
21
+ (_b = logger.logOther) === null || _b === void 0 ? void 0 : _b.call(logger, 'fetchContext:', 'offline');
22
+ // retry on online
23
+ return;
24
+ }
25
+ }
26
+ catch (err) {
27
+ if (err.message === 'fetch_cache_not_found') {
28
+ (_c = logger.logOther) === null || _c === void 0 ? void 0 : _c.call(logger, 'fetchContext:', 'fetch_cache_not_found');
29
+ }
30
+ else {
31
+ logger.error('fetchContext', 'fetch_failed', err);
32
+ throw err;
33
+ }
34
+ }
35
+ }
36
+ try {
37
+ fetchOption.cacheStrategy = 'update_cache';
38
+ const response = await serviceRequest(fetchOption);
39
+ if (((_d = response.meta) === null || _d === void 0 ? void 0 : _d.lastUpdated) === undefined || // skip lastUpdated check
40
+ ((_e = response.meta) === null || _e === void 0 ? void 0 : _e.lastUpdated) !== ((_g = (_f = contextProvider.getValue(contextName)) === null || _f === void 0 ? void 0 : _f.meta) === null || _g === void 0 ? void 0 : _g.lastUpdated)) {
41
+ (_h = logger.logOther) === null || _h === void 0 ? void 0 : _h.call(logger, 'fetchContext:', 'contextProvider.setValue(new-received-context)', { contextName });
42
+ contextProvider.setValue(contextName, response, dispatchOptions);
43
+ }
44
+ }
45
+ catch (err) {
46
+ logger.error('fetchContext', 'fetch_failed', err);
47
+ throw err;
48
+ }
49
+ }
11
50
  /**
12
51
  * Fetch from alwatr services and return standard response.
13
52
  */
14
53
  export async function serviceRequest(options) {
15
- var _a;
16
- logger.logMethod('serviceRequest');
17
- (_a = options.headers) !== null && _a !== void 0 ? _a : (options.headers = {});
18
- if (!options.headers['client-id']) {
19
- options.headers['client-id'] = getClientId();
54
+ var _a, _b;
55
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'serviceRequest', { url: options.url });
56
+ if (!NODE_MODE) {
57
+ (_b = options.headers) !== null && _b !== void 0 ? _b : (options.headers = {});
58
+ if (!options.headers['client-id']) {
59
+ options.headers['client-id'] = getClientId();
60
+ }
20
61
  }
21
62
  let response;
22
63
  try {
23
64
  response = await fetch(options);
24
65
  }
25
66
  catch (err) {
26
- logger.error('serviceRequest', err.message || 'fetch_failed', err, options);
67
+ const errMessage = err.message;
68
+ if (errMessage !== 'fetch_cache_not_found') {
69
+ logger.error('serviceRequest', err.message || 'fetch_failed', err, options);
70
+ }
27
71
  throw err;
28
72
  }
29
73
  let responseText;
@@ -75,15 +119,16 @@ export async function serviceRequest(options) {
75
119
  * ```
76
120
  */
77
121
  export function fetch(options) {
122
+ var _a;
78
123
  options = _processOptions(options);
79
- logger.logMethodArgs('fetch', { options });
124
+ (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'fetch', { options });
80
125
  return _handleCacheStrategy(options);
81
126
  }
82
127
  /**
83
128
  * Process fetch options and set defaults, etc.
84
129
  */
85
130
  function _processOptions(options) {
86
- var _a, _b, _c, _d, _e, _f, _g, _h;
131
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
87
132
  (_a = options.method) !== null && _a !== void 0 ? _a : (options.method = 'GET');
88
133
  (_b = options.window) !== null && _b !== void 0 ? _b : (options.window = null);
89
134
  (_c = options.timeout) !== null && _c !== void 0 ? _c : (options.timeout = 10000);
@@ -93,7 +138,7 @@ function _processOptions(options) {
93
138
  (_g = options.removeDuplicate) !== null && _g !== void 0 ? _g : (options.removeDuplicate = 'never');
94
139
  (_h = options.headers) !== null && _h !== void 0 ? _h : (options.headers = {});
95
140
  if (options.cacheStrategy !== 'network_only' && cacheSupported !== true) {
96
- logger.incident('fetch', 'fetch_cache_strategy_ignore', 'Cache storage not support in this browser', {
141
+ (_j = logger.incident) === null || _j === void 0 ? void 0 : _j.call(logger, 'fetch', 'fetch_cache_strategy_ignore', 'Cache storage not support in this browser', {
97
142
  cacheSupported,
98
143
  });
99
144
  options.cacheStrategy = 'network_only';
@@ -118,17 +163,21 @@ function _processOptions(options) {
118
163
  if (options.token != null) {
119
164
  options.headers.Authorization = `Bearer ${options.token}`;
120
165
  }
166
+ if (options.userAuth != null) {
167
+ options.headers.Authorization = `Bearer ${options.userAuth.id}/${options.userAuth.token}`;
168
+ }
121
169
  return options;
122
170
  }
123
171
  /**
124
172
  * Handle Cache Strategy over `_handleRemoveDuplicate`.
125
173
  */
126
174
  async function _handleCacheStrategy(options) {
175
+ var _a;
127
176
  if (options.cacheStrategy === 'network_only') {
128
177
  return _handleRemoveDuplicate(options);
129
178
  }
130
179
  // else handle cache strategies!
131
- logger.logMethod('_handleCacheStrategy');
180
+ (_a = logger.logMethod) === null || _a === void 0 ? void 0 : _a.call(logger, '_handleCacheStrategy');
132
181
  if (alwatrCacheStorage == null && options.cacheStorageName == null) {
133
182
  alwatrCacheStorage = await caches.open('alwatr_fetch_cache');
134
183
  }
@@ -202,13 +251,13 @@ async function _handleCacheStrategy(options) {
202
251
  * Handle Remove Duplicates over `_handleRetryPattern`.
203
252
  */
204
253
  async function _handleRemoveDuplicate(options) {
205
- var _a;
254
+ var _a, _b;
206
255
  if (options.removeDuplicate === 'never')
207
256
  return _handleRetryPattern(options);
208
- logger.logMethod('_handleRemoveDuplicate');
257
+ (_a = logger.logMethod) === null || _a === void 0 ? void 0 : _a.call(logger, '_handleRemoveDuplicate');
209
258
  const cacheKey = options.method + ' ' + options.url;
210
259
  // We must cache fetch promise without await for handle other parallel requests.
211
- (_a = duplicateRequestStorage[cacheKey]) !== null && _a !== void 0 ? _a : (duplicateRequestStorage[cacheKey] = _handleRetryPattern(options));
260
+ (_b = duplicateRequestStorage[cacheKey]) !== null && _b !== void 0 ? _b : (duplicateRequestStorage[cacheKey] = _handleRetryPattern(options));
212
261
  try {
213
262
  // For all requests need to await for clone responses.
214
263
  const response = await duplicateRequestStorage[cacheKey];
@@ -229,9 +278,10 @@ async function _handleRemoveDuplicate(options) {
229
278
  * Handle retry pattern over `_handleTimeout`.
230
279
  */
231
280
  async function _handleRetryPattern(options) {
281
+ var _a, _b;
232
282
  if (!(options.retry > 1))
233
283
  return _handleTimeout(options);
234
- logger.logMethod('_handleRetryPattern');
284
+ (_a = logger.logMethod) === null || _a === void 0 ? void 0 : _a.call(logger, '_handleRetryPattern');
235
285
  options.retry--;
236
286
  const externalAbortSignal = options.signal;
237
287
  try {
@@ -244,6 +294,9 @@ async function _handleRetryPattern(options) {
244
294
  }
245
295
  catch (err) {
246
296
  logger.accident('fetch', 'fetch_failed_retry', (err === null || err === void 0 ? void 0 : err.message) || 'fetch failed and retry', err);
297
+ if (((_b = globalThis.navigator) === null || _b === void 0 ? void 0 : _b.onLine) === false) {
298
+ throw new Error('offline');
299
+ }
247
300
  await _wait(options.retryDelay);
248
301
  options.signal = externalAbortSignal;
249
302
  return _handleRetryPattern(options);
@@ -253,11 +306,12 @@ async function _handleRetryPattern(options) {
253
306
  * It's a wrapper around the browser's `fetch` with timeout.
254
307
  */
255
308
  function _handleTimeout(options) {
309
+ var _a;
256
310
  if (options.timeout === 0) {
257
311
  return globalThis.fetch(options.url, options);
258
312
  }
259
313
  // else
260
- logger.logMethod('_handleTimeout');
314
+ (_a = logger.logMethod) === null || _a === void 0 ? void 0 : _a.call(logger, '_handleTimeout');
261
315
  return new Promise((resolved, reject) => {
262
316
  // TODO: AbortController polyfill
263
317
  const abortController = new AbortController();
package/fetch.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sourceRoot":"","sources":["src/fetch.ts"],"names":[],"mappings":"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","sourcesContent":["import {createLogger, globalAlwatr} from '@alwatr/logger';\nimport {getClientId} from '@alwatr/math';\n\nimport type {FetchOptions, CacheDuplicate, CacheStrategy} from './type.js';\nimport type {\n AlwatrServiceResponse,\n AlwatrServiceResponseSuccessWithMeta,\n AlwatrServiceResponseSuccess,\n StringifyableRecord,\n} from '@alwatr/type';\n\nexport type {\n FetchOptions,\n CacheDuplicate,\n CacheStrategy,\n AlwatrServiceResponse,\n AlwatrServiceResponseSuccessWithMeta,\n AlwatrServiceResponseSuccess,\n};\n\nconst logger = createLogger('alwatr/fetch');\n\nglobalAlwatr.registeredList.push({\n name: '@alwatr/fetch',\n version: _ALWATR_VERSION_,\n});\n\nlet alwatrCacheStorage: Cache;\nconst cacheSupported = 'caches' in globalThis;\n\nconst duplicateRequestStorage: Record<string, Promise<Response>> = {};\n\n/**\n * Fetch from alwatr services and return standard response.\n */\nexport async function serviceRequest<\n TData extends StringifyableRecord = StringifyableRecord,\n TMeta extends StringifyableRecord = StringifyableRecord,\n>(\n options: FetchOptions,\n): Promise<AlwatrServiceResponseSuccess<TData> | AlwatrServiceResponseSuccessWithMeta<TData, TMeta>> {\n logger.logMethod('serviceRequest');\n\n options.headers ??= {};\n if (!options.headers['client-id']) {\n options.headers['client-id'] = getClientId();\n }\n\n let response: Response;\n try {\n response = await fetch(options);\n }\n catch (err) {\n logger.error('serviceRequest', (err as Error).message || 'fetch_failed', err, options);\n throw err;\n }\n\n let responseText: string;\n try {\n responseText = await response.text();\n }\n catch (err) {\n logger.error('serviceRequest', 'invalid_response', err, {\n response,\n });\n throw err;\n }\n\n let responseJson: AlwatrServiceResponse<TData, TMeta>;\n try {\n responseJson = JSON.parse(responseText);\n }\n catch (err) {\n logger.error('serviceRequest', 'invalid_json', err, {responseText});\n throw err;\n }\n\n if (responseJson.ok !== true) {\n if (typeof responseJson.errorCode === 'string') {\n logger.accident('serviceRequest', responseJson.errorCode, 'fetch response not ok', {responseJson});\n throw new Error(responseJson.errorCode);\n }\n else {\n logger.error('serviceRequest', 'fetch_nok', 'fetch response not ok', {responseJson});\n throw new Error('fetch_nok');\n }\n }\n\n // TODO: generate fetch signals hook (for easier handle loading and show error toast)\n\n return responseJson;\n}\n\n/**\n * It's a wrapper around the browser's `fetch` function that adds retry pattern, timeout, cacheStrategy,\n * remove duplicates, etc.\n *\n * Example:\n *\n * ```ts\n * const response = await fetch({\n * url: '/api/products',\n * queryParameters: {limit: 10},\n * timeout: 10_000,\n * retry: 3,\n * cacheStrategy: 'stale_while_revalidate',\n * cacheDuplicate: 'auto',\n * });\n * ```\n */\nexport function fetch(options: FetchOptions): Promise<Response> {\n options = _processOptions(options);\n logger.logMethodArgs('fetch', {options});\n return _handleCacheStrategy(options as Required<FetchOptions>);\n}\n\n/**\n * Process fetch options and set defaults, etc.\n */\nfunction _processOptions(options: FetchOptions): Required<FetchOptions> {\n options.method ??= 'GET';\n options.window ??= null;\n\n options.timeout ??= 10_000;\n options.retry ??= 3;\n options.retryDelay ??= 1_000;\n options.cacheStrategy ??= 'network_only';\n options.removeDuplicate ??= 'never';\n options.headers ??= {};\n\n if (options.cacheStrategy !== 'network_only' && cacheSupported !== true) {\n logger.incident('fetch', 'fetch_cache_strategy_ignore', 'Cache storage not support in this browser', {\n cacheSupported,\n });\n options.cacheStrategy = 'network_only';\n }\n\n if (options.removeDuplicate === 'auto') {\n options.removeDuplicate = cacheSupported ? 'until_load' : 'always';\n }\n\n if (options.url.lastIndexOf('?') === -1 && options.queryParameters != null) {\n const queryParameters = options.queryParameters;\n // prettier-ignore\n const queryArray = Object\n .keys(queryParameters)\n .map((key) => `${key}=${String(queryParameters[key])}`);\n\n if (queryArray.length > 0) {\n options.url += '?' + queryArray.join('&');\n }\n }\n\n if (options.bodyJson != null) {\n options.body = JSON.stringify(options.bodyJson);\n options.headers['Content-Type'] = 'application/json';\n }\n\n if (options.token != null) {\n options.headers.Authorization = `Bearer ${options.token}`;\n }\n\n return options as Required<FetchOptions>;\n}\n\n/**\n * Handle Cache Strategy over `_handleRemoveDuplicate`.\n */\nasync function _handleCacheStrategy(options: Required<FetchOptions>): Promise<Response> {\n if (options.cacheStrategy === 'network_only') {\n return _handleRemoveDuplicate(options);\n }\n // else handle cache strategies!\n logger.logMethod('_handleCacheStrategy');\n\n if (alwatrCacheStorage == null && options.cacheStorageName == null) {\n alwatrCacheStorage = await caches.open('alwatr_fetch_cache');\n }\n\n const cacheStorage =\n options.cacheStorageName != null ? await caches.open(options.cacheStorageName) : alwatrCacheStorage;\n\n const request = new Request(options.url, options);\n\n switch (options.cacheStrategy) {\n case 'cache_first': {\n const cachedResponse = await cacheStorage.match(request);\n if (cachedResponse != null) {\n return cachedResponse;\n }\n // else\n const response = await _handleRemoveDuplicate(options);\n if (response.ok) {\n cacheStorage.put(request, response.clone());\n }\n return response;\n }\n\n case 'cache_only': {\n const cachedResponse = await cacheStorage.match(request);\n if (cachedResponse == null) {\n logger.accident(\n '_handleCacheStrategy',\n 'fetch_cache_not_found',\n 'cacheStorage is cache_only but no cache found',\n {url: request.url},\n );\n throw new Error('fetch_cache_not_found');\n }\n // else\n return cachedResponse;\n }\n\n case 'network_first': {\n try {\n const networkResponse = await _handleRemoveDuplicate(options);\n if (networkResponse.ok) {\n cacheStorage.put(request, networkResponse.clone());\n }\n return networkResponse;\n }\n catch (err) {\n const cachedResponse = await cacheStorage.match(request);\n if (cachedResponse != null) {\n return cachedResponse;\n }\n // else\n throw err;\n }\n }\n\n case 'update_cache': {\n const networkResponse = await _handleRemoveDuplicate(options);\n if (networkResponse.ok) {\n cacheStorage.put(request, networkResponse.clone());\n }\n return networkResponse;\n }\n\n case 'stale_while_revalidate': {\n const cachedResponse = await cacheStorage.match(request);\n const fetchedResponsePromise = _handleRemoveDuplicate(options).then((networkResponse) => {\n if (networkResponse.ok) {\n cacheStorage.put(request, networkResponse.clone());\n if (typeof options.revalidateCallback === 'function') {\n setTimeout(options.revalidateCallback, 0, networkResponse.clone());\n }\n }\n return networkResponse;\n });\n\n return cachedResponse ?? fetchedResponsePromise;\n }\n\n default: {\n return _handleRemoveDuplicate(options);\n }\n }\n}\n\n/**\n * Handle Remove Duplicates over `_handleRetryPattern`.\n */\nasync function _handleRemoveDuplicate(options: Required<FetchOptions>): Promise<Response> {\n if (options.removeDuplicate === 'never') return _handleRetryPattern(options);\n\n logger.logMethod('_handleRemoveDuplicate');\n\n const cacheKey = options.method + ' ' + options.url;\n\n // We must cache fetch promise without await for handle other parallel requests.\n duplicateRequestStorage[cacheKey] ??= _handleRetryPattern(options);\n\n try {\n // For all requests need to await for clone responses.\n const response = await duplicateRequestStorage[cacheKey];\n\n if (duplicateRequestStorage[cacheKey] != null) {\n if (response.ok !== true || options.removeDuplicate === 'until_load') {\n delete duplicateRequestStorage[cacheKey];\n }\n }\n\n return response.clone();\n }\n catch (err) {\n // clean cache on any error.\n delete duplicateRequestStorage[cacheKey];\n throw err;\n }\n}\n\n/**\n * Handle retry pattern over `_handleTimeout`.\n */\nasync function _handleRetryPattern(options: Required<FetchOptions>): Promise<Response> {\n if (!(options.retry > 1)) return _handleTimeout(options);\n\n logger.logMethod('_handleRetryPattern');\n options.retry--;\n\n const externalAbortSignal = options.signal;\n\n try {\n const response = await _handleTimeout(options);\n\n if (response.status < 500) {\n return response;\n }\n // else\n throw new Error('fetch_server_error');\n }\n catch (err) {\n logger.accident('fetch', 'fetch_failed_retry', (err as Error)?.message || 'fetch failed and retry', err);\n\n await _wait(options.retryDelay);\n\n options.signal = externalAbortSignal;\n return _handleRetryPattern(options);\n }\n}\n\n/**\n * It's a wrapper around the browser's `fetch` with timeout.\n */\nfunction _handleTimeout(options: FetchOptions): Promise<Response> {\n if (options.timeout === 0) {\n return globalThis.fetch(options.url, options);\n }\n // else\n logger.logMethod('_handleTimeout');\n return new Promise((resolved, reject) => {\n // TODO: AbortController polyfill\n const abortController = new AbortController();\n const externalAbortSignal = options.signal;\n options.signal = abortController.signal;\n\n const timeoutId = setTimeout(() => {\n reject(new Error('fetch_timeout'));\n abortController.abort('fetch_timeout');\n }, options.timeout);\n\n if (externalAbortSignal != null) {\n // Respect external abort signal\n externalAbortSignal.addEventListener('abort', () => abortController.abort(), {once: true});\n }\n\n // abortController.signal.addEventListener('abort', () => {\n // logger.incident('fetch', 'fetch_abort_signal', 'fetch abort signal received', {\n // reason: abortController.signal.reason,\n // });\n // });\n\n globalThis\n .fetch(options.url, options)\n .then((response) => resolved(response))\n .catch((reason) => reject(reason))\n .finally(() => {\n delete options.signal; // try to avoid memory leak in nodejs!\n clearTimeout(timeoutId);\n });\n });\n}\n\nconst _wait = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n"]}
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["src/fetch.ts"],"names":[],"mappings":"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","sourcesContent":["import {createLogger, globalAlwatr, NODE_MODE} from '@alwatr/logger';\nimport {contextProvider, type DispatchOptions} from '@alwatr/signal';\nimport {getClientId} from '@alwatr/util';\n\nimport type {FetchOptions} from './type.js';\nimport type {AlwatrServiceResponseSuccessWithMeta} from '@alwatr/type';\n\nexport type * from './type.js';\n\nconst logger = createLogger('alwatr/fetch');\n\nglobalAlwatr.registeredList.push({\n name: '@alwatr/fetch',\n version: _ALWATR_VERSION_,\n});\n\nlet alwatrCacheStorage: Cache;\nconst cacheSupported = 'caches' in globalThis;\n\nconst duplicateRequestStorage: Record<string, Promise<Response>> = {};\n\nexport async function fetchContext(\n contextName: string,\n fetchOption: FetchOptions,\n dispatchOptions: Partial<DispatchOptions> = {debounce: 'Timeout'},\n): Promise<void> {\n logger.logMethodArgs?.('fetchContext', {contextName});\n if (cacheSupported && contextProvider.getValue(contextName) == null) {\n try {\n fetchOption.cacheStrategy = 'cache_only';\n const response = await serviceRequest(fetchOption);\n contextProvider.setValue<typeof response>(contextName, response, dispatchOptions);\n if (navigator.onLine === false) {\n logger.logOther?.('fetchContext:', 'offline');\n // retry on online\n return;\n }\n }\n catch (err) {\n if ((err as Error).message === 'fetch_cache_not_found') {\n logger.logOther?.('fetchContext:', 'fetch_cache_not_found');\n }\n else {\n logger.error('fetchContext', 'fetch_failed', err);\n throw err;\n }\n }\n }\n\n try {\n fetchOption.cacheStrategy = 'update_cache';\n const response = await serviceRequest(fetchOption);\n if (\n response.meta?.lastUpdated === undefined || // skip lastUpdated check\n response.meta?.lastUpdated !== contextProvider.getValue<typeof response>(contextName)?.meta?.lastUpdated\n ) {\n logger.logOther?.('fetchContext:', 'contextProvider.setValue(new-received-context)', {contextName});\n contextProvider.setValue<typeof response>(contextName, response, dispatchOptions);\n }\n }\n catch (err) {\n logger.error('fetchContext', 'fetch_failed', err);\n throw err;\n }\n}\n\n/**\n * Fetch from alwatr services and return standard response.\n */\nexport async function serviceRequest<\n T extends AlwatrServiceResponseSuccessWithMeta = AlwatrServiceResponseSuccessWithMeta\n>(options: FetchOptions): Promise<T> {\n logger.logMethodArgs?.('serviceRequest', {url: options.url});\n\n if (!NODE_MODE) {\n options.headers ??= {};\n if (!options.headers['client-id']) {\n options.headers['client-id'] = getClientId();\n }\n }\n\n let response: Response;\n try {\n response = await fetch(options);\n }\n catch (err) {\n const errMessage = (err as Error).message;\n if (errMessage !== 'fetch_cache_not_found') {\n logger.error('serviceRequest', (err as Error).message || 'fetch_failed', err, options);\n }\n throw err;\n }\n\n let responseText: string;\n try {\n responseText = await response.text();\n }\n catch (err) {\n logger.error('serviceRequest', 'invalid_response', err, {\n response,\n });\n throw err;\n }\n\n let responseJson: T;\n try {\n responseJson = JSON.parse(responseText);\n }\n catch (err) {\n logger.error('serviceRequest', 'invalid_json', err, {responseText});\n throw err;\n }\n\n if (responseJson.ok !== true) {\n if (typeof responseJson.errorCode === 'string') {\n logger.accident('serviceRequest', responseJson.errorCode, 'fetch response not ok', {responseJson});\n throw new Error(responseJson.errorCode);\n }\n else {\n logger.error('serviceRequest', 'fetch_nok', 'fetch response not ok', {responseJson});\n throw new Error('fetch_nok');\n }\n }\n\n // TODO: generate fetch signals hook (for easier handle loading and show error toast)\n\n return responseJson;\n}\n\n/**\n * It's a wrapper around the browser's `fetch` function that adds retry pattern, timeout, cacheStrategy,\n * remove duplicates, etc.\n *\n * Example:\n *\n * ```ts\n * const response = await fetch({\n * url: '/api/products',\n * queryParameters: {limit: 10},\n * timeout: 10_000,\n * retry: 3,\n * cacheStrategy: 'stale_while_revalidate',\n * cacheDuplicate: 'auto',\n * });\n * ```\n */\nexport function fetch(options: FetchOptions): Promise<Response> {\n options = _processOptions(options);\n logger.logMethodArgs?.('fetch', {options});\n return _handleCacheStrategy(options as Required<FetchOptions>);\n}\n\n/**\n * Process fetch options and set defaults, etc.\n */\nfunction _processOptions(options: FetchOptions): Required<FetchOptions> {\n options.method ??= 'GET';\n options.window ??= null;\n\n options.timeout ??= 10_000;\n options.retry ??= 3;\n options.retryDelay ??= 1_000;\n options.cacheStrategy ??= 'network_only';\n options.removeDuplicate ??= 'never';\n options.headers ??= {};\n\n if (options.cacheStrategy !== 'network_only' && cacheSupported !== true) {\n logger.incident?.('fetch', 'fetch_cache_strategy_ignore', 'Cache storage not support in this browser', {\n cacheSupported,\n });\n options.cacheStrategy = 'network_only';\n }\n\n if (options.removeDuplicate === 'auto') {\n options.removeDuplicate = cacheSupported ? 'until_load' : 'always';\n }\n\n if (options.url.lastIndexOf('?') === -1 && options.queryParameters != null) {\n const queryParameters = options.queryParameters;\n // prettier-ignore\n const queryArray = Object\n .keys(queryParameters)\n .map((key) => `${key}=${String(queryParameters[key])}`);\n\n if (queryArray.length > 0) {\n options.url += '?' + queryArray.join('&');\n }\n }\n\n if (options.bodyJson != null) {\n options.body = JSON.stringify(options.bodyJson);\n options.headers['Content-Type'] = 'application/json';\n }\n\n if (options.token != null) {\n options.headers.Authorization = `Bearer ${options.token}`;\n }\n\n if (options.userAuth != null) {\n options.headers.Authorization = `Bearer ${options.userAuth.id}/${options.userAuth.token}`;\n }\n\n return options as Required<FetchOptions>;\n}\n\n/**\n * Handle Cache Strategy over `_handleRemoveDuplicate`.\n */\nasync function _handleCacheStrategy(options: Required<FetchOptions>): Promise<Response> {\n if (options.cacheStrategy === 'network_only') {\n return _handleRemoveDuplicate(options);\n }\n // else handle cache strategies!\n logger.logMethod?.('_handleCacheStrategy');\n\n if (alwatrCacheStorage == null && options.cacheStorageName == null) {\n alwatrCacheStorage = await caches.open('alwatr_fetch_cache');\n }\n\n const cacheStorage =\n options.cacheStorageName != null ? await caches.open(options.cacheStorageName) : alwatrCacheStorage;\n\n const request = new Request(options.url, options);\n\n switch (options.cacheStrategy) {\n case 'cache_first': {\n const cachedResponse = await cacheStorage.match(request);\n if (cachedResponse != null) {\n return cachedResponse;\n }\n // else\n const response = await _handleRemoveDuplicate(options);\n if (response.ok) {\n cacheStorage.put(request, response.clone());\n }\n return response;\n }\n\n case 'cache_only': {\n const cachedResponse = await cacheStorage.match(request);\n if (cachedResponse == null) {\n logger.accident(\n '_handleCacheStrategy',\n 'fetch_cache_not_found',\n 'cacheStorage is cache_only but no cache found',\n {url: request.url},\n );\n throw new Error('fetch_cache_not_found');\n }\n // else\n return cachedResponse;\n }\n\n case 'network_first': {\n try {\n const networkResponse = await _handleRemoveDuplicate(options);\n if (networkResponse.ok) {\n cacheStorage.put(request, networkResponse.clone());\n }\n return networkResponse;\n }\n catch (err) {\n const cachedResponse = await cacheStorage.match(request);\n if (cachedResponse != null) {\n return cachedResponse;\n }\n // else\n throw err;\n }\n }\n\n case 'update_cache': {\n const networkResponse = await _handleRemoveDuplicate(options);\n if (networkResponse.ok) {\n cacheStorage.put(request, networkResponse.clone());\n }\n return networkResponse;\n }\n\n case 'stale_while_revalidate': {\n const cachedResponse = await cacheStorage.match(request);\n const fetchedResponsePromise = _handleRemoveDuplicate(options).then((networkResponse) => {\n if (networkResponse.ok) {\n cacheStorage.put(request, networkResponse.clone());\n if (typeof options.revalidateCallback === 'function') {\n setTimeout(options.revalidateCallback, 0, networkResponse.clone());\n }\n }\n return networkResponse;\n });\n\n return cachedResponse ?? fetchedResponsePromise;\n }\n\n default: {\n return _handleRemoveDuplicate(options);\n }\n }\n}\n\n/**\n * Handle Remove Duplicates over `_handleRetryPattern`.\n */\nasync function _handleRemoveDuplicate(options: Required<FetchOptions>): Promise<Response> {\n if (options.removeDuplicate === 'never') return _handleRetryPattern(options);\n\n logger.logMethod?.('_handleRemoveDuplicate');\n\n const cacheKey = options.method + ' ' + options.url;\n\n // We must cache fetch promise without await for handle other parallel requests.\n duplicateRequestStorage[cacheKey] ??= _handleRetryPattern(options);\n\n try {\n // For all requests need to await for clone responses.\n const response = await duplicateRequestStorage[cacheKey];\n\n if (duplicateRequestStorage[cacheKey] != null) {\n if (response.ok !== true || options.removeDuplicate === 'until_load') {\n delete duplicateRequestStorage[cacheKey];\n }\n }\n\n return response.clone();\n }\n catch (err) {\n // clean cache on any error.\n delete duplicateRequestStorage[cacheKey];\n throw err;\n }\n}\n\n/**\n * Handle retry pattern over `_handleTimeout`.\n */\nasync function _handleRetryPattern(options: Required<FetchOptions>): Promise<Response> {\n if (!(options.retry > 1)) return _handleTimeout(options);\n\n logger.logMethod?.('_handleRetryPattern');\n options.retry--;\n\n const externalAbortSignal = options.signal;\n\n try {\n const response = await _handleTimeout(options);\n\n if (response.status < 500) {\n return response;\n }\n // else\n throw new Error('fetch_server_error');\n }\n catch (err) {\n logger.accident('fetch', 'fetch_failed_retry', (err as Error)?.message || 'fetch failed and retry', err);\n\n if (globalThis.navigator?.onLine === false) {\n throw new Error('offline');\n }\n\n await _wait(options.retryDelay);\n\n options.signal = externalAbortSignal;\n return _handleRetryPattern(options);\n }\n}\n\n/**\n * It's a wrapper around the browser's `fetch` with timeout.\n */\nfunction _handleTimeout(options: FetchOptions): Promise<Response> {\n if (options.timeout === 0) {\n return globalThis.fetch(options.url, options);\n }\n // else\n logger.logMethod?.('_handleTimeout');\n return new Promise((resolved, reject) => {\n // TODO: AbortController polyfill\n const abortController = new AbortController();\n const externalAbortSignal = options.signal;\n options.signal = abortController.signal;\n\n const timeoutId = setTimeout(() => {\n reject(new Error('fetch_timeout'));\n abortController.abort('fetch_timeout');\n }, options.timeout);\n\n if (externalAbortSignal != null) {\n // Respect external abort signal\n externalAbortSignal.addEventListener('abort', () => abortController.abort(), {once: true});\n }\n\n // abortController.signal.addEventListener('abort', () => {\n // logger.incident('fetch', 'fetch_abort_signal', 'fetch abort signal received', {\n // reason: abortController.signal.reason,\n // });\n // });\n\n globalThis\n .fetch(options.url, options)\n .then((response) => resolved(response))\n .catch((reason) => reject(reason))\n .finally(() => {\n delete options.signal; // try to avoid memory leak in nodejs!\n clearTimeout(timeoutId);\n });\n });\n}\n\nconst _wait = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwatr/fetch",
3
- "version": "0.29.0",
3
+ "version": "0.31.0",
4
4
  "description": "Enhanced fetch API with cache strategy, retry pattern, timeout, helper methods and enhanced types written in tiny TypeScript, ES module.",
5
5
  "keywords": [
6
6
  "fetch",
@@ -34,12 +34,13 @@
34
34
  "url": "https://github.com/AliMD/alwatr/issues"
35
35
  },
36
36
  "dependencies": {
37
- "@alwatr/logger": "^0.29.0",
38
- "@alwatr/math": "^0.29.0",
37
+ "@alwatr/logger": "^0.31.0",
38
+ "@alwatr/signal": "^0.31.0",
39
+ "@alwatr/util": "^0.31.0",
39
40
  "tslib": "^2.5.0"
40
41
  },
41
42
  "devDependencies": {
42
- "@alwatr/type": "^0.29.0"
43
+ "@alwatr/type": "^0.31.0"
43
44
  },
44
- "gitHead": "801487f183f8afd8cba25e0fec5d508c0b4fe809"
45
+ "gitHead": "896e64b58eed6e9048e870557ecf399d42705612"
45
46
  }
package/type.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Methods, QueryParameters } from '@alwatr/type';
1
+ import type { Methods, QueryParameters, StringifyableRecord, UserAuth } from '@alwatr/type';
2
2
  export type CacheStrategy = 'network_only' | 'network_first' | 'cache_only' | 'cache_first' | 'update_cache' | 'stale_while_revalidate';
3
3
  export type CacheDuplicate = 'never' | 'always' | 'until_load' | 'auto';
4
4
  export interface FetchOptions extends RequestInit {
@@ -72,7 +72,7 @@ export interface FetchOptions extends RequestInit {
72
72
  /**
73
73
  * Body as JS Object.
74
74
  */
75
- bodyJson?: Record<string | number, unknown>;
75
+ bodyJson?: StringifyableRecord;
76
76
  /**
77
77
  * URL Query Parameters as JS Object.
78
78
  */
@@ -81,5 +81,10 @@ export interface FetchOptions extends RequestInit {
81
81
  * Add token to Authentication bearer header.
82
82
  */
83
83
  token?: string;
84
+ /**
85
+ * Add user id and token to Authentication bearer header.
86
+ */
87
+ userAuth?: UserAuth;
84
88
  }
89
+ export type StringifyableFetchOptions = Pick<FetchOptions, 'url' | 'bodyJson' | 'cache' | 'cacheStorageName' | 'cacheStrategy' | 'headers' | 'credentials' | 'keepalive' | 'method' | 'mode' | 'queryParameters' | 'removeDuplicate' | 'timeout' | 'token' | 'retry' | 'retryDelay' | 'referrer' | 'referrerPolicy'>;
85
90
  //# sourceMappingURL=type.d.ts.map
package/type.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["src/type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAE,eAAe,EAAC,MAAM,cAAc,CAAC;AAE3D,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,eAAe,GACf,YAAY,GACZ,aAAa,GACb,cAAc,GACd,wBAAwB,CAAC;AAE7B,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,YAAY,GAAG,MAAM,CAAC;AAExE,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,cAAc,CAAC;IAEjC;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B;;OAEG;IACH,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElE;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC;IAE5C;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["src/type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,QAAQ,EAAC,MAAM,cAAc,CAAC;AAE1F,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,eAAe,GACf,YAAY,GACZ,aAAa,GACb,cAAc,GACd,wBAAwB,CAAC;AAE7B,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,YAAY,GAAG,MAAM,CAAC;AAExE,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,cAAc,CAAC;IAEjC;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B;;OAEG;IACH,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElE;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAE/B;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,YAAY,EACV,KAAK,GACL,UAAU,GACV,OAAO,GACP,kBAAkB,GAClB,eAAe,GACf,SAAS,GACT,aAAa,GACb,WAAW,GACX,QAAQ,GACR,MAAM,GACN,iBAAiB,GACjB,iBAAiB,GACjB,SAAS,GACT,OAAO,GACP,OAAO,GACP,YAAY,GACZ,UAAU,GACV,gBAAgB,CACnB,CAAC"}
package/type.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"type.js","sourceRoot":"","sources":["src/type.ts"],"names":[],"mappings":"","sourcesContent":["import type {Methods, QueryParameters} from '@alwatr/type';\n\nexport type CacheStrategy =\n | 'network_only'\n | 'network_first'\n | 'cache_only'\n | 'cache_first'\n | 'update_cache'\n | 'stale_while_revalidate';\n\nexport type CacheDuplicate = 'never' | 'always' | 'until_load' | 'auto';\n\nexport interface FetchOptions extends RequestInit {\n /**\n * Request URL.\n */\n url: string;\n\n /**\n * A string to set request's method.\n *\n * @default 'GET'\n */\n method?: Methods;\n\n /**\n * A Headers object to set request's headers.\n */\n headers?: Record<string, string>;\n\n /**\n * A timeout for the fetch request.\n * Set `0` for disable it.\n *\n * Use with cation, you will have memory leak issue in nodejs.\n *\n * @default 10_000 ms\n */\n timeout?: number;\n\n /**\n * If fetch response not acceptable or timed out, it will retry the request.\n *\n * @default 3\n */\n retry?: number;\n\n /**\n * Delay before each retries.\n *\n * @default 1_000 ms\n */\n retryDelay?: number;\n\n /**\n * Simple memory caching for remove duplicate/parallel requests.\n *\n * - `never`: Never use memory caching.\n * - `always`: Always use memory caching and remove all duplicate requests.\n * - `until_load`: Cache parallel requests until request completed (it will be removed after the promise resolved).\n * - `auto`: If CacheStorage was supported use `until_load` strategy else use `always`.\n *\n * @default 'never'\n */\n removeDuplicate?: CacheDuplicate;\n\n /**\n * Strategies for caching.\n *\n * - `network_only`: Only network request without any cache.\n * - `network_first`: Network first, falling back to cache.\n * - `cache_only`: Cache only without any network request.\n * - `cache_first`: Cache first, falling back to network.\n * - `update_cache`: Like `network_only` but with update cache.\n * - `stale_while_revalidate`: Fastest strategy, Use cached first but always request network to update the cache.\n *\n * @default 'network_only'\n */\n cacheStrategy?: CacheStrategy;\n\n /**\n * Revalidate callback for `stale_while_revalidate` cache strategy.\n */\n revalidateCallback?: (response: Response) => void | Promise<void>;\n\n /**\n * Cache storage custom name.\n */\n cacheStorageName?: string;\n\n /**\n * Body as JS Object.\n */\n bodyJson?: Record<string | number, unknown>;\n\n /**\n * URL Query Parameters as JS Object.\n */\n queryParameters?: QueryParameters;\n\n /**\n * Add token to Authentication bearer header.\n */\n token?: string;\n}\n"]}
1
+ {"version":3,"file":"type.js","sourceRoot":"","sources":["src/type.ts"],"names":[],"mappings":"","sourcesContent":["import type {Methods, QueryParameters, StringifyableRecord, UserAuth} from '@alwatr/type';\n\nexport type CacheStrategy =\n | 'network_only'\n | 'network_first'\n | 'cache_only'\n | 'cache_first'\n | 'update_cache'\n | 'stale_while_revalidate';\n\nexport type CacheDuplicate = 'never' | 'always' | 'until_load' | 'auto';\n\nexport interface FetchOptions extends RequestInit {\n /**\n * Request URL.\n */\n url: string;\n\n /**\n * A string to set request's method.\n *\n * @default 'GET'\n */\n method?: Methods;\n\n /**\n * A Headers object to set request's headers.\n */\n headers?: Record<string, string>;\n\n /**\n * A timeout for the fetch request.\n * Set `0` for disable it.\n *\n * Use with cation, you will have memory leak issue in nodejs.\n *\n * @default 10_000 ms\n */\n timeout?: number;\n\n /**\n * If fetch response not acceptable or timed out, it will retry the request.\n *\n * @default 3\n */\n retry?: number;\n\n /**\n * Delay before each retries.\n *\n * @default 1_000 ms\n */\n retryDelay?: number;\n\n /**\n * Simple memory caching for remove duplicate/parallel requests.\n *\n * - `never`: Never use memory caching.\n * - `always`: Always use memory caching and remove all duplicate requests.\n * - `until_load`: Cache parallel requests until request completed (it will be removed after the promise resolved).\n * - `auto`: If CacheStorage was supported use `until_load` strategy else use `always`.\n *\n * @default 'never'\n */\n removeDuplicate?: CacheDuplicate;\n\n /**\n * Strategies for caching.\n *\n * - `network_only`: Only network request without any cache.\n * - `network_first`: Network first, falling back to cache.\n * - `cache_only`: Cache only without any network request.\n * - `cache_first`: Cache first, falling back to network.\n * - `update_cache`: Like `network_only` but with update cache.\n * - `stale_while_revalidate`: Fastest strategy, Use cached first but always request network to update the cache.\n *\n * @default 'network_only'\n */\n cacheStrategy?: CacheStrategy;\n\n /**\n * Revalidate callback for `stale_while_revalidate` cache strategy.\n */\n revalidateCallback?: (response: Response) => void | Promise<void>;\n\n /**\n * Cache storage custom name.\n */\n cacheStorageName?: string;\n\n /**\n * Body as JS Object.\n */\n bodyJson?: StringifyableRecord;\n\n /**\n * URL Query Parameters as JS Object.\n */\n queryParameters?: QueryParameters;\n\n /**\n * Add token to Authentication bearer header.\n */\n token?: string;\n\n /**\n * Add user id and token to Authentication bearer header.\n */\n userAuth?: UserAuth;\n}\n\nexport type StringifyableFetchOptions = Pick<\n FetchOptions,\n | 'url'\n | 'bodyJson'\n | 'cache'\n | 'cacheStorageName'\n | 'cacheStrategy'\n | 'headers'\n | 'credentials'\n | 'keepalive'\n | 'method'\n | 'mode'\n | 'queryParameters'\n | 'removeDuplicate'\n | 'timeout'\n | 'token'\n | 'retry'\n | 'retryDelay'\n | 'referrer'\n | 'referrerPolicy'\n>;\n"]}