@graphql-mesh/plugin-deduplicate-request
Version:
59 lines (58 loc) • 2.6 kB
JavaScript
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 }) {
if (context != null) {
let method = 'GET';
if (options.method) {
method = options.method;
}
if (method === 'GET') {
const reqResMap = getReqResMapByContext(context);
const dedupCacheKey = JSON.stringify({
url,
headers: options.headers || {},
});
setFetchFn(() => {
let dedupRes$ = reqResMap.get(dedupCacheKey);
if (dedupRes$ == null) {
dedupRes$ = fetchFn(url, options, context, info);
reqResMap.set(dedupCacheKey, dedupRes$);
}
return dedupRes$.then(res => {
let resPropMapByRes = resPropMap.get(res);
if (!resPropMapByRes) {
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$) {
resPropResult$ = target[prop](...args);
resPropMapByRes.set(prop, resPropResult$);
}
return resPropResult$;
};
}
return target[prop];
},
});
});
});
}
}
},
};
}