@graphql-tools/executor 2.0.0-alpha-20240804115549-7dfd59247669dee6217565e3327c429dc5d3bff2 → 2.0.0-alpha-20240805144842-131e76d507ce82e59a400bf90758e7af71493abf
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/execution/IncrementalPublisher.js +74 -60
- package/cjs/execution/collectFields.js +9 -9
- package/cjs/execution/execute.js +18 -15
- package/esm/execution/IncrementalPublisher.js +74 -60
- package/esm/execution/collectFields.js +9 -9
- package/esm/execution/execute.js +18 -15
- package/package.json +2 -2
- package/typings/execution/IncrementalPublisher.d.cts +1 -2
- package/typings/execution/IncrementalPublisher.d.ts +1 -2
- package/typings/execution/collectFields.d.cts +2 -2
- package/typings/execution/collectFields.d.ts +2 -2
- package/typings/execution/execute.d.cts +9 -9
- package/typings/execution/execute.d.ts +9 -9
- package/typings/execution/types.d.cts +4 -4
- package/typings/execution/types.d.ts +4 -4
|
@@ -40,10 +40,14 @@ class IncrementalPublisher {
|
|
|
40
40
|
}
|
|
41
41
|
buildResponse(data, errors, incrementalDataRecords) {
|
|
42
42
|
const newPending = this._incrementalGraph.getNewPending(incrementalDataRecords);
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
?
|
|
46
|
-
|
|
43
|
+
const initialResult = this._context
|
|
44
|
+
.useIncrementalNotifications
|
|
45
|
+
? errors === undefined
|
|
46
|
+
? { data, pending: this._pendingSourcesToResults(newPending), hasNext: true }
|
|
47
|
+
: { errors, data, pending: this._pendingSourcesToResults(newPending), hasNext: true }
|
|
48
|
+
: errors === undefined
|
|
49
|
+
? { data, hasNext: true }
|
|
50
|
+
: { errors, data, hasNext: true };
|
|
47
51
|
return {
|
|
48
52
|
initialResult,
|
|
49
53
|
subsequentResults: this._subscribe(),
|
|
@@ -158,33 +162,29 @@ class IncrementalPublisher {
|
|
|
158
162
|
if ((0, types_js_1.isFailedExecutionGroup)(completedExecutionGroup)) {
|
|
159
163
|
for (const deferredFragmentRecord of completedExecutionGroup.pendingExecutionGroup
|
|
160
164
|
.deferredFragmentRecords) {
|
|
161
|
-
const id = deferredFragmentRecord.id;
|
|
162
165
|
if (!this._incrementalGraph.removeDeferredFragment(deferredFragmentRecord)) {
|
|
163
166
|
// This can occur if multiple deferred grouped field sets error for a fragment.
|
|
164
167
|
continue;
|
|
165
168
|
}
|
|
166
|
-
(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
+
if (this._context.useIncrementalNotifications) {
|
|
170
|
+
const id = deferredFragmentRecord.id;
|
|
171
|
+
(0, invariant_js_1.invariant)(id !== undefined);
|
|
172
|
+
context.completed.push({
|
|
169
173
|
id,
|
|
170
|
-
data: null,
|
|
171
174
|
errors: completedExecutionGroup.errors,
|
|
172
|
-
};
|
|
173
|
-
if (this._context.sendPathAndLabelOnIncremental) {
|
|
174
|
-
const { path, label } = deferredFragmentRecord;
|
|
175
|
-
incrementalEntry.path = (0, utils_1.pathToArray)(path);
|
|
176
|
-
if (label !== undefined) {
|
|
177
|
-
incrementalEntry.label = label;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
context.incremental.push(incrementalEntry);
|
|
181
|
-
context.completed.push({ id });
|
|
175
|
+
});
|
|
182
176
|
}
|
|
183
177
|
else {
|
|
184
|
-
|
|
185
|
-
id,
|
|
178
|
+
const incrementalEntry = {
|
|
186
179
|
errors: completedExecutionGroup.errors,
|
|
187
|
-
|
|
180
|
+
data: null,
|
|
181
|
+
};
|
|
182
|
+
const { path, label } = deferredFragmentRecord;
|
|
183
|
+
incrementalEntry.path = (0, utils_1.pathToArray)(path);
|
|
184
|
+
if (label !== undefined) {
|
|
185
|
+
incrementalEntry.label = label;
|
|
186
|
+
}
|
|
187
|
+
context.incremental.push(incrementalEntry);
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
return;
|
|
@@ -196,58 +196,62 @@ class IncrementalPublisher {
|
|
|
196
196
|
if (completion === undefined) {
|
|
197
197
|
continue;
|
|
198
198
|
}
|
|
199
|
-
const id = deferredFragmentRecord.id;
|
|
200
|
-
(0, invariant_js_1.invariant)(id !== undefined);
|
|
201
199
|
const incremental = context.incremental;
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
200
|
+
const successfulExecutionGroups = completion.successfulExecutionGroups;
|
|
201
|
+
if (this._context.useIncrementalNotifications) {
|
|
202
|
+
const id = deferredFragmentRecord.id;
|
|
203
|
+
(0, invariant_js_1.invariant)(id !== undefined);
|
|
204
|
+
context.pending.push(...this._pendingSourcesToResults(completion.newPending));
|
|
205
|
+
for (const successfulExecutionGroup of successfulExecutionGroups) {
|
|
206
|
+
const { bestId, subPath } = this._getBestIdAndSubPath(id, deferredFragmentRecord, successfulExecutionGroup);
|
|
207
|
+
const incrementalEntry = {
|
|
208
|
+
...successfulExecutionGroup.result,
|
|
209
|
+
id: bestId,
|
|
210
|
+
};
|
|
211
|
+
if (subPath !== undefined) {
|
|
212
|
+
incrementalEntry.subPath = subPath;
|
|
213
|
+
}
|
|
214
|
+
incremental.push(incrementalEntry);
|
|
215
|
+
}
|
|
216
|
+
context.completed.push({ id });
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
for (const successfulExecutionGroup of successfulExecutionGroups) {
|
|
220
|
+
const incrementalEntry = {
|
|
221
|
+
...successfulExecutionGroup.result,
|
|
222
|
+
};
|
|
211
223
|
const { path, label } = deferredFragmentRecord;
|
|
212
224
|
incrementalEntry.path = (0, utils_1.pathToArray)(path);
|
|
213
225
|
if (label !== undefined) {
|
|
214
226
|
incrementalEntry.label = label;
|
|
215
227
|
}
|
|
228
|
+
incremental.push(incrementalEntry);
|
|
216
229
|
}
|
|
217
|
-
if (subPath !== undefined) {
|
|
218
|
-
incrementalEntry.subPath = subPath;
|
|
219
|
-
}
|
|
220
|
-
incremental.push(incrementalEntry);
|
|
221
230
|
}
|
|
222
|
-
context.completed.push({ id });
|
|
223
231
|
}
|
|
224
232
|
}
|
|
225
233
|
_handleCompletedStreamItems(streamItemsResult, context) {
|
|
226
234
|
const streamRecord = streamItemsResult.streamRecord;
|
|
227
|
-
const id = streamRecord.id;
|
|
228
|
-
(0, invariant_js_1.invariant)(id !== undefined);
|
|
229
235
|
if (streamItemsResult.errors !== undefined) {
|
|
230
|
-
if (this._context.
|
|
231
|
-
const
|
|
232
|
-
|
|
236
|
+
if (this._context.useIncrementalNotifications) {
|
|
237
|
+
const id = streamRecord.id;
|
|
238
|
+
(0, invariant_js_1.invariant)(id !== undefined);
|
|
239
|
+
context.completed.push({
|
|
233
240
|
id,
|
|
234
241
|
errors: streamItemsResult.errors,
|
|
235
|
-
};
|
|
236
|
-
if (this._context.sendPathAndLabelOnIncremental) {
|
|
237
|
-
const { path, label, index } = streamRecord;
|
|
238
|
-
incrementalEntry.path = (0, utils_1.pathToArray)((0, utils_1.addPath)(path, index, undefined));
|
|
239
|
-
if (label !== undefined) {
|
|
240
|
-
incrementalEntry.label = label;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
context.incremental.push(incrementalEntry);
|
|
244
|
-
context.completed.push({ id });
|
|
242
|
+
});
|
|
245
243
|
}
|
|
246
244
|
else {
|
|
247
|
-
|
|
248
|
-
id,
|
|
245
|
+
const incrementalEntry = {
|
|
249
246
|
errors: streamItemsResult.errors,
|
|
250
|
-
|
|
247
|
+
items: null,
|
|
248
|
+
};
|
|
249
|
+
const { path, label, index } = streamRecord;
|
|
250
|
+
incrementalEntry.path = (0, utils_1.pathToArray)((0, utils_1.addPath)(path, index, undefined));
|
|
251
|
+
if (label !== undefined) {
|
|
252
|
+
incrementalEntry.label = label;
|
|
253
|
+
}
|
|
254
|
+
context.incremental.push(incrementalEntry);
|
|
251
255
|
}
|
|
252
256
|
this._incrementalGraph.removeStream(streamRecord);
|
|
253
257
|
if ((0, types_js_1.isCancellableStreamRecord)(streamRecord)) {
|
|
@@ -260,7 +264,11 @@ class IncrementalPublisher {
|
|
|
260
264
|
}
|
|
261
265
|
}
|
|
262
266
|
else if (streamItemsResult.result === undefined) {
|
|
263
|
-
|
|
267
|
+
if (this._context.useIncrementalNotifications) {
|
|
268
|
+
const id = streamRecord.id;
|
|
269
|
+
(0, invariant_js_1.invariant)(id !== undefined);
|
|
270
|
+
context.completed.push({ id });
|
|
271
|
+
}
|
|
264
272
|
this._incrementalGraph.removeStream(streamRecord);
|
|
265
273
|
if ((0, types_js_1.isCancellableStreamRecord)(streamRecord)) {
|
|
266
274
|
(0, invariant_js_1.invariant)(this._context.cancellableStreams !== undefined);
|
|
@@ -270,10 +278,14 @@ class IncrementalPublisher {
|
|
|
270
278
|
else {
|
|
271
279
|
const bareResult = streamItemsResult.result;
|
|
272
280
|
const incrementalEntry = {
|
|
273
|
-
id,
|
|
274
281
|
...bareResult,
|
|
275
282
|
};
|
|
276
|
-
if (this._context.
|
|
283
|
+
if (this._context.useIncrementalNotifications) {
|
|
284
|
+
const id = streamRecord.id;
|
|
285
|
+
(0, invariant_js_1.invariant)(id !== undefined);
|
|
286
|
+
incrementalEntry.id = id;
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
277
289
|
const { path, label, index } = streamRecord;
|
|
278
290
|
incrementalEntry.path = (0, utils_1.pathToArray)((0, utils_1.addPath)(path, index, undefined));
|
|
279
291
|
streamRecord.index += bareResult.items.length;
|
|
@@ -285,7 +297,9 @@ class IncrementalPublisher {
|
|
|
285
297
|
const incrementalDataRecords = streamItemsResult.incrementalDataRecords;
|
|
286
298
|
if (incrementalDataRecords !== undefined) {
|
|
287
299
|
const newPending = this._incrementalGraph.getNewPending(incrementalDataRecords);
|
|
288
|
-
|
|
300
|
+
if (this._context.useIncrementalNotifications) {
|
|
301
|
+
context.pending.push(...this._pendingSourcesToResults(newPending));
|
|
302
|
+
}
|
|
289
303
|
}
|
|
290
304
|
}
|
|
291
305
|
}
|
|
@@ -14,7 +14,7 @@ const invariant_js_1 = require("./invariant.js");
|
|
|
14
14
|
*
|
|
15
15
|
* @internal
|
|
16
16
|
*/
|
|
17
|
-
function collectFields(schema, fragments, variableValues, runtimeType, selectionSet,
|
|
17
|
+
function collectFields(schema, fragments, variableValues, runtimeType, selectionSet, errorOnSubscriptionWithIncrementalDelivery) {
|
|
18
18
|
const groupedFieldSet = new AccumulatorMap_js_1.AccumulatorMap();
|
|
19
19
|
const newDeferUsages = [];
|
|
20
20
|
const context = {
|
|
@@ -22,7 +22,7 @@ function collectFields(schema, fragments, variableValues, runtimeType, selection
|
|
|
22
22
|
fragments,
|
|
23
23
|
variableValues,
|
|
24
24
|
runtimeType,
|
|
25
|
-
|
|
25
|
+
errorOnSubscriptionWithIncrementalDelivery,
|
|
26
26
|
visitedFragmentNames: new Set(),
|
|
27
27
|
};
|
|
28
28
|
collectFieldsImpl(context, selectionSet, groupedFieldSet, newDeferUsages);
|
|
@@ -39,13 +39,13 @@ exports.collectFields = collectFields;
|
|
|
39
39
|
*
|
|
40
40
|
* @internal
|
|
41
41
|
*/
|
|
42
|
-
function collectSubfields(schema, fragments, variableValues,
|
|
42
|
+
function collectSubfields(schema, fragments, variableValues, errorOnSubscriptionWithIncrementalDelivery, returnType, fieldGroup) {
|
|
43
43
|
const context = {
|
|
44
44
|
schema,
|
|
45
45
|
fragments,
|
|
46
46
|
variableValues,
|
|
47
47
|
runtimeType: returnType,
|
|
48
|
-
|
|
48
|
+
errorOnSubscriptionWithIncrementalDelivery,
|
|
49
49
|
visitedFragmentNames: new Set(),
|
|
50
50
|
};
|
|
51
51
|
const subGroupedFieldSet = new AccumulatorMap_js_1.AccumulatorMap();
|
|
@@ -63,7 +63,7 @@ function collectSubfields(schema, fragments, variableValues, errorWithIncrementa
|
|
|
63
63
|
}
|
|
64
64
|
exports.collectSubfields = collectSubfields;
|
|
65
65
|
function collectFieldsImpl(context, selectionSet, groupedFieldSet, newDeferUsages, deferUsage) {
|
|
66
|
-
const { schema, fragments, variableValues, runtimeType,
|
|
66
|
+
const { schema, fragments, variableValues, runtimeType, errorOnSubscriptionWithIncrementalDelivery, visitedFragmentNames, } = context;
|
|
67
67
|
for (const selection of selectionSet.selections) {
|
|
68
68
|
switch (selection.kind) {
|
|
69
69
|
case graphql_1.Kind.FIELD: {
|
|
@@ -81,7 +81,7 @@ function collectFieldsImpl(context, selectionSet, groupedFieldSet, newDeferUsage
|
|
|
81
81
|
!doesFragmentConditionMatch(schema, selection, runtimeType)) {
|
|
82
82
|
continue;
|
|
83
83
|
}
|
|
84
|
-
const newDeferUsage = getDeferUsage(
|
|
84
|
+
const newDeferUsage = getDeferUsage(errorOnSubscriptionWithIncrementalDelivery, variableValues, selection, deferUsage);
|
|
85
85
|
if (!newDeferUsage) {
|
|
86
86
|
collectFieldsImpl(context, selection.selectionSet, groupedFieldSet, newDeferUsages, deferUsage);
|
|
87
87
|
}
|
|
@@ -93,7 +93,7 @@ function collectFieldsImpl(context, selectionSet, groupedFieldSet, newDeferUsage
|
|
|
93
93
|
}
|
|
94
94
|
case graphql_1.Kind.FRAGMENT_SPREAD: {
|
|
95
95
|
const fragName = selection.name.value;
|
|
96
|
-
const newDeferUsage = getDeferUsage(
|
|
96
|
+
const newDeferUsage = getDeferUsage(errorOnSubscriptionWithIncrementalDelivery, variableValues, selection, deferUsage);
|
|
97
97
|
if (!newDeferUsage &&
|
|
98
98
|
(visitedFragmentNames.has(fragName) || !shouldIncludeNode(variableValues, selection))) {
|
|
99
99
|
continue;
|
|
@@ -120,7 +120,7 @@ function collectFieldsImpl(context, selectionSet, groupedFieldSet, newDeferUsage
|
|
|
120
120
|
* deferred based on the experimental flag, defer directive present and
|
|
121
121
|
* not disabled by the "if" argument.
|
|
122
122
|
*/
|
|
123
|
-
function getDeferUsage(
|
|
123
|
+
function getDeferUsage(errorOnSubscriptionWithIncrementalDelivery, variableValues, node, parentDeferUsage) {
|
|
124
124
|
const defer = (0, graphql_1.getDirectiveValues)(utils_1.GraphQLDeferDirective, node, variableValues);
|
|
125
125
|
if (!defer) {
|
|
126
126
|
return;
|
|
@@ -128,7 +128,7 @@ function getDeferUsage(errorWithIncrementalSubscription, variableValues, node, p
|
|
|
128
128
|
if (defer['if'] === false) {
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
|
-
(0, invariant_js_1.invariant)(!
|
|
131
|
+
(0, invariant_js_1.invariant)(!errorOnSubscriptionWithIncrementalDelivery, '`@defer` directive not supported on subscription operations. Disable `@defer` by setting the `if` argument to `false`.');
|
|
132
132
|
return {
|
|
133
133
|
label: typeof defer['label'] === 'string' ? defer['label'] : undefined,
|
|
134
134
|
parentDeferUsage,
|
package/cjs/execution/execute.js
CHANGED
|
@@ -19,7 +19,7 @@ const values_js_1 = require("./values.js");
|
|
|
19
19
|
* type. Memoizing ensures the subfields are not repeatedly calculated, which
|
|
20
20
|
* saves overhead when resolving lists of values.
|
|
21
21
|
*/
|
|
22
|
-
const collectSubfields = (0, utils_1.memoize3)((exeContext, returnType, fieldGroup) => (0, collectFields_js_1.collectSubfields)(exeContext.schema, exeContext.fragments, exeContext.variableValues, exeContext.
|
|
22
|
+
const collectSubfields = (0, utils_1.memoize3)((exeContext, returnType, fieldGroup) => (0, collectFields_js_1.collectSubfields)(exeContext.schema, exeContext.fragments, exeContext.variableValues, exeContext.errorOnSubscriptionWithIncrementalDelivery, returnType, fieldGroup));
|
|
23
23
|
/**
|
|
24
24
|
* Implements the "Executing requests" section of the GraphQL specification,
|
|
25
25
|
* including `@defer` and `@stream` as proposed in
|
|
@@ -155,7 +155,7 @@ exports.getFragmentsFromDocument = (0, utils_1.memoize1)(function getFragmentsFr
|
|
|
155
155
|
* @internal
|
|
156
156
|
*/
|
|
157
157
|
function buildExecutionContext(args) {
|
|
158
|
-
const { schema, document, rootValue, contextValue, variableValues: rawVariableValues, operationName, fieldResolver, typeResolver, subscribeFieldResolver, enableEarlyExecution,
|
|
158
|
+
const { schema, document, rootValue, contextValue, variableValues: rawVariableValues, operationName, fieldResolver, typeResolver, subscribeFieldResolver, enableEarlyExecution, incrementalPreset, deferWithoutDuplication, useIncrementalNotifications, errorOnSubscriptionWithIncrementalDelivery, signal, } = args;
|
|
159
159
|
// If the schema used for execution is invalid, throw an error.
|
|
160
160
|
(0, graphql_1.assertValidSchema)(schema);
|
|
161
161
|
const fragments = (0, exports.getFragmentsFromDocument)(document);
|
|
@@ -194,6 +194,7 @@ function buildExecutionContext(args) {
|
|
|
194
194
|
if (coercedVariableValues.errors) {
|
|
195
195
|
return coercedVariableValues.errors;
|
|
196
196
|
}
|
|
197
|
+
const latestPreset = incrementalPreset !== 'v17.0.0-alpha.2';
|
|
197
198
|
return {
|
|
198
199
|
schema,
|
|
199
200
|
fragments,
|
|
@@ -205,10 +206,12 @@ function buildExecutionContext(args) {
|
|
|
205
206
|
typeResolver: typeResolver ?? exports.defaultTypeResolver,
|
|
206
207
|
subscribeFieldResolver: subscribeFieldResolver ?? exports.defaultFieldResolver,
|
|
207
208
|
enableEarlyExecution: enableEarlyExecution !== false,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
209
|
+
deferWithoutDuplication: deferWithoutDuplication != null ? deferWithoutDuplication : latestPreset,
|
|
210
|
+
useIncrementalNotifications: useIncrementalNotifications != null ? useIncrementalNotifications : latestPreset,
|
|
211
|
+
errorOnSubscriptionWithIncrementalDelivery: operation.operation === 'subscription' &&
|
|
212
|
+
(errorOnSubscriptionWithIncrementalDelivery != null
|
|
213
|
+
? errorOnSubscriptionWithIncrementalDelivery
|
|
214
|
+
: latestPreset),
|
|
212
215
|
signal,
|
|
213
216
|
errors: undefined,
|
|
214
217
|
cancellableStreams: undefined,
|
|
@@ -231,14 +234,14 @@ function executeOperation(exeContext) {
|
|
|
231
234
|
throw exeContext.signal.reason;
|
|
232
235
|
}
|
|
233
236
|
try {
|
|
234
|
-
const { operation, schema, fragments, variableValues, rootValue,
|
|
237
|
+
const { operation, schema, fragments, variableValues, rootValue, deferWithoutDuplication, errorOnSubscriptionWithIncrementalDelivery, } = exeContext;
|
|
235
238
|
const rootType = (0, utils_1.getDefinedRootType)(schema, operation.operation, [operation]);
|
|
236
239
|
if (rootType == null) {
|
|
237
240
|
(0, utils_1.createGraphQLError)(`Schema is not configured to execute ${operation.operation} operation.`, {
|
|
238
241
|
nodes: operation,
|
|
239
242
|
});
|
|
240
243
|
}
|
|
241
|
-
const collectedFields = (0, collectFields_js_1.collectFields)(schema, fragments, variableValues, rootType, operation.selectionSet,
|
|
244
|
+
const collectedFields = (0, collectFields_js_1.collectFields)(schema, fragments, variableValues, rootType, operation.selectionSet, errorOnSubscriptionWithIncrementalDelivery);
|
|
242
245
|
let groupedFieldSet = collectedFields.groupedFieldSet;
|
|
243
246
|
const newDeferUsages = collectedFields.newDeferUsages;
|
|
244
247
|
let data;
|
|
@@ -246,7 +249,7 @@ function executeOperation(exeContext) {
|
|
|
246
249
|
data = executeRootGroupedFieldSet(exeContext, operation.operation, rootType, rootValue, groupedFieldSet, undefined);
|
|
247
250
|
}
|
|
248
251
|
else {
|
|
249
|
-
const executionPlan =
|
|
252
|
+
const executionPlan = deferWithoutDuplication
|
|
250
253
|
? (0, buildExecutionPlan_js_1.buildExecutionPlan)(groupedFieldSet)
|
|
251
254
|
: (0, buildExecutionPlan_js_1.buildBranchingExecutionPlan)(groupedFieldSet);
|
|
252
255
|
groupedFieldSet = executionPlan.groupedFieldSet;
|
|
@@ -560,7 +563,7 @@ function getStreamUsage(exeContext, fieldGroup, path) {
|
|
|
560
563
|
}
|
|
561
564
|
(0, invariant_js_1.invariant)(typeof stream['initialCount'] === 'number', 'initialCount must be a number');
|
|
562
565
|
(0, invariant_js_1.invariant)(stream['initialCount'] >= 0, 'initialCount must be a positive integer');
|
|
563
|
-
(0, invariant_js_1.invariant)(!exeContext.
|
|
566
|
+
(0, invariant_js_1.invariant)(!exeContext.errorOnSubscriptionWithIncrementalDelivery, '`@stream` directive not supported on subscription operations. Disable `@stream` by setting the `if` argument to `false`.');
|
|
564
567
|
const streamedFieldGroup = fieldGroup.map(fieldDetails => ({
|
|
565
568
|
node: fieldDetails.node,
|
|
566
569
|
deferUsage: undefined,
|
|
@@ -869,7 +872,7 @@ function collectAndExecuteSubfields(exeContext, returnType, fieldGroup, path, re
|
|
|
869
872
|
if (deferMap === undefined && newDeferUsages.length === 0) {
|
|
870
873
|
return executeFields(exeContext, returnType, result, path, groupedFieldSet, incrementalContext, undefined);
|
|
871
874
|
}
|
|
872
|
-
const subExecutionPlan = buildSubExecutionPlan(groupedFieldSet, incrementalContext?.deferUsageSet, exeContext.
|
|
875
|
+
const subExecutionPlan = buildSubExecutionPlan(groupedFieldSet, incrementalContext?.deferUsageSet, exeContext.deferWithoutDuplication);
|
|
873
876
|
groupedFieldSet = subExecutionPlan.groupedFieldSet;
|
|
874
877
|
const newGroupedFieldSets = subExecutionPlan.newGroupedFieldSets;
|
|
875
878
|
const newDeferMap = addNewDeferredFragments(newDeferUsages, new Map(deferMap), path);
|
|
@@ -881,13 +884,13 @@ function collectAndExecuteSubfields(exeContext, returnType, fieldGroup, path, re
|
|
|
881
884
|
}
|
|
882
885
|
return subFields;
|
|
883
886
|
}
|
|
884
|
-
function buildSubExecutionPlan(originalGroupedFieldSet, deferUsageSet,
|
|
887
|
+
function buildSubExecutionPlan(originalGroupedFieldSet, deferUsageSet, deferWithoutDuplication) {
|
|
885
888
|
let executionPlan = originalGroupedFieldSet
|
|
886
889
|
._executionPlan;
|
|
887
890
|
if (executionPlan !== undefined) {
|
|
888
891
|
return executionPlan;
|
|
889
892
|
}
|
|
890
|
-
executionPlan =
|
|
893
|
+
executionPlan = deferWithoutDuplication
|
|
891
894
|
? (0, buildExecutionPlan_js_1.buildExecutionPlan)(originalGroupedFieldSet, deferUsageSet)
|
|
892
895
|
: (0, buildExecutionPlan_js_1.buildBranchingExecutionPlan)(originalGroupedFieldSet, deferUsageSet);
|
|
893
896
|
originalGroupedFieldSet._executionPlan =
|
|
@@ -1059,14 +1062,14 @@ function createSourceEventStreamImpl(exeContext) {
|
|
|
1059
1062
|
}
|
|
1060
1063
|
}
|
|
1061
1064
|
function executeSubscription(exeContext) {
|
|
1062
|
-
const { schema, fragments, operation, variableValues, rootValue,
|
|
1065
|
+
const { schema, fragments, operation, variableValues, rootValue, errorOnSubscriptionWithIncrementalDelivery, } = exeContext;
|
|
1063
1066
|
const rootType = schema.getSubscriptionType();
|
|
1064
1067
|
if (rootType == null) {
|
|
1065
1068
|
throw (0, utils_1.createGraphQLError)('Schema is not configured to execute subscription operation.', {
|
|
1066
1069
|
nodes: operation,
|
|
1067
1070
|
});
|
|
1068
1071
|
}
|
|
1069
|
-
const { groupedFieldSet } = (0, collectFields_js_1.collectFields)(schema, fragments, variableValues, rootType, operation.selectionSet,
|
|
1072
|
+
const { groupedFieldSet } = (0, collectFields_js_1.collectFields)(schema, fragments, variableValues, rootType, operation.selectionSet, errorOnSubscriptionWithIncrementalDelivery);
|
|
1070
1073
|
const firstRootField = [...groupedFieldSet.entries()][0];
|
|
1071
1074
|
const [responseName, fieldGroup] = firstRootField;
|
|
1072
1075
|
const fieldName = fieldGroup[0].node.name.value;
|
|
@@ -36,10 +36,14 @@ class IncrementalPublisher {
|
|
|
36
36
|
}
|
|
37
37
|
buildResponse(data, errors, incrementalDataRecords) {
|
|
38
38
|
const newPending = this._incrementalGraph.getNewPending(incrementalDataRecords);
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
?
|
|
42
|
-
|
|
39
|
+
const initialResult = this._context
|
|
40
|
+
.useIncrementalNotifications
|
|
41
|
+
? errors === undefined
|
|
42
|
+
? { data, pending: this._pendingSourcesToResults(newPending), hasNext: true }
|
|
43
|
+
: { errors, data, pending: this._pendingSourcesToResults(newPending), hasNext: true }
|
|
44
|
+
: errors === undefined
|
|
45
|
+
? { data, hasNext: true }
|
|
46
|
+
: { errors, data, hasNext: true };
|
|
43
47
|
return {
|
|
44
48
|
initialResult,
|
|
45
49
|
subsequentResults: this._subscribe(),
|
|
@@ -154,33 +158,29 @@ class IncrementalPublisher {
|
|
|
154
158
|
if (isFailedExecutionGroup(completedExecutionGroup)) {
|
|
155
159
|
for (const deferredFragmentRecord of completedExecutionGroup.pendingExecutionGroup
|
|
156
160
|
.deferredFragmentRecords) {
|
|
157
|
-
const id = deferredFragmentRecord.id;
|
|
158
161
|
if (!this._incrementalGraph.removeDeferredFragment(deferredFragmentRecord)) {
|
|
159
162
|
// This can occur if multiple deferred grouped field sets error for a fragment.
|
|
160
163
|
continue;
|
|
161
164
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
+
if (this._context.useIncrementalNotifications) {
|
|
166
|
+
const id = deferredFragmentRecord.id;
|
|
167
|
+
invariant(id !== undefined);
|
|
168
|
+
context.completed.push({
|
|
165
169
|
id,
|
|
166
|
-
data: null,
|
|
167
170
|
errors: completedExecutionGroup.errors,
|
|
168
|
-
};
|
|
169
|
-
if (this._context.sendPathAndLabelOnIncremental) {
|
|
170
|
-
const { path, label } = deferredFragmentRecord;
|
|
171
|
-
incrementalEntry.path = pathToArray(path);
|
|
172
|
-
if (label !== undefined) {
|
|
173
|
-
incrementalEntry.label = label;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
context.incremental.push(incrementalEntry);
|
|
177
|
-
context.completed.push({ id });
|
|
171
|
+
});
|
|
178
172
|
}
|
|
179
173
|
else {
|
|
180
|
-
|
|
181
|
-
id,
|
|
174
|
+
const incrementalEntry = {
|
|
182
175
|
errors: completedExecutionGroup.errors,
|
|
183
|
-
|
|
176
|
+
data: null,
|
|
177
|
+
};
|
|
178
|
+
const { path, label } = deferredFragmentRecord;
|
|
179
|
+
incrementalEntry.path = pathToArray(path);
|
|
180
|
+
if (label !== undefined) {
|
|
181
|
+
incrementalEntry.label = label;
|
|
182
|
+
}
|
|
183
|
+
context.incremental.push(incrementalEntry);
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
return;
|
|
@@ -192,58 +192,62 @@ class IncrementalPublisher {
|
|
|
192
192
|
if (completion === undefined) {
|
|
193
193
|
continue;
|
|
194
194
|
}
|
|
195
|
-
const id = deferredFragmentRecord.id;
|
|
196
|
-
invariant(id !== undefined);
|
|
197
195
|
const incremental = context.incremental;
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
196
|
+
const successfulExecutionGroups = completion.successfulExecutionGroups;
|
|
197
|
+
if (this._context.useIncrementalNotifications) {
|
|
198
|
+
const id = deferredFragmentRecord.id;
|
|
199
|
+
invariant(id !== undefined);
|
|
200
|
+
context.pending.push(...this._pendingSourcesToResults(completion.newPending));
|
|
201
|
+
for (const successfulExecutionGroup of successfulExecutionGroups) {
|
|
202
|
+
const { bestId, subPath } = this._getBestIdAndSubPath(id, deferredFragmentRecord, successfulExecutionGroup);
|
|
203
|
+
const incrementalEntry = {
|
|
204
|
+
...successfulExecutionGroup.result,
|
|
205
|
+
id: bestId,
|
|
206
|
+
};
|
|
207
|
+
if (subPath !== undefined) {
|
|
208
|
+
incrementalEntry.subPath = subPath;
|
|
209
|
+
}
|
|
210
|
+
incremental.push(incrementalEntry);
|
|
211
|
+
}
|
|
212
|
+
context.completed.push({ id });
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
for (const successfulExecutionGroup of successfulExecutionGroups) {
|
|
216
|
+
const incrementalEntry = {
|
|
217
|
+
...successfulExecutionGroup.result,
|
|
218
|
+
};
|
|
207
219
|
const { path, label } = deferredFragmentRecord;
|
|
208
220
|
incrementalEntry.path = pathToArray(path);
|
|
209
221
|
if (label !== undefined) {
|
|
210
222
|
incrementalEntry.label = label;
|
|
211
223
|
}
|
|
224
|
+
incremental.push(incrementalEntry);
|
|
212
225
|
}
|
|
213
|
-
if (subPath !== undefined) {
|
|
214
|
-
incrementalEntry.subPath = subPath;
|
|
215
|
-
}
|
|
216
|
-
incremental.push(incrementalEntry);
|
|
217
226
|
}
|
|
218
|
-
context.completed.push({ id });
|
|
219
227
|
}
|
|
220
228
|
}
|
|
221
229
|
_handleCompletedStreamItems(streamItemsResult, context) {
|
|
222
230
|
const streamRecord = streamItemsResult.streamRecord;
|
|
223
|
-
const id = streamRecord.id;
|
|
224
|
-
invariant(id !== undefined);
|
|
225
231
|
if (streamItemsResult.errors !== undefined) {
|
|
226
|
-
if (this._context.
|
|
227
|
-
const
|
|
228
|
-
|
|
232
|
+
if (this._context.useIncrementalNotifications) {
|
|
233
|
+
const id = streamRecord.id;
|
|
234
|
+
invariant(id !== undefined);
|
|
235
|
+
context.completed.push({
|
|
229
236
|
id,
|
|
230
237
|
errors: streamItemsResult.errors,
|
|
231
|
-
};
|
|
232
|
-
if (this._context.sendPathAndLabelOnIncremental) {
|
|
233
|
-
const { path, label, index } = streamRecord;
|
|
234
|
-
incrementalEntry.path = pathToArray(addPath(path, index, undefined));
|
|
235
|
-
if (label !== undefined) {
|
|
236
|
-
incrementalEntry.label = label;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
context.incremental.push(incrementalEntry);
|
|
240
|
-
context.completed.push({ id });
|
|
238
|
+
});
|
|
241
239
|
}
|
|
242
240
|
else {
|
|
243
|
-
|
|
244
|
-
id,
|
|
241
|
+
const incrementalEntry = {
|
|
245
242
|
errors: streamItemsResult.errors,
|
|
246
|
-
|
|
243
|
+
items: null,
|
|
244
|
+
};
|
|
245
|
+
const { path, label, index } = streamRecord;
|
|
246
|
+
incrementalEntry.path = pathToArray(addPath(path, index, undefined));
|
|
247
|
+
if (label !== undefined) {
|
|
248
|
+
incrementalEntry.label = label;
|
|
249
|
+
}
|
|
250
|
+
context.incremental.push(incrementalEntry);
|
|
247
251
|
}
|
|
248
252
|
this._incrementalGraph.removeStream(streamRecord);
|
|
249
253
|
if (isCancellableStreamRecord(streamRecord)) {
|
|
@@ -256,7 +260,11 @@ class IncrementalPublisher {
|
|
|
256
260
|
}
|
|
257
261
|
}
|
|
258
262
|
else if (streamItemsResult.result === undefined) {
|
|
259
|
-
|
|
263
|
+
if (this._context.useIncrementalNotifications) {
|
|
264
|
+
const id = streamRecord.id;
|
|
265
|
+
invariant(id !== undefined);
|
|
266
|
+
context.completed.push({ id });
|
|
267
|
+
}
|
|
260
268
|
this._incrementalGraph.removeStream(streamRecord);
|
|
261
269
|
if (isCancellableStreamRecord(streamRecord)) {
|
|
262
270
|
invariant(this._context.cancellableStreams !== undefined);
|
|
@@ -266,10 +274,14 @@ class IncrementalPublisher {
|
|
|
266
274
|
else {
|
|
267
275
|
const bareResult = streamItemsResult.result;
|
|
268
276
|
const incrementalEntry = {
|
|
269
|
-
id,
|
|
270
277
|
...bareResult,
|
|
271
278
|
};
|
|
272
|
-
if (this._context.
|
|
279
|
+
if (this._context.useIncrementalNotifications) {
|
|
280
|
+
const id = streamRecord.id;
|
|
281
|
+
invariant(id !== undefined);
|
|
282
|
+
incrementalEntry.id = id;
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
273
285
|
const { path, label, index } = streamRecord;
|
|
274
286
|
incrementalEntry.path = pathToArray(addPath(path, index, undefined));
|
|
275
287
|
streamRecord.index += bareResult.items.length;
|
|
@@ -281,7 +293,9 @@ class IncrementalPublisher {
|
|
|
281
293
|
const incrementalDataRecords = streamItemsResult.incrementalDataRecords;
|
|
282
294
|
if (incrementalDataRecords !== undefined) {
|
|
283
295
|
const newPending = this._incrementalGraph.getNewPending(incrementalDataRecords);
|
|
284
|
-
|
|
296
|
+
if (this._context.useIncrementalNotifications) {
|
|
297
|
+
context.pending.push(...this._pendingSourcesToResults(newPending));
|
|
298
|
+
}
|
|
285
299
|
}
|
|
286
300
|
}
|
|
287
301
|
}
|
|
@@ -11,7 +11,7 @@ import { invariant } from './invariant.js';
|
|
|
11
11
|
*
|
|
12
12
|
* @internal
|
|
13
13
|
*/
|
|
14
|
-
export function collectFields(schema, fragments, variableValues, runtimeType, selectionSet,
|
|
14
|
+
export function collectFields(schema, fragments, variableValues, runtimeType, selectionSet, errorOnSubscriptionWithIncrementalDelivery) {
|
|
15
15
|
const groupedFieldSet = new AccumulatorMap();
|
|
16
16
|
const newDeferUsages = [];
|
|
17
17
|
const context = {
|
|
@@ -19,7 +19,7 @@ export function collectFields(schema, fragments, variableValues, runtimeType, se
|
|
|
19
19
|
fragments,
|
|
20
20
|
variableValues,
|
|
21
21
|
runtimeType,
|
|
22
|
-
|
|
22
|
+
errorOnSubscriptionWithIncrementalDelivery,
|
|
23
23
|
visitedFragmentNames: new Set(),
|
|
24
24
|
};
|
|
25
25
|
collectFieldsImpl(context, selectionSet, groupedFieldSet, newDeferUsages);
|
|
@@ -35,13 +35,13 @@ export function collectFields(schema, fragments, variableValues, runtimeType, se
|
|
|
35
35
|
*
|
|
36
36
|
* @internal
|
|
37
37
|
*/
|
|
38
|
-
export function collectSubfields(schema, fragments, variableValues,
|
|
38
|
+
export function collectSubfields(schema, fragments, variableValues, errorOnSubscriptionWithIncrementalDelivery, returnType, fieldGroup) {
|
|
39
39
|
const context = {
|
|
40
40
|
schema,
|
|
41
41
|
fragments,
|
|
42
42
|
variableValues,
|
|
43
43
|
runtimeType: returnType,
|
|
44
|
-
|
|
44
|
+
errorOnSubscriptionWithIncrementalDelivery,
|
|
45
45
|
visitedFragmentNames: new Set(),
|
|
46
46
|
};
|
|
47
47
|
const subGroupedFieldSet = new AccumulatorMap();
|
|
@@ -58,7 +58,7 @@ export function collectSubfields(schema, fragments, variableValues, errorWithInc
|
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
60
|
function collectFieldsImpl(context, selectionSet, groupedFieldSet, newDeferUsages, deferUsage) {
|
|
61
|
-
const { schema, fragments, variableValues, runtimeType,
|
|
61
|
+
const { schema, fragments, variableValues, runtimeType, errorOnSubscriptionWithIncrementalDelivery, visitedFragmentNames, } = context;
|
|
62
62
|
for (const selection of selectionSet.selections) {
|
|
63
63
|
switch (selection.kind) {
|
|
64
64
|
case Kind.FIELD: {
|
|
@@ -76,7 +76,7 @@ function collectFieldsImpl(context, selectionSet, groupedFieldSet, newDeferUsage
|
|
|
76
76
|
!doesFragmentConditionMatch(schema, selection, runtimeType)) {
|
|
77
77
|
continue;
|
|
78
78
|
}
|
|
79
|
-
const newDeferUsage = getDeferUsage(
|
|
79
|
+
const newDeferUsage = getDeferUsage(errorOnSubscriptionWithIncrementalDelivery, variableValues, selection, deferUsage);
|
|
80
80
|
if (!newDeferUsage) {
|
|
81
81
|
collectFieldsImpl(context, selection.selectionSet, groupedFieldSet, newDeferUsages, deferUsage);
|
|
82
82
|
}
|
|
@@ -88,7 +88,7 @@ function collectFieldsImpl(context, selectionSet, groupedFieldSet, newDeferUsage
|
|
|
88
88
|
}
|
|
89
89
|
case Kind.FRAGMENT_SPREAD: {
|
|
90
90
|
const fragName = selection.name.value;
|
|
91
|
-
const newDeferUsage = getDeferUsage(
|
|
91
|
+
const newDeferUsage = getDeferUsage(errorOnSubscriptionWithIncrementalDelivery, variableValues, selection, deferUsage);
|
|
92
92
|
if (!newDeferUsage &&
|
|
93
93
|
(visitedFragmentNames.has(fragName) || !shouldIncludeNode(variableValues, selection))) {
|
|
94
94
|
continue;
|
|
@@ -115,7 +115,7 @@ function collectFieldsImpl(context, selectionSet, groupedFieldSet, newDeferUsage
|
|
|
115
115
|
* deferred based on the experimental flag, defer directive present and
|
|
116
116
|
* not disabled by the "if" argument.
|
|
117
117
|
*/
|
|
118
|
-
function getDeferUsage(
|
|
118
|
+
function getDeferUsage(errorOnSubscriptionWithIncrementalDelivery, variableValues, node, parentDeferUsage) {
|
|
119
119
|
const defer = getDirectiveValues(GraphQLDeferDirective, node, variableValues);
|
|
120
120
|
if (!defer) {
|
|
121
121
|
return;
|
|
@@ -123,7 +123,7 @@ function getDeferUsage(errorWithIncrementalSubscription, variableValues, node, p
|
|
|
123
123
|
if (defer['if'] === false) {
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
|
-
invariant(!
|
|
126
|
+
invariant(!errorOnSubscriptionWithIncrementalDelivery, '`@defer` directive not supported on subscription operations. Disable `@defer` by setting the `if` argument to `false`.');
|
|
127
127
|
return {
|
|
128
128
|
label: typeof defer['label'] === 'string' ? defer['label'] : undefined,
|
|
129
129
|
parentDeferUsage,
|
package/esm/execution/execute.js
CHANGED
|
@@ -16,7 +16,7 @@ import { getVariableValues } from './values.js';
|
|
|
16
16
|
* type. Memoizing ensures the subfields are not repeatedly calculated, which
|
|
17
17
|
* saves overhead when resolving lists of values.
|
|
18
18
|
*/
|
|
19
|
-
const collectSubfields = memoize3((exeContext, returnType, fieldGroup) => _collectSubfields(exeContext.schema, exeContext.fragments, exeContext.variableValues, exeContext.
|
|
19
|
+
const collectSubfields = memoize3((exeContext, returnType, fieldGroup) => _collectSubfields(exeContext.schema, exeContext.fragments, exeContext.variableValues, exeContext.errorOnSubscriptionWithIncrementalDelivery, returnType, fieldGroup));
|
|
20
20
|
/**
|
|
21
21
|
* Implements the "Executing requests" section of the GraphQL specification,
|
|
22
22
|
* including `@defer` and `@stream` as proposed in
|
|
@@ -149,7 +149,7 @@ export const getFragmentsFromDocument = memoize1(function getFragmentsFromDocume
|
|
|
149
149
|
* @internal
|
|
150
150
|
*/
|
|
151
151
|
export function buildExecutionContext(args) {
|
|
152
|
-
const { schema, document, rootValue, contextValue, variableValues: rawVariableValues, operationName, fieldResolver, typeResolver, subscribeFieldResolver, enableEarlyExecution,
|
|
152
|
+
const { schema, document, rootValue, contextValue, variableValues: rawVariableValues, operationName, fieldResolver, typeResolver, subscribeFieldResolver, enableEarlyExecution, incrementalPreset, deferWithoutDuplication, useIncrementalNotifications, errorOnSubscriptionWithIncrementalDelivery, signal, } = args;
|
|
153
153
|
// If the schema used for execution is invalid, throw an error.
|
|
154
154
|
assertValidSchema(schema);
|
|
155
155
|
const fragments = getFragmentsFromDocument(document);
|
|
@@ -188,6 +188,7 @@ export function buildExecutionContext(args) {
|
|
|
188
188
|
if (coercedVariableValues.errors) {
|
|
189
189
|
return coercedVariableValues.errors;
|
|
190
190
|
}
|
|
191
|
+
const latestPreset = incrementalPreset !== 'v17.0.0-alpha.2';
|
|
191
192
|
return {
|
|
192
193
|
schema,
|
|
193
194
|
fragments,
|
|
@@ -199,10 +200,12 @@ export function buildExecutionContext(args) {
|
|
|
199
200
|
typeResolver: typeResolver ?? defaultTypeResolver,
|
|
200
201
|
subscribeFieldResolver: subscribeFieldResolver ?? defaultFieldResolver,
|
|
201
202
|
enableEarlyExecution: enableEarlyExecution !== false,
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
203
|
+
deferWithoutDuplication: deferWithoutDuplication != null ? deferWithoutDuplication : latestPreset,
|
|
204
|
+
useIncrementalNotifications: useIncrementalNotifications != null ? useIncrementalNotifications : latestPreset,
|
|
205
|
+
errorOnSubscriptionWithIncrementalDelivery: operation.operation === 'subscription' &&
|
|
206
|
+
(errorOnSubscriptionWithIncrementalDelivery != null
|
|
207
|
+
? errorOnSubscriptionWithIncrementalDelivery
|
|
208
|
+
: latestPreset),
|
|
206
209
|
signal,
|
|
207
210
|
errors: undefined,
|
|
208
211
|
cancellableStreams: undefined,
|
|
@@ -224,14 +227,14 @@ function executeOperation(exeContext) {
|
|
|
224
227
|
throw exeContext.signal.reason;
|
|
225
228
|
}
|
|
226
229
|
try {
|
|
227
|
-
const { operation, schema, fragments, variableValues, rootValue,
|
|
230
|
+
const { operation, schema, fragments, variableValues, rootValue, deferWithoutDuplication, errorOnSubscriptionWithIncrementalDelivery, } = exeContext;
|
|
228
231
|
const rootType = getDefinedRootType(schema, operation.operation, [operation]);
|
|
229
232
|
if (rootType == null) {
|
|
230
233
|
createGraphQLError(`Schema is not configured to execute ${operation.operation} operation.`, {
|
|
231
234
|
nodes: operation,
|
|
232
235
|
});
|
|
233
236
|
}
|
|
234
|
-
const collectedFields = collectFields(schema, fragments, variableValues, rootType, operation.selectionSet,
|
|
237
|
+
const collectedFields = collectFields(schema, fragments, variableValues, rootType, operation.selectionSet, errorOnSubscriptionWithIncrementalDelivery);
|
|
235
238
|
let groupedFieldSet = collectedFields.groupedFieldSet;
|
|
236
239
|
const newDeferUsages = collectedFields.newDeferUsages;
|
|
237
240
|
let data;
|
|
@@ -239,7 +242,7 @@ function executeOperation(exeContext) {
|
|
|
239
242
|
data = executeRootGroupedFieldSet(exeContext, operation.operation, rootType, rootValue, groupedFieldSet, undefined);
|
|
240
243
|
}
|
|
241
244
|
else {
|
|
242
|
-
const executionPlan =
|
|
245
|
+
const executionPlan = deferWithoutDuplication
|
|
243
246
|
? buildExecutionPlan(groupedFieldSet)
|
|
244
247
|
: buildBranchingExecutionPlan(groupedFieldSet);
|
|
245
248
|
groupedFieldSet = executionPlan.groupedFieldSet;
|
|
@@ -552,7 +555,7 @@ function getStreamUsage(exeContext, fieldGroup, path) {
|
|
|
552
555
|
}
|
|
553
556
|
invariant(typeof stream['initialCount'] === 'number', 'initialCount must be a number');
|
|
554
557
|
invariant(stream['initialCount'] >= 0, 'initialCount must be a positive integer');
|
|
555
|
-
invariant(!exeContext.
|
|
558
|
+
invariant(!exeContext.errorOnSubscriptionWithIncrementalDelivery, '`@stream` directive not supported on subscription operations. Disable `@stream` by setting the `if` argument to `false`.');
|
|
556
559
|
const streamedFieldGroup = fieldGroup.map(fieldDetails => ({
|
|
557
560
|
node: fieldDetails.node,
|
|
558
561
|
deferUsage: undefined,
|
|
@@ -861,7 +864,7 @@ function collectAndExecuteSubfields(exeContext, returnType, fieldGroup, path, re
|
|
|
861
864
|
if (deferMap === undefined && newDeferUsages.length === 0) {
|
|
862
865
|
return executeFields(exeContext, returnType, result, path, groupedFieldSet, incrementalContext, undefined);
|
|
863
866
|
}
|
|
864
|
-
const subExecutionPlan = buildSubExecutionPlan(groupedFieldSet, incrementalContext?.deferUsageSet, exeContext.
|
|
867
|
+
const subExecutionPlan = buildSubExecutionPlan(groupedFieldSet, incrementalContext?.deferUsageSet, exeContext.deferWithoutDuplication);
|
|
865
868
|
groupedFieldSet = subExecutionPlan.groupedFieldSet;
|
|
866
869
|
const newGroupedFieldSets = subExecutionPlan.newGroupedFieldSets;
|
|
867
870
|
const newDeferMap = addNewDeferredFragments(newDeferUsages, new Map(deferMap), path);
|
|
@@ -873,13 +876,13 @@ function collectAndExecuteSubfields(exeContext, returnType, fieldGroup, path, re
|
|
|
873
876
|
}
|
|
874
877
|
return subFields;
|
|
875
878
|
}
|
|
876
|
-
function buildSubExecutionPlan(originalGroupedFieldSet, deferUsageSet,
|
|
879
|
+
function buildSubExecutionPlan(originalGroupedFieldSet, deferUsageSet, deferWithoutDuplication) {
|
|
877
880
|
let executionPlan = originalGroupedFieldSet
|
|
878
881
|
._executionPlan;
|
|
879
882
|
if (executionPlan !== undefined) {
|
|
880
883
|
return executionPlan;
|
|
881
884
|
}
|
|
882
|
-
executionPlan =
|
|
885
|
+
executionPlan = deferWithoutDuplication
|
|
883
886
|
? buildExecutionPlan(originalGroupedFieldSet, deferUsageSet)
|
|
884
887
|
: buildBranchingExecutionPlan(originalGroupedFieldSet, deferUsageSet);
|
|
885
888
|
originalGroupedFieldSet._executionPlan =
|
|
@@ -1047,14 +1050,14 @@ function createSourceEventStreamImpl(exeContext) {
|
|
|
1047
1050
|
}
|
|
1048
1051
|
}
|
|
1049
1052
|
function executeSubscription(exeContext) {
|
|
1050
|
-
const { schema, fragments, operation, variableValues, rootValue,
|
|
1053
|
+
const { schema, fragments, operation, variableValues, rootValue, errorOnSubscriptionWithIncrementalDelivery, } = exeContext;
|
|
1051
1054
|
const rootType = schema.getSubscriptionType();
|
|
1052
1055
|
if (rootType == null) {
|
|
1053
1056
|
throw createGraphQLError('Schema is not configured to execute subscription operation.', {
|
|
1054
1057
|
nodes: operation,
|
|
1055
1058
|
});
|
|
1056
1059
|
}
|
|
1057
|
-
const { groupedFieldSet } = collectFields(schema, fragments, variableValues, rootType, operation.selectionSet,
|
|
1060
|
+
const { groupedFieldSet } = collectFields(schema, fragments, variableValues, rootType, operation.selectionSet, errorOnSubscriptionWithIncrementalDelivery);
|
|
1058
1061
|
const firstRootField = [...groupedFieldSet.entries()][0];
|
|
1059
1062
|
const [responseName, fieldGroup] = firstRootField;
|
|
1060
1063
|
const fieldName = fieldGroup[0].node.name.value;
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-tools/executor",
|
|
3
|
-
"version": "2.0.0-alpha-
|
|
3
|
+
"version": "2.0.0-alpha-20240805144842-131e76d507ce82e59a400bf90758e7af71493abf",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@graphql-tools/utils": "10.4.0-alpha-
|
|
9
|
+
"@graphql-tools/utils": "10.4.0-alpha-20240805144842-131e76d507ce82e59a400bf90758e7af71493abf",
|
|
10
10
|
"@graphql-typed-document-node/core": "3.2.0",
|
|
11
11
|
"@repeaterjs/repeater": "^3.0.4",
|
|
12
12
|
"tslib": "^2.4.0",
|
|
@@ -2,8 +2,7 @@ import type { GraphQLError } from 'graphql';
|
|
|
2
2
|
import type { CancellableStreamRecord, IncrementalDataRecord, IncrementalExecutionResults } from './types.cjs';
|
|
3
3
|
export declare function buildIncrementalResponse<TData = any>(context: IncrementalPublisherContext, result: TData, errors: ReadonlyArray<GraphQLError> | undefined, incrementalDataRecords: ReadonlyArray<IncrementalDataRecord>): IncrementalExecutionResults<TData>;
|
|
4
4
|
interface IncrementalPublisherContext {
|
|
5
|
-
|
|
6
|
-
sendPathAndLabelOnIncremental: boolean;
|
|
5
|
+
useIncrementalNotifications: boolean;
|
|
7
6
|
signal: AbortSignal | undefined;
|
|
8
7
|
cancellableStreams: Set<CancellableStreamRecord> | undefined;
|
|
9
8
|
}
|
|
@@ -2,8 +2,7 @@ import type { GraphQLError } from 'graphql';
|
|
|
2
2
|
import type { CancellableStreamRecord, IncrementalDataRecord, IncrementalExecutionResults } from './types.js';
|
|
3
3
|
export declare function buildIncrementalResponse<TData = any>(context: IncrementalPublisherContext, result: TData, errors: ReadonlyArray<GraphQLError> | undefined, incrementalDataRecords: ReadonlyArray<IncrementalDataRecord>): IncrementalExecutionResults<TData>;
|
|
4
4
|
interface IncrementalPublisherContext {
|
|
5
|
-
|
|
6
|
-
sendPathAndLabelOnIncremental: boolean;
|
|
5
|
+
useIncrementalNotifications: boolean;
|
|
7
6
|
signal: AbortSignal | undefined;
|
|
8
7
|
cancellableStreams: Set<CancellableStreamRecord> | undefined;
|
|
9
8
|
}
|
|
@@ -18,7 +18,7 @@ export type GroupedFieldSet = ReadonlyMap<string, FieldGroup>;
|
|
|
18
18
|
*
|
|
19
19
|
* @internal
|
|
20
20
|
*/
|
|
21
|
-
export declare function collectFields<TVariables = any>(schema: GraphQLSchema, fragments: Record<string, FragmentDefinitionNode>, variableValues: TVariables, runtimeType: GraphQLObjectType, selectionSet: SelectionSetNode,
|
|
21
|
+
export declare function collectFields<TVariables = any>(schema: GraphQLSchema, fragments: Record<string, FragmentDefinitionNode>, variableValues: TVariables, runtimeType: GraphQLObjectType, selectionSet: SelectionSetNode, errorOnSubscriptionWithIncrementalDelivery: boolean): {
|
|
22
22
|
groupedFieldSet: GroupedFieldSet;
|
|
23
23
|
newDeferUsages: ReadonlyArray<DeferUsage>;
|
|
24
24
|
};
|
|
@@ -34,7 +34,7 @@ export declare function collectFields<TVariables = any>(schema: GraphQLSchema, f
|
|
|
34
34
|
*/
|
|
35
35
|
export declare function collectSubfields(schema: GraphQLSchema, fragments: Record<string, FragmentDefinitionNode>, variableValues: {
|
|
36
36
|
[variable: string]: unknown;
|
|
37
|
-
},
|
|
37
|
+
}, errorOnSubscriptionWithIncrementalDelivery: boolean, returnType: GraphQLObjectType, fieldGroup: FieldGroup): {
|
|
38
38
|
groupedFieldSet: GroupedFieldSet;
|
|
39
39
|
newDeferUsages: ReadonlyArray<DeferUsage>;
|
|
40
40
|
};
|
|
@@ -18,7 +18,7 @@ export type GroupedFieldSet = ReadonlyMap<string, FieldGroup>;
|
|
|
18
18
|
*
|
|
19
19
|
* @internal
|
|
20
20
|
*/
|
|
21
|
-
export declare function collectFields<TVariables = any>(schema: GraphQLSchema, fragments: Record<string, FragmentDefinitionNode>, variableValues: TVariables, runtimeType: GraphQLObjectType, selectionSet: SelectionSetNode,
|
|
21
|
+
export declare function collectFields<TVariables = any>(schema: GraphQLSchema, fragments: Record<string, FragmentDefinitionNode>, variableValues: TVariables, runtimeType: GraphQLObjectType, selectionSet: SelectionSetNode, errorOnSubscriptionWithIncrementalDelivery: boolean): {
|
|
22
22
|
groupedFieldSet: GroupedFieldSet;
|
|
23
23
|
newDeferUsages: ReadonlyArray<DeferUsage>;
|
|
24
24
|
};
|
|
@@ -34,7 +34,7 @@ export declare function collectFields<TVariables = any>(schema: GraphQLSchema, f
|
|
|
34
34
|
*/
|
|
35
35
|
export declare function collectSubfields(schema: GraphQLSchema, fragments: Record<string, FragmentDefinitionNode>, variableValues: {
|
|
36
36
|
[variable: string]: unknown;
|
|
37
|
-
},
|
|
37
|
+
}, errorOnSubscriptionWithIncrementalDelivery: boolean, returnType: GraphQLObjectType, fieldGroup: FieldGroup): {
|
|
38
38
|
groupedFieldSet: GroupedFieldSet;
|
|
39
39
|
newDeferUsages: ReadonlyArray<DeferUsage>;
|
|
40
40
|
};
|
|
@@ -39,15 +39,15 @@ export interface ExecutionContext<TVariables = any, TContext = any> {
|
|
|
39
39
|
typeResolver: GraphQLTypeResolver<any, TContext>;
|
|
40
40
|
subscribeFieldResolver: GraphQLFieldResolver<any, TContext>;
|
|
41
41
|
enableEarlyExecution: boolean;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
errorWithIncrementalSubscription: boolean;
|
|
42
|
+
deferWithoutDuplication: boolean;
|
|
43
|
+
useIncrementalNotifications: boolean;
|
|
44
|
+
errorOnSubscriptionWithIncrementalDelivery: boolean;
|
|
46
45
|
signal: AbortSignal | undefined;
|
|
47
46
|
errors: AccumulatorMap<Path | undefined, GraphQLError> | undefined;
|
|
48
47
|
cancellableStreams: Set<CancellableStreamRecord> | undefined;
|
|
49
48
|
incrementalDataRecords: Array<IncrementalDataRecord> | undefined;
|
|
50
49
|
}
|
|
50
|
+
export type IncrementalPreset = 'v17.0.0-alpha.2' | 'v17.0.0-alpha.3';
|
|
51
51
|
export interface ExecutionArgs<TData = any, TVariables = any, TContext = any> {
|
|
52
52
|
schema: GraphQLSchema;
|
|
53
53
|
document: TypedDocumentNode<TData, TVariables>;
|
|
@@ -59,10 +59,10 @@ export interface ExecutionArgs<TData = any, TVariables = any, TContext = any> {
|
|
|
59
59
|
typeResolver?: Maybe<GraphQLTypeResolver<any, TContext>>;
|
|
60
60
|
subscribeFieldResolver?: Maybe<GraphQLFieldResolver<any, TContext>>;
|
|
61
61
|
enableEarlyExecution?: Maybe<boolean>;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
incrementalPreset?: Maybe<IncrementalPreset>;
|
|
63
|
+
deferWithoutDuplication?: Maybe<boolean>;
|
|
64
|
+
useIncrementalNotifications?: Maybe<boolean>;
|
|
65
|
+
errorOnSubscriptionWithIncrementalDelivery?: Maybe<boolean>;
|
|
66
66
|
signal?: AbortSignal;
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
@@ -160,7 +160,7 @@ export declare const defaultFieldResolver: GraphQLFieldResolver<unknown, unknown
|
|
|
160
160
|
* Accepts an object with named arguments.
|
|
161
161
|
*/
|
|
162
162
|
export declare function subscribe<TData = any, TVariables = any, TContext = any>(args: ExecutionArgs<TData, TVariables, TContext> & {
|
|
163
|
-
|
|
163
|
+
errorOnSubscriptionWithIncrementalDelivery: true | undefined | null;
|
|
164
164
|
}): MaybePromise<AsyncGenerator<SingularExecutionResult<TData>, void, void> | SingularExecutionResult<TData>>;
|
|
165
165
|
export declare function subscribe<TData = any, TVariables = any, TContext = any>(args: ExecutionArgs<TData, TVariables, TContext>): MaybePromise<AsyncGenerator<SingularExecutionResult<TData> | InitialIncrementalExecutionResult<TData> | SubsequentIncrementalExecutionResult<TData>, void, void> | SingularExecutionResult<TData>>;
|
|
166
166
|
export declare function flattenIncrementalResults<TData>(incrementalResults: IncrementalExecutionResults<TData>): AsyncGenerator<SubsequentIncrementalExecutionResult<TData, Record<string, unknown>>, void, void>;
|
|
@@ -39,15 +39,15 @@ export interface ExecutionContext<TVariables = any, TContext = any> {
|
|
|
39
39
|
typeResolver: GraphQLTypeResolver<any, TContext>;
|
|
40
40
|
subscribeFieldResolver: GraphQLFieldResolver<any, TContext>;
|
|
41
41
|
enableEarlyExecution: boolean;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
errorWithIncrementalSubscription: boolean;
|
|
42
|
+
deferWithoutDuplication: boolean;
|
|
43
|
+
useIncrementalNotifications: boolean;
|
|
44
|
+
errorOnSubscriptionWithIncrementalDelivery: boolean;
|
|
46
45
|
signal: AbortSignal | undefined;
|
|
47
46
|
errors: AccumulatorMap<Path | undefined, GraphQLError> | undefined;
|
|
48
47
|
cancellableStreams: Set<CancellableStreamRecord> | undefined;
|
|
49
48
|
incrementalDataRecords: Array<IncrementalDataRecord> | undefined;
|
|
50
49
|
}
|
|
50
|
+
export type IncrementalPreset = 'v17.0.0-alpha.2' | 'v17.0.0-alpha.3';
|
|
51
51
|
export interface ExecutionArgs<TData = any, TVariables = any, TContext = any> {
|
|
52
52
|
schema: GraphQLSchema;
|
|
53
53
|
document: TypedDocumentNode<TData, TVariables>;
|
|
@@ -59,10 +59,10 @@ export interface ExecutionArgs<TData = any, TVariables = any, TContext = any> {
|
|
|
59
59
|
typeResolver?: Maybe<GraphQLTypeResolver<any, TContext>>;
|
|
60
60
|
subscribeFieldResolver?: Maybe<GraphQLFieldResolver<any, TContext>>;
|
|
61
61
|
enableEarlyExecution?: Maybe<boolean>;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
incrementalPreset?: Maybe<IncrementalPreset>;
|
|
63
|
+
deferWithoutDuplication?: Maybe<boolean>;
|
|
64
|
+
useIncrementalNotifications?: Maybe<boolean>;
|
|
65
|
+
errorOnSubscriptionWithIncrementalDelivery?: Maybe<boolean>;
|
|
66
66
|
signal?: AbortSignal;
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
@@ -160,7 +160,7 @@ export declare const defaultFieldResolver: GraphQLFieldResolver<unknown, unknown
|
|
|
160
160
|
* Accepts an object with named arguments.
|
|
161
161
|
*/
|
|
162
162
|
export declare function subscribe<TData = any, TVariables = any, TContext = any>(args: ExecutionArgs<TData, TVariables, TContext> & {
|
|
163
|
-
|
|
163
|
+
errorOnSubscriptionWithIncrementalDelivery: true | undefined | null;
|
|
164
164
|
}): MaybePromise<AsyncGenerator<SingularExecutionResult<TData>, void, void> | SingularExecutionResult<TData>>;
|
|
165
165
|
export declare function subscribe<TData = any, TVariables = any, TContext = any>(args: ExecutionArgs<TData, TVariables, TContext>): MaybePromise<AsyncGenerator<SingularExecutionResult<TData> | InitialIncrementalExecutionResult<TData> | SubsequentIncrementalExecutionResult<TData>, void, void> | SingularExecutionResult<TData>>;
|
|
166
166
|
export declare function flattenIncrementalResults<TData>(incrementalResults: IncrementalExecutionResults<TData>): AsyncGenerator<SubsequentIncrementalExecutionResult<TData, Record<string, unknown>>, void, void>;
|
|
@@ -26,13 +26,13 @@ export interface IncrementalExecutionResults<TData = unknown, TExtensions = Reco
|
|
|
26
26
|
}
|
|
27
27
|
export interface InitialIncrementalExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> extends SingularExecutionResult<TData, TExtensions> {
|
|
28
28
|
data: TData;
|
|
29
|
-
pending
|
|
29
|
+
pending?: ReadonlyArray<PendingResult>;
|
|
30
30
|
hasNext: true;
|
|
31
31
|
extensions?: TExtensions;
|
|
32
32
|
}
|
|
33
33
|
export interface FormattedInitialIncrementalExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> extends FormattedExecutionResult<TData, TExtensions> {
|
|
34
34
|
data: TData;
|
|
35
|
-
pending
|
|
35
|
+
pending?: ReadonlyArray<PendingResult>;
|
|
36
36
|
hasNext: boolean;
|
|
37
37
|
extensions?: TExtensions;
|
|
38
38
|
}
|
|
@@ -57,7 +57,7 @@ interface ExecutionGroupResult<TData = Record<string, unknown>> {
|
|
|
57
57
|
export interface IncrementalDeferResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> {
|
|
58
58
|
errors?: ReadonlyArray<GraphQLError>;
|
|
59
59
|
data: TData | null;
|
|
60
|
-
id
|
|
60
|
+
id?: string;
|
|
61
61
|
path?: ReadonlyArray<string | number>;
|
|
62
62
|
label?: string;
|
|
63
63
|
subPath?: ReadonlyArray<string | number>;
|
|
@@ -79,7 +79,7 @@ interface StreamItemsRecordResult<TData = ReadonlyArray<unknown>> {
|
|
|
79
79
|
export interface IncrementalStreamResult<TData = ReadonlyArray<unknown>, TExtensions = Record<string, unknown>> {
|
|
80
80
|
errors?: ReadonlyArray<GraphQLError>;
|
|
81
81
|
items: TData | null;
|
|
82
|
-
id
|
|
82
|
+
id?: string;
|
|
83
83
|
path?: ReadonlyArray<string | number>;
|
|
84
84
|
label?: string;
|
|
85
85
|
extensions?: TExtensions;
|
|
@@ -26,13 +26,13 @@ export interface IncrementalExecutionResults<TData = unknown, TExtensions = Reco
|
|
|
26
26
|
}
|
|
27
27
|
export interface InitialIncrementalExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> extends SingularExecutionResult<TData, TExtensions> {
|
|
28
28
|
data: TData;
|
|
29
|
-
pending
|
|
29
|
+
pending?: ReadonlyArray<PendingResult>;
|
|
30
30
|
hasNext: true;
|
|
31
31
|
extensions?: TExtensions;
|
|
32
32
|
}
|
|
33
33
|
export interface FormattedInitialIncrementalExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> extends FormattedExecutionResult<TData, TExtensions> {
|
|
34
34
|
data: TData;
|
|
35
|
-
pending
|
|
35
|
+
pending?: ReadonlyArray<PendingResult>;
|
|
36
36
|
hasNext: boolean;
|
|
37
37
|
extensions?: TExtensions;
|
|
38
38
|
}
|
|
@@ -57,7 +57,7 @@ interface ExecutionGroupResult<TData = Record<string, unknown>> {
|
|
|
57
57
|
export interface IncrementalDeferResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> {
|
|
58
58
|
errors?: ReadonlyArray<GraphQLError>;
|
|
59
59
|
data: TData | null;
|
|
60
|
-
id
|
|
60
|
+
id?: string;
|
|
61
61
|
path?: ReadonlyArray<string | number>;
|
|
62
62
|
label?: string;
|
|
63
63
|
subPath?: ReadonlyArray<string | number>;
|
|
@@ -79,7 +79,7 @@ interface StreamItemsRecordResult<TData = ReadonlyArray<unknown>> {
|
|
|
79
79
|
export interface IncrementalStreamResult<TData = ReadonlyArray<unknown>, TExtensions = Record<string, unknown>> {
|
|
80
80
|
errors?: ReadonlyArray<GraphQLError>;
|
|
81
81
|
items: TData | null;
|
|
82
|
-
id
|
|
82
|
+
id?: string;
|
|
83
83
|
path?: ReadonlyArray<string | number>;
|
|
84
84
|
label?: string;
|
|
85
85
|
extensions?: TExtensions;
|