Skip to content

Commit

Permalink
feat(fetch): serviceRequest
Browse files Browse the repository at this point in the history
  • Loading branch information
alimd committed Dec 17, 2022
1 parent 44b84f0 commit b0b5478
Showing 1 changed file with 51 additions and 14 deletions.
65 changes: 51 additions & 14 deletions core/fetch/src/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@ import type {
CacheStrategy,
AlwatrDocumentObject,
AlwatrServiceResponse,
AlwatrServiceResponseSuccessWithMeta,
AlwatrServiceResponseSuccess,
} from './type.js';

export {
FetchOptions,
CacheDuplicate,
CacheStrategy,
AlwatrDocumentObject,
AlwatrServiceResponse,
};
export {FetchOptions, CacheDuplicate, CacheStrategy, AlwatrDocumentObject, AlwatrServiceResponse};

const logger = createLogger('alwatr/fetch');

Expand All @@ -28,6 +24,46 @@ const cacheSupported = 'caches' in globalThis;

const duplicateRequestStorage: Record<string, Promise<Response>> = {};

/**
* Fetch from alwatr services and return standard response.
*/
export async function serviceRequest<TData = Record<string, unknown>, TMeta = Record<string, unknown>>(
options: FetchOptions,
): Promise<AlwatrServiceResponseSuccess<TData> | AlwatrServiceResponseSuccessWithMeta<TData, TMeta>> {
logger.logMethod('serviceRequest');

const response = await fetch(options);

let responseJson: AlwatrServiceResponse<TData, TMeta>;
try {
responseJson = await response.json();
}
catch (err) {
let responseText: string | null = null;
try {
responseText = await response.text();
}
catch {
logger.accident('serviceRequest', 'invalid_response', 'Cannot extract response.text()');
}
logger.error('serviceRequest', 'invalid_json', err, {responseText});
throw new Error('invalid_json');
}

if (responseJson.ok !== true) {
logger.error('serviceRequest', 'fetch_nok', {responseJson});
if (typeof responseJson.errorCode === 'string') {
throw new Error(responseJson.errorCode);
}
// else
throw new Error('fetch_nok');
}

// TODO: generate fetch signals hook (for easier handle loading and show error toast)

return responseJson;
}

/**
* It's a wrapper around the browser's `fetch` function that adds retry pattern, timeout, cacheStrategy,
* remove duplicates, etc.
Expand All @@ -45,10 +81,10 @@ const duplicateRequestStorage: Record<string, Promise<Response>> = {};
* });
* ```
*/
export function fetch(_options: FetchOptions): Promise<Response> {
const options = _processOptions(_options);
logger.logMethodArgs('fetch', {options});
return _handleCacheStrategy(options);
export function fetch(options: FetchOptions): Promise<Response> {
const _options = _processOptions(options);
logger.logMethodArgs('fetch', {options: _options});
return _handleCacheStrategy(_options);
}

/**
Expand Down Expand Up @@ -140,11 +176,12 @@ async function _handleCacheStrategy(options: Required<FetchOptions>): Promise<Re

case 'cache_only': {
const cachedResponse = await cacheStorage.match(request);
if (cachedResponse != null) {
return cachedResponse;
if (cachedResponse == null) {
logger.error('_handleCacheStrategy', 'fetch_cache_not_found', {request});
throw new Error('fetch_cache_not_found');
}
// else
throw new Error('fetch_cache_not_found');
return cachedResponse;
}

case 'network_first': {
Expand Down

0 comments on commit b0b5478

Please sign in to comment.