UNPKG

14.8 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var tslib_1 = require("tslib");
4var apollo_utilities_1 = require("apollo-utilities");
5var optimism_1 = require("optimism");
6var depTrackingCache_1 = require("./depTrackingCache");
7var ts_invariant_1 = require("ts-invariant");
8var StoreReader = (function () {
9 function StoreReader(_a) {
10 var _this = this;
11 var _b = _a === void 0 ? {} : _a, _c = _b.cacheKeyRoot, cacheKeyRoot = _c === void 0 ? new optimism_1.KeyTrie(apollo_utilities_1.canUseWeakMap) : _c, _d = _b.freezeResults, freezeResults = _d === void 0 ? false : _d;
12 var _e = this, executeStoreQuery = _e.executeStoreQuery, executeSelectionSet = _e.executeSelectionSet, executeSubSelectedArray = _e.executeSubSelectedArray;
13 this.freezeResults = freezeResults;
14 this.executeStoreQuery = optimism_1.wrap(function (options) {
15 return executeStoreQuery.call(_this, options);
16 }, {
17 makeCacheKey: function (_a) {
18 var query = _a.query, rootValue = _a.rootValue, contextValue = _a.contextValue, variableValues = _a.variableValues, fragmentMatcher = _a.fragmentMatcher;
19 if (contextValue.store instanceof depTrackingCache_1.DepTrackingCache) {
20 return cacheKeyRoot.lookup(contextValue.store, query, fragmentMatcher, JSON.stringify(variableValues), rootValue.id);
21 }
22 }
23 });
24 this.executeSelectionSet = optimism_1.wrap(function (options) {
25 return executeSelectionSet.call(_this, options);
26 }, {
27 makeCacheKey: function (_a) {
28 var selectionSet = _a.selectionSet, rootValue = _a.rootValue, execContext = _a.execContext;
29 if (execContext.contextValue.store instanceof depTrackingCache_1.DepTrackingCache) {
30 return cacheKeyRoot.lookup(execContext.contextValue.store, selectionSet, execContext.fragmentMatcher, JSON.stringify(execContext.variableValues), rootValue.id);
31 }
32 }
33 });
34 this.executeSubSelectedArray = optimism_1.wrap(function (options) {
35 return executeSubSelectedArray.call(_this, options);
36 }, {
37 makeCacheKey: function (_a) {
38 var field = _a.field, array = _a.array, execContext = _a.execContext;
39 if (execContext.contextValue.store instanceof depTrackingCache_1.DepTrackingCache) {
40 return cacheKeyRoot.lookup(execContext.contextValue.store, field, array, JSON.stringify(execContext.variableValues));
41 }
42 }
43 });
44 }
45 StoreReader.prototype.readQueryFromStore = function (options) {
46 return this.diffQueryAgainstStore(tslib_1.__assign(tslib_1.__assign({}, options), { returnPartialData: false })).result;
47 };
48 StoreReader.prototype.diffQueryAgainstStore = function (_a) {
49 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;
50 var queryDefinition = apollo_utilities_1.getQueryDefinition(query);
51 variables = apollo_utilities_1.assign({}, apollo_utilities_1.getDefaultValues(queryDefinition), variables);
52 var context = {
53 store: store,
54 dataIdFromObject: config && config.dataIdFromObject,
55 cacheRedirects: (config && config.cacheRedirects) || {},
56 };
57 var execResult = this.executeStoreQuery({
58 query: query,
59 rootValue: {
60 type: 'id',
61 id: rootId,
62 generated: true,
63 typename: 'Query',
64 },
65 contextValue: context,
66 variableValues: variables,
67 fragmentMatcher: fragmentMatcherFunction,
68 });
69 var hasMissingFields = execResult.missing && execResult.missing.length > 0;
70 if (hasMissingFields && !returnPartialData) {
71 execResult.missing.forEach(function (info) {
72 if (info.tolerable)
73 return;
74 throw new ts_invariant_1.InvariantError("Can't find field " + info.fieldName + " on object " + JSON.stringify(info.object, null, 2) + ".");
75 });
76 }
77 if (previousResult) {
78 if (apollo_utilities_1.isEqual(previousResult, execResult.result)) {
79 execResult.result = previousResult;
80 }
81 }
82 return {
83 result: execResult.result,
84 complete: !hasMissingFields,
85 };
86 };
87 StoreReader.prototype.executeStoreQuery = function (_a) {
88 var query = _a.query, rootValue = _a.rootValue, contextValue = _a.contextValue, variableValues = _a.variableValues, _b = _a.fragmentMatcher, fragmentMatcher = _b === void 0 ? defaultFragmentMatcher : _b;
89 var mainDefinition = apollo_utilities_1.getMainDefinition(query);
90 var fragments = apollo_utilities_1.getFragmentDefinitions(query);
91 var fragmentMap = apollo_utilities_1.createFragmentMap(fragments);
92 var execContext = {
93 query: query,
94 fragmentMap: fragmentMap,
95 contextValue: contextValue,
96 variableValues: variableValues,
97 fragmentMatcher: fragmentMatcher,
98 };
99 return this.executeSelectionSet({
100 selectionSet: mainDefinition.selectionSet,
101 rootValue: rootValue,
102 execContext: execContext,
103 });
104 };
105 StoreReader.prototype.executeSelectionSet = function (_a) {
106 var _this = this;
107 var selectionSet = _a.selectionSet, rootValue = _a.rootValue, execContext = _a.execContext;
108 var fragmentMap = execContext.fragmentMap, contextValue = execContext.contextValue, variables = execContext.variableValues;
109 var finalResult = { result: null };
110 var objectsToMerge = [];
111 var object = contextValue.store.get(rootValue.id);
112 var typename = (object && object.__typename) ||
113 (rootValue.id === 'ROOT_QUERY' && 'Query') ||
114 void 0;
115 function handleMissing(result) {
116 var _a;
117 if (result.missing) {
118 finalResult.missing = finalResult.missing || [];
119 (_a = finalResult.missing).push.apply(_a, result.missing);
120 }
121 return result.result;
122 }
123 selectionSet.selections.forEach(function (selection) {
124 var _a;
125 if (!apollo_utilities_1.shouldInclude(selection, variables)) {
126 return;
127 }
128 if (apollo_utilities_1.isField(selection)) {
129 var fieldResult = handleMissing(_this.executeField(object, typename, selection, execContext));
130 if (typeof fieldResult !== 'undefined') {
131 objectsToMerge.push((_a = {},
132 _a[apollo_utilities_1.resultKeyNameFromField(selection)] = fieldResult,
133 _a));
134 }
135 }
136 else {
137 var fragment = void 0;
138 if (apollo_utilities_1.isInlineFragment(selection)) {
139 fragment = selection;
140 }
141 else {
142 fragment = fragmentMap[selection.name.value];
143 if (!fragment) {
144 throw new ts_invariant_1.InvariantError("No fragment named " + selection.name.value);
145 }
146 }
147 var typeCondition = fragment.typeCondition && fragment.typeCondition.name.value;
148 var match = !typeCondition ||
149 execContext.fragmentMatcher(rootValue, typeCondition, contextValue);
150 if (match) {
151 var fragmentExecResult = _this.executeSelectionSet({
152 selectionSet: fragment.selectionSet,
153 rootValue: rootValue,
154 execContext: execContext,
155 });
156 if (match === 'heuristic' && fragmentExecResult.missing) {
157 fragmentExecResult = tslib_1.__assign(tslib_1.__assign({}, fragmentExecResult), { missing: fragmentExecResult.missing.map(function (info) {
158 return tslib_1.__assign(tslib_1.__assign({}, info), { tolerable: true });
159 }) });
160 }
161 objectsToMerge.push(handleMissing(fragmentExecResult));
162 }
163 }
164 });
165 finalResult.result = apollo_utilities_1.mergeDeepArray(objectsToMerge);
166 if (this.freezeResults && process.env.NODE_ENV !== 'production') {
167 Object.freeze(finalResult.result);
168 }
169 return finalResult;
170 };
171 StoreReader.prototype.executeField = function (object, typename, field, execContext) {
172 var variables = execContext.variableValues, contextValue = execContext.contextValue;
173 var fieldName = field.name.value;
174 var args = apollo_utilities_1.argumentsObjectFromField(field, variables);
175 var info = {
176 resultKey: apollo_utilities_1.resultKeyNameFromField(field),
177 directives: apollo_utilities_1.getDirectiveInfoFromField(field, variables),
178 };
179 var readStoreResult = readStoreResolver(object, typename, fieldName, args, contextValue, info);
180 if (Array.isArray(readStoreResult.result)) {
181 return this.combineExecResults(readStoreResult, this.executeSubSelectedArray({
182 field: field,
183 array: readStoreResult.result,
184 execContext: execContext,
185 }));
186 }
187 if (!field.selectionSet) {
188 assertSelectionSetForIdValue(field, readStoreResult.result);
189 if (this.freezeResults && process.env.NODE_ENV !== 'production') {
190 apollo_utilities_1.maybeDeepFreeze(readStoreResult);
191 }
192 return readStoreResult;
193 }
194 if (readStoreResult.result == null) {
195 return readStoreResult;
196 }
197 return this.combineExecResults(readStoreResult, this.executeSelectionSet({
198 selectionSet: field.selectionSet,
199 rootValue: readStoreResult.result,
200 execContext: execContext,
201 }));
202 };
203 StoreReader.prototype.combineExecResults = function () {
204 var execResults = [];
205 for (var _i = 0; _i < arguments.length; _i++) {
206 execResults[_i] = arguments[_i];
207 }
208 var missing;
209 execResults.forEach(function (execResult) {
210 if (execResult.missing) {
211 missing = missing || [];
212 missing.push.apply(missing, execResult.missing);
213 }
214 });
215 return {
216 result: execResults.pop().result,
217 missing: missing,
218 };
219 };
220 StoreReader.prototype.executeSubSelectedArray = function (_a) {
221 var _this = this;
222 var field = _a.field, array = _a.array, execContext = _a.execContext;
223 var missing;
224 function handleMissing(childResult) {
225 if (childResult.missing) {
226 missing = missing || [];
227 missing.push.apply(missing, childResult.missing);
228 }
229 return childResult.result;
230 }
231 array = array.map(function (item) {
232 if (item === null) {
233 return null;
234 }
235 if (Array.isArray(item)) {
236 return handleMissing(_this.executeSubSelectedArray({
237 field: field,
238 array: item,
239 execContext: execContext,
240 }));
241 }
242 if (field.selectionSet) {
243 return handleMissing(_this.executeSelectionSet({
244 selectionSet: field.selectionSet,
245 rootValue: item,
246 execContext: execContext,
247 }));
248 }
249 assertSelectionSetForIdValue(field, item);
250 return item;
251 });
252 if (this.freezeResults && process.env.NODE_ENV !== 'production') {
253 Object.freeze(array);
254 }
255 return { result: array, missing: missing };
256 };
257 return StoreReader;
258}());
259exports.StoreReader = StoreReader;
260function assertSelectionSetForIdValue(field, value) {
261 if (!field.selectionSet && apollo_utilities_1.isIdValue(value)) {
262 throw new ts_invariant_1.InvariantError("Missing selection set for object of type " + value.typename + " returned for query field " + field.name.value);
263 }
264}
265function defaultFragmentMatcher() {
266 return true;
267}
268function assertIdValue(idValue) {
269 ts_invariant_1.invariant(apollo_utilities_1.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.");
270}
271exports.assertIdValue = assertIdValue;
272function readStoreResolver(object, typename, fieldName, args, context, _a) {
273 var resultKey = _a.resultKey, directives = _a.directives;
274 var storeKeyName = fieldName;
275 if (args || directives) {
276 storeKeyName = apollo_utilities_1.getStoreKeyName(storeKeyName, args, directives);
277 }
278 var fieldValue = void 0;
279 if (object) {
280 fieldValue = object[storeKeyName];
281 if (typeof fieldValue === 'undefined' &&
282 context.cacheRedirects &&
283 typeof typename === 'string') {
284 var type = context.cacheRedirects[typename];
285 if (type) {
286 var resolver = type[fieldName];
287 if (resolver) {
288 fieldValue = resolver(object, args, {
289 getCacheKey: function (storeObj) {
290 var id = context.dataIdFromObject(storeObj);
291 return id && apollo_utilities_1.toIdValue({
292 id: id,
293 typename: storeObj.__typename,
294 });
295 },
296 });
297 }
298 }
299 }
300 }
301 if (typeof fieldValue === 'undefined') {
302 return {
303 result: fieldValue,
304 missing: [{
305 object: object,
306 fieldName: storeKeyName,
307 tolerable: false,
308 }],
309 };
310 }
311 if (apollo_utilities_1.isJsonValue(fieldValue)) {
312 fieldValue = fieldValue.json;
313 }
314 return {
315 result: fieldValue,
316 };
317}
318//# sourceMappingURL=readFromStore.js.map
\No newline at end of file