UNPKG

43.5 kBJavaScriptView Raw
1import { __assign, __extends } from 'tslib';
2import { ApolloCache } from 'apollo-cache';
3import { isTest, getQueryDefinition, assign, getDefaultValues, isEqual, getMainDefinition, getFragmentDefinitions, createFragmentMap, shouldInclude, isField, resultKeyNameFromField, isInlineFragment, mergeDeepArray, argumentsObjectFromField, getDirectiveInfoFromField, maybeDeepFreeze, isIdValue, getStoreKeyName, toIdValue, isJsonValue, canUseWeakMap, getOperationDefinition, isProduction, storeKeyNameFromField, addTypenameToDocument } from 'apollo-utilities';
4import { wrap, KeyTrie } from 'optimism';
5import { invariant, InvariantError } from 'ts-invariant';
6
7var haveWarned = false;
8function shouldWarn() {
9 var answer = !haveWarned;
10 if (!isTest()) {
11 haveWarned = true;
12 }
13 return answer;
14}
15var HeuristicFragmentMatcher = (function () {
16 function HeuristicFragmentMatcher() {
17 }
18 HeuristicFragmentMatcher.prototype.ensureReady = function () {
19 return Promise.resolve();
20 };
21 HeuristicFragmentMatcher.prototype.canBypassInit = function () {
22 return true;
23 };
24 HeuristicFragmentMatcher.prototype.match = function (idValue, typeCondition, context) {
25 var obj = context.store.get(idValue.id);
26 var isRootQuery = idValue.id === 'ROOT_QUERY';
27 if (!obj) {
28 return isRootQuery;
29 }
30 var _a = obj.__typename, __typename = _a === void 0 ? isRootQuery && 'Query' : _a;
31 if (!__typename) {
32 if (shouldWarn()) {
33 process.env.NODE_ENV === "production" || invariant.warn("You're using fragments in your queries, but either don't have the addTypename:\n true option set in Apollo Client, or you are trying to write a fragment to the store without the __typename.\n Please turn on the addTypename option and include __typename when writing fragments so that Apollo Client\n can accurately match fragments.");
34 process.env.NODE_ENV === "production" || invariant.warn('Could not find __typename on Fragment ', typeCondition, obj);
35 process.env.NODE_ENV === "production" || invariant.warn("DEPRECATION WARNING: using fragments without __typename is unsupported behavior " +
36 "and will be removed in future versions of Apollo client. You should fix this and set addTypename to true now.");
37 }
38 return 'heuristic';
39 }
40 if (__typename === typeCondition) {
41 return true;
42 }
43 if (shouldWarn()) {
44 process.env.NODE_ENV === "production" || invariant.error('You are using the simple (heuristic) fragment matcher, but your ' +
45 'queries contain union or interface types. Apollo Client will not be ' +
46 'able to accurately map fragments. To make this error go away, use ' +
47 'the `IntrospectionFragmentMatcher` as described in the docs: ' +
48 'https://www.apollographql.com/docs/react/advanced/fragments.html#fragment-matcher');
49 }
50 return 'heuristic';
51 };
52 return HeuristicFragmentMatcher;
53}());
54var IntrospectionFragmentMatcher = (function () {
55 function IntrospectionFragmentMatcher(options) {
56 if (options && options.introspectionQueryResultData) {
57 this.possibleTypesMap = this.parseIntrospectionResult(options.introspectionQueryResultData);
58 this.isReady = true;
59 }
60 else {
61 this.isReady = false;
62 }
63 this.match = this.match.bind(this);
64 }
65 IntrospectionFragmentMatcher.prototype.match = function (idValue, typeCondition, context) {
66 process.env.NODE_ENV === "production" ? invariant(this.isReady, 1) : invariant(this.isReady, 'FragmentMatcher.match() was called before FragmentMatcher.init()');
67 var obj = context.store.get(idValue.id);
68 var isRootQuery = idValue.id === 'ROOT_QUERY';
69 if (!obj) {
70 return isRootQuery;
71 }
72 var _a = obj.__typename, __typename = _a === void 0 ? isRootQuery && 'Query' : _a;
73 process.env.NODE_ENV === "production" ? invariant(__typename, 2) : invariant(__typename, "Cannot match fragment because __typename property is missing: " + JSON.stringify(obj));
74 if (__typename === typeCondition) {
75 return true;
76 }
77 var implementingTypes = this.possibleTypesMap[typeCondition];
78 if (__typename &&
79 implementingTypes &&
80 implementingTypes.indexOf(__typename) > -1) {
81 return true;
82 }
83 return false;
84 };
85 IntrospectionFragmentMatcher.prototype.parseIntrospectionResult = function (introspectionResultData) {
86 var typeMap = {};
87 introspectionResultData.__schema.types.forEach(function (type) {
88 if (type.kind === 'UNION' || type.kind === 'INTERFACE') {
89 typeMap[type.name] = type.possibleTypes.map(function (implementingType) { return implementingType.name; });
90 }
91 });
92 return typeMap;
93 };
94 return IntrospectionFragmentMatcher;
95}());
96
97var hasOwn = Object.prototype.hasOwnProperty;
98var DepTrackingCache = (function () {
99 function DepTrackingCache(data) {
100 var _this = this;
101 if (data === void 0) { data = Object.create(null); }
102 this.data = data;
103 this.depend = wrap(function (dataId) { return _this.data[dataId]; }, {
104 disposable: true,
105 makeCacheKey: function (dataId) {
106 return dataId;
107 },
108 });
109 }
110 DepTrackingCache.prototype.toObject = function () {
111 return this.data;
112 };
113 DepTrackingCache.prototype.get = function (dataId) {
114 this.depend(dataId);
115 return this.data[dataId];
116 };
117 DepTrackingCache.prototype.set = function (dataId, value) {
118 var oldValue = this.data[dataId];
119 if (value !== oldValue) {
120 this.data[dataId] = value;
121 this.depend.dirty(dataId);
122 }
123 };
124 DepTrackingCache.prototype.delete = function (dataId) {
125 if (hasOwn.call(this.data, dataId)) {
126 delete this.data[dataId];
127 this.depend.dirty(dataId);
128 }
129 };
130 DepTrackingCache.prototype.clear = function () {
131 this.replace(null);
132 };
133 DepTrackingCache.prototype.replace = function (newData) {
134 var _this = this;
135 if (newData) {
136 Object.keys(newData).forEach(function (dataId) {
137 _this.set(dataId, newData[dataId]);
138 });
139 Object.keys(this.data).forEach(function (dataId) {
140 if (!hasOwn.call(newData, dataId)) {
141 _this.delete(dataId);
142 }
143 });
144 }
145 else {
146 Object.keys(this.data).forEach(function (dataId) {
147 _this.delete(dataId);
148 });
149 }
150 };
151 return DepTrackingCache;
152}());
153function defaultNormalizedCacheFactory(seed) {
154 return new DepTrackingCache(seed);
155}
156
157var StoreReader = (function () {
158 function StoreReader(_a) {
159 var _this = this;
160 var _b = _a === void 0 ? {} : _a, _c = _b.cacheKeyRoot, cacheKeyRoot = _c === void 0 ? new KeyTrie(canUseWeakMap) : _c, _d = _b.freezeResults, freezeResults = _d === void 0 ? false : _d;
161 var _e = this, executeStoreQuery = _e.executeStoreQuery, executeSelectionSet = _e.executeSelectionSet, executeSubSelectedArray = _e.executeSubSelectedArray;
162 this.freezeResults = freezeResults;
163 this.executeStoreQuery = wrap(function (options) {
164 return executeStoreQuery.call(_this, options);
165 }, {
166 makeCacheKey: function (_a) {
167 var query = _a.query, rootValue = _a.rootValue, contextValue = _a.contextValue, variableValues = _a.variableValues, fragmentMatcher = _a.fragmentMatcher;
168 if (contextValue.store instanceof DepTrackingCache) {
169 return cacheKeyRoot.lookup(contextValue.store, query, fragmentMatcher, JSON.stringify(variableValues), rootValue.id);
170 }
171 }
172 });
173 this.executeSelectionSet = wrap(function (options) {
174 return executeSelectionSet.call(_this, options);
175 }, {
176 makeCacheKey: function (_a) {
177 var selectionSet = _a.selectionSet, rootValue = _a.rootValue, execContext = _a.execContext;
178 if (execContext.contextValue.store instanceof DepTrackingCache) {
179 return cacheKeyRoot.lookup(execContext.contextValue.store, selectionSet, execContext.fragmentMatcher, JSON.stringify(execContext.variableValues), rootValue.id);
180 }
181 }
182 });
183 this.executeSubSelectedArray = wrap(function (options) {
184 return executeSubSelectedArray.call(_this, options);
185 }, {
186 makeCacheKey: function (_a) {
187 var field = _a.field, array = _a.array, execContext = _a.execContext;
188 if (execContext.contextValue.store instanceof DepTrackingCache) {
189 return cacheKeyRoot.lookup(execContext.contextValue.store, field, array, JSON.stringify(execContext.variableValues));
190 }
191 }
192 });
193 }
194 StoreReader.prototype.readQueryFromStore = function (options) {
195 return this.diffQueryAgainstStore(__assign(__assign({}, options), { returnPartialData: false })).result;
196 };
197 StoreReader.prototype.diffQueryAgainstStore = function (_a) {
198 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;
199 var queryDefinition = getQueryDefinition(query);
200 variables = assign({}, getDefaultValues(queryDefinition), variables);
201 var context = {
202 store: store,
203 dataIdFromObject: config && config.dataIdFromObject,
204 cacheRedirects: (config && config.cacheRedirects) || {},
205 };
206 var execResult = this.executeStoreQuery({
207 query: query,
208 rootValue: {
209 type: 'id',
210 id: rootId,
211 generated: true,
212 typename: 'Query',
213 },
214 contextValue: context,
215 variableValues: variables,
216 fragmentMatcher: fragmentMatcherFunction,
217 });
218 var hasMissingFields = execResult.missing && execResult.missing.length > 0;
219 if (hasMissingFields && !returnPartialData) {
220 execResult.missing.forEach(function (info) {
221 if (info.tolerable)
222 return;
223 throw process.env.NODE_ENV === "production" ? new InvariantError(8) : new InvariantError("Can't find field " + info.fieldName + " on object " + JSON.stringify(info.object, null, 2) + ".");
224 });
225 }
226 if (previousResult) {
227 if (isEqual(previousResult, execResult.result)) {
228 execResult.result = previousResult;
229 }
230 }
231 return {
232 result: execResult.result,
233 complete: !hasMissingFields,
234 };
235 };
236 StoreReader.prototype.executeStoreQuery = function (_a) {
237 var query = _a.query, rootValue = _a.rootValue, contextValue = _a.contextValue, variableValues = _a.variableValues, _b = _a.fragmentMatcher, fragmentMatcher = _b === void 0 ? defaultFragmentMatcher : _b;
238 var mainDefinition = getMainDefinition(query);
239 var fragments = getFragmentDefinitions(query);
240 var fragmentMap = createFragmentMap(fragments);
241 var execContext = {
242 query: query,
243 fragmentMap: fragmentMap,
244 contextValue: contextValue,
245 variableValues: variableValues,
246 fragmentMatcher: fragmentMatcher,
247 };
248 return this.executeSelectionSet({
249 selectionSet: mainDefinition.selectionSet,
250 rootValue: rootValue,
251 execContext: execContext,
252 });
253 };
254 StoreReader.prototype.executeSelectionSet = function (_a) {
255 var _this = this;
256 var selectionSet = _a.selectionSet, rootValue = _a.rootValue, execContext = _a.execContext;
257 var fragmentMap = execContext.fragmentMap, contextValue = execContext.contextValue, variables = execContext.variableValues;
258 var finalResult = { result: null };
259 var objectsToMerge = [];
260 var object = contextValue.store.get(rootValue.id);
261 var typename = (object && object.__typename) ||
262 (rootValue.id === 'ROOT_QUERY' && 'Query') ||
263 void 0;
264 function handleMissing(result) {
265 var _a;
266 if (result.missing) {
267 finalResult.missing = finalResult.missing || [];
268 (_a = finalResult.missing).push.apply(_a, result.missing);
269 }
270 return result.result;
271 }
272 selectionSet.selections.forEach(function (selection) {
273 var _a;
274 if (!shouldInclude(selection, variables)) {
275 return;
276 }
277 if (isField(selection)) {
278 var fieldResult = handleMissing(_this.executeField(object, typename, selection, execContext));
279 if (typeof fieldResult !== 'undefined') {
280 objectsToMerge.push((_a = {},
281 _a[resultKeyNameFromField(selection)] = fieldResult,
282 _a));
283 }
284 }
285 else {
286 var fragment = void 0;
287 if (isInlineFragment(selection)) {
288 fragment = selection;
289 }
290 else {
291 fragment = fragmentMap[selection.name.value];
292 if (!fragment) {
293 throw process.env.NODE_ENV === "production" ? new InvariantError(9) : new InvariantError("No fragment named " + selection.name.value);
294 }
295 }
296 var typeCondition = fragment.typeCondition && fragment.typeCondition.name.value;
297 var match = !typeCondition ||
298 execContext.fragmentMatcher(rootValue, typeCondition, contextValue);
299 if (match) {
300 var fragmentExecResult = _this.executeSelectionSet({
301 selectionSet: fragment.selectionSet,
302 rootValue: rootValue,
303 execContext: execContext,
304 });
305 if (match === 'heuristic' && fragmentExecResult.missing) {
306 fragmentExecResult = __assign(__assign({}, fragmentExecResult), { missing: fragmentExecResult.missing.map(function (info) {
307 return __assign(__assign({}, info), { tolerable: true });
308 }) });
309 }
310 objectsToMerge.push(handleMissing(fragmentExecResult));
311 }
312 }
313 });
314 finalResult.result = mergeDeepArray(objectsToMerge);
315 if (this.freezeResults && process.env.NODE_ENV !== 'production') {
316 Object.freeze(finalResult.result);
317 }
318 return finalResult;
319 };
320 StoreReader.prototype.executeField = function (object, typename, field, execContext) {
321 var variables = execContext.variableValues, contextValue = execContext.contextValue;
322 var fieldName = field.name.value;
323 var args = argumentsObjectFromField(field, variables);
324 var info = {
325 resultKey: resultKeyNameFromField(field),
326 directives: getDirectiveInfoFromField(field, variables),
327 };
328 var readStoreResult = readStoreResolver(object, typename, fieldName, args, contextValue, info);
329 if (Array.isArray(readStoreResult.result)) {
330 return this.combineExecResults(readStoreResult, this.executeSubSelectedArray({
331 field: field,
332 array: readStoreResult.result,
333 execContext: execContext,
334 }));
335 }
336 if (!field.selectionSet) {
337 assertSelectionSetForIdValue(field, readStoreResult.result);
338 if (this.freezeResults && process.env.NODE_ENV !== 'production') {
339 maybeDeepFreeze(readStoreResult);
340 }
341 return readStoreResult;
342 }
343 if (readStoreResult.result == null) {
344 return readStoreResult;
345 }
346 return this.combineExecResults(readStoreResult, this.executeSelectionSet({
347 selectionSet: field.selectionSet,
348 rootValue: readStoreResult.result,
349 execContext: execContext,
350 }));
351 };
352 StoreReader.prototype.combineExecResults = function () {
353 var execResults = [];
354 for (var _i = 0; _i < arguments.length; _i++) {
355 execResults[_i] = arguments[_i];
356 }
357 var missing;
358 execResults.forEach(function (execResult) {
359 if (execResult.missing) {
360 missing = missing || [];
361 missing.push.apply(missing, execResult.missing);
362 }
363 });
364 return {
365 result: execResults.pop().result,
366 missing: missing,
367 };
368 };
369 StoreReader.prototype.executeSubSelectedArray = function (_a) {
370 var _this = this;
371 var field = _a.field, array = _a.array, execContext = _a.execContext;
372 var missing;
373 function handleMissing(childResult) {
374 if (childResult.missing) {
375 missing = missing || [];
376 missing.push.apply(missing, childResult.missing);
377 }
378 return childResult.result;
379 }
380 array = array.map(function (item) {
381 if (item === null) {
382 return null;
383 }
384 if (Array.isArray(item)) {
385 return handleMissing(_this.executeSubSelectedArray({
386 field: field,
387 array: item,
388 execContext: execContext,
389 }));
390 }
391 if (field.selectionSet) {
392 return handleMissing(_this.executeSelectionSet({
393 selectionSet: field.selectionSet,
394 rootValue: item,
395 execContext: execContext,
396 }));
397 }
398 assertSelectionSetForIdValue(field, item);
399 return item;
400 });
401 if (this.freezeResults && process.env.NODE_ENV !== 'production') {
402 Object.freeze(array);
403 }
404 return { result: array, missing: missing };
405 };
406 return StoreReader;
407}());
408function assertSelectionSetForIdValue(field, value) {
409 if (!field.selectionSet && isIdValue(value)) {
410 throw process.env.NODE_ENV === "production" ? new InvariantError(10) : new InvariantError("Missing selection set for object of type " + value.typename + " returned for query field " + field.name.value);
411 }
412}
413function defaultFragmentMatcher() {
414 return true;
415}
416function assertIdValue(idValue) {
417 process.env.NODE_ENV === "production" ? invariant(isIdValue(idValue), 11) : invariant(isIdValue(idValue), "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.");
418}
419function readStoreResolver(object, typename, fieldName, args, context, _a) {
420 var resultKey = _a.resultKey, directives = _a.directives;
421 var storeKeyName = fieldName;
422 if (args || directives) {
423 storeKeyName = getStoreKeyName(storeKeyName, args, directives);
424 }
425 var fieldValue = void 0;
426 if (object) {
427 fieldValue = object[storeKeyName];
428 if (typeof fieldValue === 'undefined' &&
429 context.cacheRedirects &&
430 typeof typename === 'string') {
431 var type = context.cacheRedirects[typename];
432 if (type) {
433 var resolver = type[fieldName];
434 if (resolver) {
435 fieldValue = resolver(object, args, {
436 getCacheKey: function (storeObj) {
437 var id = context.dataIdFromObject(storeObj);
438 return id && toIdValue({
439 id: id,
440 typename: storeObj.__typename,
441 });
442 },
443 });
444 }
445 }
446 }
447 }
448 if (typeof fieldValue === 'undefined') {
449 return {
450 result: fieldValue,
451 missing: [{
452 object: object,
453 fieldName: storeKeyName,
454 tolerable: false,
455 }],
456 };
457 }
458 if (isJsonValue(fieldValue)) {
459 fieldValue = fieldValue.json;
460 }
461 return {
462 result: fieldValue,
463 };
464}
465
466var ObjectCache = (function () {
467 function ObjectCache(data) {
468 if (data === void 0) { data = Object.create(null); }
469 this.data = data;
470 }
471 ObjectCache.prototype.toObject = function () {
472 return this.data;
473 };
474 ObjectCache.prototype.get = function (dataId) {
475 return this.data[dataId];
476 };
477 ObjectCache.prototype.set = function (dataId, value) {
478 this.data[dataId] = value;
479 };
480 ObjectCache.prototype.delete = function (dataId) {
481 this.data[dataId] = void 0;
482 };
483 ObjectCache.prototype.clear = function () {
484 this.data = Object.create(null);
485 };
486 ObjectCache.prototype.replace = function (newData) {
487 this.data = newData || Object.create(null);
488 };
489 return ObjectCache;
490}());
491function defaultNormalizedCacheFactory$1(seed) {
492 return new ObjectCache(seed);
493}
494
495var WriteError = (function (_super) {
496 __extends(WriteError, _super);
497 function WriteError() {
498 var _this = _super !== null && _super.apply(this, arguments) || this;
499 _this.type = 'WriteError';
500 return _this;
501 }
502 return WriteError;
503}(Error));
504function enhanceErrorWithDocument(error, document) {
505 var enhancedError = new WriteError("Error writing result to store for query:\n " + JSON.stringify(document));
506 enhancedError.message += '\n' + error.message;
507 enhancedError.stack = error.stack;
508 return enhancedError;
509}
510var StoreWriter = (function () {
511 function StoreWriter() {
512 }
513 StoreWriter.prototype.writeQueryToStore = function (_a) {
514 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;
515 return this.writeResultToStore({
516 dataId: 'ROOT_QUERY',
517 result: result,
518 document: query,
519 store: store,
520 variables: variables,
521 dataIdFromObject: dataIdFromObject,
522 fragmentMatcherFunction: fragmentMatcherFunction,
523 });
524 };
525 StoreWriter.prototype.writeResultToStore = function (_a) {
526 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;
527 var operationDefinition = getOperationDefinition(document);
528 try {
529 return this.writeSelectionSetToStore({
530 result: result,
531 dataId: dataId,
532 selectionSet: operationDefinition.selectionSet,
533 context: {
534 store: store,
535 processedData: {},
536 variables: assign({}, getDefaultValues(operationDefinition), variables),
537 dataIdFromObject: dataIdFromObject,
538 fragmentMap: createFragmentMap(getFragmentDefinitions(document)),
539 fragmentMatcherFunction: fragmentMatcherFunction,
540 },
541 });
542 }
543 catch (e) {
544 throw enhanceErrorWithDocument(e, document);
545 }
546 };
547 StoreWriter.prototype.writeSelectionSetToStore = function (_a) {
548 var _this = this;
549 var result = _a.result, dataId = _a.dataId, selectionSet = _a.selectionSet, context = _a.context;
550 var variables = context.variables, store = context.store, fragmentMap = context.fragmentMap;
551 selectionSet.selections.forEach(function (selection) {
552 var _a;
553 if (!shouldInclude(selection, variables)) {
554 return;
555 }
556 if (isField(selection)) {
557 var resultFieldKey = resultKeyNameFromField(selection);
558 var value = result[resultFieldKey];
559 if (typeof value !== 'undefined') {
560 _this.writeFieldToStore({
561 dataId: dataId,
562 value: value,
563 field: selection,
564 context: context,
565 });
566 }
567 else {
568 var isDefered = false;
569 var isClient = false;
570 if (selection.directives && selection.directives.length) {
571 isDefered = selection.directives.some(function (directive) { return directive.name && directive.name.value === 'defer'; });
572 isClient = selection.directives.some(function (directive) { return directive.name && directive.name.value === 'client'; });
573 }
574 if (!isDefered && !isClient && context.fragmentMatcherFunction) {
575 process.env.NODE_ENV === "production" || invariant.warn("Missing field " + resultFieldKey + " in " + JSON.stringify(result, null, 2).substring(0, 100));
576 }
577 }
578 }
579 else {
580 var fragment = void 0;
581 if (isInlineFragment(selection)) {
582 fragment = selection;
583 }
584 else {
585 fragment = (fragmentMap || {})[selection.name.value];
586 process.env.NODE_ENV === "production" ? invariant(fragment, 3) : invariant(fragment, "No fragment named " + selection.name.value + ".");
587 }
588 var matches = true;
589 if (context.fragmentMatcherFunction && fragment.typeCondition) {
590 var id = dataId || 'self';
591 var idValue = toIdValue({ id: id, typename: undefined });
592 var fakeContext = {
593 store: new ObjectCache((_a = {}, _a[id] = result, _a)),
594 cacheRedirects: {},
595 };
596 var match = context.fragmentMatcherFunction(idValue, fragment.typeCondition.name.value, fakeContext);
597 if (!isProduction() && match === 'heuristic') {
598 process.env.NODE_ENV === "production" || invariant.error('WARNING: heuristic fragment matching going on!');
599 }
600 matches = !!match;
601 }
602 if (matches) {
603 _this.writeSelectionSetToStore({
604 result: result,
605 selectionSet: fragment.selectionSet,
606 dataId: dataId,
607 context: context,
608 });
609 }
610 }
611 });
612 return store;
613 };
614 StoreWriter.prototype.writeFieldToStore = function (_a) {
615 var _b;
616 var field = _a.field, value = _a.value, dataId = _a.dataId, context = _a.context;
617 var variables = context.variables, dataIdFromObject = context.dataIdFromObject, store = context.store;
618 var storeValue;
619 var storeObject;
620 var storeFieldName = storeKeyNameFromField(field, variables);
621 if (!field.selectionSet || value === null) {
622 storeValue =
623 value != null && typeof value === 'object'
624 ?
625 { type: 'json', json: value }
626 :
627 value;
628 }
629 else if (Array.isArray(value)) {
630 var generatedId = dataId + "." + storeFieldName;
631 storeValue = this.processArrayValue(value, generatedId, field.selectionSet, context);
632 }
633 else {
634 var valueDataId = dataId + "." + storeFieldName;
635 var generated = true;
636 if (!isGeneratedId(valueDataId)) {
637 valueDataId = '$' + valueDataId;
638 }
639 if (dataIdFromObject) {
640 var semanticId = dataIdFromObject(value);
641 process.env.NODE_ENV === "production" ? invariant(!semanticId || !isGeneratedId(semanticId), 4) : invariant(!semanticId || !isGeneratedId(semanticId), 'IDs returned by dataIdFromObject cannot begin with the "$" character.');
642 if (semanticId ||
643 (typeof semanticId === 'number' && semanticId === 0)) {
644 valueDataId = semanticId;
645 generated = false;
646 }
647 }
648 if (!isDataProcessed(valueDataId, field, context.processedData)) {
649 this.writeSelectionSetToStore({
650 dataId: valueDataId,
651 result: value,
652 selectionSet: field.selectionSet,
653 context: context,
654 });
655 }
656 var typename = value.__typename;
657 storeValue = toIdValue({ id: valueDataId, typename: typename }, generated);
658 storeObject = store.get(dataId);
659 var escapedId = storeObject && storeObject[storeFieldName];
660 if (escapedId !== storeValue && isIdValue(escapedId)) {
661 var hadTypename = escapedId.typename !== undefined;
662 var hasTypename = typename !== undefined;
663 var typenameChanged = hadTypename && hasTypename && escapedId.typename !== typename;
664 process.env.NODE_ENV === "production" ? invariant(!generated || escapedId.generated || typenameChanged, 5) : 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));
665 process.env.NODE_ENV === "production" ? invariant(!hadTypename || hasTypename, 6) : 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));
666 if (escapedId.generated) {
667 if (typenameChanged) {
668 if (!generated) {
669 store.delete(escapedId.id);
670 }
671 }
672 else {
673 mergeWithGenerated(escapedId.id, storeValue.id, store);
674 }
675 }
676 }
677 }
678 storeObject = store.get(dataId);
679 if (!storeObject || !isEqual(storeValue, storeObject[storeFieldName])) {
680 store.set(dataId, __assign(__assign({}, storeObject), (_b = {}, _b[storeFieldName] = storeValue, _b)));
681 }
682 };
683 StoreWriter.prototype.processArrayValue = function (value, generatedId, selectionSet, context) {
684 var _this = this;
685 return value.map(function (item, index) {
686 if (item === null) {
687 return null;
688 }
689 var itemDataId = generatedId + "." + index;
690 if (Array.isArray(item)) {
691 return _this.processArrayValue(item, itemDataId, selectionSet, context);
692 }
693 var generated = true;
694 if (context.dataIdFromObject) {
695 var semanticId = context.dataIdFromObject(item);
696 if (semanticId) {
697 itemDataId = semanticId;
698 generated = false;
699 }
700 }
701 if (!isDataProcessed(itemDataId, selectionSet, context.processedData)) {
702 _this.writeSelectionSetToStore({
703 dataId: itemDataId,
704 result: item,
705 selectionSet: selectionSet,
706 context: context,
707 });
708 }
709 return toIdValue({ id: itemDataId, typename: item.__typename }, generated);
710 });
711 };
712 return StoreWriter;
713}());
714function isGeneratedId(id) {
715 return id[0] === '$';
716}
717function mergeWithGenerated(generatedKey, realKey, cache) {
718 if (generatedKey === realKey) {
719 return false;
720 }
721 var generated = cache.get(generatedKey);
722 var real = cache.get(realKey);
723 var madeChanges = false;
724 Object.keys(generated).forEach(function (key) {
725 var value = generated[key];
726 var realValue = real[key];
727 if (isIdValue(value) &&
728 isGeneratedId(value.id) &&
729 isIdValue(realValue) &&
730 !isEqual(value, realValue) &&
731 mergeWithGenerated(value.id, realValue.id, cache)) {
732 madeChanges = true;
733 }
734 });
735 cache.delete(generatedKey);
736 var newRealValue = __assign(__assign({}, generated), real);
737 if (isEqual(newRealValue, real)) {
738 return madeChanges;
739 }
740 cache.set(realKey, newRealValue);
741 return true;
742}
743function isDataProcessed(dataId, field, processedData) {
744 if (!processedData) {
745 return false;
746 }
747 if (processedData[dataId]) {
748 if (processedData[dataId].indexOf(field) >= 0) {
749 return true;
750 }
751 else {
752 processedData[dataId].push(field);
753 }
754 }
755 else {
756 processedData[dataId] = [field];
757 }
758 return false;
759}
760
761var defaultConfig = {
762 fragmentMatcher: new HeuristicFragmentMatcher(),
763 dataIdFromObject: defaultDataIdFromObject,
764 addTypename: true,
765 resultCaching: true,
766 freezeResults: false,
767};
768function defaultDataIdFromObject(result) {
769 if (result.__typename) {
770 if (result.id !== undefined) {
771 return result.__typename + ":" + result.id;
772 }
773 if (result._id !== undefined) {
774 return result.__typename + ":" + result._id;
775 }
776 }
777 return null;
778}
779var hasOwn$1 = Object.prototype.hasOwnProperty;
780var OptimisticCacheLayer = (function (_super) {
781 __extends(OptimisticCacheLayer, _super);
782 function OptimisticCacheLayer(optimisticId, parent, transaction) {
783 var _this = _super.call(this, Object.create(null)) || this;
784 _this.optimisticId = optimisticId;
785 _this.parent = parent;
786 _this.transaction = transaction;
787 return _this;
788 }
789 OptimisticCacheLayer.prototype.toObject = function () {
790 return __assign(__assign({}, this.parent.toObject()), this.data);
791 };
792 OptimisticCacheLayer.prototype.get = function (dataId) {
793 return hasOwn$1.call(this.data, dataId)
794 ? this.data[dataId]
795 : this.parent.get(dataId);
796 };
797 return OptimisticCacheLayer;
798}(ObjectCache));
799var InMemoryCache = (function (_super) {
800 __extends(InMemoryCache, _super);
801 function InMemoryCache(config) {
802 if (config === void 0) { config = {}; }
803 var _this = _super.call(this) || this;
804 _this.watches = new Set();
805 _this.typenameDocumentCache = new Map();
806 _this.cacheKeyRoot = new KeyTrie(canUseWeakMap);
807 _this.silenceBroadcast = false;
808 _this.config = __assign(__assign({}, defaultConfig), config);
809 if (_this.config.customResolvers) {
810 process.env.NODE_ENV === "production" || invariant.warn('customResolvers have been renamed to cacheRedirects. Please update your config as we will be deprecating customResolvers in the next major version.');
811 _this.config.cacheRedirects = _this.config.customResolvers;
812 }
813 if (_this.config.cacheResolvers) {
814 process.env.NODE_ENV === "production" || invariant.warn('cacheResolvers have been renamed to cacheRedirects. Please update your config as we will be deprecating cacheResolvers in the next major version.');
815 _this.config.cacheRedirects = _this.config.cacheResolvers;
816 }
817 _this.addTypename = !!_this.config.addTypename;
818 _this.data = _this.config.resultCaching
819 ? new DepTrackingCache()
820 : new ObjectCache();
821 _this.optimisticData = _this.data;
822 _this.storeWriter = new StoreWriter();
823 _this.storeReader = new StoreReader({
824 cacheKeyRoot: _this.cacheKeyRoot,
825 freezeResults: config.freezeResults,
826 });
827 var cache = _this;
828 var maybeBroadcastWatch = cache.maybeBroadcastWatch;
829 _this.maybeBroadcastWatch = wrap(function (c) {
830 return maybeBroadcastWatch.call(_this, c);
831 }, {
832 makeCacheKey: function (c) {
833 if (c.optimistic) {
834 return;
835 }
836 if (c.previousResult) {
837 return;
838 }
839 if (cache.data instanceof DepTrackingCache) {
840 return cache.cacheKeyRoot.lookup(c.query, JSON.stringify(c.variables));
841 }
842 }
843 });
844 return _this;
845 }
846 InMemoryCache.prototype.restore = function (data) {
847 if (data)
848 this.data.replace(data);
849 return this;
850 };
851 InMemoryCache.prototype.extract = function (optimistic) {
852 if (optimistic === void 0) { optimistic = false; }
853 return (optimistic ? this.optimisticData : this.data).toObject();
854 };
855 InMemoryCache.prototype.read = function (options) {
856 if (typeof options.rootId === 'string' &&
857 typeof this.data.get(options.rootId) === 'undefined') {
858 return null;
859 }
860 var fragmentMatcher = this.config.fragmentMatcher;
861 var fragmentMatcherFunction = fragmentMatcher && fragmentMatcher.match;
862 return this.storeReader.readQueryFromStore({
863 store: options.optimistic ? this.optimisticData : this.data,
864 query: this.transformDocument(options.query),
865 variables: options.variables,
866 rootId: options.rootId,
867 fragmentMatcherFunction: fragmentMatcherFunction,
868 previousResult: options.previousResult,
869 config: this.config,
870 }) || null;
871 };
872 InMemoryCache.prototype.write = function (write) {
873 var fragmentMatcher = this.config.fragmentMatcher;
874 var fragmentMatcherFunction = fragmentMatcher && fragmentMatcher.match;
875 this.storeWriter.writeResultToStore({
876 dataId: write.dataId,
877 result: write.result,
878 variables: write.variables,
879 document: this.transformDocument(write.query),
880 store: this.data,
881 dataIdFromObject: this.config.dataIdFromObject,
882 fragmentMatcherFunction: fragmentMatcherFunction,
883 });
884 this.broadcastWatches();
885 };
886 InMemoryCache.prototype.diff = function (query) {
887 var fragmentMatcher = this.config.fragmentMatcher;
888 var fragmentMatcherFunction = fragmentMatcher && fragmentMatcher.match;
889 return this.storeReader.diffQueryAgainstStore({
890 store: query.optimistic ? this.optimisticData : this.data,
891 query: this.transformDocument(query.query),
892 variables: query.variables,
893 returnPartialData: query.returnPartialData,
894 previousResult: query.previousResult,
895 fragmentMatcherFunction: fragmentMatcherFunction,
896 config: this.config,
897 });
898 };
899 InMemoryCache.prototype.watch = function (watch) {
900 var _this = this;
901 this.watches.add(watch);
902 return function () {
903 _this.watches.delete(watch);
904 };
905 };
906 InMemoryCache.prototype.evict = function (query) {
907 throw process.env.NODE_ENV === "production" ? new InvariantError(7) : new InvariantError("eviction is not implemented on InMemory Cache");
908 };
909 InMemoryCache.prototype.reset = function () {
910 this.data.clear();
911 this.broadcastWatches();
912 return Promise.resolve();
913 };
914 InMemoryCache.prototype.removeOptimistic = function (idToRemove) {
915 var toReapply = [];
916 var removedCount = 0;
917 var layer = this.optimisticData;
918 while (layer instanceof OptimisticCacheLayer) {
919 if (layer.optimisticId === idToRemove) {
920 ++removedCount;
921 }
922 else {
923 toReapply.push(layer);
924 }
925 layer = layer.parent;
926 }
927 if (removedCount > 0) {
928 this.optimisticData = layer;
929 while (toReapply.length > 0) {
930 var layer_1 = toReapply.pop();
931 this.performTransaction(layer_1.transaction, layer_1.optimisticId);
932 }
933 this.broadcastWatches();
934 }
935 };
936 InMemoryCache.prototype.performTransaction = function (transaction, optimisticId) {
937 var _a = this, data = _a.data, silenceBroadcast = _a.silenceBroadcast;
938 this.silenceBroadcast = true;
939 if (typeof optimisticId === 'string') {
940 this.data = this.optimisticData = new OptimisticCacheLayer(optimisticId, this.optimisticData, transaction);
941 }
942 try {
943 transaction(this);
944 }
945 finally {
946 this.silenceBroadcast = silenceBroadcast;
947 this.data = data;
948 }
949 this.broadcastWatches();
950 };
951 InMemoryCache.prototype.recordOptimisticTransaction = function (transaction, id) {
952 return this.performTransaction(transaction, id);
953 };
954 InMemoryCache.prototype.transformDocument = function (document) {
955 if (this.addTypename) {
956 var result = this.typenameDocumentCache.get(document);
957 if (!result) {
958 result = addTypenameToDocument(document);
959 this.typenameDocumentCache.set(document, result);
960 this.typenameDocumentCache.set(result, result);
961 }
962 return result;
963 }
964 return document;
965 };
966 InMemoryCache.prototype.broadcastWatches = function () {
967 var _this = this;
968 if (!this.silenceBroadcast) {
969 this.watches.forEach(function (c) { return _this.maybeBroadcastWatch(c); });
970 }
971 };
972 InMemoryCache.prototype.maybeBroadcastWatch = function (c) {
973 c.callback(this.diff({
974 query: c.query,
975 variables: c.variables,
976 previousResult: c.previousResult && c.previousResult(),
977 optimistic: c.optimistic,
978 }));
979 };
980 return InMemoryCache;
981}(ApolloCache));
982
983export { HeuristicFragmentMatcher, InMemoryCache, IntrospectionFragmentMatcher, ObjectCache, StoreReader, StoreWriter, WriteError, assertIdValue, defaultDataIdFromObject, defaultNormalizedCacheFactory$1 as defaultNormalizedCacheFactory, enhanceErrorWithDocument };
984//# sourceMappingURL=bundle.esm.js.map