1 | import { __assign, __awaiter, __generator } from "tslib";
|
2 | import { invariant } from "../utilities/globals/index.js";
|
3 | import { visit, BREAK, } 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.cache = cache;
|
10 | if (client) {
|
11 | this.client = client;
|
12 | }
|
13 | if (resolvers) {
|
14 | this.addResolvers(resolvers);
|
15 | }
|
16 | if (fragmentMatcher) {
|
17 | this.setFragmentMatcher(fragmentMatcher);
|
18 | }
|
19 | }
|
20 | LocalState.prototype.addResolvers = function (resolvers) {
|
21 | var _this = this;
|
22 | this.resolvers = this.resolvers || {};
|
23 | if (Array.isArray(resolvers)) {
|
24 | resolvers.forEach(function (resolverGroup) {
|
25 | _this.resolvers = mergeDeep(_this.resolvers, resolverGroup);
|
26 | });
|
27 | }
|
28 | else {
|
29 | this.resolvers = mergeDeep(this.resolvers, resolvers);
|
30 | }
|
31 | };
|
32 | LocalState.prototype.setResolvers = function (resolvers) {
|
33 | this.resolvers = {};
|
34 | this.addResolvers(resolvers);
|
35 | };
|
36 | LocalState.prototype.getResolvers = function () {
|
37 | return this.resolvers || {};
|
38 | };
|
39 | LocalState.prototype.runResolvers = function (_a) {
|
40 | var document = _a.document, remoteResult = _a.remoteResult, context = _a.context, variables = _a.variables, _b = _a.onlyRunForcedResolvers, onlyRunForcedResolvers = _b === void 0 ? false : _b;
|
41 | return __awaiter(this, void 0, void 0, function () {
|
42 | return __generator(this, function (_c) {
|
43 | if (document) {
|
44 | return [2, this.resolveDocument(document, remoteResult.data, context, variables, this.fragmentMatcher, onlyRunForcedResolvers).then(function (localResult) { return (__assign(__assign({}, remoteResult), { data: localResult.result })); })];
|
45 | }
|
46 | return [2, remoteResult];
|
47 | });
|
48 | });
|
49 | };
|
50 | LocalState.prototype.setFragmentMatcher = function (fragmentMatcher) {
|
51 | this.fragmentMatcher = fragmentMatcher;
|
52 | };
|
53 | LocalState.prototype.getFragmentMatcher = function () {
|
54 | return this.fragmentMatcher;
|
55 | };
|
56 | LocalState.prototype.clientQuery = function (document) {
|
57 | if (hasDirectives(['client'], document)) {
|
58 | if (this.resolvers) {
|
59 | return document;
|
60 | }
|
61 | }
|
62 | return null;
|
63 | };
|
64 | LocalState.prototype.serverQuery = function (document) {
|
65 | return removeClientSetsFromDocument(document);
|
66 | };
|
67 | LocalState.prototype.prepareContext = function (context) {
|
68 | var cache = this.cache;
|
69 | return __assign(__assign({}, context), { cache: cache, getCacheKey: function (obj) {
|
70 | return cache.identify(obj);
|
71 | } });
|
72 | };
|
73 | LocalState.prototype.addExportedVariables = function (document, variables, context) {
|
74 | if (variables === void 0) { variables = {}; }
|
75 | if (context === void 0) { context = {}; }
|
76 | return __awaiter(this, void 0, void 0, function () {
|
77 | return __generator(this, function (_a) {
|
78 | if (document) {
|
79 | return [2, this.resolveDocument(document, this.buildRootValueFromCache(document, variables) || {}, this.prepareContext(context), variables).then(function (data) { return (__assign(__assign({}, variables), data.exportedVariables)); })];
|
80 | }
|
81 | return [2, __assign({}, variables)];
|
82 | });
|
83 | });
|
84 | };
|
85 | LocalState.prototype.shouldForceResolvers = function (document) {
|
86 | var forceResolvers = false;
|
87 | visit(document, {
|
88 | Directive: {
|
89 | enter: function (node) {
|
90 | if (node.name.value === 'client' && node.arguments) {
|
91 | forceResolvers = node.arguments.some(function (arg) {
|
92 | return arg.name.value === 'always' &&
|
93 | arg.value.kind === 'BooleanValue' &&
|
94 | arg.value.value === true;
|
95 | });
|
96 | if (forceResolvers) {
|
97 | return BREAK;
|
98 | }
|
99 | }
|
100 | },
|
101 | },
|
102 | });
|
103 | return forceResolvers;
|
104 | };
|
105 | LocalState.prototype.buildRootValueFromCache = function (document, variables) {
|
106 | return this.cache.diff({
|
107 | query: buildQueryFromSelectionSet(document),
|
108 | variables: variables,
|
109 | returnPartialData: true,
|
110 | optimistic: false,
|
111 | }).result;
|
112 | };
|
113 | LocalState.prototype.resolveDocument = function (document, rootValue, context, variables, fragmentMatcher, onlyRunForcedResolvers) {
|
114 | if (context === void 0) { context = {}; }
|
115 | if (variables === void 0) { variables = {}; }
|
116 | if (fragmentMatcher === void 0) { fragmentMatcher = function () { return true; }; }
|
117 | if (onlyRunForcedResolvers === void 0) { onlyRunForcedResolvers = false; }
|
118 | return __awaiter(this, void 0, void 0, function () {
|
119 | var mainDefinition, fragments, fragmentMap, definitionOperation, defaultOperationType, _a, cache, client, execContext;
|
120 | return __generator(this, function (_b) {
|
121 | mainDefinition = getMainDefinition(document);
|
122 | fragments = getFragmentDefinitions(document);
|
123 | fragmentMap = createFragmentMap(fragments);
|
124 | definitionOperation = mainDefinition
|
125 | .operation;
|
126 | defaultOperationType = definitionOperation
|
127 | ? definitionOperation.charAt(0).toUpperCase() +
|
128 | definitionOperation.slice(1)
|
129 | : 'Query';
|
130 | _a = this, cache = _a.cache, client = _a.client;
|
131 | execContext = {
|
132 | fragmentMap: fragmentMap,
|
133 | context: __assign(__assign({}, context), { cache: cache, client: client }),
|
134 | variables: variables,
|
135 | fragmentMatcher: fragmentMatcher,
|
136 | defaultOperationType: defaultOperationType,
|
137 | exportedVariables: {},
|
138 | onlyRunForcedResolvers: onlyRunForcedResolvers,
|
139 | };
|
140 | return [2, this.resolveSelectionSet(mainDefinition.selectionSet, rootValue, execContext).then(function (result) { return ({
|
141 | result: result,
|
142 | exportedVariables: execContext.exportedVariables,
|
143 | }); })];
|
144 | });
|
145 | });
|
146 | };
|
147 | LocalState.prototype.resolveSelectionSet = function (selectionSet, rootValue, execContext) {
|
148 | return __awaiter(this, void 0, void 0, function () {
|
149 | var fragmentMap, context, variables, resultsToMerge, execute;
|
150 | var _this = this;
|
151 | return __generator(this, function (_a) {
|
152 | fragmentMap = execContext.fragmentMap, context = execContext.context, variables = execContext.variables;
|
153 | resultsToMerge = [rootValue];
|
154 | execute = function (selection) { return __awaiter(_this, void 0, void 0, function () {
|
155 | var fragment, typeCondition;
|
156 | return __generator(this, function (_a) {
|
157 | if (!shouldInclude(selection, variables)) {
|
158 | return [2];
|
159 | }
|
160 | if (isField(selection)) {
|
161 | return [2, this.resolveField(selection, rootValue, execContext).then(function (fieldResult) {
|
162 | var _a;
|
163 | if (typeof fieldResult !== 'undefined') {
|
164 | resultsToMerge.push((_a = {},
|
165 | _a[resultKeyNameFromField(selection)] = fieldResult,
|
166 | _a));
|
167 | }
|
168 | })];
|
169 | }
|
170 | if (isInlineFragment(selection)) {
|
171 | fragment = selection;
|
172 | }
|
173 | else {
|
174 | fragment = fragmentMap[selection.name.value];
|
175 | __DEV__ ? invariant(fragment, "No fragment named ".concat(selection.name.value)) : invariant(fragment, 9);
|
176 | }
|
177 | if (fragment && fragment.typeCondition) {
|
178 | typeCondition = fragment.typeCondition.name.value;
|
179 | if (execContext.fragmentMatcher(rootValue, typeCondition, context)) {
|
180 | return [2, this.resolveSelectionSet(fragment.selectionSet, rootValue, execContext).then(function (fragmentResult) {
|
181 | resultsToMerge.push(fragmentResult);
|
182 | })];
|
183 | }
|
184 | }
|
185 | return [2];
|
186 | });
|
187 | }); };
|
188 | return [2, Promise.all(selectionSet.selections.map(execute)).then(function () {
|
189 | return mergeDeepArray(resultsToMerge);
|
190 | })];
|
191 | });
|
192 | });
|
193 | };
|
194 | LocalState.prototype.resolveField = function (field, rootValue, execContext) {
|
195 | return __awaiter(this, void 0, void 0, function () {
|
196 | var variables, fieldName, aliasedFieldName, aliasUsed, defaultResult, resultPromise, resolverType, resolverMap, resolve;
|
197 | var _this = this;
|
198 | return __generator(this, function (_a) {
|
199 | variables = execContext.variables;
|
200 | fieldName = field.name.value;
|
201 | aliasedFieldName = resultKeyNameFromField(field);
|
202 | aliasUsed = fieldName !== aliasedFieldName;
|
203 | defaultResult = rootValue[aliasedFieldName] || rootValue[fieldName];
|
204 | resultPromise = Promise.resolve(defaultResult);
|
205 | if (!execContext.onlyRunForcedResolvers ||
|
206 | this.shouldForceResolvers(field)) {
|
207 | resolverType = rootValue.__typename || execContext.defaultOperationType;
|
208 | resolverMap = this.resolvers && this.resolvers[resolverType];
|
209 | if (resolverMap) {
|
210 | resolve = resolverMap[aliasUsed ? fieldName : aliasedFieldName];
|
211 | if (resolve) {
|
212 | resultPromise = Promise.resolve(cacheSlot.withValue(this.cache, resolve, [
|
213 | rootValue,
|
214 | argumentsObjectFromField(field, variables),
|
215 | execContext.context,
|
216 | { field: field, fragmentMap: execContext.fragmentMap },
|
217 | ]));
|
218 | }
|
219 | }
|
220 | }
|
221 | return [2, resultPromise.then(function (result) {
|
222 | if (result === void 0) { result = defaultResult; }
|
223 | if (field.directives) {
|
224 | field.directives.forEach(function (directive) {
|
225 | if (directive.name.value === 'export' && directive.arguments) {
|
226 | directive.arguments.forEach(function (arg) {
|
227 | if (arg.name.value === 'as' && arg.value.kind === 'StringValue') {
|
228 | execContext.exportedVariables[arg.value.value] = result;
|
229 | }
|
230 | });
|
231 | }
|
232 | });
|
233 | }
|
234 | if (!field.selectionSet) {
|
235 | return result;
|
236 | }
|
237 | if (result == null) {
|
238 | return result;
|
239 | }
|
240 | if (Array.isArray(result)) {
|
241 | return _this.resolveSubSelectedArray(field, result, execContext);
|
242 | }
|
243 | if (field.selectionSet) {
|
244 | return _this.resolveSelectionSet(field.selectionSet, result, execContext);
|
245 | }
|
246 | })];
|
247 | });
|
248 | });
|
249 | };
|
250 | LocalState.prototype.resolveSubSelectedArray = function (field, result, execContext) {
|
251 | var _this = this;
|
252 | return Promise.all(result.map(function (item) {
|
253 | if (item === null) {
|
254 | return null;
|
255 | }
|
256 | if (Array.isArray(item)) {
|
257 | return _this.resolveSubSelectedArray(field, item, execContext);
|
258 | }
|
259 | if (field.selectionSet) {
|
260 | return _this.resolveSelectionSet(field.selectionSet, item, execContext);
|
261 | }
|
262 | }));
|
263 | };
|
264 | return LocalState;
|
265 | }());
|
266 | export { LocalState };
|
267 |
|
\ | No newline at end of file |