1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var tslib_1 = require("tslib");
|
4 | var apollo_utilities_1 = require("apollo-utilities");
|
5 | var optimism_1 = require("optimism");
|
6 | var depTrackingCache_1 = require("./depTrackingCache");
|
7 | var ts_invariant_1 = require("ts-invariant");
|
8 | var 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 | }());
|
259 | exports.StoreReader = StoreReader;
|
260 | function 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 | }
|
265 | function defaultFragmentMatcher() {
|
266 | return true;
|
267 | }
|
268 | function 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 | }
|
271 | exports.assertIdValue = assertIdValue;
|
272 | function 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 |
|
\ | No newline at end of file |