apollo-cache-inmemory
Advanced tools
Comparing version 1.3.0-beta.7 to 1.3.0-beta.8
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('apollo-utilities'), require('graphql/language/printer'), require('apollo-cache')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'apollo-utilities', 'graphql/language/printer', 'apollo-cache'], factory) : | ||
(factory((global.apollo = global.apollo || {}, global.apollo.cache = global.apollo.cache || {}, global.apollo.cache.inmemory = {}),global.apollo.utilities,global.printer,global.apolloCache.core)); | ||
(factory((global.apollo = global.apollo || {}, global.apollo.cache = global.apollo.cache || {}, global.apollo.cache.inmemory = {}),global.apollo.utilities,global.print,global.apolloCache.core)); | ||
}(this, (function (exports,apolloUtilities,printer,apolloCache) { 'use strict'; | ||
var haveWarned = false; | ||
/** | ||
* This fragment matcher is very basic and unable to match union or interface type conditions | ||
*/ | ||
var HeuristicFragmentMatcher = /** @class */ (function () { | ||
var HeuristicFragmentMatcher = (function () { | ||
function HeuristicFragmentMatcher() { | ||
// do nothing | ||
} | ||
@@ -19,3 +15,3 @@ HeuristicFragmentMatcher.prototype.ensureReady = function () { | ||
HeuristicFragmentMatcher.prototype.canBypassInit = function () { | ||
return true; // we don't need to initialize this fragment matcher. | ||
return true; | ||
}; | ||
@@ -36,5 +32,3 @@ HeuristicFragmentMatcher.prototype.match = function (idValue, typeCondition, context) { | ||
"and will be removed in future versions of Apollo client. You should fix this and set addTypename to true now."); | ||
/* istanbul ignore if */ | ||
if (!apolloUtilities.isTest()) { | ||
// When running tests, we want to print the warning every time | ||
haveWarned = true; | ||
@@ -48,10 +42,7 @@ } | ||
} | ||
// XXX here we reach an issue - we don't know if this fragment should match or not. It's either: | ||
// 1. A fragment on a non-matching concrete type or interface or union | ||
// 2. A fragment on a matching interface or union | ||
// If it's 1, we don't want to return anything, if it's 2 we want to match. We can't tell the | ||
// difference, so we warn the user, but still try to match it (backcompat). | ||
apolloUtilities.warnOnceInDevelopment("You are using the simple (heuristic) fragment matcher, but your queries contain union or interface types.\n Apollo Client will not be able to able to accurately map fragments." + | ||
"To make this error go away, use the IntrospectionFragmentMatcher as described in the docs: " + | ||
"https://www.apollographql.com/docs/react/recipes/fragment-matching.html", 'error'); | ||
apolloUtilities.warnOnceInDevelopment('You are using the simple (heuristic) fragment matcher, but your ' + | ||
'queries contain union or interface types. Apollo Client will not be ' + | ||
'able to accurately map fragments. To make this error go away, use ' + | ||
'the `IntrospectionFragmentMatcher` as described in the docs: ' + | ||
'https://www.apollographql.com/docs/react/recipes/fragment-matching.html', 'error'); | ||
return 'heuristic'; | ||
@@ -61,3 +52,3 @@ }; | ||
}()); | ||
var IntrospectionFragmentMatcher = /** @class */ (function () { | ||
var IntrospectionFragmentMatcher = (function () { | ||
function IntrospectionFragmentMatcher(options) { | ||
@@ -75,3 +66,2 @@ if (options && options.introspectionQueryResultData) { | ||
if (!this.isReady) { | ||
// this should basically never happen in proper use. | ||
throw new Error('FragmentMatcher.match() was called before FragmentMatcher.init()'); | ||
@@ -107,3 +97,3 @@ } | ||
var ObjectCache = /** @class */ (function () { | ||
var ObjectCache = (function () { | ||
function ObjectCache(data) { | ||
@@ -137,6 +127,6 @@ if (data === void 0) { data = Object.create(null); } | ||
var _a = require('optimism'), wrap = _a.wrap, defaultMakeCacheKey = _a.defaultMakeCacheKey; // tslint:disable-line | ||
var _a = require('optimism'), wrap = _a.wrap, defaultMakeCacheKey = _a.defaultMakeCacheKey; | ||
var hasOwn = Object.prototype.hasOwnProperty; | ||
var DepTrackingCache = /** @class */ (function () { | ||
var DepTrackingCache = (function () { | ||
function DepTrackingCache(data) { | ||
@@ -198,5 +188,8 @@ if (data === void 0) { data = Object.create(null); } | ||
var __extends = (undefined && undefined.__extends) || (function () { | ||
var extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
@@ -208,11 +201,14 @@ extendStatics(d, b); | ||
})(); | ||
var __assign = (undefined && undefined.__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; | ||
var __assign = (undefined && undefined.__assign) || function () { | ||
__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; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var WriteError = /** @class */ (function (_super) { | ||
var WriteError = (function (_super) { | ||
__extends(WriteError, _super); | ||
@@ -227,3 +223,2 @@ function WriteError() { | ||
function enhanceErrorWithDocument(error, document) { | ||
// XXX A bit hacky maybe ... | ||
var enhancedError = new WriteError("Error writing result to store for query:\n " + printer.print(document)); | ||
@@ -234,19 +229,2 @@ enhancedError.message += '\n' + error.message; | ||
} | ||
/** | ||
* Writes the result of a query to the store. | ||
* | ||
* @param result The result object returned for the query document. | ||
* | ||
* @param query The query document whose result we are writing to the store. | ||
* | ||
* @param store The {@link NormalizedCache} used by Apollo for the `data` portion of the store. | ||
* | ||
* @param variables A map from the name of a variable to its value. These variables can be | ||
* referenced by the query document. | ||
* | ||
* @param dataIdFromObject A function that returns an object identifier given a particular result | ||
* object. See the store documentation for details and an example of this function. | ||
* | ||
* @param fragmentMatcherFunction A function to use for matching fragment conditions in GraphQL documents | ||
*/ | ||
function writeQueryToStore(_a) { | ||
@@ -266,3 +244,2 @@ var query = _a.query, result = _a.result, _b = _a.store, store = _b === void 0 ? defaultNormalizedCacheFactory$1() : _b, variables = _a.variables, dataIdFromObject = _a.dataIdFromObject, fragmentMatcherFunction = _a.fragmentMatcherFunction; | ||
var dataId = _a.dataId, result = _a.result, document = _a.document, _b = _a.store, store = _b === void 0 ? defaultNormalizedCacheFactory$1() : _b, variables = _a.variables, dataIdFromObject = _a.dataIdFromObject, fragmentMatcherFunction = _a.fragmentMatcherFunction; | ||
// XXX TODO REFACTOR: this is a temporary workaround until query normalization is made to work with documents. | ||
var operationDefinition = apolloUtilities.getOperationDefinition(document); | ||
@@ -307,3 +284,2 @@ try { | ||
else { | ||
// if this is a defered field we don't need to throw / wanr | ||
var isDefered = selection.directives && | ||
@@ -313,5 +289,2 @@ selection.directives.length && | ||
if (!isDefered && context.fragmentMatcherFunction) { | ||
// XXX We'd like to throw an error, but for backwards compatibility's sake | ||
// we just print a warning for the time being. | ||
//throw new WriteError(`Missing field ${resultFieldKey} in ${JSON.stringify(result, null, 2).substring(0, 100)}`); | ||
if (!apolloUtilities.isProduction()) { | ||
@@ -324,3 +297,2 @@ console.warn("Missing field " + resultFieldKey + " in " + JSON.stringify(result, null, 2).substring(0, 100)); | ||
else { | ||
// This is not a field, so it must be a fragment, either inline or named | ||
var fragment = void 0; | ||
@@ -331,3 +303,2 @@ if (apolloUtilities.isInlineFragment(selection)) { | ||
else { | ||
// Named fragment | ||
fragment = (fragmentMap || {})[selection.name.value]; | ||
@@ -340,9 +311,4 @@ if (!fragment) { | ||
if (context.fragmentMatcherFunction && fragment.typeCondition) { | ||
// TODO we need to rewrite the fragment matchers for this to work properly and efficiently | ||
// Right now we have to pretend that we're passing in an idValue and that there's a store | ||
// on the context. | ||
var idValue = apolloUtilities.toIdValue({ id: 'self', typename: undefined }); | ||
var fakeContext = { | ||
// NOTE: fakeContext always uses ObjectCache | ||
// since this is only to ensure the return value of 'matches' | ||
store: new ObjectCache({ self: result }), | ||
@@ -369,4 +335,2 @@ cacheRedirects: {}, | ||
} | ||
// Checks if the id given is an id that was generated by Apollo | ||
// rather than by dataIdFromObject. | ||
function isGeneratedId(id) { | ||
@@ -412,10 +376,8 @@ return id[0] === '$'; | ||
var storeFieldName = apolloUtilities.storeKeyNameFromField(field, variables); | ||
// If this is a scalar value... | ||
if (!field.selectionSet || value === null) { | ||
storeValue = | ||
value != null && typeof value === 'object' | ||
? // If the scalar value is a JSON blob, we have to "escape" it so it can’t pretend to be | ||
// an id. | ||
? | ||
{ type: 'json', json: value } | ||
: // Otherwise, just store the scalar directly in the store. | ||
: | ||
value; | ||
@@ -428,7 +390,4 @@ } | ||
else { | ||
// It's an object | ||
var valueDataId = dataId + "." + storeFieldName; | ||
var generated = true; | ||
// We only prepend the '$' if the valueDataId isn't already a generated | ||
// id. | ||
if (!isGeneratedId(valueDataId)) { | ||
@@ -439,6 +398,2 @@ valueDataId = '$' + valueDataId; | ||
var semanticId = dataIdFromObject(value); | ||
// We throw an error if the first character of the id is '$. This is | ||
// because we use that character to designate an Apollo-generated id | ||
// and we use the distinction between user-desiginated and application-provided | ||
// ids when managing overwrites. | ||
if (semanticId && isGeneratedId(semanticId)) { | ||
@@ -460,9 +415,4 @@ throw new Error('IDs returned by dataIdFromObject cannot begin with the "$" character.'); | ||
} | ||
// We take the id and escape it (i.e. wrap it with an enclosing object). | ||
// This allows us to distinguish IDs from normal scalars. | ||
var typename = value.__typename; | ||
storeValue = apolloUtilities.toIdValue({ id: valueDataId, typename: typename }, generated); | ||
// check if there was a generated id at the location where we're | ||
// about to place this new id. If there was, we have to merge the | ||
// data from that id with the data we're about to write in the store. | ||
storeObject = store.get(dataId); | ||
@@ -474,7 +424,2 @@ var escapedId = storeObject && storeObject[storeFieldName]; | ||
var typenameChanged = hadTypename && hasTypename && escapedId.typename !== typename; | ||
// If there is already a real id in the store and the current id we | ||
// are dealing with is generated, we throw an error. | ||
// One exception we allow is when the typename has changed, which occurs | ||
// when schema defines a union, both with and without an ID in the same place. | ||
// checks if we "lost" the read id | ||
if (generated && !escapedId.generated && !typenameChanged) { | ||
@@ -486,3 +431,2 @@ throw new Error("Store error: the application attempted to write an object with no provided id" + | ||
} | ||
// checks if we "lost" the typename | ||
if (hadTypename && !hasTypename) { | ||
@@ -495,8 +439,3 @@ throw new Error("Store error: the application attempted to write an object with no provided typename" + | ||
if (escapedId.generated) { | ||
// We should only merge if it's an object of the same type, | ||
// otherwise we should delete the generated object | ||
if (typenameChanged) { | ||
// Only delete the generated object when the old object was | ||
// inlined, and the new object is not. This is indicated by | ||
// the old id being generated, and the new id being real. | ||
if (!generated) { | ||
@@ -546,11 +485,14 @@ store.delete(escapedId.id); | ||
var __assign$1 = (undefined && undefined.__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; | ||
var __assign$1 = (undefined && undefined.__assign) || function () { | ||
__assign$1 = 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; | ||
}; | ||
return __assign$1.apply(this, arguments); | ||
}; | ||
var StoreReader = /** @class */ (function () { | ||
var StoreReader = (function () { | ||
function StoreReader() { | ||
@@ -564,5 +506,2 @@ var _this = this; | ||
var query = _a.query, rootValue = _a.rootValue, contextValue = _a.contextValue, variableValues = _a.variableValues; | ||
// The result of executeStoreQuery can be safely cached only if the | ||
// underlying store is capable of tracking dependencies and invalidating | ||
// the cache when relevant data have changed. | ||
if (contextValue.store instanceof DepTrackingCache) { | ||
@@ -579,7 +518,3 @@ return defaultMakeCacheKey(query, contextValue.store, JSON.stringify(variableValues)); | ||
if (execContext.contextValue.store instanceof DepTrackingCache) { | ||
return defaultMakeCacheKey(selectionSet, execContext.contextValue.store, JSON.stringify(execContext.variableValues), | ||
// Unlike executeStoreQuery, executeSelectionSet can be called | ||
// recursively on nested objects, so it's important to include the | ||
// ID of the current parent object in the cache key. | ||
rootValue.id); | ||
return defaultMakeCacheKey(selectionSet, execContext.contextValue.store, JSON.stringify(execContext.variableValues), rootValue.id); | ||
} | ||
@@ -589,17 +524,2 @@ } | ||
} | ||
/** | ||
* Resolves the result of a query solely from the store (i.e. never hits the server). | ||
* | ||
* @param {Store} store The {@link NormalizedCache} used by Apollo for the `data` portion of the | ||
* store. | ||
* | ||
* @param {DocumentNode} query The query document to resolve from the data available in the store. | ||
* | ||
* @param {Object} [variables] A map from the name of a variable to its value. These variables can | ||
* be referenced by the query document. | ||
* | ||
* @param {any} previousResult The previous result returned by this function for the same query. | ||
* If nothing in the store changed since that previous result then values from the previous result | ||
* will be returned to preserve referential equality. | ||
*/ | ||
StoreReader.prototype.readQueryFromStore = function (options) { | ||
@@ -609,17 +529,7 @@ var optsPatch = { returnPartialData: false }; | ||
}; | ||
/** | ||
* Given a store and a query, return as much of the result as possible and | ||
* identify if any data was missing from the store. | ||
* @param {DocumentNode} query A parsed GraphQL query document | ||
* @param {Store} store The Apollo Client store object | ||
* @param {any} previousResult The previous result returned by this function for the same query | ||
* @return {result: Object, complete: [boolean]} | ||
*/ | ||
StoreReader.prototype.diffQueryAgainstStore = function (_a) { | ||
var store = _a.store, query = _a.query, variables = _a.variables, previousResult = _a.previousResult, _b = _a.returnPartialData, returnPartialData = _b === void 0 ? true : _b, _c = _a.rootId, rootId = _c === void 0 ? 'ROOT_QUERY' : _c, fragmentMatcherFunction = _a.fragmentMatcherFunction, config = _a.config; | ||
// Throw the right validation error by trying to find a query in the document | ||
var queryDefinition = apolloUtilities.getQueryDefinition(query); | ||
variables = apolloUtilities.assign({}, apolloUtilities.getDefaultValues(queryDefinition), variables); | ||
var context = { | ||
// Global settings | ||
store: store, | ||
@@ -659,26 +569,4 @@ dataIdFromObject: (config && config.dataIdFromObject) || null, | ||
}; | ||
/** | ||
* Based on graphql function from graphql-js: | ||
* | ||
* graphql( | ||
* schema: GraphQLSchema, | ||
* requestString: string, | ||
* rootValue?: ?any, | ||
* contextValue?: ?any, | ||
* variableValues?: ?{[key: string]: any}, | ||
* operationName?: ?string | ||
* ): Promise<GraphQLResult> | ||
* | ||
* The default export as of graphql-anywhere is sync as of 4.0, | ||
* but below is an exported alternative that is async. | ||
* In the 5.0 version, this will be the only export again | ||
* and it will be async | ||
* | ||
*/ | ||
StoreReader.prototype.executeStoreQuery = function (_a) { | ||
var query = _a.query, rootValue = _a.rootValue, contextValue = _a.contextValue, variableValues = _a.variableValues, | ||
// Default matcher always matches all fragments | ||
_b = _a.fragmentMatcher, | ||
// Default matcher always matches all fragments | ||
fragmentMatcher = _b === void 0 ? function () { return true; } : _b; | ||
var query = _a.query, rootValue = _a.rootValue, contextValue = _a.contextValue, variableValues = _a.variableValues, _b = _a.fragmentMatcher, fragmentMatcher = _b === void 0 ? function () { return true; } : _b; | ||
var mainDefinition = apolloUtilities.getMainDefinition(query); | ||
@@ -717,3 +605,2 @@ var fragments = apolloUtilities.getFragmentDefinitions(query); | ||
if (!apolloUtilities.shouldInclude(selection, variables)) { | ||
// Skip this entirely | ||
return; | ||
@@ -735,3 +622,2 @@ } | ||
else { | ||
// This is a named fragment | ||
fragment = fragmentMap[selection.name.value]; | ||
@@ -770,10 +656,6 @@ if (!fragment) { | ||
var readStoreResult = readStoreResolver(fieldName, rootValue, args, contextValue, info); | ||
// Handle all scalar types here | ||
if (!field.selectionSet) { | ||
return readStoreResult; | ||
} | ||
// From here down, the field has a selection set, which means it's trying to | ||
// query a GraphQLObjectType | ||
if (readStoreResult.result == null) { | ||
// Basically any field in a GraphQL response can be null, or missing | ||
return readStoreResult; | ||
@@ -799,3 +681,2 @@ } | ||
} | ||
// Returned value is an object, and the query has a sub-selection. Recurse. | ||
return handleMissing(this.executeSelectionSet({ | ||
@@ -818,11 +699,8 @@ selectionSet: field.selectionSet, | ||
result = result.map(function (item) { | ||
// null value in array | ||
if (item === null) { | ||
return null; | ||
} | ||
// This is a nested array, recurse | ||
if (Array.isArray(item)) { | ||
return handleMissing(_this.executeSubSelectedArray(field, item, execContext)); | ||
} | ||
// This is an object, run the selection set on it | ||
return handleMissing(_this.executeSelectionSet({ | ||
@@ -850,6 +728,2 @@ selectionSet: field.selectionSet, | ||
if (args || directives) { | ||
// We happen to know here that getStoreKeyName returns its first | ||
// argument unmodified if there are no args or directives, so we can | ||
// avoid calling the function at all in that case, as a small but | ||
// important optimization to this frequently executed code. | ||
storeKeyName = apolloUtilities.getStoreKeyName(storeKeyName, args, directives); | ||
@@ -864,6 +738,4 @@ } | ||
var typename = obj.__typename || 'Query'; | ||
// Look for the type in the custom resolver map | ||
var type = context.cacheRedirects[typename]; | ||
if (type) { | ||
// Look for the field in the custom resolver map | ||
var resolver = type[fieldName]; | ||
@@ -903,7 +775,3 @@ if (resolver) { | ||
if (source !== null && typeof source === 'object' && | ||
// Due to result caching, it's possible that source and target will | ||
// be === at some point in the tree, which means we can stop early. | ||
source !== target) { | ||
// In case the target has been frozen, make an extensible copy so that | ||
// we can merge properties into the copy. | ||
if (Object.isExtensible && !Object.isExtensible(target)) { | ||
@@ -925,11 +793,14 @@ target = __assign$1({}, target); | ||
var __assign$2 = (undefined && undefined.__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; | ||
var __assign$2 = (undefined && undefined.__assign) || function () { | ||
__assign$2 = 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; | ||
}; | ||
return __assign$2.apply(this, arguments); | ||
}; | ||
var RecordingCache = /** @class */ (function () { | ||
var RecordingCache = (function () { | ||
function RecordingCache(data) { | ||
@@ -951,3 +822,2 @@ if (data === void 0) { data = {}; } | ||
if (this.recordedData.hasOwnProperty(dataId)) { | ||
// recording always takes precedence: | ||
return this.recordedData[dataId]; | ||
@@ -982,5 +852,8 @@ } | ||
var __extends$1 = (undefined && undefined.__extends) || (function () { | ||
var extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
@@ -992,9 +865,12 @@ extendStatics(d, b); | ||
})(); | ||
var __assign$3 = (undefined && undefined.__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; | ||
var __assign$3 = (undefined && undefined.__assign) || function () { | ||
__assign$3 = 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; | ||
}; | ||
return __assign$3.apply(this, arguments); | ||
}; | ||
@@ -1017,3 +893,3 @@ var defaultConfig = { | ||
} | ||
var InMemoryCache = /** @class */ (function (_super) { | ||
var InMemoryCache = (function (_super) { | ||
__extends$1(InMemoryCache, _super); | ||
@@ -1026,7 +902,4 @@ function InMemoryCache(config) { | ||
_this.typenameDocumentCache = new WeakMap(); | ||
// Set this while in a transaction to prevent broadcasts... | ||
// don't forget to turn it back on! | ||
_this.silenceBroadcast = false; | ||
_this.config = __assign$3({}, defaultConfig, config); | ||
// backwards compat | ||
if (_this.config.customResolvers) { | ||
@@ -1050,9 +923,5 @@ console.warn('customResolvers have been renamed to cacheRedirects. Please update your config as we will be deprecating customResolvers in the next major version.'); | ||
if (c.optimistic && cache.optimistic.length > 0) { | ||
// If we're reading optimistic data, it doesn't matter if this.data | ||
// is a DepTrackingCache, since it will be ignored. | ||
return; | ||
} | ||
if (cache.data instanceof DepTrackingCache) { | ||
// Return a cache key (thus enabling caching) only if we're currently | ||
// using a data store that can track cache dependencies. | ||
return defaultMakeCacheKey(c.query, JSON.stringify(c.variables)); | ||
@@ -1137,6 +1006,4 @@ } | ||
var _this = this; | ||
// Throw away optimistic changes of that particular mutation | ||
var toPerform = this.optimistic.filter(function (item) { return item.id !== id; }); | ||
this.optimistic = []; | ||
// Re-run all of our optimistic data actions on top of one another. | ||
toPerform.forEach(function (change) { | ||
@@ -1148,3 +1015,2 @@ _this.recordOptimisticTransaction(change.transaction, change.id); | ||
InMemoryCache.prototype.performTransaction = function (transaction) { | ||
// TODO: does this need to be different, or is this okay for an in-memory cache? | ||
var alreadySilenced = this.silenceBroadcast; | ||
@@ -1154,4 +1020,2 @@ this.silenceBroadcast = true; | ||
if (!alreadySilenced) { | ||
// Don't un-silence since this is a nested transaction | ||
// (for example, a transaction inside an optimistic record) | ||
this.silenceBroadcast = false; | ||
@@ -1165,4 +1029,2 @@ } | ||
var patch = record(this.extract(true), function (recordingCache) { | ||
// swapping data instance on 'this' is currently necessary | ||
// because of the current architecture | ||
var dataCache = _this.data; | ||
@@ -1229,4 +1091,2 @@ _this.data = recordingCache; | ||
}; | ||
// This method is wrapped in the constructor so that it will be called only | ||
// if the data that would be broadcast has changed. | ||
InMemoryCache.prototype.maybeBroadcastWatch = function (c) { | ||
@@ -1236,4 +1096,2 @@ c.callback(this.diff({ | ||
variables: c.variables, | ||
// TODO: previousResult isn't in the types, so this will only work | ||
// with ObservableQuery which is in a different package. | ||
previousResult: c.previousResult && c.previousResult(), | ||
@@ -1240,0 +1098,0 @@ optimistic: c.optimistic, |
@@ -14,1 +14,2 @@ import { NormalizedCache, NormalizedCacheObject, StoreObject } from './types'; | ||
export declare function defaultNormalizedCacheFactory(seed?: NormalizedCacheObject): NormalizedCache; | ||
//# sourceMappingURL=depTrackingCache.d.ts.map |
import { wrap } from './optimism'; | ||
var hasOwn = Object.prototype.hasOwnProperty; | ||
var DepTrackingCache = /** @class */ (function () { | ||
var DepTrackingCache = (function () { | ||
function DepTrackingCache(data) { | ||
@@ -5,0 +5,0 @@ if (data === void 0) { data = Object.create(null); } |
import { IdValue } from 'apollo-utilities'; | ||
import { ReadStoreContext, FragmentMatcherInterface, IntrospectionResultData } from './types'; | ||
/** | ||
* This fragment matcher is very basic and unable to match union or interface type conditions | ||
*/ | ||
export declare class HeuristicFragmentMatcher implements FragmentMatcherInterface { | ||
@@ -21,1 +18,2 @@ constructor(); | ||
} | ||
//# sourceMappingURL=fragmentMatcher.d.ts.map |
import { isTest, warnOnceInDevelopment } from 'apollo-utilities'; | ||
var haveWarned = false; | ||
/** | ||
* This fragment matcher is very basic and unable to match union or interface type conditions | ||
*/ | ||
var HeuristicFragmentMatcher = /** @class */ (function () { | ||
var HeuristicFragmentMatcher = (function () { | ||
function HeuristicFragmentMatcher() { | ||
// do nothing | ||
} | ||
@@ -14,3 +10,3 @@ HeuristicFragmentMatcher.prototype.ensureReady = function () { | ||
HeuristicFragmentMatcher.prototype.canBypassInit = function () { | ||
return true; // we don't need to initialize this fragment matcher. | ||
return true; | ||
}; | ||
@@ -31,5 +27,3 @@ HeuristicFragmentMatcher.prototype.match = function (idValue, typeCondition, context) { | ||
"and will be removed in future versions of Apollo client. You should fix this and set addTypename to true now."); | ||
/* istanbul ignore if */ | ||
if (!isTest()) { | ||
// When running tests, we want to print the warning every time | ||
haveWarned = true; | ||
@@ -43,10 +37,7 @@ } | ||
} | ||
// XXX here we reach an issue - we don't know if this fragment should match or not. It's either: | ||
// 1. A fragment on a non-matching concrete type or interface or union | ||
// 2. A fragment on a matching interface or union | ||
// If it's 1, we don't want to return anything, if it's 2 we want to match. We can't tell the | ||
// difference, so we warn the user, but still try to match it (backcompat). | ||
warnOnceInDevelopment("You are using the simple (heuristic) fragment matcher, but your queries contain union or interface types.\n Apollo Client will not be able to able to accurately map fragments." + | ||
"To make this error go away, use the IntrospectionFragmentMatcher as described in the docs: " + | ||
"https://www.apollographql.com/docs/react/recipes/fragment-matching.html", 'error'); | ||
warnOnceInDevelopment('You are using the simple (heuristic) fragment matcher, but your ' + | ||
'queries contain union or interface types. Apollo Client will not be ' + | ||
'able to accurately map fragments. To make this error go away, use ' + | ||
'the `IntrospectionFragmentMatcher` as described in the docs: ' + | ||
'https://www.apollographql.com/docs/react/recipes/fragment-matching.html', 'error'); | ||
return 'heuristic'; | ||
@@ -57,3 +48,3 @@ }; | ||
export { HeuristicFragmentMatcher }; | ||
var IntrospectionFragmentMatcher = /** @class */ (function () { | ||
var IntrospectionFragmentMatcher = (function () { | ||
function IntrospectionFragmentMatcher(options) { | ||
@@ -71,3 +62,2 @@ if (options && options.introspectionQueryResultData) { | ||
if (!this.isReady) { | ||
// this should basically never happen in proper use. | ||
throw new Error('FragmentMatcher.match() was called before FragmentMatcher.init()'); | ||
@@ -74,0 +64,0 @@ } |
declare const query: any; | ||
export default query; | ||
//# sourceMappingURL=fragmentMatcherIntrospectionQuery.d.ts.map |
@@ -8,1 +8,2 @@ export { InMemoryCache, defaultDataIdFromObject } from './inMemoryCache'; | ||
export * from './types'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -34,1 +34,2 @@ import { DocumentNode } from 'graphql'; | ||
} | ||
//# sourceMappingURL=inMemoryCache.d.ts.map |
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
} | ||
return function (d, b) { | ||
@@ -11,9 +14,12 @@ extendStatics(d, b); | ||
})(); | ||
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; | ||
var __assign = (this && this.__assign) || function () { | ||
__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; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
@@ -44,3 +50,3 @@ import { ApolloCache } from 'apollo-cache'; | ||
} | ||
var InMemoryCache = /** @class */ (function (_super) { | ||
var InMemoryCache = (function (_super) { | ||
__extends(InMemoryCache, _super); | ||
@@ -53,7 +59,4 @@ function InMemoryCache(config) { | ||
_this.typenameDocumentCache = new WeakMap(); | ||
// Set this while in a transaction to prevent broadcasts... | ||
// don't forget to turn it back on! | ||
_this.silenceBroadcast = false; | ||
_this.config = __assign({}, defaultConfig, config); | ||
// backwards compat | ||
if (_this.config.customResolvers) { | ||
@@ -77,9 +80,5 @@ console.warn('customResolvers have been renamed to cacheRedirects. Please update your config as we will be deprecating customResolvers in the next major version.'); | ||
if (c.optimistic && cache.optimistic.length > 0) { | ||
// If we're reading optimistic data, it doesn't matter if this.data | ||
// is a DepTrackingCache, since it will be ignored. | ||
return; | ||
} | ||
if (cache.data instanceof DepTrackingCache) { | ||
// Return a cache key (thus enabling caching) only if we're currently | ||
// using a data store that can track cache dependencies. | ||
return defaultMakeCacheKey(c.query, JSON.stringify(c.variables)); | ||
@@ -164,6 +163,4 @@ } | ||
var _this = this; | ||
// Throw away optimistic changes of that particular mutation | ||
var toPerform = this.optimistic.filter(function (item) { return item.id !== id; }); | ||
this.optimistic = []; | ||
// Re-run all of our optimistic data actions on top of one another. | ||
toPerform.forEach(function (change) { | ||
@@ -175,3 +172,2 @@ _this.recordOptimisticTransaction(change.transaction, change.id); | ||
InMemoryCache.prototype.performTransaction = function (transaction) { | ||
// TODO: does this need to be different, or is this okay for an in-memory cache? | ||
var alreadySilenced = this.silenceBroadcast; | ||
@@ -181,4 +177,2 @@ this.silenceBroadcast = true; | ||
if (!alreadySilenced) { | ||
// Don't un-silence since this is a nested transaction | ||
// (for example, a transaction inside an optimistic record) | ||
this.silenceBroadcast = false; | ||
@@ -192,4 +186,2 @@ } | ||
var patch = record(this.extract(true), function (recordingCache) { | ||
// swapping data instance on 'this' is currently necessary | ||
// because of the current architecture | ||
var dataCache = _this.data; | ||
@@ -256,4 +248,2 @@ _this.data = recordingCache; | ||
}; | ||
// This method is wrapped in the constructor so that it will be called only | ||
// if the data that would be broadcast has changed. | ||
InMemoryCache.prototype.maybeBroadcastWatch = function (c) { | ||
@@ -263,4 +253,2 @@ c.callback(this.diff({ | ||
variables: c.variables, | ||
// TODO: previousResult isn't in the types, so this will only work | ||
// with ObservableQuery which is in a different package. | ||
previousResult: c.previousResult && c.previousResult(), | ||
@@ -267,0 +255,0 @@ optimistic: c.optimistic, |
import { NormalizedCache, NormalizedCacheObject, StoreObject } from './types'; | ||
/** | ||
* A Map-based implementation of the NormalizedCache. | ||
* Note that you need a polyfill for Object.entries for this to work. | ||
*/ | ||
export declare class MapCache implements NormalizedCache { | ||
@@ -17,1 +13,2 @@ private cache; | ||
export declare function mapNormalizedCacheFactory(seed?: NormalizedCacheObject): NormalizedCache; | ||
//# sourceMappingURL=mapCache.d.ts.map |
@@ -1,6 +0,2 @@ | ||
/** | ||
* A Map-based implementation of the NormalizedCache. | ||
* Note that you need a polyfill for Object.entries for this to work. | ||
*/ | ||
var MapCache = /** @class */ (function () { | ||
var MapCache = (function () { | ||
function MapCache(data) { | ||
@@ -7,0 +3,0 @@ if (data === void 0) { data = {}; } |
@@ -13,1 +13,2 @@ import { NormalizedCache, NormalizedCacheObject, StoreObject } from './types'; | ||
export declare function defaultNormalizedCacheFactory(seed?: NormalizedCacheObject): NormalizedCache; | ||
//# sourceMappingURL=objectCache.d.ts.map |
@@ -1,2 +0,2 @@ | ||
var ObjectCache = /** @class */ (function () { | ||
var ObjectCache = (function () { | ||
function ObjectCache(data) { | ||
@@ -3,0 +3,0 @@ if (data === void 0) { data = Object.create(null); } |
@@ -11,1 +11,2 @@ export declare type OptimisticWrapperFunction<T = (...args: any[]) => any> = T & { | ||
export { wrap, defaultMakeCacheKey }; | ||
//# sourceMappingURL=optimism.d.ts.map |
@@ -1,3 +0,3 @@ | ||
var _a = require('optimism'), wrap = _a.wrap, defaultMakeCacheKey = _a.defaultMakeCacheKey; // tslint:disable-line | ||
var _a = require('optimism'), wrap = _a.wrap, defaultMakeCacheKey = _a.defaultMakeCacheKey; | ||
export { wrap, defaultMakeCacheKey }; | ||
//# sourceMappingURL=optimism.js.map |
@@ -20,45 +20,4 @@ import { IdValue } from 'apollo-utilities'; | ||
constructor(); | ||
/** | ||
* Resolves the result of a query solely from the store (i.e. never hits the server). | ||
* | ||
* @param {Store} store The {@link NormalizedCache} used by Apollo for the `data` portion of the | ||
* store. | ||
* | ||
* @param {DocumentNode} query The query document to resolve from the data available in the store. | ||
* | ||
* @param {Object} [variables] A map from the name of a variable to its value. These variables can | ||
* be referenced by the query document. | ||
* | ||
* @param {any} previousResult The previous result returned by this function for the same query. | ||
* If nothing in the store changed since that previous result then values from the previous result | ||
* will be returned to preserve referential equality. | ||
*/ | ||
readQueryFromStore<QueryType>(options: ReadQueryOptions): QueryType; | ||
/** | ||
* Given a store and a query, return as much of the result as possible and | ||
* identify if any data was missing from the store. | ||
* @param {DocumentNode} query A parsed GraphQL query document | ||
* @param {Store} store The Apollo Client store object | ||
* @param {any} previousResult The previous result returned by this function for the same query | ||
* @return {result: Object, complete: [boolean]} | ||
*/ | ||
diffQueryAgainstStore<T>({ store, query, variables, previousResult, returnPartialData, rootId, fragmentMatcherFunction, config, }: DiffQueryAgainstStoreOptions): Cache.DiffResult<T>; | ||
/** | ||
* Based on graphql function from graphql-js: | ||
* | ||
* graphql( | ||
* schema: GraphQLSchema, | ||
* requestString: string, | ||
* rootValue?: ?any, | ||
* contextValue?: ?any, | ||
* variableValues?: ?{[key: string]: any}, | ||
* operationName?: ?string | ||
* ): Promise<GraphQLResult> | ||
* | ||
* The default export as of graphql-anywhere is sync as of 4.0, | ||
* but below is an exported alternative that is async. | ||
* In the 5.0 version, this will be the only export again | ||
* and it will be async | ||
* | ||
*/ | ||
private executeStoreQuery; | ||
@@ -70,1 +29,2 @@ private executeSelectionSet; | ||
export declare function assertIdValue(idValue: IdValue): void; | ||
//# sourceMappingURL=readFromStore.d.ts.map |
@@ -1,8 +0,11 @@ | ||
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; | ||
var __assign = (this && this.__assign) || function () { | ||
__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; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
@@ -12,3 +15,3 @@ import { assign, getDefaultValues, getQueryDefinition, isEqual, argumentsObjectFromField, createFragmentMap, getDirectiveInfoFromField, getFragmentDefinitions, getMainDefinition, getStoreKeyName, isField, isIdValue, isInlineFragment, isJsonValue, resultKeyNameFromField, shouldInclude, toIdValue, } from 'apollo-utilities'; | ||
import { DepTrackingCache } from './depTrackingCache'; | ||
var StoreReader = /** @class */ (function () { | ||
var StoreReader = (function () { | ||
function StoreReader() { | ||
@@ -22,5 +25,2 @@ var _this = this; | ||
var query = _a.query, rootValue = _a.rootValue, contextValue = _a.contextValue, variableValues = _a.variableValues; | ||
// The result of executeStoreQuery can be safely cached only if the | ||
// underlying store is capable of tracking dependencies and invalidating | ||
// the cache when relevant data have changed. | ||
if (contextValue.store instanceof DepTrackingCache) { | ||
@@ -37,7 +37,3 @@ return defaultMakeCacheKey(query, contextValue.store, JSON.stringify(variableValues)); | ||
if (execContext.contextValue.store instanceof DepTrackingCache) { | ||
return defaultMakeCacheKey(selectionSet, execContext.contextValue.store, JSON.stringify(execContext.variableValues), | ||
// Unlike executeStoreQuery, executeSelectionSet can be called | ||
// recursively on nested objects, so it's important to include the | ||
// ID of the current parent object in the cache key. | ||
rootValue.id); | ||
return defaultMakeCacheKey(selectionSet, execContext.contextValue.store, JSON.stringify(execContext.variableValues), rootValue.id); | ||
} | ||
@@ -47,17 +43,2 @@ } | ||
} | ||
/** | ||
* Resolves the result of a query solely from the store (i.e. never hits the server). | ||
* | ||
* @param {Store} store The {@link NormalizedCache} used by Apollo for the `data` portion of the | ||
* store. | ||
* | ||
* @param {DocumentNode} query The query document to resolve from the data available in the store. | ||
* | ||
* @param {Object} [variables] A map from the name of a variable to its value. These variables can | ||
* be referenced by the query document. | ||
* | ||
* @param {any} previousResult The previous result returned by this function for the same query. | ||
* If nothing in the store changed since that previous result then values from the previous result | ||
* will be returned to preserve referential equality. | ||
*/ | ||
StoreReader.prototype.readQueryFromStore = function (options) { | ||
@@ -67,17 +48,7 @@ var optsPatch = { returnPartialData: false }; | ||
}; | ||
/** | ||
* Given a store and a query, return as much of the result as possible and | ||
* identify if any data was missing from the store. | ||
* @param {DocumentNode} query A parsed GraphQL query document | ||
* @param {Store} store The Apollo Client store object | ||
* @param {any} previousResult The previous result returned by this function for the same query | ||
* @return {result: Object, complete: [boolean]} | ||
*/ | ||
StoreReader.prototype.diffQueryAgainstStore = function (_a) { | ||
var store = _a.store, query = _a.query, variables = _a.variables, previousResult = _a.previousResult, _b = _a.returnPartialData, returnPartialData = _b === void 0 ? true : _b, _c = _a.rootId, rootId = _c === void 0 ? 'ROOT_QUERY' : _c, fragmentMatcherFunction = _a.fragmentMatcherFunction, config = _a.config; | ||
// Throw the right validation error by trying to find a query in the document | ||
var queryDefinition = getQueryDefinition(query); | ||
variables = assign({}, getDefaultValues(queryDefinition), variables); | ||
var context = { | ||
// Global settings | ||
store: store, | ||
@@ -117,26 +88,4 @@ dataIdFromObject: (config && config.dataIdFromObject) || null, | ||
}; | ||
/** | ||
* Based on graphql function from graphql-js: | ||
* | ||
* graphql( | ||
* schema: GraphQLSchema, | ||
* requestString: string, | ||
* rootValue?: ?any, | ||
* contextValue?: ?any, | ||
* variableValues?: ?{[key: string]: any}, | ||
* operationName?: ?string | ||
* ): Promise<GraphQLResult> | ||
* | ||
* The default export as of graphql-anywhere is sync as of 4.0, | ||
* but below is an exported alternative that is async. | ||
* In the 5.0 version, this will be the only export again | ||
* and it will be async | ||
* | ||
*/ | ||
StoreReader.prototype.executeStoreQuery = function (_a) { | ||
var query = _a.query, rootValue = _a.rootValue, contextValue = _a.contextValue, variableValues = _a.variableValues, | ||
// Default matcher always matches all fragments | ||
_b = _a.fragmentMatcher, | ||
// Default matcher always matches all fragments | ||
fragmentMatcher = _b === void 0 ? function () { return true; } : _b; | ||
var query = _a.query, rootValue = _a.rootValue, contextValue = _a.contextValue, variableValues = _a.variableValues, _b = _a.fragmentMatcher, fragmentMatcher = _b === void 0 ? function () { return true; } : _b; | ||
var mainDefinition = getMainDefinition(query); | ||
@@ -175,3 +124,2 @@ var fragments = getFragmentDefinitions(query); | ||
if (!shouldInclude(selection, variables)) { | ||
// Skip this entirely | ||
return; | ||
@@ -193,3 +141,2 @@ } | ||
else { | ||
// This is a named fragment | ||
fragment = fragmentMap[selection.name.value]; | ||
@@ -228,10 +175,6 @@ if (!fragment) { | ||
var readStoreResult = readStoreResolver(fieldName, rootValue, args, contextValue, info); | ||
// Handle all scalar types here | ||
if (!field.selectionSet) { | ||
return readStoreResult; | ||
} | ||
// From here down, the field has a selection set, which means it's trying to | ||
// query a GraphQLObjectType | ||
if (readStoreResult.result == null) { | ||
// Basically any field in a GraphQL response can be null, or missing | ||
return readStoreResult; | ||
@@ -257,3 +200,2 @@ } | ||
} | ||
// Returned value is an object, and the query has a sub-selection. Recurse. | ||
return handleMissing(this.executeSelectionSet({ | ||
@@ -276,11 +218,8 @@ selectionSet: field.selectionSet, | ||
result = result.map(function (item) { | ||
// null value in array | ||
if (item === null) { | ||
return null; | ||
} | ||
// This is a nested array, recurse | ||
if (Array.isArray(item)) { | ||
return handleMissing(_this.executeSubSelectedArray(field, item, execContext)); | ||
} | ||
// This is an object, run the selection set on it | ||
return handleMissing(_this.executeSelectionSet({ | ||
@@ -309,6 +248,2 @@ selectionSet: field.selectionSet, | ||
if (args || directives) { | ||
// We happen to know here that getStoreKeyName returns its first | ||
// argument unmodified if there are no args or directives, so we can | ||
// avoid calling the function at all in that case, as a small but | ||
// important optimization to this frequently executed code. | ||
storeKeyName = getStoreKeyName(storeKeyName, args, directives); | ||
@@ -323,6 +258,4 @@ } | ||
var typename = obj.__typename || 'Query'; | ||
// Look for the type in the custom resolver map | ||
var type = context.cacheRedirects[typename]; | ||
if (type) { | ||
// Look for the field in the custom resolver map | ||
var resolver = type[fieldName]; | ||
@@ -362,7 +295,3 @@ if (resolver) { | ||
if (source !== null && typeof source === 'object' && | ||
// Due to result caching, it's possible that source and target will | ||
// be === at some point in the tree, which means we can stop early. | ||
source !== target) { | ||
// In case the target has been frozen, make an extensible copy so that | ||
// we can merge properties into the copy. | ||
if (Object.isExtensible && !Object.isExtensible(target)) { | ||
@@ -369,0 +298,0 @@ target = __assign({}, target); |
@@ -15,1 +15,2 @@ import { NormalizedCache, NormalizedCacheObject, StoreObject } from './types'; | ||
export declare function record(startingState: NormalizedCacheObject, transaction: (recordingCache: RecordingCache) => void): NormalizedCacheObject; | ||
//# sourceMappingURL=recordingCache.d.ts.map |
@@ -1,10 +0,13 @@ | ||
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; | ||
var __assign = (this && this.__assign) || function () { | ||
__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; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var RecordingCache = /** @class */ (function () { | ||
var RecordingCache = (function () { | ||
function RecordingCache(data) { | ||
@@ -26,3 +29,2 @@ if (data === void 0) { data = {}; } | ||
if (this.recordedData.hasOwnProperty(dataId)) { | ||
// recording always takes precedence: | ||
return this.recordedData[dataId]; | ||
@@ -29,0 +31,0 @@ } |
@@ -10,6 +10,2 @@ import { DocumentNode } from 'graphql'; | ||
export declare type IdGetter = (value: IdGetterObj) => string | null | undefined; | ||
/** | ||
* This is an interface used to access, set and remove | ||
* StoreObjects from the cache | ||
*/ | ||
export interface NormalizedCache { | ||
@@ -20,15 +16,5 @@ get(dataId: string): StoreObject; | ||
clear(): void; | ||
/** | ||
* returns an Object with key-value pairs matching the contents of the store | ||
*/ | ||
toObject(): NormalizedCacheObject; | ||
/** | ||
* replace the state of the store | ||
*/ | ||
replace(newData: NormalizedCacheObject): void; | ||
} | ||
/** | ||
* This is a normalized representation of the Apollo query result cache. It consists of | ||
* a flattened representation of query result trees. | ||
*/ | ||
export interface NormalizedCacheObject { | ||
@@ -96,1 +82,2 @@ [dataId: string]: StoreObject; | ||
export declare type CustomResolverMap = CacheResolverMap; | ||
//# sourceMappingURL=types.d.ts.map |
@@ -9,19 +9,2 @@ import { SelectionSetNode, FieldNode, DocumentNode } from 'graphql'; | ||
export declare function enhanceErrorWithDocument(error: Error, document: DocumentNode): WriteError; | ||
/** | ||
* Writes the result of a query to the store. | ||
* | ||
* @param result The result object returned for the query document. | ||
* | ||
* @param query The query document whose result we are writing to the store. | ||
* | ||
* @param store The {@link NormalizedCache} used by Apollo for the `data` portion of the store. | ||
* | ||
* @param variables A map from the name of a variable to its value. These variables can be | ||
* referenced by the query document. | ||
* | ||
* @param dataIdFromObject A function that returns an object identifier given a particular result | ||
* object. See the store documentation for details and an example of this function. | ||
* | ||
* @param fragmentMatcherFunction A function to use for matching fragment conditions in GraphQL documents | ||
*/ | ||
export declare function writeQueryToStore({ query, result, store, variables, dataIdFromObject, fragmentMatcherFunction, }: { | ||
@@ -60,1 +43,2 @@ query: DocumentNode; | ||
}): NormalizedCache; | ||
//# sourceMappingURL=writeToStore.d.ts.map |
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
} | ||
return function (d, b) { | ||
@@ -11,9 +14,12 @@ extendStatics(d, b); | ||
})(); | ||
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; | ||
var __assign = (this && this.__assign) || function () { | ||
__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; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
@@ -24,3 +30,3 @@ import { print } from 'graphql/language/printer'; | ||
import { defaultNormalizedCacheFactory } from './depTrackingCache'; | ||
var WriteError = /** @class */ (function (_super) { | ||
var WriteError = (function (_super) { | ||
__extends(WriteError, _super); | ||
@@ -36,3 +42,2 @@ function WriteError() { | ||
export function enhanceErrorWithDocument(error, document) { | ||
// XXX A bit hacky maybe ... | ||
var enhancedError = new WriteError("Error writing result to store for query:\n " + print(document)); | ||
@@ -43,19 +48,2 @@ enhancedError.message += '\n' + error.message; | ||
} | ||
/** | ||
* Writes the result of a query to the store. | ||
* | ||
* @param result The result object returned for the query document. | ||
* | ||
* @param query The query document whose result we are writing to the store. | ||
* | ||
* @param store The {@link NormalizedCache} used by Apollo for the `data` portion of the store. | ||
* | ||
* @param variables A map from the name of a variable to its value. These variables can be | ||
* referenced by the query document. | ||
* | ||
* @param dataIdFromObject A function that returns an object identifier given a particular result | ||
* object. See the store documentation for details and an example of this function. | ||
* | ||
* @param fragmentMatcherFunction A function to use for matching fragment conditions in GraphQL documents | ||
*/ | ||
export function writeQueryToStore(_a) { | ||
@@ -75,3 +63,2 @@ var query = _a.query, result = _a.result, _b = _a.store, store = _b === void 0 ? defaultNormalizedCacheFactory() : _b, variables = _a.variables, dataIdFromObject = _a.dataIdFromObject, fragmentMatcherFunction = _a.fragmentMatcherFunction; | ||
var dataId = _a.dataId, result = _a.result, document = _a.document, _b = _a.store, store = _b === void 0 ? defaultNormalizedCacheFactory() : _b, variables = _a.variables, dataIdFromObject = _a.dataIdFromObject, fragmentMatcherFunction = _a.fragmentMatcherFunction; | ||
// XXX TODO REFACTOR: this is a temporary workaround until query normalization is made to work with documents. | ||
var operationDefinition = getOperationDefinition(document); | ||
@@ -116,3 +103,2 @@ try { | ||
else { | ||
// if this is a defered field we don't need to throw / wanr | ||
var isDefered = selection.directives && | ||
@@ -122,5 +108,2 @@ selection.directives.length && | ||
if (!isDefered && context.fragmentMatcherFunction) { | ||
// XXX We'd like to throw an error, but for backwards compatibility's sake | ||
// we just print a warning for the time being. | ||
//throw new WriteError(`Missing field ${resultFieldKey} in ${JSON.stringify(result, null, 2).substring(0, 100)}`); | ||
if (!isProduction()) { | ||
@@ -133,3 +116,2 @@ console.warn("Missing field " + resultFieldKey + " in " + JSON.stringify(result, null, 2).substring(0, 100)); | ||
else { | ||
// This is not a field, so it must be a fragment, either inline or named | ||
var fragment = void 0; | ||
@@ -140,3 +122,2 @@ if (isInlineFragment(selection)) { | ||
else { | ||
// Named fragment | ||
fragment = (fragmentMap || {})[selection.name.value]; | ||
@@ -149,9 +130,4 @@ if (!fragment) { | ||
if (context.fragmentMatcherFunction && fragment.typeCondition) { | ||
// TODO we need to rewrite the fragment matchers for this to work properly and efficiently | ||
// Right now we have to pretend that we're passing in an idValue and that there's a store | ||
// on the context. | ||
var idValue = toIdValue({ id: 'self', typename: undefined }); | ||
var fakeContext = { | ||
// NOTE: fakeContext always uses ObjectCache | ||
// since this is only to ensure the return value of 'matches' | ||
store: new ObjectCache({ self: result }), | ||
@@ -178,4 +154,2 @@ cacheRedirects: {}, | ||
} | ||
// Checks if the id given is an id that was generated by Apollo | ||
// rather than by dataIdFromObject. | ||
function isGeneratedId(id) { | ||
@@ -221,10 +195,8 @@ return id[0] === '$'; | ||
var storeFieldName = storeKeyNameFromField(field, variables); | ||
// If this is a scalar value... | ||
if (!field.selectionSet || value === null) { | ||
storeValue = | ||
value != null && typeof value === 'object' | ||
? // If the scalar value is a JSON blob, we have to "escape" it so it can’t pretend to be | ||
// an id. | ||
? | ||
{ type: 'json', json: value } | ||
: // Otherwise, just store the scalar directly in the store. | ||
: | ||
value; | ||
@@ -237,7 +209,4 @@ } | ||
else { | ||
// It's an object | ||
var valueDataId = dataId + "." + storeFieldName; | ||
var generated = true; | ||
// We only prepend the '$' if the valueDataId isn't already a generated | ||
// id. | ||
if (!isGeneratedId(valueDataId)) { | ||
@@ -248,6 +217,2 @@ valueDataId = '$' + valueDataId; | ||
var semanticId = dataIdFromObject(value); | ||
// We throw an error if the first character of the id is '$. This is | ||
// because we use that character to designate an Apollo-generated id | ||
// and we use the distinction between user-desiginated and application-provided | ||
// ids when managing overwrites. | ||
if (semanticId && isGeneratedId(semanticId)) { | ||
@@ -269,9 +234,4 @@ throw new Error('IDs returned by dataIdFromObject cannot begin with the "$" character.'); | ||
} | ||
// We take the id and escape it (i.e. wrap it with an enclosing object). | ||
// This allows us to distinguish IDs from normal scalars. | ||
var typename = value.__typename; | ||
storeValue = toIdValue({ id: valueDataId, typename: typename }, generated); | ||
// check if there was a generated id at the location where we're | ||
// about to place this new id. If there was, we have to merge the | ||
// data from that id with the data we're about to write in the store. | ||
storeObject = store.get(dataId); | ||
@@ -283,7 +243,2 @@ var escapedId = storeObject && storeObject[storeFieldName]; | ||
var typenameChanged = hadTypename && hasTypename && escapedId.typename !== typename; | ||
// If there is already a real id in the store and the current id we | ||
// are dealing with is generated, we throw an error. | ||
// One exception we allow is when the typename has changed, which occurs | ||
// when schema defines a union, both with and without an ID in the same place. | ||
// checks if we "lost" the read id | ||
if (generated && !escapedId.generated && !typenameChanged) { | ||
@@ -295,3 +250,2 @@ throw new Error("Store error: the application attempted to write an object with no provided id" + | ||
} | ||
// checks if we "lost" the typename | ||
if (hadTypename && !hasTypename) { | ||
@@ -304,8 +258,3 @@ throw new Error("Store error: the application attempted to write an object with no provided typename" + | ||
if (escapedId.generated) { | ||
// We should only merge if it's an object of the same type, | ||
// otherwise we should delete the generated object | ||
if (typenameChanged) { | ||
// Only delete the generated object when the old object was | ||
// inlined, and the new object is not. This is indicated by | ||
// the old id being generated, and the new id being real. | ||
if (!generated) { | ||
@@ -312,0 +261,0 @@ store.delete(escapedId.id); |
{ | ||
"name": "apollo-cache-inmemory", | ||
"version": "1.3.0-beta.7", | ||
"version": "1.3.0-beta.8", | ||
"description": "Core abstract of Caching layer for Apollo Client", | ||
@@ -28,19 +28,19 @@ "author": "James Baxley <james@meteor.com>", | ||
"scripts": { | ||
"prepare": "npm run build", | ||
"coverage": "jest --coverage", | ||
"test": "jest", | ||
"lint": "tslint --type-check -p tsconfig.json src/*.ts", | ||
"lint": "tslint -c \"../../config/tslint.json\" -p tsconfig.json src/*.ts", | ||
"prebuild": "npm run clean", | ||
"build": "tsc -p .", | ||
"postbuild": "npm run bundle", | ||
"bundle": "rollup -c rollup.config.js", | ||
"bundle": "../../node_modules/rollup/bin/rollup -c rollup.config.js", | ||
"watch": "tsc -w -p .", | ||
"clean": "rimraf coverage/* && rimraf lib/*", | ||
"clean": "rm -rf coverage/* && rm -rf lib/*", | ||
"prepublishOnly": "npm run build", | ||
"build:browser": "browserify ./lib/bundle.umd.js --i apollo-cache --i apollo-utilities --i graphql -o=./lib/bundle.js && npm run minify:browser", | ||
"minify:browser": "uglifyjs -c -m -o ./lib/bundle.min.js -- ./lib/bundle.js", | ||
"filesize": "npm run build:browser" | ||
"minify": "../../node_modules/uglify-js/bin/uglifyjs -c -m -o ./lib/bundle.min.js -- ./lib/bundle.umd.js", | ||
"filesize": "npm run minify" | ||
}, | ||
"dependencies": { | ||
"apollo-cache": "^1.1.13", | ||
"apollo-utilities": "^1.0.17", | ||
"apollo-cache": "file:../apollo-cache", | ||
"apollo-utilities": "file:../apollo-utilities", | ||
"optimism": "^0.6.5" | ||
@@ -51,21 +51,5 @@ }, | ||
}, | ||
"devDependencies": { | ||
"@types/graphql": "0.12.7", | ||
"@types/jest": "22.2.3", | ||
"@types/lodash": "4.14.115", | ||
"browserify": "15.2.0", | ||
"graphql": "0.13.2", | ||
"graphql-tag": "2.9.2", | ||
"jest": "23.0.0", | ||
"lodash": "4.17.10", | ||
"rimraf": "2.6.2", | ||
"rollup": "0.63.5", | ||
"ts-jest": "20.0.14", | ||
"tslint": "5.11.0", | ||
"typescript": "2.9.2", | ||
"uglify-js": "^3.4.6" | ||
}, | ||
"jest": { | ||
"transform": { | ||
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js" | ||
".(ts|tsx)": "ts-jest" | ||
}, | ||
@@ -72,0 +56,0 @@ "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$", |
@@ -79,6 +79,7 @@ import { isTest, warnOnceInDevelopment, IdValue } from 'apollo-utilities'; | ||
warnOnceInDevelopment( | ||
`You are using the simple (heuristic) fragment matcher, but your queries contain union or interface types. | ||
Apollo Client will not be able to able to accurately map fragments.` + | ||
`To make this error go away, use the IntrospectionFragmentMatcher as described in the docs: ` + | ||
`https://www.apollographql.com/docs/react/recipes/fragment-matching.html`, | ||
'You are using the simple (heuristic) fragment matcher, but your ' + | ||
'queries contain union or interface types. Apollo Client will not be ' + | ||
'able to accurately map fragments. To make this error go away, use ' + | ||
'the `IntrospectionFragmentMatcher` as described in the docs: ' + | ||
'https://www.apollographql.com/docs/react/recipes/fragment-matching.html', | ||
'error', | ||
@@ -85,0 +86,0 @@ ); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
0
78
454935
9589
- Removed@wry/equality@0.1.11(transitive)
- Removedapollo-cache@1.3.5(transitive)
- Removedapollo-utilities@1.3.4(transitive)
- Removedfast-json-stable-stringify@2.1.0(transitive)
- Removedgraphql@15.9.0(transitive)
- Removedts-invariant@0.4.4(transitive)
- Removedtslib@1.14.1(transitive)