@graphql-mesh/plugin-deduplicate-request
Version:
67 lines (66 loc) • 3.15 kB
JavaScript
import { getHeadersObj } from '@graphql-mesh/utils';
import { handleMaybePromise } from '@whatwg-node/promise-helpers';
export default function useDeduplicateRequest() {
const reqResMapByContext = new WeakMap();
function getReqResMapByContext(context) {
let reqResMap = reqResMapByContext.get(context);
if (!reqResMap) {
reqResMap = new Map();
reqResMapByContext.set(context, reqResMap);
}
return reqResMap;
}
const resPropMap = new WeakMap();
return {
onFetch({ url, options, context, info, fetchFn, setFetchFn, endResponse }) {
if (context != null) {
let method = 'GET';
if (options.method) {
method = options.method;
}
if (method === 'GET') {
const reqResMap = getReqResMapByContext(context);
let dedupCacheKey = url;
if (options.headers) {
const headersObj = getHeadersObj(options.headers);
dedupCacheKey += JSON.stringify(headersObj);
}
const dedupRes$ = reqResMap.get(dedupCacheKey);
if (dedupRes$) {
endResponse(dedupRes$);
return;
}
setFetchFn(() => {
let dedupRes$ = reqResMap.get(dedupCacheKey);
if (dedupRes$ == null) {
dedupRes$ = handleMaybePromise(() => fetchFn(url, options, context, info), res => {
let resPropMapByRes = resPropMap.get(res);
if (resPropMapByRes == null) {
resPropMapByRes = new Map();
resPropMap.set(res, resPropMapByRes);
}
return new Proxy(res, {
get(target, prop) {
if (typeof target[prop] === 'function') {
return (...args) => {
let resPropResult$ = resPropMapByRes.get(prop);
if (resPropResult$ == null) {
resPropResult$ = target[prop](...args);
resPropMapByRes.set(prop, resPropResult$);
}
return resPropResult$;
};
}
return target[prop];
},
});
});
reqResMap.set(dedupCacheKey, dedupRes$);
}
return dedupRes$;
});
}
}
},
};
}