@graphql-tools/executor 0.0.2-alpha-20221029195929-bc9be579 → 0.0.2-alpha-20221029200225-c09daca7

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.
Files changed (45) hide show
  1. package/cjs/execution/execute.js +109 -656
  2. package/cjs/execution/subscribe.js +158 -0
  3. package/cjs/index.js +0 -1
  4. package/esm/execution/execute.js +108 -653
  5. package/esm/execution/subscribe.js +153 -0
  6. package/esm/index.js +0 -1
  7. package/package.json +2 -2
  8. package/typings/execution/execute.d.cts +22 -167
  9. package/typings/execution/execute.d.ts +22 -167
  10. package/typings/execution/subscribe.d.cts +59 -0
  11. package/typings/execution/subscribe.d.ts +59 -0
  12. package/typings/index.d.cts +0 -1
  13. package/typings/index.d.ts +0 -1
  14. package/cjs/directives/defer.js +0 -23
  15. package/cjs/directives/index.js +0 -5
  16. package/cjs/directives/stream.js +0 -28
  17. package/cjs/execution/AccumulatorMap.js +0 -21
  18. package/cjs/execution/collectFields.js +0 -126
  19. package/cjs/execution/flattenAsyncIterable.js +0 -91
  20. package/cjs/execution/invariant.js +0 -9
  21. package/cjs/execution/promiseForObject.js +0 -21
  22. package/esm/directives/defer.js +0 -20
  23. package/esm/directives/index.js +0 -2
  24. package/esm/directives/stream.js +0 -25
  25. package/esm/execution/AccumulatorMap.js +0 -17
  26. package/esm/execution/collectFields.js +0 -122
  27. package/esm/execution/flattenAsyncIterable.js +0 -87
  28. package/esm/execution/invariant.js +0 -5
  29. package/esm/execution/promiseForObject.js +0 -17
  30. package/typings/directives/defer.d.cts +0 -5
  31. package/typings/directives/defer.d.ts +0 -5
  32. package/typings/directives/index.d.cts +0 -2
  33. package/typings/directives/index.d.ts +0 -2
  34. package/typings/directives/stream.d.cts +0 -5
  35. package/typings/directives/stream.d.ts +0 -5
  36. package/typings/execution/AccumulatorMap.d.cts +0 -7
  37. package/typings/execution/AccumulatorMap.d.ts +0 -7
  38. package/typings/execution/collectFields.d.cts +0 -32
  39. package/typings/execution/collectFields.d.ts +0 -32
  40. package/typings/execution/flattenAsyncIterable.d.cts +0 -7
  41. package/typings/execution/flattenAsyncIterable.d.ts +0 -7
  42. package/typings/execution/invariant.d.cts +0 -1
  43. package/typings/execution/invariant.d.ts +0 -1
  44. package/typings/execution/promiseForObject.d.cts +0 -12
  45. package/typings/execution/promiseForObject.d.ts +0 -12
@@ -1,21 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFieldDef = exports.createSourceEventStream = exports.experimentalSubscribeIncrementally = exports.subscribe = exports.defaultFieldResolver = exports.defaultTypeResolver = exports.buildResolveInfo = exports.buildExecutionContext = exports.assertValidExecutionArguments = exports.executeSync = exports.experimentalExecuteIncrementally = exports.execute = void 0;
3
+ exports.getFieldDef = exports.createSourceEventStream = exports.subscribe = exports.defaultFieldResolver = exports.defaultTypeResolver = exports.buildResolveInfo = exports.buildExecutionContext = exports.assertValidExecutionArguments = exports.executeSync = exports.execute = void 0;
4
4
  const graphql_1 = require("graphql");
5
5
  const utils_1 = require("@graphql-tools/utils");
6
6
  const values_js_1 = require("./values.js");
7
- const promiseForObject_js_1 = require("./promiseForObject.js");
8
- const flattenAsyncIterable_js_1 = require("./flattenAsyncIterable.js");
9
- const collectFields_js_1 = require("./collectFields.js");
10
- const index_js_1 = require("../directives/index.js");
11
- const invariant_js_1 = require("./invariant.js");
12
- /**
13
- * A memoized collection of relevant subfields with regard to the return
14
- * type. Memoizing ensures the subfields are not repeatedly calculated, which
15
- * saves overhead when resolving lists of values.
16
- */
17
- const collectSubfields = (0, utils_1.memoize3)((exeContext, returnType, fieldNodes) => (0, collectFields_js_1.collectSubfields)(exeContext.schema, exeContext.fragments, exeContext.variableValues, returnType, fieldNodes));
18
- const UNEXPECTED_MULTIPLE_PAYLOADS = 'Executing this GraphQL operation would unexpectedly produce multiple payloads (due to @defer or @stream directive)';
19
7
  /**
20
8
  * Implements the "Executing requests" section of the GraphQL specification.
21
9
  *
@@ -25,44 +13,8 @@ const UNEXPECTED_MULTIPLE_PAYLOADS = 'Executing this GraphQL operation would une
25
13
  *
26
14
  * If the arguments to this function do not result in a legal execution context,
27
15
  * a GraphQLError will be thrown immediately explaining the invalid input.
28
- *
29
- * This function does not support incremental delivery (`@defer` and `@stream`).
30
- * If an operation which would defer or stream data is executed with this
31
- * function, it will throw or resolve to an object containing an error instead.
32
- * Use `experimentalExecuteIncrementally` if you want to support incremental
33
- * delivery.
34
16
  */
35
17
  function execute(args) {
36
- const result = experimentalExecuteIncrementally(args);
37
- if (!(0, utils_1.isPromise)(result)) {
38
- if ('initialResult' in result) {
39
- throw new Error(UNEXPECTED_MULTIPLE_PAYLOADS);
40
- }
41
- return result;
42
- }
43
- return result.then(incrementalResult => {
44
- if ('initialResult' in incrementalResult) {
45
- return {
46
- errors: [(0, utils_1.createGraphQLError)(UNEXPECTED_MULTIPLE_PAYLOADS)],
47
- };
48
- }
49
- return incrementalResult;
50
- });
51
- }
52
- exports.execute = execute;
53
- /**
54
- * Implements the "Executing requests" section of the GraphQL specification,
55
- * including `@defer` and `@stream` as proposed in
56
- * https://github.com/graphql/graphql-spec/pull/742
57
- *
58
- * This function returns a Promise of an ExperimentalIncrementalExecutionResults
59
- * object. This object either consists of a single ExecutionResult, or an
60
- * object containing an `initialResult` and a stream of `subsequentResults`.
61
- *
62
- * If the arguments to this function do not result in a legal execution context,
63
- * a GraphQLError will be thrown immediately explaining the invalid input.
64
- */
65
- function experimentalExecuteIncrementally(args) {
66
18
  // If a valid execution context cannot be created due to incorrect arguments,
67
19
  // a "Response" with only errors is returned.
68
20
  const exeContext = buildExecutionContext(args);
@@ -72,7 +24,7 @@ function experimentalExecuteIncrementally(args) {
72
24
  }
73
25
  return executeImpl(exeContext);
74
26
  }
75
- exports.experimentalExecuteIncrementally = experimentalExecuteIncrementally;
27
+ exports.execute = execute;
76
28
  function executeImpl(exeContext) {
77
29
  // Return a Promise that will eventually resolve to the data described by
78
30
  // The "Response" section of the GraphQL specification.
@@ -88,34 +40,12 @@ function executeImpl(exeContext) {
88
40
  try {
89
41
  const result = executeOperation(exeContext);
90
42
  if ((0, utils_1.isPromise)(result)) {
91
- return result.then(data => {
92
- const initialResult = buildResponse(data, exeContext.errors);
93
- if (exeContext.subsequentPayloads.size > 0) {
94
- return {
95
- initialResult: {
96
- ...initialResult,
97
- hasNext: true,
98
- },
99
- subsequentResults: yieldSubsequentPayloads(exeContext),
100
- };
101
- }
102
- return initialResult;
103
- }, error => {
43
+ return result.then(data => buildResponse(data, exeContext.errors), error => {
104
44
  exeContext.errors.push(error);
105
45
  return buildResponse(null, exeContext.errors);
106
46
  });
107
47
  }
108
- const initialResult = buildResponse(result, exeContext.errors);
109
- if (exeContext.subsequentPayloads.size > 0) {
110
- return {
111
- initialResult: {
112
- ...initialResult,
113
- hasNext: true,
114
- },
115
- subsequentResults: yieldSubsequentPayloads(exeContext),
116
- };
117
- }
118
- return initialResult;
48
+ return buildResponse(result, exeContext.errors);
119
49
  }
120
50
  catch (error) {
121
51
  exeContext.errors.push(error);
@@ -128,9 +58,9 @@ function executeImpl(exeContext) {
128
58
  * that all field resolvers are also synchronous.
129
59
  */
130
60
  function executeSync(args) {
131
- const result = experimentalExecuteIncrementally(args);
61
+ const result = execute(args);
132
62
  // Assert that the execution was synchronous.
133
- if ((0, utils_1.isPromise)(result) || 'initialResult' in result) {
63
+ if ((0, utils_1.isPromise)(result)) {
134
64
  throw new Error('GraphQL execution failed to complete synchronously.');
135
65
  }
136
66
  return result;
@@ -218,7 +148,6 @@ function buildExecutionContext(args) {
218
148
  fieldResolver: fieldResolver !== null && fieldResolver !== void 0 ? fieldResolver : exports.defaultFieldResolver,
219
149
  typeResolver: typeResolver !== null && typeResolver !== void 0 ? typeResolver : exports.defaultTypeResolver,
220
150
  subscribeFieldResolver: subscribeFieldResolver !== null && subscribeFieldResolver !== void 0 ? subscribeFieldResolver : exports.defaultFieldResolver,
221
- subsequentPayloads: new Set(),
222
151
  errors: [],
223
152
  };
224
153
  }
@@ -227,7 +156,6 @@ function buildPerEventExecutionContext(exeContext, payload) {
227
156
  return {
228
157
  ...exeContext,
229
158
  rootValue: payload,
230
- subsequentPayloads: new Set(),
231
159
  errors: [],
232
160
  };
233
161
  }
@@ -237,32 +165,26 @@ function buildPerEventExecutionContext(exeContext, payload) {
237
165
  function executeOperation(exeContext) {
238
166
  const { operation, schema, fragments, variableValues, rootValue } = exeContext;
239
167
  const rootType = (0, utils_1.getDefinedRootType)(schema, operation.operation, [operation]);
240
- if (rootType == null) {
241
- (0, utils_1.createGraphQLError)(`Schema is not configured to execute ${operation.operation} operation.`, {
242
- nodes: operation,
243
- });
244
- }
245
- const { fields: rootFields, patches } = (0, collectFields_js_1.collectFields)(schema, fragments, variableValues, rootType, operation.selectionSet);
168
+ const rootFields = (0, utils_1.collectFields)(schema, fragments, variableValues, rootType, operation.selectionSet);
246
169
  const path = undefined;
247
- let result;
248
- if (operation.operation === 'mutation') {
249
- result = executeFieldsSerially(exeContext, rootType, rootValue, path, rootFields);
250
- }
251
- else {
252
- result = executeFields(exeContext, rootType, rootValue, path, rootFields);
253
- }
254
- for (const patch of patches) {
255
- const { label, fields: patchFields } = patch;
256
- executeDeferredFragment(exeContext, rootType, rootValue, patchFields, label, path);
257
- }
258
- return result;
170
+ switch (operation.operation) {
171
+ case 'query':
172
+ return executeFields(exeContext, rootType, rootValue, path, rootFields);
173
+ case 'mutation':
174
+ return executeFieldsSerially(exeContext, rootType, rootValue, path, rootFields);
175
+ case 'subscription':
176
+ // TODO: deprecate `subscribe` and move all logic here
177
+ // Temporary solution until we finish merging execute and subscribe together
178
+ return executeFields(exeContext, rootType, rootValue, path, rootFields);
179
+ }
180
+ throw new Error(`Can only execute queries, mutations and subscriptions, got "${operation.operation}".`);
259
181
  }
260
182
  /**
261
183
  * Implements the "Executing selection sets" section of the spec
262
184
  * for fields that must be executed serially.
263
185
  */
264
186
  function executeFieldsSerially(exeContext, parentType, sourceValue, path, fields) {
265
- return (0, utils_1.promiseReduce)(fields, (results, [responseName, fieldNodes]) => {
187
+ return (0, utils_1.promiseReduce)(fields.entries(), (results, [responseName, fieldNodes]) => {
266
188
  const fieldPath = (0, utils_1.addPath)(path, responseName, parentType.name);
267
189
  const result = executeField(exeContext, parentType, sourceValue, fieldNodes, fieldPath);
268
190
  if (result === undefined) {
@@ -282,30 +204,19 @@ function executeFieldsSerially(exeContext, parentType, sourceValue, path, fields
282
204
  * Implements the "Executing selection sets" section of the spec
283
205
  * for fields that may be executed in parallel.
284
206
  */
285
- function executeFields(exeContext, parentType, sourceValue, path, fields, asyncPayloadRecord) {
207
+ function executeFields(exeContext, parentType, sourceValue, path, fields) {
286
208
  const results = Object.create(null);
287
209
  let containsPromise = false;
288
- try {
289
- for (const [responseName, fieldNodes] of fields) {
290
- const fieldPath = (0, utils_1.addPath)(path, responseName, parentType.name);
291
- const result = executeField(exeContext, parentType, sourceValue, fieldNodes, fieldPath, asyncPayloadRecord);
292
- if (result !== undefined) {
293
- results[responseName] = result;
294
- if ((0, utils_1.isPromise)(result)) {
295
- containsPromise = true;
296
- }
210
+ for (const [responseName, fieldNodes] of fields.entries()) {
211
+ const fieldPath = (0, utils_1.addPath)(path, responseName, parentType.name);
212
+ const result = executeField(exeContext, parentType, sourceValue, fieldNodes, fieldPath);
213
+ if (result !== undefined) {
214
+ results[responseName] = result;
215
+ if ((0, utils_1.isPromise)(result)) {
216
+ containsPromise = true;
297
217
  }
298
218
  }
299
219
  }
300
- catch (error) {
301
- if (containsPromise) {
302
- // Ensure that any promises returned by other fields are handled, as they may also reject.
303
- return (0, promiseForObject_js_1.promiseForObject)(results).finally(() => {
304
- throw error;
305
- });
306
- }
307
- throw error;
308
- }
309
220
  // If there are no promises, we can just return the object
310
221
  if (!containsPromise) {
311
222
  return results;
@@ -313,7 +224,13 @@ function executeFields(exeContext, parentType, sourceValue, path, fields, asyncP
313
224
  // Otherwise, results is a map from field name to the result of resolving that
314
225
  // field, which is possibly a promise. Return a promise that will return this
315
226
  // same map, but with any promises replaced with the values they resolved to.
316
- return (0, promiseForObject_js_1.promiseForObject)(results);
227
+ return Promise.all(Object.values(results)).then(resolvedValues => {
228
+ const resolvedObject = Object.create(null);
229
+ for (const [i, key] of Object.keys(results).entries()) {
230
+ resolvedObject[key] = resolvedValues[i];
231
+ }
232
+ return resolvedObject;
233
+ });
317
234
  }
318
235
  /**
319
236
  * Implements the "Executing fields" section of the spec
@@ -321,15 +238,14 @@ function executeFields(exeContext, parentType, sourceValue, path, fields, asyncP
321
238
  * calling its resolve function, then calls completeValue to complete promises,
322
239
  * serialize scalars, or execute the sub-selection-set for objects.
323
240
  */
324
- function executeField(exeContext, parentType, source, fieldNodes, path, asyncPayloadRecord) {
325
- var _a, _b;
326
- const errors = (_a = asyncPayloadRecord === null || asyncPayloadRecord === void 0 ? void 0 : asyncPayloadRecord.errors) !== null && _a !== void 0 ? _a : exeContext.errors;
241
+ function executeField(exeContext, parentType, source, fieldNodes, path) {
242
+ var _a;
327
243
  const fieldDef = getFieldDef(exeContext.schema, parentType, fieldNodes[0]);
328
244
  if (!fieldDef) {
329
245
  return;
330
246
  }
331
247
  const returnType = fieldDef.type;
332
- const resolveFn = (_b = fieldDef.resolve) !== null && _b !== void 0 ? _b : exeContext.fieldResolver;
248
+ const resolveFn = (_a = fieldDef.resolve) !== null && _a !== void 0 ? _a : exeContext.fieldResolver;
333
249
  const info = buildResolveInfo(exeContext, fieldDef, fieldNodes, parentType, path);
334
250
  // Get the resolve function, regardless of if its result is normal or abrupt (error).
335
251
  try {
@@ -344,28 +260,24 @@ function executeField(exeContext, parentType, source, fieldNodes, path, asyncPay
344
260
  const result = resolveFn(source, args, contextValue, info);
345
261
  let completed;
346
262
  if ((0, utils_1.isPromise)(result)) {
347
- completed = result.then(resolved => completeValue(exeContext, returnType, fieldNodes, info, path, resolved, asyncPayloadRecord));
263
+ completed = result.then(resolved => completeValue(exeContext, returnType, fieldNodes, info, path, resolved));
348
264
  }
349
265
  else {
350
- completed = completeValue(exeContext, returnType, fieldNodes, info, path, result, asyncPayloadRecord);
266
+ completed = completeValue(exeContext, returnType, fieldNodes, info, path, result);
351
267
  }
352
268
  if ((0, utils_1.isPromise)(completed)) {
353
269
  // Note: we don't rely on a `catch` method, but we do expect "thenable"
354
270
  // to take a second callback for the error case.
355
271
  return completed.then(undefined, rawError => {
356
272
  const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(path));
357
- const handledError = handleFieldError(error, returnType, errors);
358
- filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
359
- return handledError;
273
+ return handleFieldError(error, returnType, exeContext);
360
274
  });
361
275
  }
362
276
  return completed;
363
277
  }
364
278
  catch (rawError) {
365
279
  const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(path));
366
- const handledError = handleFieldError(error, returnType, errors);
367
- filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
368
- return handledError;
280
+ return handleFieldError(error, returnType, exeContext);
369
281
  }
370
282
  }
371
283
  /**
@@ -389,7 +301,7 @@ function buildResolveInfo(exeContext, fieldDef, fieldNodes, parentType, path) {
389
301
  };
390
302
  }
391
303
  exports.buildResolveInfo = buildResolveInfo;
392
- function handleFieldError(error, returnType, errors) {
304
+ function handleFieldError(error, returnType, exeContext) {
393
305
  // If the field type is non-nullable, then it is resolved without any
394
306
  // protection from errors, however it still properly locates the error.
395
307
  if ((0, graphql_1.isNonNullType)(returnType)) {
@@ -397,7 +309,7 @@ function handleFieldError(error, returnType, errors) {
397
309
  }
398
310
  // Otherwise, error protection is applied, logging the error and resolving
399
311
  // a null value for this field if one is encountered.
400
- errors.push(error);
312
+ exeContext.errors.push(error);
401
313
  return null;
402
314
  }
403
315
  /**
@@ -421,7 +333,7 @@ function handleFieldError(error, returnType, errors) {
421
333
  * Otherwise, the field type expects a sub-selection set, and will complete the
422
334
  * value by executing all sub-selections.
423
335
  */
424
- function completeValue(exeContext, returnType, fieldNodes, info, path, result, asyncPayloadRecord) {
336
+ function completeValue(exeContext, returnType, fieldNodes, info, path, result) {
425
337
  // If result is an Error, throw a located error.
426
338
  if (result instanceof Error) {
427
339
  throw result;
@@ -429,7 +341,7 @@ function completeValue(exeContext, returnType, fieldNodes, info, path, result, a
429
341
  // If field type is NonNull, complete for inner type, and throw field error
430
342
  // if result is null.
431
343
  if ((0, graphql_1.isNonNullType)(returnType)) {
432
- const completed = completeValue(exeContext, returnType.ofType, fieldNodes, info, path, result, asyncPayloadRecord);
344
+ const completed = completeValue(exeContext, returnType.ofType, fieldNodes, info, path, result);
433
345
  if (completed === null) {
434
346
  throw new Error(`Cannot return null for non-nullable field ${info.parentType.name}.${info.fieldName}.`);
435
347
  }
@@ -441,7 +353,7 @@ function completeValue(exeContext, returnType, fieldNodes, info, path, result, a
441
353
  }
442
354
  // If field type is List, complete each item in the list with the inner type
443
355
  if ((0, graphql_1.isListType)(returnType)) {
444
- return completeListValue(exeContext, returnType, fieldNodes, info, path, result, asyncPayloadRecord);
356
+ return completeListValue(exeContext, returnType, fieldNodes, info, path, result);
445
357
  }
446
358
  // If field type is a leaf type, Scalar or Enum, serialize to a valid value,
447
359
  // returning null if serialization is not possible.
@@ -451,74 +363,51 @@ function completeValue(exeContext, returnType, fieldNodes, info, path, result, a
451
363
  // If field type is an abstract type, Interface or Union, determine the
452
364
  // runtime Object type and complete for that type.
453
365
  if ((0, graphql_1.isAbstractType)(returnType)) {
454
- return completeAbstractValue(exeContext, returnType, fieldNodes, info, path, result, asyncPayloadRecord);
366
+ return completeAbstractValue(exeContext, returnType, fieldNodes, info, path, result);
455
367
  }
456
368
  // If field type is Object, execute and complete all sub-selections.
457
369
  if ((0, graphql_1.isObjectType)(returnType)) {
458
- return completeObjectValue(exeContext, returnType, fieldNodes, info, path, result, asyncPayloadRecord);
370
+ return completeObjectValue(exeContext, returnType, fieldNodes, info, path, result);
459
371
  }
460
372
  /* c8 ignore next 6 */
461
373
  // Not reachable, all possible output types have been considered.
462
374
  console.assert(false, 'Cannot complete value of unexpected output type: ' + (0, utils_1.inspect)(returnType));
463
375
  }
464
- /**
465
- * Returns an object containing the `@stream` arguments if a field should be
466
- * streamed based on the experimental flag, stream directive present and
467
- * not disabled by the "if" argument.
468
- */
469
- function getStreamValues(exeContext, fieldNodes, path) {
470
- // do not stream inner lists of multi-dimensional lists
471
- if (typeof path.key === 'number') {
472
- return;
473
- }
474
- // validation only allows equivalent streams on multiple fields, so it is
475
- // safe to only check the first fieldNode for the stream directive
476
- const stream = (0, graphql_1.getDirectiveValues)(index_js_1.GraphQLStreamDirective, fieldNodes[0], exeContext.variableValues);
477
- if (!stream) {
478
- return;
479
- }
480
- if (stream['if'] === false) {
481
- return;
482
- }
483
- (0, invariant_js_1.invariant)(typeof stream['initialCount'] === 'number', 'initialCount must be a number');
484
- (0, invariant_js_1.invariant)(stream['initialCount'] >= 0, 'initialCount must be a positive integer');
485
- return {
486
- initialCount: stream['initialCount'],
487
- label: typeof stream['label'] === 'string' ? stream['label'] : undefined,
488
- };
489
- }
490
376
  /**
491
377
  * Complete a async iterator value by completing the result and calling
492
378
  * recursively until all the results are completed.
493
379
  */
494
- async function completeAsyncIteratorValue(exeContext, itemType, fieldNodes, info, path, iterator, asyncPayloadRecord) {
495
- var _a;
496
- const errors = (_a = asyncPayloadRecord === null || asyncPayloadRecord === void 0 ? void 0 : asyncPayloadRecord.errors) !== null && _a !== void 0 ? _a : exeContext.errors;
497
- const stream = getStreamValues(exeContext, fieldNodes, path);
380
+ async function completeAsyncIteratorValue(exeContext, itemType, fieldNodes, info, path, iterator) {
498
381
  let containsPromise = false;
499
382
  const completedResults = [];
500
383
  let index = 0;
501
384
  while (true) {
502
- if (stream && typeof stream.initialCount === 'number' && index >= stream.initialCount) {
503
- executeStreamIterator(index, iterator, exeContext, fieldNodes, info, itemType, path, stream.label, asyncPayloadRecord);
504
- break;
505
- }
506
- const itemPath = (0, utils_1.addPath)(path, index, undefined);
507
- let iteration;
385
+ const fieldPath = (0, utils_1.addPath)(path, index, undefined);
508
386
  try {
509
- iteration = await iterator.next();
510
- if (iteration.done) {
387
+ const { value, done } = await iterator.next();
388
+ if (done) {
511
389
  break;
512
390
  }
391
+ try {
392
+ // TODO can the error checking logic be consolidated with completeListValue?
393
+ const completedItem = completeValue(exeContext, itemType, fieldNodes, info, fieldPath, value);
394
+ if ((0, utils_1.isPromise)(completedItem)) {
395
+ containsPromise = true;
396
+ }
397
+ completedResults.push(completedItem);
398
+ }
399
+ catch (rawError) {
400
+ completedResults.push(null);
401
+ const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(fieldPath));
402
+ handleFieldError(error, itemType, exeContext);
403
+ }
513
404
  }
514
405
  catch (rawError) {
515
- const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(itemPath));
516
- completedResults.push(handleFieldError(error, itemType, errors));
406
+ completedResults.push(null);
407
+ const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(fieldPath));
408
+ handleFieldError(error, itemType, exeContext);
517
409
  break;
518
410
  }
519
- if (completeListItemValue(iteration.value, completedResults, errors, exeContext, itemType, fieldNodes, info, itemPath, asyncPayloadRecord)) {
520
- containsPromise = true;
521
- }
522
411
  index += 1;
523
412
  }
524
413
  return containsPromise ? Promise.all(completedResults) : completedResults;
@@ -527,75 +416,48 @@ async function completeAsyncIteratorValue(exeContext, itemType, fieldNodes, info
527
416
  * Complete a list value by completing each item in the list with the
528
417
  * inner type
529
418
  */
530
- function completeListValue(exeContext, returnType, fieldNodes, info, path, result, asyncPayloadRecord) {
531
- var _a;
419
+ function completeListValue(exeContext, returnType, fieldNodes, info, path, result) {
532
420
  const itemType = returnType.ofType;
533
- const errors = (_a = asyncPayloadRecord === null || asyncPayloadRecord === void 0 ? void 0 : asyncPayloadRecord.errors) !== null && _a !== void 0 ? _a : exeContext.errors;
534
421
  if ((0, utils_1.isAsyncIterable)(result)) {
535
422
  const iterator = result[Symbol.asyncIterator]();
536
- return completeAsyncIteratorValue(exeContext, itemType, fieldNodes, info, path, iterator, asyncPayloadRecord);
423
+ return completeAsyncIteratorValue(exeContext, itemType, fieldNodes, info, path, iterator);
537
424
  }
538
425
  if (!(0, utils_1.isIterableObject)(result)) {
539
426
  throw (0, utils_1.createGraphQLError)(`Expected Iterable, but did not find one for field "${info.parentType.name}.${info.fieldName}".`);
540
427
  }
541
- const stream = getStreamValues(exeContext, fieldNodes, path);
542
428
  // This is specified as a simple map, however we're optimizing the path
543
429
  // where the list contains no Promises by avoiding creating another Promise.
544
430
  let containsPromise = false;
545
- let previousAsyncPayloadRecord = asyncPayloadRecord;
546
- const completedResults = [];
547
- let index = 0;
548
- for (const item of result) {
431
+ const completedResults = Array.from(result, (item, index) => {
549
432
  // No need to modify the info object containing the path,
550
433
  // since from here on it is not ever accessed by resolver functions.
551
434
  const itemPath = (0, utils_1.addPath)(path, index, undefined);
552
- if (stream && typeof stream.initialCount === 'number' && index >= stream.initialCount) {
553
- previousAsyncPayloadRecord = executeStreamField(path, itemPath, item, exeContext, fieldNodes, info, itemType, stream.label, previousAsyncPayloadRecord);
554
- index++;
555
- continue;
435
+ try {
436
+ let completedItem;
437
+ if ((0, utils_1.isPromise)(item)) {
438
+ completedItem = item.then(resolved => completeValue(exeContext, itemType, fieldNodes, info, itemPath, resolved));
439
+ }
440
+ else {
441
+ completedItem = completeValue(exeContext, itemType, fieldNodes, info, itemPath, item);
442
+ }
443
+ if ((0, utils_1.isPromise)(completedItem)) {
444
+ containsPromise = true;
445
+ // Note: we don't rely on a `catch` method, but we do expect "thenable"
446
+ // to take a second callback for the error case.
447
+ return completedItem.then(undefined, rawError => {
448
+ const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(itemPath));
449
+ return handleFieldError(error, itemType, exeContext);
450
+ });
451
+ }
452
+ return completedItem;
556
453
  }
557
- if (completeListItemValue(item, completedResults, errors, exeContext, itemType, fieldNodes, info, itemPath, asyncPayloadRecord)) {
558
- containsPromise = true;
454
+ catch (rawError) {
455
+ const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(itemPath));
456
+ return handleFieldError(error, itemType, exeContext);
559
457
  }
560
- index++;
561
- }
458
+ });
562
459
  return containsPromise ? Promise.all(completedResults) : completedResults;
563
460
  }
564
- /**
565
- * Complete a list item value by adding it to the completed results.
566
- *
567
- * Returns true if the value is a Promise.
568
- */
569
- function completeListItemValue(item, completedResults, errors, exeContext, itemType, fieldNodes, info, itemPath, asyncPayloadRecord) {
570
- try {
571
- let completedItem;
572
- if ((0, utils_1.isPromise)(item)) {
573
- completedItem = item.then(resolved => completeValue(exeContext, itemType, fieldNodes, info, itemPath, resolved, asyncPayloadRecord));
574
- }
575
- else {
576
- completedItem = completeValue(exeContext, itemType, fieldNodes, info, itemPath, item, asyncPayloadRecord);
577
- }
578
- if ((0, utils_1.isPromise)(completedItem)) {
579
- // Note: we don't rely on a `catch` method, but we do expect "thenable"
580
- // to take a second callback for the error case.
581
- completedResults.push(completedItem.then(undefined, rawError => {
582
- const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(itemPath));
583
- const handledError = handleFieldError(error, itemType, errors);
584
- filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
585
- return handledError;
586
- }));
587
- return true;
588
- }
589
- completedResults.push(completedItem);
590
- }
591
- catch (rawError) {
592
- const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(itemPath));
593
- const handledError = handleFieldError(error, itemType, errors);
594
- filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
595
- completedResults.push(handledError);
596
- }
597
- return false;
598
- }
599
461
  /**
600
462
  * Complete a Scalar or Enum by serializing to a valid value, returning
601
463
  * null if serialization is not possible.
@@ -612,15 +474,15 @@ function completeLeafValue(returnType, result) {
612
474
  * Complete a value of an abstract type by determining the runtime object type
613
475
  * of that value, then complete the value for that type.
614
476
  */
615
- function completeAbstractValue(exeContext, returnType, fieldNodes, info, path, result, asyncPayloadRecord) {
477
+ function completeAbstractValue(exeContext, returnType, fieldNodes, info, path, result) {
616
478
  var _a;
617
479
  const resolveTypeFn = (_a = returnType.resolveType) !== null && _a !== void 0 ? _a : exeContext.typeResolver;
618
480
  const contextValue = exeContext.contextValue;
619
481
  const runtimeType = resolveTypeFn(result, contextValue, info, returnType);
620
482
  if ((0, utils_1.isPromise)(runtimeType)) {
621
- return runtimeType.then(resolvedRuntimeType => completeObjectValue(exeContext, ensureValidRuntimeType(resolvedRuntimeType, exeContext, returnType, fieldNodes, info, result), fieldNodes, info, path, result, asyncPayloadRecord));
483
+ return runtimeType.then(resolvedRuntimeType => completeObjectValue(exeContext, ensureValidRuntimeType(resolvedRuntimeType, exeContext, returnType, fieldNodes, info, result), fieldNodes, info, path, result));
622
484
  }
623
- return completeObjectValue(exeContext, ensureValidRuntimeType(runtimeType, exeContext, returnType, fieldNodes, info, result), fieldNodes, info, path, result, asyncPayloadRecord);
485
+ return completeObjectValue(exeContext, ensureValidRuntimeType(runtimeType, exeContext, returnType, fieldNodes, info, result), fieldNodes, info, path, result);
624
486
  }
625
487
  function ensureValidRuntimeType(runtimeTypeName, exeContext, returnType, fieldNodes, info, result) {
626
488
  if (runtimeTypeName == null) {
@@ -650,7 +512,9 @@ function ensureValidRuntimeType(runtimeTypeName, exeContext, returnType, fieldNo
650
512
  /**
651
513
  * Complete an Object value by executing all sub-selections.
652
514
  */
653
- function completeObjectValue(exeContext, returnType, fieldNodes, info, path, result, asyncPayloadRecord) {
515
+ function completeObjectValue(exeContext, returnType, fieldNodes, info, path, result) {
516
+ // Collect sub-fields to execute to complete this value.
517
+ const subFieldNodes = (0, utils_1.collectSubFields)(exeContext.schema, exeContext.fragments, exeContext.variableValues, returnType, fieldNodes);
654
518
  // If there is an isTypeOf predicate function, call it with the
655
519
  // current result. If isTypeOf returns false, then raise an error rather
656
520
  // than continuing execution.
@@ -661,30 +525,20 @@ function completeObjectValue(exeContext, returnType, fieldNodes, info, path, res
661
525
  if (!resolvedIsTypeOf) {
662
526
  throw invalidReturnTypeError(returnType, result, fieldNodes);
663
527
  }
664
- return collectAndExecuteSubfields(exeContext, returnType, fieldNodes, path, result, asyncPayloadRecord);
528
+ return executeFields(exeContext, returnType, result, path, subFieldNodes);
665
529
  });
666
530
  }
667
531
  if (!isTypeOf) {
668
532
  throw invalidReturnTypeError(returnType, result, fieldNodes);
669
533
  }
670
534
  }
671
- return collectAndExecuteSubfields(exeContext, returnType, fieldNodes, path, result, asyncPayloadRecord);
535
+ return executeFields(exeContext, returnType, result, path, subFieldNodes);
672
536
  }
673
537
  function invalidReturnTypeError(returnType, result, fieldNodes) {
674
538
  return (0, utils_1.createGraphQLError)(`Expected value of type "${returnType.name}" but got: ${(0, utils_1.inspect)(result)}.`, {
675
539
  nodes: fieldNodes,
676
540
  });
677
541
  }
678
- function collectAndExecuteSubfields(exeContext, returnType, fieldNodes, path, result, asyncPayloadRecord) {
679
- // Collect sub-fields to execute to complete this value.
680
- const { fields: subFieldNodes, patches: subPatches } = collectSubfields(exeContext, returnType, fieldNodes);
681
- const subFields = executeFields(exeContext, returnType, result, path, subFieldNodes, asyncPayloadRecord);
682
- for (const subPatch of subPatches) {
683
- const { label, fields: subPatchFieldNodes } = subPatch;
684
- executeDeferredFragment(exeContext, returnType, result, subPatchFieldNodes, label, path, asyncPayloadRecord);
685
- }
686
- return subFields;
687
- }
688
542
  /**
689
543
  * If a resolveType function is not given, then a default resolve behavior is
690
544
  * used which attempts two strategies:
@@ -752,78 +606,19 @@ exports.defaultFieldResolver = defaultFieldResolver;
752
606
  * is not an async iterable.
753
607
  *
754
608
  * If the client-provided arguments to this function do not result in a
755
- * compliant subscription, a GraphQL Response (ExecutionResult) with descriptive
756
- * errors and no data will be returned.
609
+ * compliant subscription, a GraphQL Response (ExecutionResult) with
610
+ * descriptive errors and no data will be returned.
757
611
  *
758
- * If the source stream could not be created due to faulty subscription resolver
759
- * logic or underlying systems, the promise will resolve to a single
612
+ * If the source stream could not be created due to faulty subscription
613
+ * resolver logic or underlying systems, the promise will resolve to a single
760
614
  * ExecutionResult containing `errors` and no `data`.
761
615
  *
762
616
  * If the operation succeeded, the promise resolves to an AsyncIterator, which
763
617
  * yields a stream of ExecutionResults representing the response stream.
764
618
  *
765
- * This function does not support incremental delivery (`@defer` and `@stream`).
766
- * If an operation which would defer or stream data is executed with this
767
- * function, each `InitialIncrementalExecutionResult` and
768
- * `SubsequentIncrementalExecutionResult` in the result stream will be replaced
769
- * with an `ExecutionResult` with a single error stating that defer/stream is
770
- * not supported. Use `experimentalSubscribeIncrementally` if you want to
771
- * support incremental delivery.
772
- *
773
- * Accepts an object with named arguments.
619
+ * Accepts either an object with named arguments, or individual arguments.
774
620
  */
775
621
  function subscribe(args) {
776
- const maybePromise = experimentalSubscribeIncrementally(args);
777
- if ((0, utils_1.isPromise)(maybePromise)) {
778
- return maybePromise.then(resultOrIterable => (0, utils_1.isAsyncIterable)(resultOrIterable)
779
- ? (0, utils_1.mapAsyncIterator)(resultOrIterable, ensureSingleExecutionResult)
780
- : resultOrIterable);
781
- }
782
- return (0, utils_1.isAsyncIterable)(maybePromise) ? (0, utils_1.mapAsyncIterator)(maybePromise, ensureSingleExecutionResult) : maybePromise;
783
- }
784
- exports.subscribe = subscribe;
785
- function ensureSingleExecutionResult(result) {
786
- if ('hasNext' in result) {
787
- return {
788
- errors: [(0, utils_1.createGraphQLError)(UNEXPECTED_MULTIPLE_PAYLOADS)],
789
- };
790
- }
791
- return result;
792
- }
793
- /**
794
- * Implements the "Subscribe" algorithm described in the GraphQL specification,
795
- * including `@defer` and `@stream` as proposed in
796
- * https://github.com/graphql/graphql-spec/pull/742
797
- *
798
- * Returns a Promise which resolves to either an AsyncIterator (if successful)
799
- * or an ExecutionResult (error). The promise will be rejected if the schema or
800
- * other arguments to this function are invalid, or if the resolved event stream
801
- * is not an async iterable.
802
- *
803
- * If the client-provided arguments to this function do not result in a
804
- * compliant subscription, a GraphQL Response (ExecutionResult) with descriptive
805
- * errors and no data will be returned.
806
- *
807
- * If the source stream could not be created due to faulty subscription resolver
808
- * logic or underlying systems, the promise will resolve to a single
809
- * ExecutionResult containing `errors` and no `data`.
810
- *
811
- * If the operation succeeded, the promise resolves to an AsyncIterator, which
812
- * yields a stream of result representing the response stream.
813
- *
814
- * Each result may be an ExecutionResult with no `hasNext` (if executing the
815
- * event did not use `@defer` or `@stream`), or an
816
- * `InitialIncrementalExecutionResult` or `SubsequentIncrementalExecutionResult`
817
- * (if executing the event used `@defer` or `@stream`). In the case of
818
- * incremental execution results, each event produces a single
819
- * `InitialIncrementalExecutionResult` followed by one or more
820
- * `SubsequentIncrementalExecutionResult`s; all but the last have `hasNext: true`,
821
- * and the last has `hasNext: false`. There is no interleaving between results
822
- * generated from the same original event.
823
- *
824
- * Accepts an object with named arguments.
825
- */
826
- function experimentalSubscribeIncrementally(args) {
827
622
  // If a valid execution context cannot be created due to incorrect arguments,
828
623
  // a "Response" with only errors is returned.
829
624
  const exeContext = buildExecutionContext(args);
@@ -837,16 +632,7 @@ function experimentalSubscribeIncrementally(args) {
837
632
  }
838
633
  return mapSourceToResponse(exeContext, resultOrStream);
839
634
  }
840
- exports.experimentalSubscribeIncrementally = experimentalSubscribeIncrementally;
841
- async function* ensureAsyncIterable(someExecutionResult) {
842
- if ('initialResult' in someExecutionResult) {
843
- yield someExecutionResult.initialResult;
844
- yield* someExecutionResult.subsequentResults;
845
- }
846
- else {
847
- yield someExecutionResult;
848
- }
849
- }
635
+ exports.subscribe = subscribe;
850
636
  function mapSourceToResponse(exeContext, resultOrStream) {
851
637
  if (!(0, utils_1.isAsyncIterable)(resultOrStream)) {
852
638
  return resultOrStream;
@@ -857,7 +643,7 @@ function mapSourceToResponse(exeContext, resultOrStream) {
857
643
  // the GraphQL specification. The `execute` function provides the
858
644
  // "ExecuteSubscriptionEvent" algorithm, as it is nearly identical to the
859
645
  // "ExecuteQuery" algorithm, for which `execute` is also used.
860
- return (0, flattenAsyncIterable_js_1.flattenAsyncIterable)((0, utils_1.mapAsyncIterator)(resultOrStream[Symbol.asyncIterator](), async (payload) => ensureAsyncIterable(await executeImpl(buildPerEventExecutionContext(exeContext, payload)))));
646
+ return (0, utils_1.mapAsyncIterator)(resultOrStream[Symbol.asyncIterator](), (payload) => executeImpl(buildPerEventExecutionContext(exeContext, payload)));
861
647
  }
862
648
  /**
863
649
  * Implements the "CreateSourceEventStream" algorithm described in the
@@ -917,7 +703,7 @@ function executeSubscription(exeContext) {
917
703
  if (rootType == null) {
918
704
  throw (0, utils_1.createGraphQLError)('Schema is not configured to execute subscription operation.', { nodes: operation });
919
705
  }
920
- const { fields: rootFields } = (0, collectFields_js_1.collectFields)(schema, fragments, variableValues, rootType, operation.selectionSet);
706
+ const rootFields = (0, utils_1.collectFields)(schema, fragments, variableValues, rootType, operation.selectionSet);
921
707
  const [responseName, fieldNodes] = [...rootFields.entries()][0];
922
708
  const fieldName = fieldNodes[0].name.value;
923
709
  const fieldDef = getFieldDef(schema, rootType, fieldNodes[0]);
@@ -961,339 +747,6 @@ function assertEventStream(result) {
961
747
  }
962
748
  return result;
963
749
  }
964
- function executeDeferredFragment(exeContext, parentType, sourceValue, fields, label, path, parentContext) {
965
- const asyncPayloadRecord = new DeferredFragmentRecord({
966
- label,
967
- path,
968
- parentContext,
969
- exeContext,
970
- });
971
- let promiseOrData;
972
- try {
973
- promiseOrData = executeFields(exeContext, parentType, sourceValue, path, fields, asyncPayloadRecord);
974
- if ((0, utils_1.isPromise)(promiseOrData)) {
975
- promiseOrData = promiseOrData.then(null, e => {
976
- asyncPayloadRecord.errors.push(e);
977
- return null;
978
- });
979
- }
980
- }
981
- catch (e) {
982
- asyncPayloadRecord.errors.push(e);
983
- promiseOrData = null;
984
- }
985
- asyncPayloadRecord.addData(promiseOrData);
986
- }
987
- function executeStreamField(path, itemPath, item, exeContext, fieldNodes, info, itemType, label, parentContext) {
988
- const asyncPayloadRecord = new StreamRecord({
989
- label,
990
- path: itemPath,
991
- parentContext,
992
- exeContext,
993
- });
994
- let completedItem;
995
- try {
996
- try {
997
- if ((0, utils_1.isPromise)(item)) {
998
- completedItem = item.then(resolved => completeValue(exeContext, itemType, fieldNodes, info, itemPath, resolved, asyncPayloadRecord));
999
- }
1000
- else {
1001
- completedItem = completeValue(exeContext, itemType, fieldNodes, info, itemPath, item, asyncPayloadRecord);
1002
- }
1003
- if ((0, utils_1.isPromise)(completedItem)) {
1004
- // Note: we don't rely on a `catch` method, but we do expect "thenable"
1005
- // to take a second callback for the error case.
1006
- completedItem = completedItem.then(undefined, rawError => {
1007
- const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(itemPath));
1008
- const handledError = handleFieldError(error, itemType, asyncPayloadRecord.errors);
1009
- filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
1010
- return handledError;
1011
- });
1012
- }
1013
- }
1014
- catch (rawError) {
1015
- const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(itemPath));
1016
- completedItem = handleFieldError(error, itemType, asyncPayloadRecord.errors);
1017
- filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
1018
- }
1019
- }
1020
- catch (error) {
1021
- asyncPayloadRecord.errors.push(error);
1022
- filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
1023
- asyncPayloadRecord.addItems(null);
1024
- return asyncPayloadRecord;
1025
- }
1026
- let completedItems;
1027
- if ((0, utils_1.isPromise)(completedItem)) {
1028
- completedItems = completedItem.then(value => [value], error => {
1029
- asyncPayloadRecord.errors.push(error);
1030
- filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
1031
- return null;
1032
- });
1033
- }
1034
- else {
1035
- completedItems = [completedItem];
1036
- }
1037
- asyncPayloadRecord.addItems(completedItems);
1038
- return asyncPayloadRecord;
1039
- }
1040
- async function executeStreamIteratorItem(iterator, exeContext, fieldNodes, info, itemType, asyncPayloadRecord, itemPath) {
1041
- let item;
1042
- try {
1043
- const { value, done } = await iterator.next();
1044
- if (done) {
1045
- asyncPayloadRecord.setIsCompletedIterator();
1046
- return { done, value: undefined };
1047
- }
1048
- item = value;
1049
- }
1050
- catch (rawError) {
1051
- const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(itemPath));
1052
- const value = handleFieldError(error, itemType, asyncPayloadRecord.errors);
1053
- // don't continue if iterator throws
1054
- return { done: true, value };
1055
- }
1056
- let completedItem;
1057
- try {
1058
- completedItem = completeValue(exeContext, itemType, fieldNodes, info, itemPath, item, asyncPayloadRecord);
1059
- if ((0, utils_1.isPromise)(completedItem)) {
1060
- completedItem = completedItem.then(undefined, rawError => {
1061
- const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(itemPath));
1062
- const handledError = handleFieldError(error, itemType, asyncPayloadRecord.errors);
1063
- filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
1064
- return handledError;
1065
- });
1066
- }
1067
- return { done: false, value: completedItem };
1068
- }
1069
- catch (rawError) {
1070
- const error = (0, graphql_1.locatedError)(rawError, fieldNodes, (0, utils_1.pathToArray)(itemPath));
1071
- const value = handleFieldError(error, itemType, asyncPayloadRecord.errors);
1072
- filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
1073
- return { done: false, value };
1074
- }
1075
- }
1076
- async function executeStreamIterator(initialIndex, iterator, exeContext, fieldNodes, info, itemType, path, label, parentContext) {
1077
- let index = initialIndex;
1078
- let previousAsyncPayloadRecord = parentContext !== null && parentContext !== void 0 ? parentContext : undefined;
1079
- while (true) {
1080
- const itemPath = (0, utils_1.addPath)(path, index, undefined);
1081
- const asyncPayloadRecord = new StreamRecord({
1082
- label,
1083
- path: itemPath,
1084
- parentContext: previousAsyncPayloadRecord,
1085
- iterator,
1086
- exeContext,
1087
- });
1088
- let iteration;
1089
- try {
1090
- iteration = await executeStreamIteratorItem(iterator, exeContext, fieldNodes, info, itemType, asyncPayloadRecord, itemPath);
1091
- }
1092
- catch (error) {
1093
- asyncPayloadRecord.errors.push(error);
1094
- filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
1095
- asyncPayloadRecord.addItems(null);
1096
- // entire stream has errored and bubbled upwards
1097
- if (iterator === null || iterator === void 0 ? void 0 : iterator.return) {
1098
- iterator.return().catch(() => {
1099
- // ignore errors
1100
- });
1101
- }
1102
- return;
1103
- }
1104
- const { done, value: completedItem } = iteration;
1105
- let completedItems;
1106
- if ((0, utils_1.isPromise)(completedItem)) {
1107
- completedItems = completedItem.then(value => [value], error => {
1108
- asyncPayloadRecord.errors.push(error);
1109
- filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
1110
- return null;
1111
- });
1112
- }
1113
- else {
1114
- completedItems = [completedItem];
1115
- }
1116
- asyncPayloadRecord.addItems(completedItems);
1117
- if (done) {
1118
- break;
1119
- }
1120
- previousAsyncPayloadRecord = asyncPayloadRecord;
1121
- index++;
1122
- }
1123
- }
1124
- function filterSubsequentPayloads(exeContext, nullPath, currentAsyncRecord) {
1125
- const nullPathArray = (0, utils_1.pathToArray)(nullPath);
1126
- exeContext.subsequentPayloads.forEach(asyncRecord => {
1127
- var _a;
1128
- if (asyncRecord === currentAsyncRecord) {
1129
- // don't remove payload from where error originates
1130
- return;
1131
- }
1132
- for (let i = 0; i < nullPathArray.length; i++) {
1133
- if (asyncRecord.path[i] !== nullPathArray[i]) {
1134
- // asyncRecord points to a path unaffected by this payload
1135
- return;
1136
- }
1137
- }
1138
- // asyncRecord path points to nulled error field
1139
- if (isStreamPayload(asyncRecord) && ((_a = asyncRecord.iterator) === null || _a === void 0 ? void 0 : _a.return)) {
1140
- asyncRecord.iterator.return().catch(() => {
1141
- // ignore error
1142
- });
1143
- }
1144
- exeContext.subsequentPayloads.delete(asyncRecord);
1145
- });
1146
- }
1147
- function getCompletedIncrementalResults(exeContext) {
1148
- const incrementalResults = [];
1149
- for (const asyncPayloadRecord of exeContext.subsequentPayloads) {
1150
- const incrementalResult = {};
1151
- if (!asyncPayloadRecord.isCompleted) {
1152
- continue;
1153
- }
1154
- exeContext.subsequentPayloads.delete(asyncPayloadRecord);
1155
- if (isStreamPayload(asyncPayloadRecord)) {
1156
- const items = asyncPayloadRecord.items;
1157
- if (asyncPayloadRecord.isCompletedIterator) {
1158
- // async iterable resolver just finished but there may be pending payloads
1159
- continue;
1160
- }
1161
- incrementalResult.items = items;
1162
- }
1163
- else {
1164
- const data = asyncPayloadRecord.data;
1165
- incrementalResult.data = data !== null && data !== void 0 ? data : null;
1166
- }
1167
- incrementalResult.path = asyncPayloadRecord.path;
1168
- if (asyncPayloadRecord.label) {
1169
- incrementalResult.label = asyncPayloadRecord.label;
1170
- }
1171
- if (asyncPayloadRecord.errors.length > 0) {
1172
- incrementalResult.errors = asyncPayloadRecord.errors;
1173
- }
1174
- incrementalResults.push(incrementalResult);
1175
- }
1176
- return incrementalResults;
1177
- }
1178
- function yieldSubsequentPayloads(exeContext) {
1179
- let isDone = false;
1180
- async function next() {
1181
- if (isDone) {
1182
- return { value: undefined, done: true };
1183
- }
1184
- await Promise.race(Array.from(exeContext.subsequentPayloads).map(p => p.promise));
1185
- if (isDone) {
1186
- // a different call to next has exhausted all payloads
1187
- return { value: undefined, done: true };
1188
- }
1189
- const incremental = getCompletedIncrementalResults(exeContext);
1190
- const hasNext = exeContext.subsequentPayloads.size > 0;
1191
- if (!incremental.length && hasNext) {
1192
- return next();
1193
- }
1194
- if (!hasNext) {
1195
- isDone = true;
1196
- }
1197
- return {
1198
- value: incremental.length ? { incremental, hasNext } : { hasNext },
1199
- done: false,
1200
- };
1201
- }
1202
- function returnStreamIterators() {
1203
- const promises = [];
1204
- exeContext.subsequentPayloads.forEach(asyncPayloadRecord => {
1205
- var _a;
1206
- if (isStreamPayload(asyncPayloadRecord) && ((_a = asyncPayloadRecord.iterator) === null || _a === void 0 ? void 0 : _a.return)) {
1207
- promises.push(asyncPayloadRecord.iterator.return());
1208
- }
1209
- });
1210
- return Promise.all(promises);
1211
- }
1212
- return {
1213
- [Symbol.asyncIterator]() {
1214
- return this;
1215
- },
1216
- next,
1217
- async return() {
1218
- await returnStreamIterators();
1219
- isDone = true;
1220
- return { value: undefined, done: true };
1221
- },
1222
- async throw(error) {
1223
- await returnStreamIterators();
1224
- isDone = true;
1225
- return Promise.reject(error);
1226
- },
1227
- };
1228
- }
1229
- class DeferredFragmentRecord {
1230
- constructor(opts) {
1231
- this.type = 'defer';
1232
- this.label = opts.label;
1233
- this.path = (0, utils_1.pathToArray)(opts.path);
1234
- this.parentContext = opts.parentContext;
1235
- this.errors = [];
1236
- this._exeContext = opts.exeContext;
1237
- this._exeContext.subsequentPayloads.add(this);
1238
- this.isCompleted = false;
1239
- this.data = null;
1240
- this.promise = new Promise(resolve => {
1241
- this._resolve = MaybePromise => {
1242
- resolve(MaybePromise);
1243
- };
1244
- }).then(data => {
1245
- this.data = data;
1246
- this.isCompleted = true;
1247
- });
1248
- }
1249
- addData(data) {
1250
- var _a, _b, _c;
1251
- const parentData = (_a = this.parentContext) === null || _a === void 0 ? void 0 : _a.promise;
1252
- if (parentData) {
1253
- (_b = this._resolve) === null || _b === void 0 ? void 0 : _b.call(this, parentData.then(() => data));
1254
- return;
1255
- }
1256
- (_c = this._resolve) === null || _c === void 0 ? void 0 : _c.call(this, data);
1257
- }
1258
- }
1259
- class StreamRecord {
1260
- constructor(opts) {
1261
- this.type = 'stream';
1262
- this.items = null;
1263
- this.label = opts.label;
1264
- this.path = (0, utils_1.pathToArray)(opts.path);
1265
- this.parentContext = opts.parentContext;
1266
- this.iterator = opts.iterator;
1267
- this.errors = [];
1268
- this._exeContext = opts.exeContext;
1269
- this._exeContext.subsequentPayloads.add(this);
1270
- this.isCompleted = false;
1271
- this.items = null;
1272
- this.promise = new Promise(resolve => {
1273
- this._resolve = MaybePromise => {
1274
- resolve(MaybePromise);
1275
- };
1276
- }).then(items => {
1277
- this.items = items;
1278
- this.isCompleted = true;
1279
- });
1280
- }
1281
- addItems(items) {
1282
- var _a, _b, _c;
1283
- const parentData = (_a = this.parentContext) === null || _a === void 0 ? void 0 : _a.promise;
1284
- if (parentData) {
1285
- (_b = this._resolve) === null || _b === void 0 ? void 0 : _b.call(this, parentData.then(() => items));
1286
- return;
1287
- }
1288
- (_c = this._resolve) === null || _c === void 0 ? void 0 : _c.call(this, items);
1289
- }
1290
- setIsCompletedIterator() {
1291
- this.isCompletedIterator = true;
1292
- }
1293
- }
1294
- function isStreamPayload(asyncPayload) {
1295
- return asyncPayload.type === 'stream';
1296
- }
1297
750
  /**
1298
751
  * This method looks up the field on the given type definition.
1299
752
  * It has special casing for the three introspection fields,