@alwatr/fetch 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,10 +3,101 @@
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
- ## [1.0.1](https://github.com/AliMD/alwatr/compare/v1.0.0...v1.0.1) (2023-06-21)
6
+ ## [1.1.1](https://github.com/AliMD/alwatr/compare/@alwatr/fetch@1.1.0...@alwatr/fetch@1.1.1) (2023-09-12)
7
7
 
8
8
  **Note:** Version bump only for package @alwatr/fetch
9
9
 
10
+ # 1.1.0 (2023-09-12)
11
+
12
+ # 1.0.0 (2023-06-14)
13
+
14
+ # 0.32.0 (2023-05-27)
15
+
16
+ ### Bug Fixes
17
+
18
+ * **fetch:** serviceRequest type ([44c1086](https://github.com/AliMD/alwatr/commit/44c10866e1c630bc3cf85b3e9be38b268b5b0c31))
19
+ * **fetch:** userAuth in StringifyableFetchOptions ([f554b57](https://github.com/AliMD/alwatr/commit/f554b575584cb1464d48fbe8a8c4006125365853))
20
+
21
+ # 0.31.0 (2023-05-08)
22
+
23
+ ### Bug Fixes
24
+
25
+ * **fetch.ts:** compatible with node ([c3acb53](https://github.com/AliMD/alwatr/commit/c3acb53effd4a79e389bc4de1567b0285c03d71d))
26
+ * **fetch:** bodyJson type ([5740467](https://github.com/AliMD/alwatr/commit/57404673e7f031a73d1cf23501e6fa8d89759769))
27
+ * **fetch:** check node_mode before use navigator.online ([a688f48](https://github.com/AliMD/alwatr/commit/a688f48e9ce4b103c25ffd50f1b8c96e89c205d1))
28
+ * **fetch:** serviceRequest generic type ([074ef38](https://github.com/AliMD/alwatr/commit/074ef3876086f93486753559d8e3db0b60c52a0e))
29
+ * **fetch:** suppress fetch_cache_not_found extra error ([c04f609](https://github.com/AliMD/alwatr/commit/c04f60944106dbd8d1bf2fb5ce0e7be644c3abc6))
30
+ * new logger api ([9d83a7d](https://github.com/AliMD/alwatr/commit/9d83a7dc5c103bc3bb4282dacfd85fa998915300))
31
+
32
+ ### Features
33
+
34
+ * **fetch:** add user auth ([811fbc0](https://github.com/AliMD/alwatr/commit/811fbc018c2b4e3b808704e8623bd5dff2b2f3f7))
35
+ * **fetch:** StringifyableFetchOptions type ([e13fdb2](https://github.com/AliMD/alwatr/commit/e13fdb2550cf3a2102c331aa7980234ca6f86e08))
36
+
37
+ # 0.30.0 (2023-03-06)
38
+
39
+ ### Bug Fixes
40
+
41
+ * **fetch:** fetchContext duplicate setSignalValue ([8aa9b00](https://github.com/AliMD/alwatr/commit/8aa9b003a2d7b7ffc8243ff7092d9560763d7273))
42
+ * **fetch:** getClientId in nodejs ([c99e41c](https://github.com/AliMD/alwatr/commit/c99e41c9e9a979ca50cc01aeb5371a3487d9da2e))
43
+
44
+ ### Features
45
+
46
+ * **fetch:** enhance fetchContext with dispatchOptions and only cache_only request in first time ([1f6b575](https://github.com/AliMD/alwatr/commit/1f6b575437104d64ede8a2c23d141160360d2cd5))
47
+ * **fetch:** fetchContext ([d63d17e](https://github.com/AliMD/alwatr/commit/d63d17ecb58221159dc45a473fdd1c992d306d2b))
48
+ * **fetch:** fetchContext skip online request when offline ([7c2b649](https://github.com/AliMD/alwatr/commit/7c2b6491f78acb961cdc0583112e3c709a177b79))
49
+ * **fetch:** fetchContext work on background ([2e12bfd](https://github.com/AliMD/alwatr/commit/2e12bfde0a0636c30e60906c4812ec66b2d36742))
50
+ * **fetch:** handle offline for all requests ([6a8d7b7](https://github.com/AliMD/alwatr/commit/6a8d7b7159732d834be052191935580331e36962))
51
+
52
+ # 0.29.0 (2023-02-10)
53
+
54
+ ### Bug Fixes
55
+
56
+ * **fetch:** device id to client id ([077e467](https://github.com/AliMD/alwatr/commit/077e4671d804d43c8f61a9d163d8d51d7a69134e))
57
+ * **fetch:** headers type ([cd4b14e](https://github.com/AliMD/alwatr/commit/cd4b14e46b5090b6df8cb4f89d22b53966b9151e))
58
+
59
+ ### Features
60
+
61
+ * **fetch:** add update_cache to CacheStrategy ([e1406b1](https://github.com/AliMD/alwatr/commit/e1406b12e1276de3295c47506c8102ab3f8bfa79))
62
+ * **fetch:** clientId on service request ([9575a1d](https://github.com/AliMD/alwatr/commit/9575a1d595a0a4757581a29a66837cbe4be46ed3))
63
+
64
+ # 0.28.0 (2023-01-20)
65
+
66
+ # 0.27.0 (2022-12-29)
67
+
68
+ ### Bug Fixes
69
+
70
+ * review issue ([e5d192c](https://github.com/AliMD/alwatr/commit/e5d192cbee6917c2de01146cf8bd026895724ab8))
71
+
72
+ ### Features
73
+
74
+ * **type:** add types ([2de3842](https://github.com/AliMD/alwatr/commit/2de384297b70b9818ec8d62ce8d31be4822d95a4))
75
+
76
+ # 0.26.0 (2022-12-22)
77
+
78
+ ### Bug Fixes
79
+
80
+ * all import without .js ([fa739ab](https://github.com/AliMD/alwatr/commit/fa739ab23f67bae1d10bfcc146920b71377a26fc))
81
+ * **core/fetch:** tsconfig refrences ([e6b9542](https://github.com/AliMD/alwatr/commit/e6b9542284e67b67600da4dcebd19daedb031c9c))
82
+ * **fetch:** always call revalidateCallback ([444edc5](https://github.com/AliMD/alwatr/commit/444edc52b6dd5de5418ae8630e1f2270f0114372))
83
+ * **fetch:** enhance handle and report errors in serviceRequest ([dbfc7ff](https://github.com/AliMD/alwatr/commit/dbfc7ff2a036216498dc8e2ff58b74b7eb8d9bc0))
84
+ * **fetch:** fetch_cache_not_found is not error ([3d1aa4e](https://github.com/AliMD/alwatr/commit/3d1aa4e572fbf4bc7b0a527a3fdcf4c521af18dd))
85
+ * **fetch:** fetch_failed error message ([3e98bd9](https://github.com/AliMD/alwatr/commit/3e98bd926a495c13d476f2f1cfb9e546a059d4d8))
86
+ * **fetch:** remove extra _options ([ad24c81](https://github.com/AliMD/alwatr/commit/ad24c8104b944ebda52308e60d41976ac1eeee81))
87
+ * **fetch:** revalidateCallback issue ([7207909](https://github.com/AliMD/alwatr/commit/72079098edb438c28256dad03d7802bc2fab0858))
88
+ * set correct path ([d01ce6f](https://github.com/AliMD/alwatr/commit/d01ce6ffa749a5e3e0e11e35b4ed61d75d61fec9))
89
+ * **storage-engine:** AlwatrDocumentStorage ([ca9a7bf](https://github.com/AliMD/alwatr/commit/ca9a7bf5e17b333538e749ada5d481a06c847101))
90
+ * tsconfig ([e96dcd3](https://github.com/AliMD/alwatr/commit/e96dcd30774a9f06f7d051e0504192cbbe019e35))
91
+ * tsconfig refrences ([cea0562](https://github.com/AliMD/alwatr/commit/cea05621ecfa499476c5b10a412e60f27ba6a06d))
92
+
93
+ ### Features
94
+
95
+ * **fetch:** add AlwatrDocumentStorage type ([44b84f0](https://github.com/AliMD/alwatr/commit/44b84f0754169a707472655811020f6e542a6e5d))
96
+ * **fetch:** serviceRequest ([b0b5478](https://github.com/AliMD/alwatr/commit/b0b5478d16b2cb590cfc29d644006e4a459dd6d6))
97
+ * **fetch:** serviceRequest ([#513](https://github.com/AliMD/alwatr/issues/513)) ([113ee49](https://github.com/AliMD/alwatr/commit/113ee498c778d9efc00cc4807bfef09e52336a31))
98
+ * improve accident debugging ([d697e6c](https://github.com/AliMD/alwatr/commit/d697e6c4c7d0a4172f4dba9caf6fbd478f79de9c))
99
+ * improve error debugging ([1fba504](https://github.com/AliMD/alwatr/commit/1fba50400a1e8ececc10bbe8ea11cc8dcea2289c))
100
+
10
101
  # [1.0.0](https://github.com/AliMD/alwatr/compare/v0.32.0...v1.0.0) (2023-06-14)
11
102
 
12
103
  **Note:** Version bump only for package @alwatr/fetch
package/fetch.js CHANGED
@@ -10,22 +10,21 @@ let alwatrCacheStorage;
10
10
  const cacheSupported = 'caches' in globalThis;
11
11
  const duplicateRequestStorage = {};
12
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 });
13
+ logger.logMethodArgs?.('fetchContext', { contextName });
15
14
  if (cacheSupported && contextProvider.getValue(contextName) == null) {
16
15
  try {
17
16
  fetchOption.cacheStrategy = 'cache_only';
18
17
  const response = await serviceRequest(fetchOption);
19
18
  contextProvider.setValue(contextName, response, dispatchOptions);
20
19
  if (navigator.onLine === false) {
21
- (_b = logger.logOther) === null || _b === void 0 ? void 0 : _b.call(logger, 'fetchContext:', 'offline');
20
+ logger.logOther?.('fetchContext:', 'offline');
22
21
  // retry on online
23
22
  return;
24
23
  }
25
24
  }
26
25
  catch (err) {
27
26
  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');
27
+ logger.logOther?.('fetchContext:', 'fetch_cache_not_found');
29
28
  }
30
29
  else {
31
30
  logger.error('fetchContext', 'fetch_failed', err);
@@ -36,9 +35,9 @@ export async function fetchContext(contextName, fetchOption, dispatchOptions = {
36
35
  try {
37
36
  fetchOption.cacheStrategy = 'update_cache';
38
37
  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 });
38
+ if (response.meta?.lastUpdated === undefined || // skip lastUpdated check
39
+ response.meta?.lastUpdated !== contextProvider.getValue(contextName)?.meta?.lastUpdated) {
40
+ logger.logOther?.('fetchContext:', 'contextProvider.setValue(new-received-context)', { contextName });
42
41
  contextProvider.setValue(contextName, response, dispatchOptions);
43
42
  }
44
43
  }
@@ -51,10 +50,9 @@ export async function fetchContext(contextName, fetchOption, dispatchOptions = {
51
50
  * Fetch from alwatr services and return standard response.
52
51
  */
53
52
  export async function serviceRequest(options) {
54
- var _a, _b;
55
- (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'serviceRequest', { url: options.url });
53
+ logger.logMethodArgs?.('serviceRequest', { url: options.url });
56
54
  if (!NODE_MODE) {
57
- (_b = options.headers) !== null && _b !== void 0 ? _b : (options.headers = {});
55
+ options.headers ?? (options.headers = {});
58
56
  if (!options.headers['client-id']) {
59
57
  options.headers['client-id'] = getClientId();
60
58
  }
@@ -119,26 +117,24 @@ export async function serviceRequest(options) {
119
117
  * ```
120
118
  */
121
119
  export function fetch(options) {
122
- var _a;
123
120
  options = _processOptions(options);
124
- (_a = logger.logMethodArgs) === null || _a === void 0 ? void 0 : _a.call(logger, 'fetch', { options });
121
+ logger.logMethodArgs?.('fetch', { options });
125
122
  return _handleCacheStrategy(options);
126
123
  }
127
124
  /**
128
125
  * Process fetch options and set defaults, etc.
129
126
  */
130
127
  function _processOptions(options) {
131
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
132
- (_a = options.method) !== null && _a !== void 0 ? _a : (options.method = 'GET');
133
- (_b = options.window) !== null && _b !== void 0 ? _b : (options.window = null);
134
- (_c = options.timeout) !== null && _c !== void 0 ? _c : (options.timeout = 10000);
135
- (_d = options.retry) !== null && _d !== void 0 ? _d : (options.retry = 3);
136
- (_e = options.retryDelay) !== null && _e !== void 0 ? _e : (options.retryDelay = 1000);
137
- (_f = options.cacheStrategy) !== null && _f !== void 0 ? _f : (options.cacheStrategy = 'network_only');
138
- (_g = options.removeDuplicate) !== null && _g !== void 0 ? _g : (options.removeDuplicate = 'never');
139
- (_h = options.headers) !== null && _h !== void 0 ? _h : (options.headers = {});
128
+ options.method ?? (options.method = 'GET');
129
+ options.window ?? (options.window = null);
130
+ options.timeout ?? (options.timeout = 10000);
131
+ options.retry ?? (options.retry = 3);
132
+ options.retryDelay ?? (options.retryDelay = 1000);
133
+ options.cacheStrategy ?? (options.cacheStrategy = 'network_only');
134
+ options.removeDuplicate ?? (options.removeDuplicate = 'never');
135
+ options.headers ?? (options.headers = {});
140
136
  if (options.cacheStrategy !== 'network_only' && cacheSupported !== true) {
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', {
137
+ logger.incident?.('fetch', 'fetch_cache_strategy_ignore', 'Cache storage not support in this browser', {
142
138
  cacheSupported,
143
139
  });
144
140
  options.cacheStrategy = 'network_only';
@@ -172,12 +168,11 @@ function _processOptions(options) {
172
168
  * Handle Cache Strategy over `_handleRemoveDuplicate`.
173
169
  */
174
170
  async function _handleCacheStrategy(options) {
175
- var _a;
176
171
  if (options.cacheStrategy === 'network_only') {
177
172
  return _handleRemoveDuplicate(options);
178
173
  }
179
174
  // else handle cache strategies!
180
- (_a = logger.logMethod) === null || _a === void 0 ? void 0 : _a.call(logger, '_handleCacheStrategy');
175
+ logger.logMethod?.('_handleCacheStrategy');
181
176
  if (alwatrCacheStorage == null && options.cacheStorageName == null) {
182
177
  alwatrCacheStorage = await caches.open('alwatr_fetch_cache');
183
178
  }
@@ -240,7 +235,7 @@ async function _handleCacheStrategy(options) {
240
235
  }
241
236
  return networkResponse;
242
237
  });
243
- return cachedResponse !== null && cachedResponse !== void 0 ? cachedResponse : fetchedResponsePromise;
238
+ return cachedResponse ?? fetchedResponsePromise;
244
239
  }
245
240
  default: {
246
241
  return _handleRemoveDuplicate(options);
@@ -251,13 +246,12 @@ async function _handleCacheStrategy(options) {
251
246
  * Handle Remove Duplicates over `_handleRetryPattern`.
252
247
  */
253
248
  async function _handleRemoveDuplicate(options) {
254
- var _a, _b;
255
249
  if (options.removeDuplicate === 'never')
256
250
  return _handleRetryPattern(options);
257
- (_a = logger.logMethod) === null || _a === void 0 ? void 0 : _a.call(logger, '_handleRemoveDuplicate');
251
+ logger.logMethod?.('_handleRemoveDuplicate');
258
252
  const cacheKey = options.method + ' ' + options.url;
259
253
  // We must cache fetch promise without await for handle other parallel requests.
260
- (_b = duplicateRequestStorage[cacheKey]) !== null && _b !== void 0 ? _b : (duplicateRequestStorage[cacheKey] = _handleRetryPattern(options));
254
+ duplicateRequestStorage[cacheKey] ?? (duplicateRequestStorage[cacheKey] = _handleRetryPattern(options));
261
255
  try {
262
256
  // For all requests need to await for clone responses.
263
257
  const response = await duplicateRequestStorage[cacheKey];
@@ -278,10 +272,9 @@ async function _handleRemoveDuplicate(options) {
278
272
  * Handle retry pattern over `_handleTimeout`.
279
273
  */
280
274
  async function _handleRetryPattern(options) {
281
- var _a, _b;
282
275
  if (!(options.retry > 1))
283
276
  return _handleTimeout(options);
284
- (_a = logger.logMethod) === null || _a === void 0 ? void 0 : _a.call(logger, '_handleRetryPattern');
277
+ logger.logMethod?.('_handleRetryPattern');
285
278
  options.retry--;
286
279
  const externalAbortSignal = options.signal;
287
280
  try {
@@ -293,8 +286,8 @@ async function _handleRetryPattern(options) {
293
286
  throw new Error('fetch_server_error');
294
287
  }
295
288
  catch (err) {
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) {
289
+ logger.accident('fetch', 'fetch_failed_retry', err?.message || 'fetch failed and retry', err);
290
+ if (globalThis.navigator?.onLine === false) {
298
291
  throw new Error('offline');
299
292
  }
300
293
  await delay(options.retryDelay);
@@ -306,12 +299,11 @@ async function _handleRetryPattern(options) {
306
299
  * It's a wrapper around the browser's `fetch` with timeout.
307
300
  */
308
301
  function _handleTimeout(options) {
309
- var _a;
310
302
  if (options.timeout === 0) {
311
303
  return globalThis.fetch(options.url, options);
312
304
  }
313
305
  // else
314
- (_a = logger.logMethod) === null || _a === void 0 ? void 0 : _a.call(logger, '_handleTimeout');
306
+ logger.logMethod?.('_handleTimeout');
315
307
  return new Promise((resolved, reject) => {
316
308
  // TODO: AbortController polyfill
317
309
  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, NODE_MODE} from '@alwatr/logger';\nimport {contextProvider, type DispatchOptions} from '@alwatr/signal';\nimport {getClientId, delay} from '@alwatr/util';\n\nimport type {FetchOptions} from './type.js';\nimport type {AlwatrServiceResponse} 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 AlwatrServiceResponse = AlwatrServiceResponse\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 delay(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"]}
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, delay} from '@alwatr/util';\n\nimport type {FetchOptions} from './type.js';\nimport type {AlwatrServiceResponse} 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 AlwatrServiceResponse = AlwatrServiceResponse\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 delay(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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwatr/fetch",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
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,13 +34,10 @@
34
34
  "url": "https://github.com/AliMD/alwatr/issues"
35
35
  },
36
36
  "dependencies": {
37
- "@alwatr/logger": "^1.0.1",
38
- "@alwatr/signal": "^1.0.1",
39
- "@alwatr/util": "^1.0.1",
40
- "tslib": "^2.5.3"
37
+ "@alwatr/logger": "^1.1.1",
38
+ "@alwatr/signal": "^1.1.1",
39
+ "@alwatr/util": "^1.1.1",
40
+ "tslib": "^2.6.2"
41
41
  },
42
- "devDependencies": {
43
- "@alwatr/type": "^1.0.1"
44
- },
45
- "gitHead": "10b9734389e27538ba4fa4ac7871ec0354ca9285"
42
+ "gitHead": "ebc98f75330ab77c7a5bfeebe0fd1f4748bf3821"
46
43
  }