From e8a3f8d178451fcd2b8c052f9a3b33bcdb8f792e Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Tue, 15 Nov 2022 21:08:27 +0330 Subject: [PATCH 1/3] refactor(fetch): remove getJson --- demo/fetch/node.ts | 19 +++++++----- packages/core/fetch/README.md | 53 ++++++++------------------------ packages/core/fetch/src/fetch.ts | 49 ----------------------------- 3 files changed, 25 insertions(+), 96 deletions(-) diff --git a/demo/fetch/node.ts b/demo/fetch/node.ts index 8e6be7bd9..0e309a919 100644 --- a/demo/fetch/node.ts +++ b/demo/fetch/node.ts @@ -1,10 +1,15 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import {fetch} from '@alwatr/fetch'; -const response = await fetch({ - url: 'http://httpbin.org/uuid', - timeout: 3_000, - removeDuplicate: 'auto', -}); - -console.log(await response.text()); +try { + const response = await fetch({ + url: 'http://httpbin.org/uuid', + timeout: 3_000, + removeDuplicate: 'auto', + }); + console.log('ok: %s', response.ok); + console.log('text: %s', await response.text()); +} +catch (err) { + console.error(err); +} diff --git a/packages/core/fetch/README.md b/packages/core/fetch/README.md index 850851413..b03461894 100644 --- a/packages/core/fetch/README.md +++ b/packages/core/fetch/README.md @@ -4,26 +4,29 @@ Enhanced fetch API with cache strategy, retry pattern, timeout, helper methods a ## Example usage -```ts -import {getJson} from 'https://esm.run/@alwatr/fetch'; +### `fetch(options: FetchOptions): Promise` -interface ProductInterface { - _id: string; - name: string; - description: string; - image: string; -} +It's a wrapper around the browser's `fetch` function that adds retry pattern with timeout and cacheStrategy. + +```ts +import {fetch} from 'https://esm.run/@alwatr/fetch'; -const productList = await getJson>({ +const response = await fetch({ url: '/api/products', queryParameters: {limit: 10}, timeout: 5_000, retry: 3, cacheStrategy: 'stale_while_revalidate', }); + +if (!response.ok) throw new Error('fetch_failed'); + +const productList = await response.json(); + +console.log(productList); ``` -## Fetch Options +### Fetch Options `FetchOptions` inherited from the [fetch standard parameters](https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters) and some other... @@ -48,33 +51,3 @@ const productList = await getJson>({ - `cacheStorageName`: Cache storage custom name (default `alwatr_fetch_cache`). [Read more about standard cache strategies](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#caching-strategies) - -## API - -### `fetch(options: FetchOptions): Promise` - -It's a wrapper around the browser's `fetch` function that adds retry pattern with timeout and cacheStrategy. - -```ts -const response = await fetch({ - url: '/api/products', - queryParameters: {limit: 10}, - timeout: 5_000, - retry: 3, - cacheStrategy: 'stale_while_revalidate', -}); -``` - -### `getJson(options: FetchOptions): Promise` - -It fetches a JSON file from a URL, and returns the parsed data. - -```ts -const productList = await getJson({ - url: '/api/products', - queryParameters: {limit: 10}, - timeout: 5_000, - retry: 3, - cacheStrategy: 'stale_while_revalidate', -}); -``` diff --git a/packages/core/fetch/src/fetch.ts b/packages/core/fetch/src/fetch.ts index 58ca076ac..44002c262 100644 --- a/packages/core/fetch/src/fetch.ts +++ b/packages/core/fetch/src/fetch.ts @@ -93,55 +93,6 @@ const cacheSupported = 'caches' in globalThis; const duplicateRequestStorage: Record> = {}; -/** - * It fetches a JSON file from a URL, and returns the parsed data. - * - * Example: - * - * ```ts - * const productList = await getJson({ - * url: '/api/products', - * queryParameters: {limit: 10}, - * timeout: 10_000, - * retry: 3, - * cacheStrategy: 'stale_while_revalidate', - * cacheDuplicate: 'auto', - * }); - * ``` - */ -export async function getJson>( - _options: Partial & {url: string}, -): Promise { - const options = _processOptions(_options); - logger.logMethodArgs('getJson', {options}); - - const response = await _handleRemoveDuplicate(options); - - let data: ResponseType; - - try { - if (!response.ok) { - throw new Error('fetch_nok'); - } - data = (await response.json()) as ResponseType; - } - catch (err) { - logger.accident('getJson', 'response_json', 'response json error', { - retry: options.retry, - err, - }); - - if (options.retry > 1) { - data = await getJson(options); - } - else { - throw err; - } - } - - return data; -} - /** * It's a wrapper around the browser's `fetch` function that adds retry pattern, timeout, cacheStrategy, * remove duplicates, etc. From 147840123159d6b37c90e64693fd6aae444e663a Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Wed, 16 Nov 2022 12:25:14 +0330 Subject: [PATCH 2/3] refactor(i18n): use new fetch --- packages/core/i18n/src/i18n.ts | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/core/i18n/src/i18n.ts b/packages/core/i18n/src/i18n.ts index 198abe358..db9043d36 100644 --- a/packages/core/i18n/src/i18n.ts +++ b/packages/core/i18n/src/i18n.ts @@ -1,4 +1,4 @@ -import {getJson} from '@alwatr/fetch'; +import {fetch} from '@alwatr/fetch'; import {alwatrRegisteredList, createLogger} from '@alwatr/logger'; import {SignalInterface} from '@alwatr/signal'; @@ -112,9 +112,28 @@ l10n.resourceChangeSignal.setProvider(async (locale) => { return; } - return await getJson({url: `${l10n.config.resourcePath}/${locale.code}.json`}); - // TODO: cache requests using fetch (add feature for fetch) - // TODO: catch errors and fallback + const url = `${l10n.config.resourcePath}/${locale.code}.json`; + try { + const response = await fetch({ + url, + retry: 20, + retryDelay: 1_000, + timeout: 10_000, + removeDuplicate: 'auto', + cacheStrategy: 'stale_while_revalidate', + }); + + if (response.ok) { + return response.json(); + } + else { + throw new Error('fetch_nok'); + } + } + catch (err) { + logger.error('resourceProvider', 'fetch_failed', (err as Error).stack || err, {locale, url}); + // TODO: user error signal. + } }); /** From fe4ac12b4ad3086d44e545591c767cb322e32b8d Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Wed, 16 Nov 2022 12:25:32 +0330 Subject: [PATCH 3/3] fix(fetch): _handleRetryPattern --- packages/core/fetch/src/fetch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/fetch/src/fetch.ts b/packages/core/fetch/src/fetch.ts index 44002c262..2bc7e5031 100644 --- a/packages/core/fetch/src/fetch.ts +++ b/packages/core/fetch/src/fetch.ts @@ -283,7 +283,7 @@ async function _handleRetryPattern(options: FetchOptions): Promise { options.retry--; options.signal = externalAbortSignal; await _wait(options.retryDelay); - return _handleCacheStrategy(options); // maybe cache updated by another request ;) + return _handleRetryPattern(options); }; try {