UNPKG

apollo-client

Version:
158 lines 6.36 kB
var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; import graphqlAnywhere from 'graphql-anywhere'; import { isJsonValue, isIdValue, } from './storeUtils'; import { storeKeyNameFromFieldNameAndArgs, } from './storeUtils'; import { getQueryDefinition, } from '../queries/getFromAST'; import { isEqual, } from '../util/isEqual'; import { isTest, } from '../util/environment'; export var ID_KEY = typeof Symbol !== 'undefined' ? Symbol('id') : '@@id'; export function readQueryFromStore(options) { var optsPatch = { returnPartialData: ((options.returnPartialData !== undefined) ? options.returnPartialData : false), }; return diffQueryAgainstStore(__assign({}, options, optsPatch)).result; } var haveWarned = false; var fragmentMatcher = function (idValue, typeCondition, context) { assertIdValue(idValue); var obj = context.store[idValue.id]; if (!obj) { return false; } if (!obj.__typename) { if (!haveWarned) { console.warn("You're using fragments in your queries, but don't have the addTypename:\ntrue option set in Apollo Client. Please turn on that option so that we can accurately\nmatch fragments."); if (!isTest()) { haveWarned = true; } } context.returnPartialData = true; return true; } if (obj.__typename === typeCondition) { return true; } context.returnPartialData = true; return true; }; var readStoreResolver = function (fieldName, idValue, args, context, _a) { var resultKey = _a.resultKey; assertIdValue(idValue); var objId = idValue.id; var obj = context.store[objId]; var storeKeyName = storeKeyNameFromFieldNameAndArgs(fieldName, args); var fieldValue = (obj || {})[storeKeyName]; if (typeof fieldValue === 'undefined') { if (context.customResolvers && obj && (obj.__typename || objId === 'ROOT_QUERY')) { var typename = obj.__typename || 'Query'; var type = context.customResolvers[typename]; if (type) { var resolver = type[fieldName]; if (resolver) { return resolver(obj, args); } } } if (!context.returnPartialData) { throw new Error("Can't find field " + storeKeyName + " on object (" + objId + ") " + JSON.stringify(obj, null, 2) + ".\nPerhaps you want to use the `returnPartialData` option?"); } context.hasMissingField = true; return fieldValue; } if (isJsonValue(fieldValue)) { if (idValue.previousResult && isEqual(idValue.previousResult[resultKey], fieldValue.json)) { return idValue.previousResult[resultKey]; } return fieldValue.json; } if (idValue.previousResult) { fieldValue = addPreviousResultToIdValues(fieldValue, idValue.previousResult[resultKey]); } return fieldValue; }; export function diffQueryAgainstStore(_a) { var store = _a.store, query = _a.query, variables = _a.variables, _b = _a.returnPartialData, returnPartialData = _b === void 0 ? true : _b, previousResult = _a.previousResult, config = _a.config; getQueryDefinition(query); var context = { store: store, returnPartialData: returnPartialData, customResolvers: (config && config.customResolvers) || {}, hasMissingField: false, }; var rootIdValue = { type: 'id', id: 'ROOT_QUERY', previousResult: previousResult, }; var result = graphqlAnywhere(readStoreResolver, query, rootIdValue, context, variables, { fragmentMatcher: fragmentMatcher, resultMapper: resultMapper, }); return { result: result, isMissing: context.hasMissingField, }; } function assertIdValue(idValue) { if (!isIdValue(idValue)) { throw new Error("Encountered a sub-selection on the query, but the store doesn't have an object reference. This should never happen during normal use unless you have custom code that is directly manipulating the store; please file an issue."); } } function addPreviousResultToIdValues(value, previousResult) { if (isIdValue(value)) { return __assign({}, value, { previousResult: previousResult }); } else if (Array.isArray(value)) { var idToPreviousResult_1 = {}; if (Array.isArray(previousResult)) { previousResult.forEach(function (item) { if (item[ID_KEY]) { idToPreviousResult_1[item[ID_KEY]] = item; } }); } return value.map(function (item, i) { var itemPreviousResult = previousResult && previousResult[i]; if (isIdValue(item)) { itemPreviousResult = idToPreviousResult_1[item.id] || itemPreviousResult; } return addPreviousResultToIdValues(item, itemPreviousResult); }); } return value; } function resultMapper(resultFields, idValue) { if (idValue.previousResult) { var currentResultKeys_1 = Object.keys(resultFields); var sameAsPreviousResult = Object.keys(idValue.previousResult) .reduce(function (sameKeys, key) { return sameKeys && currentResultKeys_1.indexOf(key) > -1; }, true) && currentResultKeys_1.reduce(function (same, key) { return (same && areNestedArrayItemsStrictlyEqual(resultFields[key], idValue.previousResult[key])); }, true); if (sameAsPreviousResult) { return idValue.previousResult; } } Object.defineProperty(resultFields, ID_KEY, { enumerable: false, configurable: false, writable: false, value: idValue.id, }); return resultFields; } function areNestedArrayItemsStrictlyEqual(a, b) { if (a === b) { return true; } if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) { return false; } return a.reduce(function (same, item, i) { return same && areNestedArrayItemsStrictlyEqual(item, b[i]); }, true); } //# sourceMappingURL=readFromStore.js.map