@envelop/core 1.7.2-alpha-7ca7cb8.0 → 2.0.0-alpha-dc1e98d.0
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/index.js +171 -105
- package/index.mjs +172 -106
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -27,8 +27,69 @@ function enableIf(condition, plugin) {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
const trackedSchemaSymbol = Symbol('TRACKED_SCHEMA');
|
|
31
31
|
const resolversHooksSymbol = Symbol('RESOLVERS_HOOKS');
|
|
32
|
+
function prepareTracedSchema(schema) {
|
|
33
|
+
if (!schema || schema[trackedSchemaSymbol]) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
schema[trackedSchemaSymbol] = true;
|
|
37
|
+
const entries = Object.values(schema.getTypeMap());
|
|
38
|
+
for (const type of entries) {
|
|
39
|
+
if (!graphql.isIntrospectionType(type) && graphql.isObjectType(type)) {
|
|
40
|
+
const fields = Object.values(type.getFields());
|
|
41
|
+
for (const field of fields) {
|
|
42
|
+
let resolverFn = (field.resolve || graphql.defaultFieldResolver);
|
|
43
|
+
field.resolve = async (root, args, context, info) => {
|
|
44
|
+
if (context && context[resolversHooksSymbol]) {
|
|
45
|
+
const hooks = context[resolversHooksSymbol];
|
|
46
|
+
const afterCalls = [];
|
|
47
|
+
for (const hook of hooks) {
|
|
48
|
+
const afterFn = await hook({
|
|
49
|
+
root,
|
|
50
|
+
args,
|
|
51
|
+
context,
|
|
52
|
+
info,
|
|
53
|
+
resolverFn,
|
|
54
|
+
replaceResolverFn: newFn => {
|
|
55
|
+
resolverFn = newFn;
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
afterFn && afterCalls.push(afterFn);
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
let result = await resolverFn(root, args, context, info);
|
|
62
|
+
for (const afterFn of afterCalls) {
|
|
63
|
+
afterFn({
|
|
64
|
+
result,
|
|
65
|
+
setResult: newResult => {
|
|
66
|
+
result = newResult;
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
let resultErr = e;
|
|
74
|
+
for (const afterFn of afterCalls) {
|
|
75
|
+
afterFn({
|
|
76
|
+
result: resultErr,
|
|
77
|
+
setResult: newResult => {
|
|
78
|
+
resultErr = newResult;
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
throw resultErr;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return resolverFn(root, args, context, info);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
32
93
|
|
|
33
94
|
const envelopIsIntrospectionSymbol = Symbol('ENVELOP_IS_INTROSPECTION');
|
|
34
95
|
function isOperationDefinition(def) {
|
|
@@ -242,10 +303,19 @@ function errorAsyncIterator(source, onError) {
|
|
|
242
303
|
function createEnvelopOrchestrator(plugins) {
|
|
243
304
|
let schema = null;
|
|
244
305
|
let initDone = false;
|
|
306
|
+
const onResolversHandlers = [];
|
|
307
|
+
for (const plugin of plugins) {
|
|
308
|
+
if (plugin.onResolverCalled) {
|
|
309
|
+
onResolversHandlers.push(plugin.onResolverCalled);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
245
312
|
// Define the initial method for replacing the GraphQL schema, this is needed in order
|
|
246
313
|
// to allow setting the schema from the onPluginInit callback. We also need to make sure
|
|
247
314
|
// here not to call the same plugin that initiated the schema switch.
|
|
248
315
|
const replaceSchema = (newSchema, ignorePluginIndex = -1) => {
|
|
316
|
+
if (onResolversHandlers.length) {
|
|
317
|
+
prepareTracedSchema(newSchema);
|
|
318
|
+
}
|
|
249
319
|
schema = newSchema;
|
|
250
320
|
if (initDone) {
|
|
251
321
|
for (const [i, plugin] of plugins.entries()) {
|
|
@@ -450,101 +520,100 @@ function createEnvelopOrchestrator(plugins) {
|
|
|
450
520
|
}
|
|
451
521
|
}
|
|
452
522
|
: initialContext => orchestratorCtx => orchestratorCtx ? { ...initialContext, ...orchestratorCtx } : initialContext;
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
if (after
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
onResolversHandlers.push(after.onResolverCalled);
|
|
523
|
+
const useCustomSubscribe = beforeCallbacks.subscribe.length || onResolversHandlers.length;
|
|
524
|
+
const customSubscribe = useCustomSubscribe
|
|
525
|
+
? makeSubscribe(async (args) => {
|
|
526
|
+
let subscribeFn = graphql.subscribe;
|
|
527
|
+
const afterCalls = [];
|
|
528
|
+
const subscribeErrorHandlers = [];
|
|
529
|
+
let context = args.contextValue || {};
|
|
530
|
+
for (const onSubscribe of beforeCallbacks.subscribe) {
|
|
531
|
+
const after = await onSubscribe({
|
|
532
|
+
subscribeFn,
|
|
533
|
+
setSubscribeFn: newSubscribeFn => {
|
|
534
|
+
subscribeFn = newSubscribeFn;
|
|
535
|
+
},
|
|
536
|
+
extendContext: extension => {
|
|
537
|
+
context = { ...context, ...extension };
|
|
538
|
+
},
|
|
539
|
+
args: args,
|
|
540
|
+
});
|
|
541
|
+
if (after) {
|
|
542
|
+
if (after.onSubscribeResult) {
|
|
543
|
+
afterCalls.push(after.onSubscribeResult);
|
|
544
|
+
}
|
|
545
|
+
if (after.onSubscribeError) {
|
|
546
|
+
subscribeErrorHandlers.push(after.onSubscribeError);
|
|
547
|
+
}
|
|
479
548
|
}
|
|
480
549
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
context[resolversHooksSymbol] = onResolversHandlers;
|
|
484
|
-
}
|
|
485
|
-
let result = await subscribeFn({
|
|
486
|
-
...args,
|
|
487
|
-
contextValue: context,
|
|
488
|
-
// Casted for GraphQL.js 15 compatibility
|
|
489
|
-
// Can be removed once we drop support for GraphQL.js 15
|
|
490
|
-
});
|
|
491
|
-
const onNextHandler = [];
|
|
492
|
-
const onEndHandler = [];
|
|
493
|
-
for (const afterCb of afterCalls) {
|
|
494
|
-
const hookResult = afterCb({
|
|
495
|
-
args: args,
|
|
496
|
-
result,
|
|
497
|
-
setResult: newResult => {
|
|
498
|
-
result = newResult;
|
|
499
|
-
},
|
|
500
|
-
});
|
|
501
|
-
if (hookResult) {
|
|
502
|
-
if (hookResult.onNext) {
|
|
503
|
-
onNextHandler.push(hookResult.onNext);
|
|
504
|
-
}
|
|
505
|
-
if (hookResult.onEnd) {
|
|
506
|
-
onEndHandler.push(hookResult.onEnd);
|
|
507
|
-
}
|
|
550
|
+
if (onResolversHandlers.length) {
|
|
551
|
+
context[resolversHooksSymbol] = onResolversHandlers;
|
|
508
552
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
args: args,
|
|
515
|
-
result,
|
|
516
|
-
setResult: newResult => (result = newResult),
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
return result;
|
|
520
|
-
});
|
|
521
|
-
}
|
|
522
|
-
if (onEndHandler.length && isAsyncIterable(result)) {
|
|
523
|
-
result = finalAsyncIterator(result, () => {
|
|
524
|
-
for (const onEnd of onEndHandler) {
|
|
525
|
-
onEnd();
|
|
526
|
-
}
|
|
553
|
+
let result = await subscribeFn({
|
|
554
|
+
...args,
|
|
555
|
+
contextValue: context,
|
|
556
|
+
// Casted for GraphQL.js 15 compatibility
|
|
557
|
+
// Can be removed once we drop support for GraphQL.js 15
|
|
527
558
|
});
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
559
|
+
const onNextHandler = [];
|
|
560
|
+
const onEndHandler = [];
|
|
561
|
+
for (const afterCb of afterCalls) {
|
|
562
|
+
const hookResult = afterCb({
|
|
563
|
+
args: args,
|
|
564
|
+
result,
|
|
565
|
+
setResult: newResult => {
|
|
566
|
+
result = newResult;
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
if (hookResult) {
|
|
570
|
+
if (hookResult.onNext) {
|
|
571
|
+
onNextHandler.push(hookResult.onNext);
|
|
572
|
+
}
|
|
573
|
+
if (hookResult.onEnd) {
|
|
574
|
+
onEndHandler.push(hookResult.onEnd);
|
|
575
|
+
}
|
|
539
576
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
577
|
+
}
|
|
578
|
+
if (onNextHandler.length && isAsyncIterable(result)) {
|
|
579
|
+
result = mapAsyncIterator(result, async (result) => {
|
|
580
|
+
for (const onNext of onNextHandler) {
|
|
581
|
+
await onNext({
|
|
582
|
+
args: args,
|
|
583
|
+
result,
|
|
584
|
+
setResult: newResult => (result = newResult),
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
return result;
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
if (onEndHandler.length && isAsyncIterable(result)) {
|
|
591
|
+
result = finalAsyncIterator(result, () => {
|
|
592
|
+
for (const onEnd of onEndHandler) {
|
|
593
|
+
onEnd();
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
if (subscribeErrorHandlers.length && isAsyncIterable(result)) {
|
|
598
|
+
result = errorAsyncIterator(result, err => {
|
|
599
|
+
let error = err;
|
|
600
|
+
for (const handler of subscribeErrorHandlers) {
|
|
601
|
+
handler({
|
|
602
|
+
error,
|
|
603
|
+
setError: err => {
|
|
604
|
+
error = err;
|
|
605
|
+
},
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
throw error;
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
return result;
|
|
612
|
+
})
|
|
613
|
+
: makeSubscribe(graphql.subscribe);
|
|
614
|
+
const useCustomExecute = beforeCallbacks.execute.length || onResolversHandlers.length;
|
|
615
|
+
const customExecute = useCustomExecute
|
|
546
616
|
? makeExecute(async (args) => {
|
|
547
|
-
const onResolversHandlers = [];
|
|
548
617
|
let executeFn = graphql.execute;
|
|
549
618
|
let result;
|
|
550
619
|
const afterCalls = [];
|
|
@@ -580,9 +649,6 @@ function createEnvelopOrchestrator(plugins) {
|
|
|
580
649
|
if (after.onExecuteDone) {
|
|
581
650
|
afterCalls.push(after.onExecuteDone);
|
|
582
651
|
}
|
|
583
|
-
if (after.onResolverCalled) {
|
|
584
|
-
onResolversHandlers.push(after.onResolverCalled);
|
|
585
|
-
}
|
|
586
652
|
}
|
|
587
653
|
}
|
|
588
654
|
if (onResolversHandlers.length) {
|
|
@@ -935,12 +1001,12 @@ const useTiming = (rawOptions) => {
|
|
|
935
1001
|
onExecuteDone: () => {
|
|
936
1002
|
options.onExecutionMeasurement(args, deltaFrom(executeStartTime));
|
|
937
1003
|
},
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
1004
|
+
};
|
|
1005
|
+
};
|
|
1006
|
+
result.onResolverCalled = ({ info }) => {
|
|
1007
|
+
const resolverStartTime = process.hrtime();
|
|
1008
|
+
return () => {
|
|
1009
|
+
options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
|
|
944
1010
|
};
|
|
945
1011
|
};
|
|
946
1012
|
}
|
|
@@ -969,12 +1035,12 @@ const useTiming = (rawOptions) => {
|
|
|
969
1035
|
onSubscribeResult: () => {
|
|
970
1036
|
options.onSubscriptionMeasurement && options.onSubscriptionMeasurement(args, deltaFrom(subscribeStartTime));
|
|
971
1037
|
},
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1038
|
+
};
|
|
1039
|
+
};
|
|
1040
|
+
result.onResolverCalled = ({ info }) => {
|
|
1041
|
+
const resolverStartTime = process.hrtime();
|
|
1042
|
+
return () => {
|
|
1043
|
+
options.onResolverMeasurement && options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
|
|
978
1044
|
};
|
|
979
1045
|
};
|
|
980
1046
|
}
|
package/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from '@envelop/types';
|
|
2
|
-
import { Kind, visit, BREAK, parse, specifiedRules, validate,
|
|
2
|
+
import { isIntrospectionType, isObjectType, defaultFieldResolver, Kind, visit, BREAK, parse, specifiedRules, validate, subscribe, execute, GraphQLSchema, getOperationAST, GraphQLError } from 'graphql';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* This enum is used only internally in order to create nominal type for the disabled plugin
|
|
@@ -23,8 +23,69 @@ function enableIf(condition, plugin) {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
const trackedSchemaSymbol = Symbol('TRACKED_SCHEMA');
|
|
27
27
|
const resolversHooksSymbol = Symbol('RESOLVERS_HOOKS');
|
|
28
|
+
function prepareTracedSchema(schema) {
|
|
29
|
+
if (!schema || schema[trackedSchemaSymbol]) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
schema[trackedSchemaSymbol] = true;
|
|
33
|
+
const entries = Object.values(schema.getTypeMap());
|
|
34
|
+
for (const type of entries) {
|
|
35
|
+
if (!isIntrospectionType(type) && isObjectType(type)) {
|
|
36
|
+
const fields = Object.values(type.getFields());
|
|
37
|
+
for (const field of fields) {
|
|
38
|
+
let resolverFn = (field.resolve || defaultFieldResolver);
|
|
39
|
+
field.resolve = async (root, args, context, info) => {
|
|
40
|
+
if (context && context[resolversHooksSymbol]) {
|
|
41
|
+
const hooks = context[resolversHooksSymbol];
|
|
42
|
+
const afterCalls = [];
|
|
43
|
+
for (const hook of hooks) {
|
|
44
|
+
const afterFn = await hook({
|
|
45
|
+
root,
|
|
46
|
+
args,
|
|
47
|
+
context,
|
|
48
|
+
info,
|
|
49
|
+
resolverFn,
|
|
50
|
+
replaceResolverFn: newFn => {
|
|
51
|
+
resolverFn = newFn;
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
afterFn && afterCalls.push(afterFn);
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
let result = await resolverFn(root, args, context, info);
|
|
58
|
+
for (const afterFn of afterCalls) {
|
|
59
|
+
afterFn({
|
|
60
|
+
result,
|
|
61
|
+
setResult: newResult => {
|
|
62
|
+
result = newResult;
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
let resultErr = e;
|
|
70
|
+
for (const afterFn of afterCalls) {
|
|
71
|
+
afterFn({
|
|
72
|
+
result: resultErr,
|
|
73
|
+
setResult: newResult => {
|
|
74
|
+
resultErr = newResult;
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
throw resultErr;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
return resolverFn(root, args, context, info);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
28
89
|
|
|
29
90
|
const envelopIsIntrospectionSymbol = Symbol('ENVELOP_IS_INTROSPECTION');
|
|
30
91
|
function isOperationDefinition(def) {
|
|
@@ -238,10 +299,19 @@ function errorAsyncIterator(source, onError) {
|
|
|
238
299
|
function createEnvelopOrchestrator(plugins) {
|
|
239
300
|
let schema = null;
|
|
240
301
|
let initDone = false;
|
|
302
|
+
const onResolversHandlers = [];
|
|
303
|
+
for (const plugin of plugins) {
|
|
304
|
+
if (plugin.onResolverCalled) {
|
|
305
|
+
onResolversHandlers.push(plugin.onResolverCalled);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
241
308
|
// Define the initial method for replacing the GraphQL schema, this is needed in order
|
|
242
309
|
// to allow setting the schema from the onPluginInit callback. We also need to make sure
|
|
243
310
|
// here not to call the same plugin that initiated the schema switch.
|
|
244
311
|
const replaceSchema = (newSchema, ignorePluginIndex = -1) => {
|
|
312
|
+
if (onResolversHandlers.length) {
|
|
313
|
+
prepareTracedSchema(newSchema);
|
|
314
|
+
}
|
|
245
315
|
schema = newSchema;
|
|
246
316
|
if (initDone) {
|
|
247
317
|
for (const [i, plugin] of plugins.entries()) {
|
|
@@ -446,101 +516,100 @@ function createEnvelopOrchestrator(plugins) {
|
|
|
446
516
|
}
|
|
447
517
|
}
|
|
448
518
|
: initialContext => orchestratorCtx => orchestratorCtx ? { ...initialContext, ...orchestratorCtx } : initialContext;
|
|
449
|
-
const
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
if (after
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
onResolversHandlers.push(after.onResolverCalled);
|
|
519
|
+
const useCustomSubscribe = beforeCallbacks.subscribe.length || onResolversHandlers.length;
|
|
520
|
+
const customSubscribe = useCustomSubscribe
|
|
521
|
+
? makeSubscribe(async (args) => {
|
|
522
|
+
let subscribeFn = subscribe;
|
|
523
|
+
const afterCalls = [];
|
|
524
|
+
const subscribeErrorHandlers = [];
|
|
525
|
+
let context = args.contextValue || {};
|
|
526
|
+
for (const onSubscribe of beforeCallbacks.subscribe) {
|
|
527
|
+
const after = await onSubscribe({
|
|
528
|
+
subscribeFn,
|
|
529
|
+
setSubscribeFn: newSubscribeFn => {
|
|
530
|
+
subscribeFn = newSubscribeFn;
|
|
531
|
+
},
|
|
532
|
+
extendContext: extension => {
|
|
533
|
+
context = { ...context, ...extension };
|
|
534
|
+
},
|
|
535
|
+
args: args,
|
|
536
|
+
});
|
|
537
|
+
if (after) {
|
|
538
|
+
if (after.onSubscribeResult) {
|
|
539
|
+
afterCalls.push(after.onSubscribeResult);
|
|
540
|
+
}
|
|
541
|
+
if (after.onSubscribeError) {
|
|
542
|
+
subscribeErrorHandlers.push(after.onSubscribeError);
|
|
543
|
+
}
|
|
475
544
|
}
|
|
476
545
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
context[resolversHooksSymbol] = onResolversHandlers;
|
|
480
|
-
}
|
|
481
|
-
let result = await subscribeFn({
|
|
482
|
-
...args,
|
|
483
|
-
contextValue: context,
|
|
484
|
-
// Casted for GraphQL.js 15 compatibility
|
|
485
|
-
// Can be removed once we drop support for GraphQL.js 15
|
|
486
|
-
});
|
|
487
|
-
const onNextHandler = [];
|
|
488
|
-
const onEndHandler = [];
|
|
489
|
-
for (const afterCb of afterCalls) {
|
|
490
|
-
const hookResult = afterCb({
|
|
491
|
-
args: args,
|
|
492
|
-
result,
|
|
493
|
-
setResult: newResult => {
|
|
494
|
-
result = newResult;
|
|
495
|
-
},
|
|
496
|
-
});
|
|
497
|
-
if (hookResult) {
|
|
498
|
-
if (hookResult.onNext) {
|
|
499
|
-
onNextHandler.push(hookResult.onNext);
|
|
500
|
-
}
|
|
501
|
-
if (hookResult.onEnd) {
|
|
502
|
-
onEndHandler.push(hookResult.onEnd);
|
|
503
|
-
}
|
|
546
|
+
if (onResolversHandlers.length) {
|
|
547
|
+
context[resolversHooksSymbol] = onResolversHandlers;
|
|
504
548
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
args: args,
|
|
511
|
-
result,
|
|
512
|
-
setResult: newResult => (result = newResult),
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
return result;
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
if (onEndHandler.length && isAsyncIterable(result)) {
|
|
519
|
-
result = finalAsyncIterator(result, () => {
|
|
520
|
-
for (const onEnd of onEndHandler) {
|
|
521
|
-
onEnd();
|
|
522
|
-
}
|
|
549
|
+
let result = await subscribeFn({
|
|
550
|
+
...args,
|
|
551
|
+
contextValue: context,
|
|
552
|
+
// Casted for GraphQL.js 15 compatibility
|
|
553
|
+
// Can be removed once we drop support for GraphQL.js 15
|
|
523
554
|
});
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
555
|
+
const onNextHandler = [];
|
|
556
|
+
const onEndHandler = [];
|
|
557
|
+
for (const afterCb of afterCalls) {
|
|
558
|
+
const hookResult = afterCb({
|
|
559
|
+
args: args,
|
|
560
|
+
result,
|
|
561
|
+
setResult: newResult => {
|
|
562
|
+
result = newResult;
|
|
563
|
+
},
|
|
564
|
+
});
|
|
565
|
+
if (hookResult) {
|
|
566
|
+
if (hookResult.onNext) {
|
|
567
|
+
onNextHandler.push(hookResult.onNext);
|
|
568
|
+
}
|
|
569
|
+
if (hookResult.onEnd) {
|
|
570
|
+
onEndHandler.push(hookResult.onEnd);
|
|
571
|
+
}
|
|
535
572
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
573
|
+
}
|
|
574
|
+
if (onNextHandler.length && isAsyncIterable(result)) {
|
|
575
|
+
result = mapAsyncIterator(result, async (result) => {
|
|
576
|
+
for (const onNext of onNextHandler) {
|
|
577
|
+
await onNext({
|
|
578
|
+
args: args,
|
|
579
|
+
result,
|
|
580
|
+
setResult: newResult => (result = newResult),
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
return result;
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
if (onEndHandler.length && isAsyncIterable(result)) {
|
|
587
|
+
result = finalAsyncIterator(result, () => {
|
|
588
|
+
for (const onEnd of onEndHandler) {
|
|
589
|
+
onEnd();
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
if (subscribeErrorHandlers.length && isAsyncIterable(result)) {
|
|
594
|
+
result = errorAsyncIterator(result, err => {
|
|
595
|
+
let error = err;
|
|
596
|
+
for (const handler of subscribeErrorHandlers) {
|
|
597
|
+
handler({
|
|
598
|
+
error,
|
|
599
|
+
setError: err => {
|
|
600
|
+
error = err;
|
|
601
|
+
},
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
throw error;
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
return result;
|
|
608
|
+
})
|
|
609
|
+
: makeSubscribe(subscribe);
|
|
610
|
+
const useCustomExecute = beforeCallbacks.execute.length || onResolversHandlers.length;
|
|
611
|
+
const customExecute = useCustomExecute
|
|
542
612
|
? makeExecute(async (args) => {
|
|
543
|
-
const onResolversHandlers = [];
|
|
544
613
|
let executeFn = execute;
|
|
545
614
|
let result;
|
|
546
615
|
const afterCalls = [];
|
|
@@ -576,9 +645,6 @@ function createEnvelopOrchestrator(plugins) {
|
|
|
576
645
|
if (after.onExecuteDone) {
|
|
577
646
|
afterCalls.push(after.onExecuteDone);
|
|
578
647
|
}
|
|
579
|
-
if (after.onResolverCalled) {
|
|
580
|
-
onResolversHandlers.push(after.onResolverCalled);
|
|
581
|
-
}
|
|
582
648
|
}
|
|
583
649
|
}
|
|
584
650
|
if (onResolversHandlers.length) {
|
|
@@ -931,12 +997,12 @@ const useTiming = (rawOptions) => {
|
|
|
931
997
|
onExecuteDone: () => {
|
|
932
998
|
options.onExecutionMeasurement(args, deltaFrom(executeStartTime));
|
|
933
999
|
},
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
1000
|
+
};
|
|
1001
|
+
};
|
|
1002
|
+
result.onResolverCalled = ({ info }) => {
|
|
1003
|
+
const resolverStartTime = process.hrtime();
|
|
1004
|
+
return () => {
|
|
1005
|
+
options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
|
|
940
1006
|
};
|
|
941
1007
|
};
|
|
942
1008
|
}
|
|
@@ -965,12 +1031,12 @@ const useTiming = (rawOptions) => {
|
|
|
965
1031
|
onSubscribeResult: () => {
|
|
966
1032
|
options.onSubscriptionMeasurement && options.onSubscriptionMeasurement(args, deltaFrom(subscribeStartTime));
|
|
967
1033
|
},
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1034
|
+
};
|
|
1035
|
+
};
|
|
1036
|
+
result.onResolverCalled = ({ info }) => {
|
|
1037
|
+
const resolverStartTime = process.hrtime();
|
|
1038
|
+
return () => {
|
|
1039
|
+
options.onResolverMeasurement && options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
|
|
974
1040
|
};
|
|
975
1041
|
};
|
|
976
1042
|
}
|