@apollo/client
Version:
A fully-featured caching GraphQL client.
118 lines • 5.01 kB
JavaScript
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