1 | import { __assign, __awaiter, __generator } from "tslib";
|
2 | import { invariant } from "../utilities/globals/index.js";
|
3 | import { visit, BREAK, isSelectionNode } from "graphql";
|
4 | import { argumentsObjectFromField, buildQueryFromSelectionSet, createFragmentMap, getFragmentDefinitions, getMainDefinition, hasDirectives, isField, isInlineFragment, mergeDeep, mergeDeepArray, removeClientSetsFromDocument, resultKeyNameFromField, shouldInclude, } from "../utilities/index.js";
|
5 | import { cacheSlot } from "../cache/index.js";
|
6 | var LocalState = (function () {
|
7 | function LocalState(_a) {
|
8 | var cache = _a.cache, client = _a.client, resolvers = _a.resolvers, fragmentMatcher = _a.fragmentMatcher;
|
9 | this.selectionsToResolveCache = new WeakMap();
|
10 | this.cache = cache;
|
11 | if (client) {
|
12 | this.client = client;
|
13 | }
|
14 | if (resolvers) {
|
15 | this.addResolvers(resolvers);
|
16 | }
|
17 | if (fragmentMatcher) {
|
18 | this.setFragmentMatcher(fragmentMatcher);
|
19 | }
|
20 | }
|
21 | LocalState.prototype.addResolvers = function (resolvers) {
|
22 | var _this = this;
|
23 | this.resolvers = this.resolvers || {};
|
24 | if (Array.isArray(resolvers)) {
|
25 | resolvers.forEach(function (resolverGroup) {
|
26 | _this.resolvers = mergeDeep(_this.resolvers, resolverGroup);
|
27 | });
|
28 | }
|
29 | else {
|
30 | this.resolvers = mergeDeep(this.resolvers, resolvers);
|
31 | }
|
32 | };
|
33 | LocalState.prototype.setResolvers = function (resolvers) {
|
34 | this.resolvers = {};
|
35 | this.addResolvers(resolvers);
|
36 | };
|
37 | LocalState.prototype.getResolvers = function () {
|
38 | return this.resolvers || {};
|
39 | };
|
40 |
|
41 |
|
42 |
|
43 |
|
44 | LocalState.prototype.runResolvers = function (_a) {
|
45 | return __awaiter(this, arguments, void 0, function (_b) {
|
46 | var document = _b.document, remoteResult = _b.remoteResult, context = _b.context, variables = _b.variables, _c = _b.onlyRunForcedResolvers, onlyRunForcedResolvers = _c === void 0 ? false : _c;
|
47 | return __generator(this, function (_d) {
|
48 | if (document) {
|
49 | return [2 , this.resolveDocument(document, remoteResult.data, context, variables, this.fragmentMatcher, onlyRunForcedResolvers).then(function (localResult) { return (__assign(__assign({}, remoteResult), { data: localResult.result })); })];
|
50 | }
|
51 | return [2 , remoteResult];
|
52 | });
|
53 | });
|
54 | };
|
55 | LocalState.prototype.setFragmentMatcher = function (fragmentMatcher) {
|
56 | this.fragmentMatcher = fragmentMatcher;
|
57 | };
|
58 | LocalState.prototype.getFragmentMatcher = function () {
|
59 | return this.fragmentMatcher;
|
60 | };
|
61 |
|
62 |
|
63 | LocalState.prototype.clientQuery = function (document) {
|
64 | if (hasDirectives(["client"], document)) {
|
65 | if (this.resolvers) {
|
66 | return document;
|
67 | }
|
68 | }
|
69 | return null;
|
70 | };
|
71 |
|
72 | LocalState.prototype.serverQuery = function (document) {
|
73 | return removeClientSetsFromDocument(document);
|
74 | };
|
75 | LocalState.prototype.prepareContext = function (context) {
|
76 | var cache = this.cache;
|
77 | return __assign(__assign({}, context), { cache: cache,
|
78 |
|
79 | getCacheKey: function (obj) {
|
80 | return cache.identify(obj);
|
81 | } });
|
82 | };
|
83 |
|
84 |
|
85 |
|
86 | LocalState.prototype.addExportedVariables = function (document_1) {
|
87 | return __awaiter(this, arguments, void 0, function (document, variables, context) {
|
88 | if (variables === void 0) { variables = {}; }
|
89 | if (context === void 0) { context = {}; }
|
90 | return __generator(this, function (_a) {
|
91 | if (document) {
|
92 | return [2 , this.resolveDocument(document, this.buildRootValueFromCache(document, variables) || {}, this.prepareContext(context), variables).then(function (data) { return (__assign(__assign({}, variables), data.exportedVariables)); })];
|
93 | }
|
94 | return [2 , __assign({}, variables)];
|
95 | });
|
96 | });
|
97 | };
|
98 | LocalState.prototype.shouldForceResolvers = function (document) {
|
99 | var forceResolvers = false;
|
100 | visit(document, {
|
101 | Directive: {
|
102 | enter: function (node) {
|
103 | if (node.name.value === "client" && node.arguments) {
|
104 | forceResolvers = node.arguments.some(function (arg) {
|
105 | return arg.name.value === "always" &&
|
106 | arg.value.kind === "BooleanValue" &&
|
107 | arg.value.value === true;
|
108 | });
|
109 | if (forceResolvers) {
|
110 | return BREAK;
|
111 | }
|
112 | }
|
113 | },
|
114 | },
|
115 | });
|
116 | return forceResolvers;
|
117 | };
|
118 |
|
119 | LocalState.prototype.buildRootValueFromCache = function (document, variables) {
|
120 | return this.cache.diff({
|
121 | query: buildQueryFromSelectionSet(document),
|
122 | variables: variables,
|
123 | returnPartialData: true,
|
124 | optimistic: false,
|
125 | }).result;
|
126 | };
|
127 | LocalState.prototype.resolveDocument = function (document_1, rootValue_1) {
|
128 | return __awaiter(this, arguments, void 0, function (document, rootValue, context, variables, fragmentMatcher, onlyRunForcedResolvers) {
|
129 | var mainDefinition, fragments, fragmentMap, selectionsToResolve, definitionOperation, defaultOperationType, _a, cache, client, execContext, isClientFieldDescendant;
|
130 | if (context === void 0) { context = {}; }
|
131 | if (variables === void 0) { variables = {}; }
|
132 | if (fragmentMatcher === void 0) { fragmentMatcher = function () { return true; }; }
|
133 | if (onlyRunForcedResolvers === void 0) { onlyRunForcedResolvers = false; }
|
134 | return __generator(this, function (_b) {
|
135 | mainDefinition = getMainDefinition(document);
|
136 | fragments = getFragmentDefinitions(document);
|
137 | fragmentMap = createFragmentMap(fragments);
|
138 | selectionsToResolve = this.collectSelectionsToResolve(mainDefinition, fragmentMap);
|
139 | definitionOperation = mainDefinition.operation;
|
140 | defaultOperationType = definitionOperation ?
|
141 | definitionOperation.charAt(0).toUpperCase() +
|
142 | definitionOperation.slice(1)
|
143 | : "Query";
|
144 | _a = this, cache = _a.cache, client = _a.client;
|
145 | execContext = {
|
146 | fragmentMap: fragmentMap,
|
147 | context: __assign(__assign({}, context), { cache: cache, client: client }),
|
148 | variables: variables,
|
149 | fragmentMatcher: fragmentMatcher,
|
150 | defaultOperationType: defaultOperationType,
|
151 | exportedVariables: {},
|
152 | selectionsToResolve: selectionsToResolve,
|
153 | onlyRunForcedResolvers: onlyRunForcedResolvers,
|
154 | };
|
155 | isClientFieldDescendant = false;
|
156 | return [2 , this.resolveSelectionSet(mainDefinition.selectionSet, isClientFieldDescendant, rootValue, execContext).then(function (result) { return ({
|
157 | result: result,
|
158 | exportedVariables: execContext.exportedVariables,
|
159 | }); })];
|
160 | });
|
161 | });
|
162 | };
|
163 | LocalState.prototype.resolveSelectionSet = function (selectionSet, isClientFieldDescendant, rootValue, execContext) {
|
164 | return __awaiter(this, void 0, void 0, function () {
|
165 | var fragmentMap, context, variables, resultsToMerge, execute;
|
166 | var _this = this;
|
167 | return __generator(this, function (_a) {
|
168 | fragmentMap = execContext.fragmentMap, context = execContext.context, variables = execContext.variables;
|
169 | resultsToMerge = [rootValue];
|
170 | execute = function (selection) { return __awaiter(_this, void 0, void 0, function () {
|
171 | var fragment, typeCondition;
|
172 | return __generator(this, function (_a) {
|
173 | if (!isClientFieldDescendant &&
|
174 | !execContext.selectionsToResolve.has(selection)) {
|
175 |
|
176 |
|
177 | return [2 ];
|
178 | }
|
179 | if (!shouldInclude(selection, variables)) {
|
180 |
|
181 | return [2 ];
|
182 | }
|
183 | if (isField(selection)) {
|
184 | return [2 , this.resolveField(selection, isClientFieldDescendant, rootValue, execContext).then(function (fieldResult) {
|
185 | var _a;
|
186 | if (typeof fieldResult !== "undefined") {
|
187 | resultsToMerge.push((_a = {},
|
188 | _a[resultKeyNameFromField(selection)] = fieldResult,
|
189 | _a));
|
190 | }
|
191 | })];
|
192 | }
|
193 | if (isInlineFragment(selection)) {
|
194 | fragment = selection;
|
195 | }
|
196 | else {
|
197 |
|
198 | fragment = fragmentMap[selection.name.value];
|
199 | invariant(fragment, 18, selection.name.value);
|
200 | }
|
201 | if (fragment && fragment.typeCondition) {
|
202 | typeCondition = fragment.typeCondition.name.value;
|
203 | if (execContext.fragmentMatcher(rootValue, typeCondition, context)) {
|
204 | return [2 , this.resolveSelectionSet(fragment.selectionSet, isClientFieldDescendant, rootValue, execContext).then(function (fragmentResult) {
|
205 | resultsToMerge.push(fragmentResult);
|
206 | })];
|
207 | }
|
208 | }
|
209 | return [2 ];
|
210 | });
|
211 | }); };
|
212 | return [2 , Promise.all(selectionSet.selections.map(execute)).then(function () {
|
213 | return mergeDeepArray(resultsToMerge);
|
214 | })];
|
215 | });
|
216 | });
|
217 | };
|
218 | LocalState.prototype.resolveField = function (field, isClientFieldDescendant, rootValue, execContext) {
|
219 | return __awaiter(this, void 0, void 0, function () {
|
220 | var variables, fieldName, aliasedFieldName, aliasUsed, defaultResult, resultPromise, resolverType, resolverMap, resolve;
|
221 | var _this = this;
|
222 | return __generator(this, function (_a) {
|
223 | if (!rootValue) {
|
224 | return [2 , null];
|
225 | }
|
226 | variables = execContext.variables;
|
227 | fieldName = field.name.value;
|
228 | aliasedFieldName = resultKeyNameFromField(field);
|
229 | aliasUsed = fieldName !== aliasedFieldName;
|
230 | defaultResult = rootValue[aliasedFieldName] || rootValue[fieldName];
|
231 | resultPromise = Promise.resolve(defaultResult);
|
232 |
|
233 |
|
234 |
|
235 |
|
236 | if (!execContext.onlyRunForcedResolvers ||
|
237 | this.shouldForceResolvers(field)) {
|
238 | resolverType = rootValue.__typename || execContext.defaultOperationType;
|
239 | resolverMap = this.resolvers && this.resolvers[resolverType];
|
240 | if (resolverMap) {
|
241 | resolve = resolverMap[aliasUsed ? fieldName : aliasedFieldName];
|
242 | if (resolve) {
|
243 | resultPromise = Promise.resolve(
|
244 |
|
245 |
|
246 | cacheSlot.withValue(this.cache, resolve, [
|
247 | rootValue,
|
248 | argumentsObjectFromField(field, variables),
|
249 | execContext.context,
|
250 | { field: field, fragmentMap: execContext.fragmentMap },
|
251 | ]));
|
252 | }
|
253 | }
|
254 | }
|
255 | return [2 , resultPromise.then(function (result) {
|
256 | var _a, _b;
|
257 | if (result === void 0) { result = defaultResult; }
|
258 |
|
259 |
|
260 | if (field.directives) {
|
261 | field.directives.forEach(function (directive) {
|
262 | if (directive.name.value === "export" && directive.arguments) {
|
263 | directive.arguments.forEach(function (arg) {
|
264 | if (arg.name.value === "as" && arg.value.kind === "StringValue") {
|
265 | execContext.exportedVariables[arg.value.value] = result;
|
266 | }
|
267 | });
|
268 | }
|
269 | });
|
270 | }
|
271 |
|
272 | if (!field.selectionSet) {
|
273 | return result;
|
274 | }
|
275 |
|
276 |
|
277 | if (result == null) {
|
278 |
|
279 | return result;
|
280 | }
|
281 | var isClientField = (_b = (_a = field.directives) === null || _a === void 0 ? void 0 : _a.some(function (d) { return d.name.value === "client"; })) !== null && _b !== void 0 ? _b : false;
|
282 | if (Array.isArray(result)) {
|
283 | return _this.resolveSubSelectedArray(field, isClientFieldDescendant || isClientField, result, execContext);
|
284 | }
|
285 |
|
286 | if (field.selectionSet) {
|
287 | return _this.resolveSelectionSet(field.selectionSet, isClientFieldDescendant || isClientField, result, execContext);
|
288 | }
|
289 | })];
|
290 | });
|
291 | });
|
292 | };
|
293 | LocalState.prototype.resolveSubSelectedArray = function (field, isClientFieldDescendant, result, execContext) {
|
294 | var _this = this;
|
295 | return Promise.all(result.map(function (item) {
|
296 | if (item === null) {
|
297 | return null;
|
298 | }
|
299 |
|
300 | if (Array.isArray(item)) {
|
301 | return _this.resolveSubSelectedArray(field, isClientFieldDescendant, item, execContext);
|
302 | }
|
303 |
|
304 | if (field.selectionSet) {
|
305 | return _this.resolveSelectionSet(field.selectionSet, isClientFieldDescendant, item, execContext);
|
306 | }
|
307 | }));
|
308 | };
|
309 |
|
310 |
|
311 |
|
312 | LocalState.prototype.collectSelectionsToResolve = function (mainDefinition, fragmentMap) {
|
313 | var isSingleASTNode = function (node) { return !Array.isArray(node); };
|
314 | var selectionsToResolveCache = this.selectionsToResolveCache;
|
315 | function collectByDefinition(definitionNode) {
|
316 | if (!selectionsToResolveCache.has(definitionNode)) {
|
317 | var matches_1 = new Set();
|
318 | selectionsToResolveCache.set(definitionNode, matches_1);
|
319 | visit(definitionNode, {
|
320 | Directive: function (node, _, __, ___, ancestors) {
|
321 | if (node.name.value === "client") {
|
322 | ancestors.forEach(function (node) {
|
323 | if (isSingleASTNode(node) && isSelectionNode(node)) {
|
324 | matches_1.add(node);
|
325 | }
|
326 | });
|
327 | }
|
328 | },
|
329 | FragmentSpread: function (spread, _, __, ___, ancestors) {
|
330 | var fragment = fragmentMap[spread.name.value];
|
331 | invariant(fragment, 19, spread.name.value);
|
332 | var fragmentSelections = collectByDefinition(fragment);
|
333 | if (fragmentSelections.size > 0) {
|
334 |
|
335 |
|
336 | ancestors.forEach(function (node) {
|
337 | if (isSingleASTNode(node) && isSelectionNode(node)) {
|
338 | matches_1.add(node);
|
339 | }
|
340 | });
|
341 | matches_1.add(spread);
|
342 | fragmentSelections.forEach(function (selection) {
|
343 | matches_1.add(selection);
|
344 | });
|
345 | }
|
346 | },
|
347 | });
|
348 | }
|
349 | return selectionsToResolveCache.get(definitionNode);
|
350 | }
|
351 | return collectByDefinition(mainDefinition);
|
352 | };
|
353 | return LocalState;
|
354 | }());
|
355 | export { LocalState };
|
356 |
|
\ | No newline at end of file |