@graphql-tools/executor 1.4.2 → 1.4.3-alpha-20250226150456-c866968c9e16e4eb2d1460dcbf97397c4a27ca60
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/execute.js +42 -13
- package/cjs/execution/promiseForObject.js +19 -8
- package/esm/execution/execute.js +44 -15
- package/esm/execution/promiseForObject.js +20 -9
- package/package.json +2 -2
- package/typings/execution/execute.d.cts +2 -0
- package/typings/execution/execute.d.ts +2 -0
- package/typings/execution/promiseForObject.d.cts +1 -1
- package/typings/execution/promiseForObject.d.ts +1 -1
package/cjs/execution/execute.js
CHANGED
|
@@ -150,6 +150,7 @@ exports.getFragmentsFromDocument = (0, utils_1.memoize1)(function getFragmentsFr
|
|
|
150
150
|
*/
|
|
151
151
|
function buildExecutionContext(args) {
|
|
152
152
|
const { schema, document, rootValue, contextValue, variableValues: rawVariableValues, operationName, fieldResolver, typeResolver, subscribeFieldResolver, signal, } = args;
|
|
153
|
+
signal?.throwIfAborted();
|
|
153
154
|
// If the schema used for execution is invalid, throw an error.
|
|
154
155
|
(0, graphql_1.assertValidSchema)(schema);
|
|
155
156
|
const fragments = (0, exports.getFragmentsFromDocument)(document);
|
|
@@ -204,6 +205,28 @@ function buildExecutionContext(args) {
|
|
|
204
205
|
if (coercedVariableValues.errors) {
|
|
205
206
|
return coercedVariableValues.errors;
|
|
206
207
|
}
|
|
208
|
+
signal?.throwIfAborted();
|
|
209
|
+
let onSignalAbort;
|
|
210
|
+
let signalPromise;
|
|
211
|
+
if (signal) {
|
|
212
|
+
const listeners = new Set();
|
|
213
|
+
const signalDeferred = (0, promise_helpers_1.createDeferredPromise)();
|
|
214
|
+
signalPromise = signalDeferred.promise;
|
|
215
|
+
const sharedListener = () => {
|
|
216
|
+
signalDeferred.reject(signal.reason);
|
|
217
|
+
signal.removeEventListener('abort', sharedListener);
|
|
218
|
+
};
|
|
219
|
+
signal.addEventListener('abort', sharedListener, { once: true });
|
|
220
|
+
signalPromise.catch(() => {
|
|
221
|
+
for (const listener of listeners) {
|
|
222
|
+
listener();
|
|
223
|
+
}
|
|
224
|
+
listeners.clear();
|
|
225
|
+
});
|
|
226
|
+
onSignalAbort = handler => {
|
|
227
|
+
listeners.add(handler);
|
|
228
|
+
};
|
|
229
|
+
}
|
|
207
230
|
return {
|
|
208
231
|
schema,
|
|
209
232
|
fragments,
|
|
@@ -217,6 +240,8 @@ function buildExecutionContext(args) {
|
|
|
217
240
|
subsequentPayloads: new Set(),
|
|
218
241
|
errors: [],
|
|
219
242
|
signal,
|
|
243
|
+
onSignalAbort,
|
|
244
|
+
signalPromise,
|
|
220
245
|
};
|
|
221
246
|
}
|
|
222
247
|
function buildPerEventExecutionContext(exeContext, payload) {
|
|
@@ -291,9 +316,9 @@ function executeFields(exeContext, parentType, sourceValue, path, fields, asyncP
|
|
|
291
316
|
}
|
|
292
317
|
}
|
|
293
318
|
catch (error) {
|
|
294
|
-
if (containsPromise) {
|
|
319
|
+
if (error !== exeContext.signal?.reason && containsPromise) {
|
|
295
320
|
// Ensure that any promises returned by other fields are handled, as they may also reject.
|
|
296
|
-
return (0, promiseForObject_js_1.promiseForObject)(results, exeContext.signal).finally(() => {
|
|
321
|
+
return (0, promiseForObject_js_1.promiseForObject)(results, exeContext.signal, exeContext.signalPromise).finally(() => {
|
|
297
322
|
throw error;
|
|
298
323
|
});
|
|
299
324
|
}
|
|
@@ -306,7 +331,7 @@ function executeFields(exeContext, parentType, sourceValue, path, fields, asyncP
|
|
|
306
331
|
// Otherwise, results is a map from field name to the result of resolving that
|
|
307
332
|
// field, which is possibly a promise. Return a promise that will return this
|
|
308
333
|
// same map, but with any promises replaced with the values they resolved to.
|
|
309
|
-
return (0, promiseForObject_js_1.promiseForObject)(results, exeContext.signal);
|
|
334
|
+
return (0, promiseForObject_js_1.promiseForObject)(results, exeContext.signal, exeContext.signalPromise);
|
|
310
335
|
}
|
|
311
336
|
/**
|
|
312
337
|
* Implements the "Executing fields" section of the spec
|
|
@@ -325,6 +350,7 @@ function executeField(exeContext, parentType, source, fieldNodes, path, asyncPay
|
|
|
325
350
|
const info = buildResolveInfo(exeContext, fieldDef, fieldNodes, parentType, path);
|
|
326
351
|
// Get the resolve function, regardless of if its result is normal or abrupt (error).
|
|
327
352
|
try {
|
|
353
|
+
exeContext.signal?.throwIfAborted();
|
|
328
354
|
// Build a JS object of arguments from the field.arguments AST, using the
|
|
329
355
|
// variables scope to fulfill any variable references.
|
|
330
356
|
// TODO: find a way to memoize, in case this field is within a List type.
|
|
@@ -506,8 +532,9 @@ function getStreamValues(exeContext, fieldNodes, path) {
|
|
|
506
532
|
* recursively until all the results are completed.
|
|
507
533
|
*/
|
|
508
534
|
async function completeAsyncIteratorValue(exeContext, itemType, fieldNodes, info, path, iterator, asyncPayloadRecord) {
|
|
509
|
-
|
|
510
|
-
|
|
535
|
+
exeContext.signal?.throwIfAborted();
|
|
536
|
+
if (iterator.return) {
|
|
537
|
+
exeContext.onSignalAbort?.(() => {
|
|
511
538
|
iterator.return?.();
|
|
512
539
|
});
|
|
513
540
|
}
|
|
@@ -949,17 +976,20 @@ function executeSubscription(exeContext) {
|
|
|
949
976
|
const resolveFn = fieldDef.subscribe ?? exeContext.subscribeFieldResolver;
|
|
950
977
|
const result = resolveFn(rootValue, args, contextValue, info);
|
|
951
978
|
if ((0, utils_1.isPromise)(result)) {
|
|
952
|
-
return result
|
|
979
|
+
return result
|
|
980
|
+
.then(result => assertEventStream(result, exeContext.signal, exeContext.onSignalAbort))
|
|
981
|
+
.then(undefined, error => {
|
|
953
982
|
throw (0, graphql_1.locatedError)(error, fieldNodes, (0, utils_1.pathToArray)(path));
|
|
954
983
|
});
|
|
955
984
|
}
|
|
956
|
-
return assertEventStream(result, exeContext.signal);
|
|
985
|
+
return assertEventStream(result, exeContext.signal, exeContext.onSignalAbort);
|
|
957
986
|
}
|
|
958
987
|
catch (error) {
|
|
959
988
|
throw (0, graphql_1.locatedError)(error, fieldNodes, (0, utils_1.pathToArray)(path));
|
|
960
989
|
}
|
|
961
990
|
}
|
|
962
|
-
function assertEventStream(result, signal) {
|
|
991
|
+
function assertEventStream(result, signal, onSignalAbort) {
|
|
992
|
+
signal?.throwIfAborted();
|
|
963
993
|
if (result instanceof Error) {
|
|
964
994
|
throw result;
|
|
965
995
|
}
|
|
@@ -967,12 +997,12 @@ function assertEventStream(result, signal) {
|
|
|
967
997
|
if (!(0, utils_1.isAsyncIterable)(result)) {
|
|
968
998
|
throw (0, utils_1.createGraphQLError)('Subscription field must return Async Iterable. ' + `Received: ${(0, utils_1.inspect)(result)}.`);
|
|
969
999
|
}
|
|
970
|
-
if (
|
|
1000
|
+
if (onSignalAbort) {
|
|
971
1001
|
return {
|
|
972
1002
|
[Symbol.asyncIterator]() {
|
|
973
1003
|
const asyncIterator = result[Symbol.asyncIterator]();
|
|
974
1004
|
if (asyncIterator.return) {
|
|
975
|
-
(
|
|
1005
|
+
onSignalAbort?.(() => {
|
|
976
1006
|
asyncIterator.return?.();
|
|
977
1007
|
});
|
|
978
1008
|
}
|
|
@@ -1200,14 +1230,13 @@ function getCompletedIncrementalResults(exeContext) {
|
|
|
1200
1230
|
}
|
|
1201
1231
|
function yieldSubsequentPayloads(exeContext) {
|
|
1202
1232
|
let isDone = false;
|
|
1203
|
-
const abortPromise = exeContext.signal ? (0, utils_1.getAbortPromise)(exeContext.signal) : undefined;
|
|
1204
1233
|
async function next() {
|
|
1205
1234
|
if (isDone) {
|
|
1206
1235
|
return { value: undefined, done: true };
|
|
1207
1236
|
}
|
|
1208
1237
|
const subSequentPayloadPromises = Array.from(exeContext.subsequentPayloads).map(record => record.promise);
|
|
1209
|
-
if (
|
|
1210
|
-
await Promise.race([
|
|
1238
|
+
if (exeContext.signalPromise) {
|
|
1239
|
+
await Promise.race([exeContext.signalPromise, ...subSequentPayloadPromises]);
|
|
1211
1240
|
}
|
|
1212
1241
|
else {
|
|
1213
1242
|
await Promise.race(subSequentPayloadPromises);
|
|
@@ -9,14 +9,25 @@ const utils_1 = require("@graphql-tools/utils");
|
|
|
9
9
|
* This is akin to bluebird's `Promise.props`, but implemented only using
|
|
10
10
|
* `Promise.all` so it will work with any implementation of ES6 promises.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
function promiseForObject(object, signal, signalPromise) {
|
|
13
|
+
signal?.throwIfAborted();
|
|
13
14
|
const resolvedObject = Object.create(null);
|
|
14
|
-
const promises =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
const promises = [];
|
|
16
|
+
for (const key in object) {
|
|
17
|
+
const value = object[key];
|
|
18
|
+
if ((0, utils_1.isPromise)(value)) {
|
|
19
|
+
promises.push(value.then(value => {
|
|
20
|
+
signal?.throwIfAborted();
|
|
21
|
+
resolvedObject[key] = value;
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
resolvedObject[key] = value;
|
|
26
|
+
}
|
|
20
27
|
}
|
|
21
|
-
|
|
28
|
+
const promiseAll = Promise.all(promises);
|
|
29
|
+
if (signalPromise) {
|
|
30
|
+
return Promise.race([signalPromise, promiseAll]).then(() => resolvedObject);
|
|
31
|
+
}
|
|
32
|
+
return promiseAll.then(() => resolvedObject);
|
|
22
33
|
}
|
package/esm/execution/execute.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { assertValidSchema, getDirectiveValues, GraphQLError, isAbstractType, isLeafType, isListType, isNonNullType, isObjectType, Kind, locatedError, SchemaMetaFieldDef, TypeMetaFieldDef, TypeNameMetaFieldDef, versionInfo, } from 'graphql';
|
|
2
|
-
import { collectSubFields as _collectSubfields, addPath, collectFields, createGraphQLError, fakePromise,
|
|
2
|
+
import { collectSubFields as _collectSubfields, addPath, collectFields, createGraphQLError, fakePromise, getArgumentValues, getDefinedRootType, GraphQLStreamDirective, inspect, isAsyncIterable, isIterableObject, isObjectLike, isPromise, mapAsyncIterator, memoize1, memoize3, pathToArray, promiseReduce, } from '@graphql-tools/utils';
|
|
3
3
|
import { DisposableSymbols } from '@whatwg-node/disposablestack';
|
|
4
|
-
import { handleMaybePromise } from '@whatwg-node/promise-helpers';
|
|
4
|
+
import { createDeferredPromise, handleMaybePromise } from '@whatwg-node/promise-helpers';
|
|
5
5
|
import { coerceError } from './coerceError.js';
|
|
6
6
|
import { flattenAsyncIterable } from './flattenAsyncIterable.js';
|
|
7
7
|
import { invariant } from './invariant.js';
|
|
@@ -137,6 +137,7 @@ export const getFragmentsFromDocument = memoize1(function getFragmentsFromDocume
|
|
|
137
137
|
*/
|
|
138
138
|
export function buildExecutionContext(args) {
|
|
139
139
|
const { schema, document, rootValue, contextValue, variableValues: rawVariableValues, operationName, fieldResolver, typeResolver, subscribeFieldResolver, signal, } = args;
|
|
140
|
+
signal?.throwIfAborted();
|
|
140
141
|
// If the schema used for execution is invalid, throw an error.
|
|
141
142
|
assertValidSchema(schema);
|
|
142
143
|
const fragments = getFragmentsFromDocument(document);
|
|
@@ -191,6 +192,28 @@ export function buildExecutionContext(args) {
|
|
|
191
192
|
if (coercedVariableValues.errors) {
|
|
192
193
|
return coercedVariableValues.errors;
|
|
193
194
|
}
|
|
195
|
+
signal?.throwIfAborted();
|
|
196
|
+
let onSignalAbort;
|
|
197
|
+
let signalPromise;
|
|
198
|
+
if (signal) {
|
|
199
|
+
const listeners = new Set();
|
|
200
|
+
const signalDeferred = createDeferredPromise();
|
|
201
|
+
signalPromise = signalDeferred.promise;
|
|
202
|
+
const sharedListener = () => {
|
|
203
|
+
signalDeferred.reject(signal.reason);
|
|
204
|
+
signal.removeEventListener('abort', sharedListener);
|
|
205
|
+
};
|
|
206
|
+
signal.addEventListener('abort', sharedListener, { once: true });
|
|
207
|
+
signalPromise.catch(() => {
|
|
208
|
+
for (const listener of listeners) {
|
|
209
|
+
listener();
|
|
210
|
+
}
|
|
211
|
+
listeners.clear();
|
|
212
|
+
});
|
|
213
|
+
onSignalAbort = handler => {
|
|
214
|
+
listeners.add(handler);
|
|
215
|
+
};
|
|
216
|
+
}
|
|
194
217
|
return {
|
|
195
218
|
schema,
|
|
196
219
|
fragments,
|
|
@@ -204,6 +227,8 @@ export function buildExecutionContext(args) {
|
|
|
204
227
|
subsequentPayloads: new Set(),
|
|
205
228
|
errors: [],
|
|
206
229
|
signal,
|
|
230
|
+
onSignalAbort,
|
|
231
|
+
signalPromise,
|
|
207
232
|
};
|
|
208
233
|
}
|
|
209
234
|
function buildPerEventExecutionContext(exeContext, payload) {
|
|
@@ -278,9 +303,9 @@ function executeFields(exeContext, parentType, sourceValue, path, fields, asyncP
|
|
|
278
303
|
}
|
|
279
304
|
}
|
|
280
305
|
catch (error) {
|
|
281
|
-
if (containsPromise) {
|
|
306
|
+
if (error !== exeContext.signal?.reason && containsPromise) {
|
|
282
307
|
// Ensure that any promises returned by other fields are handled, as they may also reject.
|
|
283
|
-
return promiseForObject(results, exeContext.signal).finally(() => {
|
|
308
|
+
return promiseForObject(results, exeContext.signal, exeContext.signalPromise).finally(() => {
|
|
284
309
|
throw error;
|
|
285
310
|
});
|
|
286
311
|
}
|
|
@@ -293,7 +318,7 @@ function executeFields(exeContext, parentType, sourceValue, path, fields, asyncP
|
|
|
293
318
|
// Otherwise, results is a map from field name to the result of resolving that
|
|
294
319
|
// field, which is possibly a promise. Return a promise that will return this
|
|
295
320
|
// same map, but with any promises replaced with the values they resolved to.
|
|
296
|
-
return promiseForObject(results, exeContext.signal);
|
|
321
|
+
return promiseForObject(results, exeContext.signal, exeContext.signalPromise);
|
|
297
322
|
}
|
|
298
323
|
/**
|
|
299
324
|
* Implements the "Executing fields" section of the spec
|
|
@@ -312,6 +337,7 @@ function executeField(exeContext, parentType, source, fieldNodes, path, asyncPay
|
|
|
312
337
|
const info = buildResolveInfo(exeContext, fieldDef, fieldNodes, parentType, path);
|
|
313
338
|
// Get the resolve function, regardless of if its result is normal or abrupt (error).
|
|
314
339
|
try {
|
|
340
|
+
exeContext.signal?.throwIfAborted();
|
|
315
341
|
// Build a JS object of arguments from the field.arguments AST, using the
|
|
316
342
|
// variables scope to fulfill any variable references.
|
|
317
343
|
// TODO: find a way to memoize, in case this field is within a List type.
|
|
@@ -493,8 +519,9 @@ function getStreamValues(exeContext, fieldNodes, path) {
|
|
|
493
519
|
* recursively until all the results are completed.
|
|
494
520
|
*/
|
|
495
521
|
async function completeAsyncIteratorValue(exeContext, itemType, fieldNodes, info, path, iterator, asyncPayloadRecord) {
|
|
496
|
-
|
|
497
|
-
|
|
522
|
+
exeContext.signal?.throwIfAborted();
|
|
523
|
+
if (iterator.return) {
|
|
524
|
+
exeContext.onSignalAbort?.(() => {
|
|
498
525
|
iterator.return?.();
|
|
499
526
|
});
|
|
500
527
|
}
|
|
@@ -934,17 +961,20 @@ function executeSubscription(exeContext) {
|
|
|
934
961
|
const resolveFn = fieldDef.subscribe ?? exeContext.subscribeFieldResolver;
|
|
935
962
|
const result = resolveFn(rootValue, args, contextValue, info);
|
|
936
963
|
if (isPromise(result)) {
|
|
937
|
-
return result
|
|
964
|
+
return result
|
|
965
|
+
.then(result => assertEventStream(result, exeContext.signal, exeContext.onSignalAbort))
|
|
966
|
+
.then(undefined, error => {
|
|
938
967
|
throw locatedError(error, fieldNodes, pathToArray(path));
|
|
939
968
|
});
|
|
940
969
|
}
|
|
941
|
-
return assertEventStream(result, exeContext.signal);
|
|
970
|
+
return assertEventStream(result, exeContext.signal, exeContext.onSignalAbort);
|
|
942
971
|
}
|
|
943
972
|
catch (error) {
|
|
944
973
|
throw locatedError(error, fieldNodes, pathToArray(path));
|
|
945
974
|
}
|
|
946
975
|
}
|
|
947
|
-
function assertEventStream(result, signal) {
|
|
976
|
+
function assertEventStream(result, signal, onSignalAbort) {
|
|
977
|
+
signal?.throwIfAborted();
|
|
948
978
|
if (result instanceof Error) {
|
|
949
979
|
throw result;
|
|
950
980
|
}
|
|
@@ -952,12 +982,12 @@ function assertEventStream(result, signal) {
|
|
|
952
982
|
if (!isAsyncIterable(result)) {
|
|
953
983
|
throw createGraphQLError('Subscription field must return Async Iterable. ' + `Received: ${inspect(result)}.`);
|
|
954
984
|
}
|
|
955
|
-
if (
|
|
985
|
+
if (onSignalAbort) {
|
|
956
986
|
return {
|
|
957
987
|
[Symbol.asyncIterator]() {
|
|
958
988
|
const asyncIterator = result[Symbol.asyncIterator]();
|
|
959
989
|
if (asyncIterator.return) {
|
|
960
|
-
|
|
990
|
+
onSignalAbort?.(() => {
|
|
961
991
|
asyncIterator.return?.();
|
|
962
992
|
});
|
|
963
993
|
}
|
|
@@ -1185,14 +1215,13 @@ function getCompletedIncrementalResults(exeContext) {
|
|
|
1185
1215
|
}
|
|
1186
1216
|
function yieldSubsequentPayloads(exeContext) {
|
|
1187
1217
|
let isDone = false;
|
|
1188
|
-
const abortPromise = exeContext.signal ? getAbortPromise(exeContext.signal) : undefined;
|
|
1189
1218
|
async function next() {
|
|
1190
1219
|
if (isDone) {
|
|
1191
1220
|
return { value: undefined, done: true };
|
|
1192
1221
|
}
|
|
1193
1222
|
const subSequentPayloadPromises = Array.from(exeContext.subsequentPayloads).map(record => record.promise);
|
|
1194
|
-
if (
|
|
1195
|
-
await Promise.race([
|
|
1223
|
+
if (exeContext.signalPromise) {
|
|
1224
|
+
await Promise.race([exeContext.signalPromise, ...subSequentPayloadPromises]);
|
|
1196
1225
|
}
|
|
1197
1226
|
else {
|
|
1198
1227
|
await Promise.race(subSequentPayloadPromises);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isPromise } from '@graphql-tools/utils';
|
|
2
2
|
/**
|
|
3
3
|
* This function transforms a JS object `Record<string, Promise<T>>` into
|
|
4
4
|
* a `Promise<Record<string, T>>`
|
|
@@ -6,14 +6,25 @@ import { getAbortPromise } from '@graphql-tools/utils';
|
|
|
6
6
|
* This is akin to bluebird's `Promise.props`, but implemented only using
|
|
7
7
|
* `Promise.all` so it will work with any implementation of ES6 promises.
|
|
8
8
|
*/
|
|
9
|
-
export
|
|
9
|
+
export function promiseForObject(object, signal, signalPromise) {
|
|
10
|
+
signal?.throwIfAborted();
|
|
10
11
|
const resolvedObject = Object.create(null);
|
|
11
|
-
const promises =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const promises = [];
|
|
13
|
+
for (const key in object) {
|
|
14
|
+
const value = object[key];
|
|
15
|
+
if (isPromise(value)) {
|
|
16
|
+
promises.push(value.then(value => {
|
|
17
|
+
signal?.throwIfAborted();
|
|
18
|
+
resolvedObject[key] = value;
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
resolvedObject[key] = value;
|
|
23
|
+
}
|
|
17
24
|
}
|
|
18
|
-
|
|
25
|
+
const promiseAll = Promise.all(promises);
|
|
26
|
+
if (signalPromise) {
|
|
27
|
+
return Promise.race([signalPromise, promiseAll]).then(() => resolvedObject);
|
|
28
|
+
}
|
|
29
|
+
return promiseAll.then(() => resolvedObject);
|
|
19
30
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-tools/executor",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3-alpha-20250226150456-c866968c9e16e4eb2d1460dcbf97397c4a27ca60",
|
|
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": "
|
|
9
|
+
"@graphql-tools/utils": "10.8.4-alpha-20250226150456-c866968c9e16e4eb2d1460dcbf97397c4a27ca60",
|
|
10
10
|
"@graphql-typed-document-node/core": "^3.2.0",
|
|
11
11
|
"@repeaterjs/repeater": "^3.0.4",
|
|
12
12
|
"@whatwg-node/disposablestack": "^0.0.6",
|
|
@@ -44,6 +44,8 @@ export interface ExecutionContext<TVariables = any, TContext = any> {
|
|
|
44
44
|
errors: Array<GraphQLError>;
|
|
45
45
|
subsequentPayloads: Set<AsyncPayloadRecord>;
|
|
46
46
|
signal?: AbortSignal;
|
|
47
|
+
onSignalAbort?(handler: () => void): void;
|
|
48
|
+
signalPromise?: Promise<never>;
|
|
47
49
|
}
|
|
48
50
|
export interface FormattedExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> {
|
|
49
51
|
errors?: ReadonlyArray<GraphQLFormattedError>;
|
|
@@ -44,6 +44,8 @@ export interface ExecutionContext<TVariables = any, TContext = any> {
|
|
|
44
44
|
errors: Array<GraphQLError>;
|
|
45
45
|
subsequentPayloads: Set<AsyncPayloadRecord>;
|
|
46
46
|
signal?: AbortSignal;
|
|
47
|
+
onSignalAbort?(handler: () => void): void;
|
|
48
|
+
signalPromise?: Promise<never>;
|
|
47
49
|
}
|
|
48
50
|
export interface FormattedExecutionResult<TData = Record<string, unknown>, TExtensions = Record<string, unknown>> {
|
|
49
51
|
errors?: ReadonlyArray<GraphQLFormattedError>;
|
|
@@ -8,5 +8,5 @@ type ResolvedObject<TData> = {
|
|
|
8
8
|
* This is akin to bluebird's `Promise.props`, but implemented only using
|
|
9
9
|
* `Promise.all` so it will work with any implementation of ES6 promises.
|
|
10
10
|
*/
|
|
11
|
-
export declare function promiseForObject<TData>(object: TData, signal?: AbortSignal): Promise<ResolvedObject<TData>>;
|
|
11
|
+
export declare function promiseForObject<TData>(object: TData, signal?: AbortSignal, signalPromise?: Promise<never>): Promise<ResolvedObject<TData>>;
|
|
12
12
|
export {};
|
|
@@ -8,5 +8,5 @@ type ResolvedObject<TData> = {
|
|
|
8
8
|
* This is akin to bluebird's `Promise.props`, but implemented only using
|
|
9
9
|
* `Promise.all` so it will work with any implementation of ES6 promises.
|
|
10
10
|
*/
|
|
11
|
-
export declare function promiseForObject<TData>(object: TData, signal?: AbortSignal): Promise<ResolvedObject<TData>>;
|
|
11
|
+
export declare function promiseForObject<TData>(object: TData, signal?: AbortSignal, signalPromise?: Promise<never>): Promise<ResolvedObject<TData>>;
|
|
12
12
|
export {};
|