UNPKG

43.6 kBJavaScriptView Raw
1(function (global, factory) {
2 if (typeof define === "function" && define.amd) {
3 define(["exports", "tslib", "apollo-cache", "apollo-utilities", "optimism", "ts-invariant"], factory);
4 } else if (typeof exports !== "undefined") {
5 factory(exports, require("tslib"), require("apollo-cache"), require("apollo-utilities"), require("optimism"), require("ts-invariant"));
6 } else {
7 var mod = {
8 exports: {}
9 };
10 factory(mod.exports, global.tslib, global.apolloCache, global.apolloUtilities, global.optimism, global.tsInvariant);
11 global.unknown = mod.exports;
12 }
13})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _tslib, _apolloCache, _apolloUtilities, _optimism, _tsInvariant) {
14
15 _exports.__esModule = true;
16 _exports.assertIdValue = assertIdValue;
17 _exports.defaultDataIdFromObject = defaultDataIdFromObject;
18 _exports.defaultNormalizedCacheFactory = defaultNormalizedCacheFactory$1;
19 _exports.enhanceErrorWithDocument = enhanceErrorWithDocument;
20 _exports.WriteError = _exports.StoreWriter = _exports.StoreReader = _exports.ObjectCache = _exports.IntrospectionFragmentMatcher = _exports.InMemoryCache = _exports.HeuristicFragmentMatcher = void 0;
21 var haveWarned = false;
22
23 function shouldWarn() {
24 var answer = !haveWarned;
25
26 if (!(0, _apolloUtilities.isTest)()) {
27 haveWarned = true;
28 }
29
30 return answer;
31 }
32
33 var HeuristicFragmentMatcher = function () {
34 function HeuristicFragmentMatcher() {}
35
36 HeuristicFragmentMatcher.prototype.ensureReady = function () {
37 return Promise.resolve();
38 };
39
40 HeuristicFragmentMatcher.prototype.canBypassInit = function () {
41 return true;
42 };
43
44 HeuristicFragmentMatcher.prototype.match = function (idValue, typeCondition, context) {
45 var obj = context.store.get(idValue.id);
46 var isRootQuery = idValue.id === 'ROOT_QUERY';
47
48 if (!obj) {
49 return isRootQuery;
50 }
51
52 var _a = obj.__typename,
53 __typename = _a === void 0 ? isRootQuery && 'Query' : _a;
54
55 if (!__typename) {
56 if (shouldWarn()) {
57 process.env.NODE_ENV === "production" || _tsInvariant.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.");
58 process.env.NODE_ENV === "production" || _tsInvariant.invariant.warn('Could not find __typename on Fragment ', typeCondition, obj);
59 process.env.NODE_ENV === "production" || _tsInvariant.invariant.warn("DEPRECATION WARNING: using fragments without __typename is unsupported behavior " + "and will be removed in future versions of Apollo client. You should fix this and set addTypename to true now.");
60 }
61
62 return 'heuristic';
63 }
64
65 if (__typename === typeCondition) {
66 return true;
67 }
68
69 if (shouldWarn()) {
70 process.env.NODE_ENV === "production" || _tsInvariant.invariant.error('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/advanced/fragments.html#fragment-matcher');
71 }
72
73 return 'heuristic';
74 };
75
76 return HeuristicFragmentMatcher;
77 }();
78
79 _exports.HeuristicFragmentMatcher = HeuristicFragmentMatcher;
80
81 var IntrospectionFragmentMatcher = function () {
82 function IntrospectionFragmentMatcher(options) {
83 if (options && options.introspectionQueryResultData) {
84 this.possibleTypesMap = this.parseIntrospectionResult(options.introspectionQueryResultData);
85 this.isReady = true;
86 } else {
87 this.isReady = false;
88 }
89
90 this.match = this.match.bind(this);
91 }
92
93 IntrospectionFragmentMatcher.prototype.match = function (idValue, typeCondition, context) {
94 process.env.NODE_ENV === "production" ? (0, _tsInvariant.invariant)(this.isReady, 1) : (0, _tsInvariant.invariant)(this.isReady, 'FragmentMatcher.match() was called before FragmentMatcher.init()');
95 var obj = context.store.get(idValue.id);
96 var isRootQuery = idValue.id === 'ROOT_QUERY';
97
98 if (!obj) {
99 return isRootQuery;
100 }
101
102 var _a = obj.__typename,
103 __typename = _a === void 0 ? isRootQuery && 'Query' : _a;
104
105 process.env.NODE_ENV === "production" ? (0, _tsInvariant.invariant)(__typename, 2) : (0, _tsInvariant.invariant)(__typename, "Cannot match fragment because __typename property is missing: " + JSON.stringify(obj));
106
107 if (__typename === typeCondition) {
108 return true;
109 }
110
111 var implementingTypes = this.possibleTypesMap[typeCondition];
112
113 if (__typename && implementingTypes && implementingTypes.indexOf(__typename) > -1) {
114 return true;
115 }
116
117 return false;
118 };
119
120 IntrospectionFragmentMatcher.prototype.parseIntrospectionResult = function (introspectionResultData) {
121 var typeMap = {};
122
123 introspectionResultData.__schema.types.forEach(function (type) {
124 if (type.kind === 'UNION' || type.kind === 'INTERFACE') {
125 typeMap[type.name] = type.possibleTypes.map(function (implementingType) {
126 return implementingType.name;
127 });
128 }
129 });
130
131 return typeMap;
132 };
133
134 return IntrospectionFragmentMatcher;
135 }();
136
137 _exports.IntrospectionFragmentMatcher = IntrospectionFragmentMatcher;
138 var hasOwn = Object.prototype.hasOwnProperty;
139
140 var DepTrackingCache = function () {
141 function DepTrackingCache(data) {
142 var _this = this;
143
144 if (data === void 0) {
145 data = Object.create(null);
146 }
147
148 this.data = data;
149 this.depend = (0, _optimism.wrap)(function (dataId) {
150 return _this.data[dataId];
151 }, {
152 disposable: true,
153 makeCacheKey: function (dataId) {
154 return dataId;
155 }
156 });
157 }
158
159 DepTrackingCache.prototype.toObject = function () {
160 return this.data;
161 };
162
163 DepTrackingCache.prototype.get = function (dataId) {
164 this.depend(dataId);
165 return this.data[dataId];
166 };
167
168 DepTrackingCache.prototype.set = function (dataId, value) {
169 var oldValue = this.data[dataId];
170
171 if (value !== oldValue) {
172 this.data[dataId] = value;
173 this.depend.dirty(dataId);
174 }
175 };
176
177 DepTrackingCache.prototype.delete = function (dataId) {
178 if (hasOwn.call(this.data, dataId)) {
179 delete this.data[dataId];
180 this.depend.dirty(dataId);
181 }
182 };
183
184 DepTrackingCache.prototype.clear = function () {
185 this.replace(null);
186 };
187
188 DepTrackingCache.prototype.replace = function (newData) {
189 var _this = this;
190
191 if (newData) {
192 Object.keys(newData).forEach(function (dataId) {
193 _this.set(dataId, newData[dataId]);
194 });
195 Object.keys(this.data).forEach(function (dataId) {
196 if (!hasOwn.call(newData, dataId)) {
197 _this.delete(dataId);
198 }
199 });
200 } else {
201 Object.keys(this.data).forEach(function (dataId) {
202 _this.delete(dataId);
203 });
204 }
205 };
206
207 return DepTrackingCache;
208 }();
209
210 function defaultNormalizedCacheFactory(seed) {
211 return new DepTrackingCache(seed);
212 }
213
214 var StoreReader = function () {
215 function StoreReader(_a) {
216 var _this = this;
217
218 var _b = _a === void 0 ? {} : _a,
219 _c = _b.cacheKeyRoot,
220 cacheKeyRoot = _c === void 0 ? new _optimism.KeyTrie(_apolloUtilities.canUseWeakMap) : _c,
221 _d = _b.freezeResults,
222 freezeResults = _d === void 0 ? false : _d;
223
224 var _e = this,
225 executeStoreQuery = _e.executeStoreQuery,
226 executeSelectionSet = _e.executeSelectionSet,
227 executeSubSelectedArray = _e.executeSubSelectedArray;
228
229 this.freezeResults = freezeResults;
230 this.executeStoreQuery = (0, _optimism.wrap)(function (options) {
231 return executeStoreQuery.call(_this, options);
232 }, {
233 makeCacheKey: function (_a) {
234 var query = _a.query,
235 rootValue = _a.rootValue,
236 contextValue = _a.contextValue,
237 variableValues = _a.variableValues,
238 fragmentMatcher = _a.fragmentMatcher;
239
240 if (contextValue.store instanceof DepTrackingCache) {
241 return cacheKeyRoot.lookup(contextValue.store, query, fragmentMatcher, JSON.stringify(variableValues), rootValue.id);
242 }
243 }
244 });
245 this.executeSelectionSet = (0, _optimism.wrap)(function (options) {
246 return executeSelectionSet.call(_this, options);
247 }, {
248 makeCacheKey: function (_a) {
249 var selectionSet = _a.selectionSet,
250 rootValue = _a.rootValue,
251 execContext = _a.execContext;
252
253 if (execContext.contextValue.store instanceof DepTrackingCache) {
254 return cacheKeyRoot.lookup(execContext.contextValue.store, selectionSet, execContext.fragmentMatcher, JSON.stringify(execContext.variableValues), rootValue.id);
255 }
256 }
257 });
258 this.executeSubSelectedArray = (0, _optimism.wrap)(function (options) {
259 return executeSubSelectedArray.call(_this, options);
260 }, {
261 makeCacheKey: function (_a) {
262 var field = _a.field,
263 array = _a.array,
264 execContext = _a.execContext;
265
266 if (execContext.contextValue.store instanceof DepTrackingCache) {
267 return cacheKeyRoot.lookup(execContext.contextValue.store, field, array, JSON.stringify(execContext.variableValues));
268 }
269 }
270 });
271 }
272
273 StoreReader.prototype.readQueryFromStore = function (options) {
274 return this.diffQueryAgainstStore((0, _tslib.__assign)((0, _tslib.__assign)({}, options), {
275 returnPartialData: false
276 })).result;
277 };
278
279 StoreReader.prototype.diffQueryAgainstStore = function (_a) {
280 var store = _a.store,
281 query = _a.query,
282 variables = _a.variables,
283 previousResult = _a.previousResult,
284 _b = _a.returnPartialData,
285 returnPartialData = _b === void 0 ? true : _b,
286 _c = _a.rootId,
287 rootId = _c === void 0 ? 'ROOT_QUERY' : _c,
288 fragmentMatcherFunction = _a.fragmentMatcherFunction,
289 config = _a.config;
290 var queryDefinition = (0, _apolloUtilities.getQueryDefinition)(query);
291 variables = (0, _apolloUtilities.assign)({}, (0, _apolloUtilities.getDefaultValues)(queryDefinition), variables);
292 var context = {
293 store: store,
294 dataIdFromObject: config && config.dataIdFromObject,
295 cacheRedirects: config && config.cacheRedirects || {}
296 };
297 var execResult = this.executeStoreQuery({
298 query: query,
299 rootValue: {
300 type: 'id',
301 id: rootId,
302 generated: true,
303 typename: 'Query'
304 },
305 contextValue: context,
306 variableValues: variables,
307 fragmentMatcher: fragmentMatcherFunction
308 });
309 var hasMissingFields = execResult.missing && execResult.missing.length > 0;
310
311 if (hasMissingFields && !returnPartialData) {
312 execResult.missing.forEach(function (info) {
313 if (info.tolerable) return;
314 throw process.env.NODE_ENV === "production" ? new _tsInvariant.InvariantError(8) : new _tsInvariant.InvariantError("Can't find field " + info.fieldName + " on object " + JSON.stringify(info.object, null, 2) + ".");
315 });
316 }
317
318 if (previousResult) {
319 if ((0, _apolloUtilities.isEqual)(previousResult, execResult.result)) {
320 execResult.result = previousResult;
321 }
322 }
323
324 return {
325 result: execResult.result,
326 complete: !hasMissingFields
327 };
328 };
329
330 StoreReader.prototype.executeStoreQuery = function (_a) {
331 var query = _a.query,
332 rootValue = _a.rootValue,
333 contextValue = _a.contextValue,
334 variableValues = _a.variableValues,
335 _b = _a.fragmentMatcher,
336 fragmentMatcher = _b === void 0 ? defaultFragmentMatcher : _b;
337 var mainDefinition = (0, _apolloUtilities.getMainDefinition)(query);
338 var fragments = (0, _apolloUtilities.getFragmentDefinitions)(query);
339 var fragmentMap = (0, _apolloUtilities.createFragmentMap)(fragments);
340 var execContext = {
341 query: query,
342 fragmentMap: fragmentMap,
343 contextValue: contextValue,
344 variableValues: variableValues,
345 fragmentMatcher: fragmentMatcher
346 };
347 return this.executeSelectionSet({
348 selectionSet: mainDefinition.selectionSet,
349 rootValue: rootValue,
350 execContext: execContext
351 });
352 };
353
354 StoreReader.prototype.executeSelectionSet = function (_a) {
355 var _this = this;
356
357 var selectionSet = _a.selectionSet,
358 rootValue = _a.rootValue,
359 execContext = _a.execContext;
360 var fragmentMap = execContext.fragmentMap,
361 contextValue = execContext.contextValue,
362 variables = execContext.variableValues;
363 var finalResult = {
364 result: null
365 };
366 var objectsToMerge = [];
367 var object = contextValue.store.get(rootValue.id);
368 var typename = object && object.__typename || rootValue.id === 'ROOT_QUERY' && 'Query' || void 0;
369
370 function handleMissing(result) {
371 var _a;
372
373 if (result.missing) {
374 finalResult.missing = finalResult.missing || [];
375
376 (_a = finalResult.missing).push.apply(_a, result.missing);
377 }
378
379 return result.result;
380 }
381
382 selectionSet.selections.forEach(function (selection) {
383 var _a;
384
385 if (!(0, _apolloUtilities.shouldInclude)(selection, variables)) {
386 return;
387 }
388
389 if ((0, _apolloUtilities.isField)(selection)) {
390 var fieldResult = handleMissing(_this.executeField(object, typename, selection, execContext));
391
392 if (typeof fieldResult !== 'undefined') {
393 objectsToMerge.push((_a = {}, _a[(0, _apolloUtilities.resultKeyNameFromField)(selection)] = fieldResult, _a));
394 }
395 } else {
396 var fragment = void 0;
397
398 if ((0, _apolloUtilities.isInlineFragment)(selection)) {
399 fragment = selection;
400 } else {
401 fragment = fragmentMap[selection.name.value];
402
403 if (!fragment) {
404 throw process.env.NODE_ENV === "production" ? new _tsInvariant.InvariantError(9) : new _tsInvariant.InvariantError("No fragment named " + selection.name.value);
405 }
406 }
407
408 var typeCondition = fragment.typeCondition && fragment.typeCondition.name.value;
409 var match = !typeCondition || execContext.fragmentMatcher(rootValue, typeCondition, contextValue);
410
411 if (match) {
412 var fragmentExecResult = _this.executeSelectionSet({
413 selectionSet: fragment.selectionSet,
414 rootValue: rootValue,
415 execContext: execContext
416 });
417
418 if (match === 'heuristic' && fragmentExecResult.missing) {
419 fragmentExecResult = (0, _tslib.__assign)((0, _tslib.__assign)({}, fragmentExecResult), {
420 missing: fragmentExecResult.missing.map(function (info) {
421 return (0, _tslib.__assign)((0, _tslib.__assign)({}, info), {
422 tolerable: true
423 });
424 })
425 });
426 }
427
428 objectsToMerge.push(handleMissing(fragmentExecResult));
429 }
430 }
431 });
432 finalResult.result = (0, _apolloUtilities.mergeDeepArray)(objectsToMerge);
433
434 if (this.freezeResults && process.env.NODE_ENV !== 'production') {
435 Object.freeze(finalResult.result);
436 }
437
438 return finalResult;
439 };
440
441 StoreReader.prototype.executeField = function (object, typename, field, execContext) {
442 var variables = execContext.variableValues,
443 contextValue = execContext.contextValue;
444 var fieldName = field.name.value;
445 var args = (0, _apolloUtilities.argumentsObjectFromField)(field, variables);
446 var info = {
447 resultKey: (0, _apolloUtilities.resultKeyNameFromField)(field),
448 directives: (0, _apolloUtilities.getDirectiveInfoFromField)(field, variables)
449 };
450 var readStoreResult = readStoreResolver(object, typename, fieldName, args, contextValue, info);
451
452 if (Array.isArray(readStoreResult.result)) {
453 return this.combineExecResults(readStoreResult, this.executeSubSelectedArray({
454 field: field,
455 array: readStoreResult.result,
456 execContext: execContext
457 }));
458 }
459
460 if (!field.selectionSet) {
461 assertSelectionSetForIdValue(field, readStoreResult.result);
462
463 if (this.freezeResults && process.env.NODE_ENV !== 'production') {
464 (0, _apolloUtilities.maybeDeepFreeze)(readStoreResult);
465 }
466
467 return readStoreResult;
468 }
469
470 if (readStoreResult.result == null) {
471 return readStoreResult;
472 }
473
474 return this.combineExecResults(readStoreResult, this.executeSelectionSet({
475 selectionSet: field.selectionSet,
476 rootValue: readStoreResult.result,
477 execContext: execContext
478 }));
479 };
480
481 StoreReader.prototype.combineExecResults = function () {
482 var execResults = [];
483
484 for (var _i = 0; _i < arguments.length; _i++) {
485 execResults[_i] = arguments[_i];
486 }
487
488 var missing;
489 execResults.forEach(function (execResult) {
490 if (execResult.missing) {
491 missing = missing || [];
492 missing.push.apply(missing, execResult.missing);
493 }
494 });
495 return {
496 result: execResults.pop().result,
497 missing: missing
498 };
499 };
500
501 StoreReader.prototype.executeSubSelectedArray = function (_a) {
502 var _this = this;
503
504 var field = _a.field,
505 array = _a.array,
506 execContext = _a.execContext;
507 var missing;
508
509 function handleMissing(childResult) {
510 if (childResult.missing) {
511 missing = missing || [];
512 missing.push.apply(missing, childResult.missing);
513 }
514
515 return childResult.result;
516 }
517
518 array = array.map(function (item) {
519 if (item === null) {
520 return null;
521 }
522
523 if (Array.isArray(item)) {
524 return handleMissing(_this.executeSubSelectedArray({
525 field: field,
526 array: item,
527 execContext: execContext
528 }));
529 }
530
531 if (field.selectionSet) {
532 return handleMissing(_this.executeSelectionSet({
533 selectionSet: field.selectionSet,
534 rootValue: item,
535 execContext: execContext
536 }));
537 }
538
539 assertSelectionSetForIdValue(field, item);
540 return item;
541 });
542
543 if (this.freezeResults && process.env.NODE_ENV !== 'production') {
544 Object.freeze(array);
545 }
546
547 return {
548 result: array,
549 missing: missing
550 };
551 };
552
553 return StoreReader;
554 }();
555
556 _exports.StoreReader = StoreReader;
557
558 function assertSelectionSetForIdValue(field, value) {
559 if (!field.selectionSet && (0, _apolloUtilities.isIdValue)(value)) {
560 throw process.env.NODE_ENV === "production" ? new _tsInvariant.InvariantError(10) : new _tsInvariant.InvariantError("Missing selection set for object of type " + value.typename + " returned for query field " + field.name.value);
561 }
562 }
563
564 function defaultFragmentMatcher() {
565 return true;
566 }
567
568 function assertIdValue(idValue) {
569 process.env.NODE_ENV === "production" ? (0, _tsInvariant.invariant)((0, _apolloUtilities.isIdValue)(idValue), 11) : (0, _tsInvariant.invariant)((0, _apolloUtilities.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.");
570 }
571
572 function readStoreResolver(object, typename, fieldName, args, context, _a) {
573 var resultKey = _a.resultKey,
574 directives = _a.directives;
575 var storeKeyName = fieldName;
576
577 if (args || directives) {
578 storeKeyName = (0, _apolloUtilities.getStoreKeyName)(storeKeyName, args, directives);
579 }
580
581 var fieldValue = void 0;
582
583 if (object) {
584 fieldValue = object[storeKeyName];
585
586 if (typeof fieldValue === 'undefined' && context.cacheRedirects && typeof typename === 'string') {
587 var type = context.cacheRedirects[typename];
588
589 if (type) {
590 var resolver = type[fieldName];
591
592 if (resolver) {
593 fieldValue = resolver(object, args, {
594 getCacheKey: function (storeObj) {
595 var id = context.dataIdFromObject(storeObj);
596 return id && (0, _apolloUtilities.toIdValue)({
597 id: id,
598 typename: storeObj.__typename
599 });
600 }
601 });
602 }
603 }
604 }
605 }
606
607 if (typeof fieldValue === 'undefined') {
608 return {
609 result: fieldValue,
610 missing: [{
611 object: object,
612 fieldName: storeKeyName,
613 tolerable: false
614 }]
615 };
616 }
617
618 if ((0, _apolloUtilities.isJsonValue)(fieldValue)) {
619 fieldValue = fieldValue.json;
620 }
621
622 return {
623 result: fieldValue
624 };
625 }
626
627 var ObjectCache = function () {
628 function ObjectCache(data) {
629 if (data === void 0) {
630 data = Object.create(null);
631 }
632
633 this.data = data;
634 }
635
636 ObjectCache.prototype.toObject = function () {
637 return this.data;
638 };
639
640 ObjectCache.prototype.get = function (dataId) {
641 return this.data[dataId];
642 };
643
644 ObjectCache.prototype.set = function (dataId, value) {
645 this.data[dataId] = value;
646 };
647
648 ObjectCache.prototype.delete = function (dataId) {
649 this.data[dataId] = void 0;
650 };
651
652 ObjectCache.prototype.clear = function () {
653 this.data = Object.create(null);
654 };
655
656 ObjectCache.prototype.replace = function (newData) {
657 this.data = newData || Object.create(null);
658 };
659
660 return ObjectCache;
661 }();
662
663 _exports.ObjectCache = ObjectCache;
664
665 function defaultNormalizedCacheFactory$1(seed) {
666 return new ObjectCache(seed);
667 }
668
669 var WriteError = function (_super) {
670 (0, _tslib.__extends)(WriteError, _super);
671
672 function WriteError() {
673 var _this = _super !== null && _super.apply(this, arguments) || this;
674
675 _this.type = 'WriteError';
676 return _this;
677 }
678
679 return WriteError;
680 }(Error);
681
682 _exports.WriteError = WriteError;
683
684 function enhanceErrorWithDocument(error, document) {
685 var enhancedError = new WriteError("Error writing result to store for query:\n " + JSON.stringify(document));
686 enhancedError.message += '\n' + error.message;
687 enhancedError.stack = error.stack;
688 return enhancedError;
689 }
690
691 var StoreWriter = function () {
692 function StoreWriter() {}
693
694 StoreWriter.prototype.writeQueryToStore = function (_a) {
695 var query = _a.query,
696 result = _a.result,
697 _b = _a.store,
698 store = _b === void 0 ? defaultNormalizedCacheFactory() : _b,
699 variables = _a.variables,
700 dataIdFromObject = _a.dataIdFromObject,
701 fragmentMatcherFunction = _a.fragmentMatcherFunction;
702 return this.writeResultToStore({
703 dataId: 'ROOT_QUERY',
704 result: result,
705 document: query,
706 store: store,
707 variables: variables,
708 dataIdFromObject: dataIdFromObject,
709 fragmentMatcherFunction: fragmentMatcherFunction
710 });
711 };
712
713 StoreWriter.prototype.writeResultToStore = function (_a) {
714 var dataId = _a.dataId,
715 result = _a.result,
716 document = _a.document,
717 _b = _a.store,
718 store = _b === void 0 ? defaultNormalizedCacheFactory() : _b,
719 variables = _a.variables,
720 dataIdFromObject = _a.dataIdFromObject,
721 fragmentMatcherFunction = _a.fragmentMatcherFunction;
722 var operationDefinition = (0, _apolloUtilities.getOperationDefinition)(document);
723
724 try {
725 return this.writeSelectionSetToStore({
726 result: result,
727 dataId: dataId,
728 selectionSet: operationDefinition.selectionSet,
729 context: {
730 store: store,
731 processedData: {},
732 variables: (0, _apolloUtilities.assign)({}, (0, _apolloUtilities.getDefaultValues)(operationDefinition), variables),
733 dataIdFromObject: dataIdFromObject,
734 fragmentMap: (0, _apolloUtilities.createFragmentMap)((0, _apolloUtilities.getFragmentDefinitions)(document)),
735 fragmentMatcherFunction: fragmentMatcherFunction
736 }
737 });
738 } catch (e) {
739 throw enhanceErrorWithDocument(e, document);
740 }
741 };
742
743 StoreWriter.prototype.writeSelectionSetToStore = function (_a) {
744 var _this = this;
745
746 var result = _a.result,
747 dataId = _a.dataId,
748 selectionSet = _a.selectionSet,
749 context = _a.context;
750 var variables = context.variables,
751 store = context.store,
752 fragmentMap = context.fragmentMap;
753 selectionSet.selections.forEach(function (selection) {
754 var _a;
755
756 if (!(0, _apolloUtilities.shouldInclude)(selection, variables)) {
757 return;
758 }
759
760 if ((0, _apolloUtilities.isField)(selection)) {
761 var resultFieldKey = (0, _apolloUtilities.resultKeyNameFromField)(selection);
762 var value = result[resultFieldKey];
763
764 if (typeof value !== 'undefined') {
765 _this.writeFieldToStore({
766 dataId: dataId,
767 value: value,
768 field: selection,
769 context: context
770 });
771 } else {
772 var isDefered = false;
773 var isClient = false;
774
775 if (selection.directives && selection.directives.length) {
776 isDefered = selection.directives.some(function (directive) {
777 return directive.name && directive.name.value === 'defer';
778 });
779 isClient = selection.directives.some(function (directive) {
780 return directive.name && directive.name.value === 'client';
781 });
782 }
783
784 if (!isDefered && !isClient && context.fragmentMatcherFunction) {
785 process.env.NODE_ENV === "production" || _tsInvariant.invariant.warn("Missing field " + resultFieldKey + " in " + JSON.stringify(result, null, 2).substring(0, 100));
786 }
787 }
788 } else {
789 var fragment = void 0;
790
791 if ((0, _apolloUtilities.isInlineFragment)(selection)) {
792 fragment = selection;
793 } else {
794 fragment = (fragmentMap || {})[selection.name.value];
795 process.env.NODE_ENV === "production" ? (0, _tsInvariant.invariant)(fragment, 3) : (0, _tsInvariant.invariant)(fragment, "No fragment named " + selection.name.value + ".");
796 }
797
798 var matches = true;
799
800 if (context.fragmentMatcherFunction && fragment.typeCondition) {
801 var id = dataId || 'self';
802 var idValue = (0, _apolloUtilities.toIdValue)({
803 id: id,
804 typename: undefined
805 });
806 var fakeContext = {
807 store: new ObjectCache((_a = {}, _a[id] = result, _a)),
808 cacheRedirects: {}
809 };
810 var match = context.fragmentMatcherFunction(idValue, fragment.typeCondition.name.value, fakeContext);
811
812 if (!(0, _apolloUtilities.isProduction)() && match === 'heuristic') {
813 process.env.NODE_ENV === "production" || _tsInvariant.invariant.error('WARNING: heuristic fragment matching going on!');
814 }
815
816 matches = !!match;
817 }
818
819 if (matches) {
820 _this.writeSelectionSetToStore({
821 result: result,
822 selectionSet: fragment.selectionSet,
823 dataId: dataId,
824 context: context
825 });
826 }
827 }
828 });
829 return store;
830 };
831
832 StoreWriter.prototype.writeFieldToStore = function (_a) {
833 var _b;
834
835 var field = _a.field,
836 value = _a.value,
837 dataId = _a.dataId,
838 context = _a.context;
839 var variables = context.variables,
840 dataIdFromObject = context.dataIdFromObject,
841 store = context.store;
842 var storeValue;
843 var storeObject;
844 var storeFieldName = (0, _apolloUtilities.storeKeyNameFromField)(field, variables);
845
846 if (!field.selectionSet || value === null) {
847 storeValue = value != null && typeof value === 'object' ? {
848 type: 'json',
849 json: value
850 } : value;
851 } else if (Array.isArray(value)) {
852 var generatedId = dataId + "." + storeFieldName;
853 storeValue = this.processArrayValue(value, generatedId, field.selectionSet, context);
854 } else {
855 var valueDataId = dataId + "." + storeFieldName;
856 var generated = true;
857
858 if (!isGeneratedId(valueDataId)) {
859 valueDataId = '$' + valueDataId;
860 }
861
862 if (dataIdFromObject) {
863 var semanticId = dataIdFromObject(value);
864 process.env.NODE_ENV === "production" ? (0, _tsInvariant.invariant)(!semanticId || !isGeneratedId(semanticId), 4) : (0, _tsInvariant.invariant)(!semanticId || !isGeneratedId(semanticId), 'IDs returned by dataIdFromObject cannot begin with the "$" character.');
865
866 if (semanticId || typeof semanticId === 'number' && semanticId === 0) {
867 valueDataId = semanticId;
868 generated = false;
869 }
870 }
871
872 if (!isDataProcessed(valueDataId, field, context.processedData)) {
873 this.writeSelectionSetToStore({
874 dataId: valueDataId,
875 result: value,
876 selectionSet: field.selectionSet,
877 context: context
878 });
879 }
880
881 var typename = value.__typename;
882 storeValue = (0, _apolloUtilities.toIdValue)({
883 id: valueDataId,
884 typename: typename
885 }, generated);
886 storeObject = store.get(dataId);
887 var escapedId = storeObject && storeObject[storeFieldName];
888
889 if (escapedId !== storeValue && (0, _apolloUtilities.isIdValue)(escapedId)) {
890 var hadTypename = escapedId.typename !== undefined;
891 var hasTypename = typename !== undefined;
892 var typenameChanged = hadTypename && hasTypename && escapedId.typename !== typename;
893 process.env.NODE_ENV === "production" ? (0, _tsInvariant.invariant)(!generated || escapedId.generated || typenameChanged, 5) : (0, _tsInvariant.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));
894 process.env.NODE_ENV === "production" ? (0, _tsInvariant.invariant)(!hadTypename || hasTypename, 6) : (0, _tsInvariant.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));
895
896 if (escapedId.generated) {
897 if (typenameChanged) {
898 if (!generated) {
899 store.delete(escapedId.id);
900 }
901 } else {
902 mergeWithGenerated(escapedId.id, storeValue.id, store);
903 }
904 }
905 }
906 }
907
908 storeObject = store.get(dataId);
909
910 if (!storeObject || !(0, _apolloUtilities.isEqual)(storeValue, storeObject[storeFieldName])) {
911 store.set(dataId, (0, _tslib.__assign)((0, _tslib.__assign)({}, storeObject), (_b = {}, _b[storeFieldName] = storeValue, _b)));
912 }
913 };
914
915 StoreWriter.prototype.processArrayValue = function (value, generatedId, selectionSet, context) {
916 var _this = this;
917
918 return value.map(function (item, index) {
919 if (item === null) {
920 return null;
921 }
922
923 var itemDataId = generatedId + "." + index;
924
925 if (Array.isArray(item)) {
926 return _this.processArrayValue(item, itemDataId, selectionSet, context);
927 }
928
929 var generated = true;
930
931 if (context.dataIdFromObject) {
932 var semanticId = context.dataIdFromObject(item);
933
934 if (semanticId) {
935 itemDataId = semanticId;
936 generated = false;
937 }
938 }
939
940 if (!isDataProcessed(itemDataId, selectionSet, context.processedData)) {
941 _this.writeSelectionSetToStore({
942 dataId: itemDataId,
943 result: item,
944 selectionSet: selectionSet,
945 context: context
946 });
947 }
948
949 return (0, _apolloUtilities.toIdValue)({
950 id: itemDataId,
951 typename: item.__typename
952 }, generated);
953 });
954 };
955
956 return StoreWriter;
957 }();
958
959 _exports.StoreWriter = StoreWriter;
960
961 function isGeneratedId(id) {
962 return id[0] === '$';
963 }
964
965 function mergeWithGenerated(generatedKey, realKey, cache) {
966 if (generatedKey === realKey) {
967 return false;
968 }
969
970 var generated = cache.get(generatedKey);
971 var real = cache.get(realKey);
972 var madeChanges = false;
973 Object.keys(generated).forEach(function (key) {
974 var value = generated[key];
975 var realValue = real[key];
976
977 if ((0, _apolloUtilities.isIdValue)(value) && isGeneratedId(value.id) && (0, _apolloUtilities.isIdValue)(realValue) && !(0, _apolloUtilities.isEqual)(value, realValue) && mergeWithGenerated(value.id, realValue.id, cache)) {
978 madeChanges = true;
979 }
980 });
981 cache.delete(generatedKey);
982 var newRealValue = (0, _tslib.__assign)((0, _tslib.__assign)({}, generated), real);
983
984 if ((0, _apolloUtilities.isEqual)(newRealValue, real)) {
985 return madeChanges;
986 }
987
988 cache.set(realKey, newRealValue);
989 return true;
990 }
991
992 function isDataProcessed(dataId, field, processedData) {
993 if (!processedData) {
994 return false;
995 }
996
997 if (processedData[dataId]) {
998 if (processedData[dataId].indexOf(field) >= 0) {
999 return true;
1000 } else {
1001 processedData[dataId].push(field);
1002 }
1003 } else {
1004 processedData[dataId] = [field];
1005 }
1006
1007 return false;
1008 }
1009
1010 var defaultConfig = {
1011 fragmentMatcher: new HeuristicFragmentMatcher(),
1012 dataIdFromObject: defaultDataIdFromObject,
1013 addTypename: true,
1014 resultCaching: true,
1015 freezeResults: false
1016 };
1017
1018 function defaultDataIdFromObject(result) {
1019 if (result.__typename) {
1020 if (result.id !== undefined) {
1021 return result.__typename + ":" + result.id;
1022 }
1023
1024 if (result._id !== undefined) {
1025 return result.__typename + ":" + result._id;
1026 }
1027 }
1028
1029 return null;
1030 }
1031
1032 var hasOwn$1 = Object.prototype.hasOwnProperty;
1033
1034 var OptimisticCacheLayer = function (_super) {
1035 (0, _tslib.__extends)(OptimisticCacheLayer, _super);
1036
1037 function OptimisticCacheLayer(optimisticId, parent, transaction) {
1038 var _this = _super.call(this, Object.create(null)) || this;
1039
1040 _this.optimisticId = optimisticId;
1041 _this.parent = parent;
1042 _this.transaction = transaction;
1043 return _this;
1044 }
1045
1046 OptimisticCacheLayer.prototype.toObject = function () {
1047 return (0, _tslib.__assign)((0, _tslib.__assign)({}, this.parent.toObject()), this.data);
1048 };
1049
1050 OptimisticCacheLayer.prototype.get = function (dataId) {
1051 return hasOwn$1.call(this.data, dataId) ? this.data[dataId] : this.parent.get(dataId);
1052 };
1053
1054 return OptimisticCacheLayer;
1055 }(ObjectCache);
1056
1057 var InMemoryCache = function (_super) {
1058 (0, _tslib.__extends)(InMemoryCache, _super);
1059
1060 function InMemoryCache(config) {
1061 if (config === void 0) {
1062 config = {};
1063 }
1064
1065 var _this = _super.call(this) || this;
1066
1067 _this.watches = new Set();
1068 _this.typenameDocumentCache = new Map();
1069 _this.cacheKeyRoot = new _optimism.KeyTrie(_apolloUtilities.canUseWeakMap);
1070 _this.silenceBroadcast = false;
1071 _this.config = (0, _tslib.__assign)((0, _tslib.__assign)({}, defaultConfig), config);
1072
1073 if (_this.config.customResolvers) {
1074 process.env.NODE_ENV === "production" || _tsInvariant.invariant.warn('customResolvers have been renamed to cacheRedirects. Please update your config as we will be deprecating customResolvers in the next major version.');
1075 _this.config.cacheRedirects = _this.config.customResolvers;
1076 }
1077
1078 if (_this.config.cacheResolvers) {
1079 process.env.NODE_ENV === "production" || _tsInvariant.invariant.warn('cacheResolvers have been renamed to cacheRedirects. Please update your config as we will be deprecating cacheResolvers in the next major version.');
1080 _this.config.cacheRedirects = _this.config.cacheResolvers;
1081 }
1082
1083 _this.addTypename = !!_this.config.addTypename;
1084 _this.data = _this.config.resultCaching ? new DepTrackingCache() : new ObjectCache();
1085 _this.optimisticData = _this.data;
1086 _this.storeWriter = new StoreWriter();
1087 _this.storeReader = new StoreReader({
1088 cacheKeyRoot: _this.cacheKeyRoot,
1089 freezeResults: config.freezeResults
1090 });
1091 var cache = _this;
1092 var maybeBroadcastWatch = cache.maybeBroadcastWatch;
1093 _this.maybeBroadcastWatch = (0, _optimism.wrap)(function (c) {
1094 return maybeBroadcastWatch.call(_this, c);
1095 }, {
1096 makeCacheKey: function (c) {
1097 if (c.optimistic) {
1098 return;
1099 }
1100
1101 if (c.previousResult) {
1102 return;
1103 }
1104
1105 if (cache.data instanceof DepTrackingCache) {
1106 return cache.cacheKeyRoot.lookup(c.query, JSON.stringify(c.variables));
1107 }
1108 }
1109 });
1110 return _this;
1111 }
1112
1113 InMemoryCache.prototype.restore = function (data) {
1114 if (data) this.data.replace(data);
1115 return this;
1116 };
1117
1118 InMemoryCache.prototype.extract = function (optimistic) {
1119 if (optimistic === void 0) {
1120 optimistic = false;
1121 }
1122
1123 return (optimistic ? this.optimisticData : this.data).toObject();
1124 };
1125
1126 InMemoryCache.prototype.read = function (options) {
1127 if (typeof options.rootId === 'string' && typeof this.data.get(options.rootId) === 'undefined') {
1128 return null;
1129 }
1130
1131 var fragmentMatcher = this.config.fragmentMatcher;
1132 var fragmentMatcherFunction = fragmentMatcher && fragmentMatcher.match;
1133 return this.storeReader.readQueryFromStore({
1134 store: options.optimistic ? this.optimisticData : this.data,
1135 query: this.transformDocument(options.query),
1136 variables: options.variables,
1137 rootId: options.rootId,
1138 fragmentMatcherFunction: fragmentMatcherFunction,
1139 previousResult: options.previousResult,
1140 config: this.config
1141 }) || null;
1142 };
1143
1144 InMemoryCache.prototype.write = function (write) {
1145 var fragmentMatcher = this.config.fragmentMatcher;
1146 var fragmentMatcherFunction = fragmentMatcher && fragmentMatcher.match;
1147 this.storeWriter.writeResultToStore({
1148 dataId: write.dataId,
1149 result: write.result,
1150 variables: write.variables,
1151 document: this.transformDocument(write.query),
1152 store: this.data,
1153 dataIdFromObject: this.config.dataIdFromObject,
1154 fragmentMatcherFunction: fragmentMatcherFunction
1155 });
1156 this.broadcastWatches();
1157 };
1158
1159 InMemoryCache.prototype.diff = function (query) {
1160 var fragmentMatcher = this.config.fragmentMatcher;
1161 var fragmentMatcherFunction = fragmentMatcher && fragmentMatcher.match;
1162 return this.storeReader.diffQueryAgainstStore({
1163 store: query.optimistic ? this.optimisticData : this.data,
1164 query: this.transformDocument(query.query),
1165 variables: query.variables,
1166 returnPartialData: query.returnPartialData,
1167 previousResult: query.previousResult,
1168 fragmentMatcherFunction: fragmentMatcherFunction,
1169 config: this.config
1170 });
1171 };
1172
1173 InMemoryCache.prototype.watch = function (watch) {
1174 var _this = this;
1175
1176 this.watches.add(watch);
1177 return function () {
1178 _this.watches.delete(watch);
1179 };
1180 };
1181
1182 InMemoryCache.prototype.evict = function (query) {
1183 throw process.env.NODE_ENV === "production" ? new _tsInvariant.InvariantError(7) : new _tsInvariant.InvariantError("eviction is not implemented on InMemory Cache");
1184 };
1185
1186 InMemoryCache.prototype.reset = function () {
1187 this.data.clear();
1188 this.broadcastWatches();
1189 return Promise.resolve();
1190 };
1191
1192 InMemoryCache.prototype.removeOptimistic = function (idToRemove) {
1193 var toReapply = [];
1194 var removedCount = 0;
1195 var layer = this.optimisticData;
1196
1197 while (layer instanceof OptimisticCacheLayer) {
1198 if (layer.optimisticId === idToRemove) {
1199 ++removedCount;
1200 } else {
1201 toReapply.push(layer);
1202 }
1203
1204 layer = layer.parent;
1205 }
1206
1207 if (removedCount > 0) {
1208 this.optimisticData = layer;
1209
1210 while (toReapply.length > 0) {
1211 var layer_1 = toReapply.pop();
1212 this.performTransaction(layer_1.transaction, layer_1.optimisticId);
1213 }
1214
1215 this.broadcastWatches();
1216 }
1217 };
1218
1219 InMemoryCache.prototype.performTransaction = function (transaction, optimisticId) {
1220 var _a = this,
1221 data = _a.data,
1222 silenceBroadcast = _a.silenceBroadcast;
1223
1224 this.silenceBroadcast = true;
1225
1226 if (typeof optimisticId === 'string') {
1227 this.data = this.optimisticData = new OptimisticCacheLayer(optimisticId, this.optimisticData, transaction);
1228 }
1229
1230 try {
1231 transaction(this);
1232 } finally {
1233 this.silenceBroadcast = silenceBroadcast;
1234 this.data = data;
1235 }
1236
1237 this.broadcastWatches();
1238 };
1239
1240 InMemoryCache.prototype.recordOptimisticTransaction = function (transaction, id) {
1241 return this.performTransaction(transaction, id);
1242 };
1243
1244 InMemoryCache.prototype.transformDocument = function (document) {
1245 if (this.addTypename) {
1246 var result = this.typenameDocumentCache.get(document);
1247
1248 if (!result) {
1249 result = (0, _apolloUtilities.addTypenameToDocument)(document);
1250 this.typenameDocumentCache.set(document, result);
1251 this.typenameDocumentCache.set(result, result);
1252 }
1253
1254 return result;
1255 }
1256
1257 return document;
1258 };
1259
1260 InMemoryCache.prototype.broadcastWatches = function () {
1261 var _this = this;
1262
1263 if (!this.silenceBroadcast) {
1264 this.watches.forEach(function (c) {
1265 return _this.maybeBroadcastWatch(c);
1266 });
1267 }
1268 };
1269
1270 InMemoryCache.prototype.maybeBroadcastWatch = function (c) {
1271 c.callback(this.diff({
1272 query: c.query,
1273 variables: c.variables,
1274 previousResult: c.previousResult && c.previousResult(),
1275 optimistic: c.optimistic
1276 }));
1277 };
1278
1279 return InMemoryCache;
1280 }(_apolloCache.ApolloCache);
1281
1282
1283 _exports.InMemoryCache = InMemoryCache;
1284});