UNPKG

@apollo/client

Version:

A fully-featured caching GraphQL client.

118 lines 5.01 kB
import { invariant } from "../../utilities/globals/index.js"; import { argumentsObjectFromField, DeepMerger, isNonEmptyArray, isNonNullObject, } from "../../utilities/index.js"; import { hasOwn, isArray } from "./helpers.js"; var specifierInfoCache = Object.create(null); function lookupSpecifierInfo(spec) { var cacheKey = JSON.stringify(spec); return specifierInfoCache[cacheKey] || (specifierInfoCache[cacheKey] = Object.create(null)); } export function keyFieldsFnFromSpecifier(specifier) { var info = lookupSpecifierInfo(specifier); return info.keyFieldsFn || (info.keyFieldsFn = function (object, context) { var extract = function (from, key) { return context.readField(key, from); }; var keyObject = context.keyObject = collectSpecifierPaths(specifier, function (schemaKeyPath) { var extracted = extractKeyPath(context.storeObject, schemaKeyPath, extract); if (extracted === void 0 && object !== context.storeObject && hasOwn.call(object, schemaKeyPath[0])) { extracted = extractKeyPath(object, schemaKeyPath, extractKey); } __DEV__ ? invariant(extracted !== void 0, "Missing field '".concat(schemaKeyPath.join('.'), "' while extracting keyFields from ").concat(JSON.stringify(object))) : invariant(extracted !== void 0, 2); return extracted; }); return "".concat(context.typename, ":").concat(JSON.stringify(keyObject)); }); } export function keyArgsFnFromSpecifier(specifier) { var info = lookupSpecifierInfo(specifier); return info.keyArgsFn || (info.keyArgsFn = function (args, _a) { var field = _a.field, variables = _a.variables, fieldName = _a.fieldName; var collected = collectSpecifierPaths(specifier, function (keyPath) { var firstKey = keyPath[0]; var firstChar = firstKey.charAt(0); if (firstChar === "@") { if (field && isNonEmptyArray(field.directives)) { var directiveName_1 = firstKey.slice(1); var d = field.directives.find(function (d) { return d.name.value === directiveName_1; }); var directiveArgs = d && argumentsObjectFromField(d, variables); return directiveArgs && extractKeyPath(directiveArgs, keyPath.slice(1)); } return; } if (firstChar === "$") { var variableName = firstKey.slice(1); if (variables && hasOwn.call(variables, variableName)) { var varKeyPath = keyPath.slice(0); varKeyPath[0] = variableName; return extractKeyPath(variables, varKeyPath); } return; } if (args) { return extractKeyPath(args, keyPath); } }); var suffix = JSON.stringify(collected); if (args || suffix !== "{}") { fieldName += ":" + suffix; } return fieldName; }); } export function collectSpecifierPaths(specifier, extractor) { var merger = new DeepMerger; return getSpecifierPaths(specifier).reduce(function (collected, path) { var _a; var toMerge = extractor(path); if (toMerge !== void 0) { for (var i = path.length - 1; i >= 0; --i) { toMerge = (_a = {}, _a[path[i]] = toMerge, _a); } collected = merger.merge(collected, toMerge); } return collected; }, Object.create(null)); } export function getSpecifierPaths(spec) { var info = lookupSpecifierInfo(spec); if (!info.paths) { var paths_1 = info.paths = []; var currentPath_1 = []; spec.forEach(function (s, i) { if (isArray(s)) { getSpecifierPaths(s).forEach(function (p) { return paths_1.push(currentPath_1.concat(p)); }); currentPath_1.length = 0; } else { currentPath_1.push(s); if (!isArray(spec[i + 1])) { paths_1.push(currentPath_1.slice(0)); currentPath_1.length = 0; } } }); } return info.paths; } function extractKey(object, key) { return object[key]; } export function extractKeyPath(object, path, extract) { extract = extract || extractKey; return normalize(path.reduce(function reducer(obj, key) { return isArray(obj) ? obj.map(function (child) { return reducer(child, key); }) : obj && extract(obj, key); }, object)); } function normalize(value) { if (isNonNullObject(value)) { if (isArray(value)) { return value.map(normalize); } return collectSpecifierPaths(Object.keys(value).sort(), function (path) { return extractKeyPath(value, path); }); } return value; } //# sourceMappingURL=key-extractor.js.map