"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var apollo_utilities_1 = require("apollo-utilities"); var ts_invariant_1 = require("ts-invariant"); var objectCache_1 = require("./objectCache"); var depTrackingCache_1 = require("./depTrackingCache"); var WriteError = (function (_super) { tslib_1.__extends(WriteError, _super); function WriteError() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'WriteError'; return _this; } return WriteError; }(Error)); exports.WriteError = WriteError; function enhanceErrorWithDocument(error, document) { var enhancedError = new WriteError("Error writing result to store for query:\n " + JSON.stringify(document)); enhancedError.message += '\n' + error.message; enhancedError.stack = error.stack; return enhancedError; } exports.enhanceErrorWithDocument = enhanceErrorWithDocument; var StoreWriter = (function () { function StoreWriter() { } StoreWriter.prototype.writeQueryToStore = function (_a) { var query = _a.query, result = _a.result, _b = _a.store, store = _b === void 0 ? depTrackingCache_1.defaultNormalizedCacheFactory() : _b, variables = _a.variables, dataIdFromObject = _a.dataIdFromObject, fragmentMatcherFunction = _a.fragmentMatcherFunction; return this.writeResultToStore({ dataId: 'ROOT_QUERY', result: result, document: query, store: store, variables: variables, dataIdFromObject: dataIdFromObject, fragmentMatcherFunction: fragmentMatcherFunction, }); }; StoreWriter.prototype.writeResultToStore = function (_a) { var dataId = _a.dataId, result = _a.result, document = _a.document, _b = _a.store, store = _b === void 0 ? depTrackingCache_1.defaultNormalizedCacheFactory() : _b, variables = _a.variables, dataIdFromObject = _a.dataIdFromObject, fragmentMatcherFunction = _a.fragmentMatcherFunction; var operationDefinition = apollo_utilities_1.getOperationDefinition(document); try { return this.writeSelectionSetToStore({ result: result, dataId: dataId, selectionSet: operationDefinition.selectionSet, context: { store: store, processedData: {}, variables: apollo_utilities_1.assign({}, apollo_utilities_1.getDefaultValues(operationDefinition), variables), dataIdFromObject: dataIdFromObject, fragmentMap: apollo_utilities_1.createFragmentMap(apollo_utilities_1.getFragmentDefinitions(document)), fragmentMatcherFunction: fragmentMatcherFunction, }, }); } catch (e) { throw enhanceErrorWithDocument(e, document); } }; StoreWriter.prototype.writeSelectionSetToStore = function (_a) { var _this = this; var result = _a.result, dataId = _a.dataId, selectionSet = _a.selectionSet, context = _a.context; var variables = context.variables, store = context.store, fragmentMap = context.fragmentMap; selectionSet.selections.forEach(function (selection) { var _a; if (!apollo_utilities_1.shouldInclude(selection, variables)) { return; } if (apollo_utilities_1.isField(selection)) { var resultFieldKey = apollo_utilities_1.resultKeyNameFromField(selection); var value = result[resultFieldKey]; if (typeof value !== 'undefined') { _this.writeFieldToStore({ dataId: dataId, value: value, field: selection, context: context, }); } else { var isDefered = false; var isClient = false; if (selection.directives && selection.directives.length) { isDefered = selection.directives.some(function (directive) { return directive.name && directive.name.value === 'defer'; }); isClient = selection.directives.some(function (directive) { return directive.name && directive.name.value === 'client'; }); } if (!isDefered && !isClient && context.fragmentMatcherFunction) { ts_invariant_1.invariant.warn("Missing field " + resultFieldKey + " in " + JSON.stringify(result, null, 2).substring(0, 100)); } } } else { var fragment = void 0; if (apollo_utilities_1.isInlineFragment(selection)) { fragment = selection; } else { fragment = (fragmentMap || {})[selection.name.value]; ts_invariant_1.invariant(fragment, "No fragment named " + selection.name.value + "."); } var matches = true; if (context.fragmentMatcherFunction && fragment.typeCondition) { var id = dataId || 'self'; var idValue = apollo_utilities_1.toIdValue({ id: id, typename: undefined }); var fakeContext = { store: new objectCache_1.ObjectCache((_a = {}, _a[id] = result, _a)), cacheRedirects: {}, }; var match = context.fragmentMatcherFunction(idValue, fragment.typeCondition.name.value, fakeContext); if (!apollo_utilities_1.isProduction() && match === 'heuristic') { ts_invariant_1.invariant.error('WARNING: heuristic fragment matching going on!'); } matches = !!match; } if (matches) { _this.writeSelectionSetToStore({ result: result, selectionSet: fragment.selectionSet, dataId: dataId, context: context, }); } } }); return store; }; StoreWriter.prototype.writeFieldToStore = function (_a) { var _b; var field = _a.field, value = _a.value, dataId = _a.dataId, context = _a.context; var variables = context.variables, dataIdFromObject = context.dataIdFromObject, store = context.store; var storeValue; var storeObject; var storeFieldName = apollo_utilities_1.storeKeyNameFromField(field, variables); if (!field.selectionSet || value === null) { storeValue = value != null && typeof value === 'object' ? { type: 'json', json: value } : value; } else if (Array.isArray(value)) { var generatedId = dataId + "." + storeFieldName; storeValue = this.processArrayValue(value, generatedId, field.selectionSet, context); } else { var valueDataId = dataId + "." + storeFieldName; var generated = true; if (!isGeneratedId(valueDataId)) { valueDataId = '$' + valueDataId; } if (dataIdFromObject) { var semanticId = dataIdFromObject(value); ts_invariant_1.invariant(!semanticId || !isGeneratedId(semanticId), 'IDs returned by dataIdFromObject cannot begin with the "$" character.'); if (semanticId || (typeof semanticId === 'number' && semanticId === 0)) { valueDataId = semanticId; generated = false; } } if (!isDataProcessed(valueDataId, field, context.processedData)) { this.writeSelectionSetToStore({ dataId: valueDataId, result: value, selectionSet: field.selectionSet, context: context, }); } var typename = value.__typename; storeValue = apollo_utilities_1.toIdValue({ id: valueDataId, typename: typename }, generated); storeObject = store.get(dataId); var escapedId = storeObject && storeObject[storeFieldName]; if (escapedId !== storeValue && apollo_utilities_1.isIdValue(escapedId)) { var hadTypename = escapedId.typename !== undefined; var hasTypename = typename !== undefined; var typenameChanged = hadTypename && hasTypename && escapedId.typename !== typename; ts_invariant_1.invariant(!generated || escapedId.generated || typenameChanged, "Store error: the application attempted to write an object with no provided id but the store already contains an id of " + escapedId.id + " for this object. The selectionSet that was trying to be written is:\n" + JSON.stringify(field)); ts_invariant_1.invariant(!hadTypename || hasTypename, "Store error: the application attempted to write an object with no provided typename but the store already contains an object with typename of " + escapedId.typename + " for the object of id " + escapedId.id + ". The selectionSet that was trying to be written is:\n" + JSON.stringify(field)); if (escapedId.generated) { if (typenameChanged) { if (!generated) { store.delete(escapedId.id); } } else { mergeWithGenerated(escapedId.id, storeValue.id, store); } } } } storeObject = store.get(dataId); if (!storeObject || !apollo_utilities_1.isEqual(storeValue, storeObject[storeFieldName])) { store.set(dataId, tslib_1.__assign(tslib_1.__assign({}, storeObject), (_b = {}, _b[storeFieldName] = storeValue, _b))); } }; StoreWriter.prototype.processArrayValue = function (value, generatedId, selectionSet, context) { var _this = this; return value.map(function (item, index) { if (item === null) { return null; } var itemDataId = generatedId + "." + index; if (Array.isArray(item)) { return _this.processArrayValue(item, itemDataId, selectionSet, context); } var generated = true; if (context.dataIdFromObject) { var semanticId = context.dataIdFromObject(item); if (semanticId) { itemDataId = semanticId; generated = false; } } if (!isDataProcessed(itemDataId, selectionSet, context.processedData)) { _this.writeSelectionSetToStore({ dataId: itemDataId, result: item, selectionSet: selectionSet, context: context, }); } return apollo_utilities_1.toIdValue({ id: itemDataId, typename: item.__typename }, generated); }); }; return StoreWriter; }()); exports.StoreWriter = StoreWriter; function isGeneratedId(id) { return id[0] === '$'; } function mergeWithGenerated(generatedKey, realKey, cache) { if (generatedKey === realKey) { return false; } var generated = cache.get(generatedKey); var real = cache.get(realKey); var madeChanges = false; Object.keys(generated).forEach(function (key) { var value = generated[key]; var realValue = real[key]; if (apollo_utilities_1.isIdValue(value) && isGeneratedId(value.id) && apollo_utilities_1.isIdValue(realValue) && !apollo_utilities_1.isEqual(value, realValue) && mergeWithGenerated(value.id, realValue.id, cache)) { madeChanges = true; } }); cache.delete(generatedKey); var newRealValue = tslib_1.__assign(tslib_1.__assign({}, generated), real); if (apollo_utilities_1.isEqual(newRealValue, real)) { return madeChanges; } cache.set(realKey, newRealValue); return true; } function isDataProcessed(dataId, field, processedData) { if (!processedData) { return false; } if (processedData[dataId]) { if (processedData[dataId].indexOf(field) >= 0) { return true; } else { processedData[dataId].push(field); } } else { processedData[dataId] = [field]; } return false; } //# sourceMappingURL=writeToStore.js.map