graphql-modules 2.4.0 → 2.4.1-alpha-20241223144441-674927c3a29a8c57bbdad7eb31576cb88178f815
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/application/context.d.ts +4 -1
- package/index.js +104 -79
- package/index.mjs +104 -79
- package/package.json +1 -1
package/application/context.d.ts
CHANGED
|
@@ -3,7 +3,10 @@ import { ResolvedProvider } from '../di/resolution';
|
|
|
3
3
|
import type { InternalAppContext, ModulesMap } from './application';
|
|
4
4
|
export type ExecutionContextBuilder<TContext extends {
|
|
5
5
|
[key: string]: any;
|
|
6
|
-
} = {}> = (context: TContext) => {
|
|
6
|
+
} = {}> = (context: TContext) => ExecutionContextEnv & {
|
|
7
|
+
runWithContext<TReturn = any>(cb: (env: ExecutionContextEnv) => TReturn): TReturn;
|
|
8
|
+
};
|
|
9
|
+
export type ExecutionContextEnv = {
|
|
7
10
|
context: InternalAppContext;
|
|
8
11
|
ɵdestroy(): void;
|
|
9
12
|
ɵinjector: Injector;
|
package/index.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
const schema = require('@graphql-tools/schema');
|
|
6
6
|
const graphql = require('graphql');
|
|
7
|
+
const async_hooks = require('async_hooks');
|
|
7
8
|
const wrap = require('@graphql-tools/wrap');
|
|
8
9
|
const ramda = require('ramda');
|
|
9
10
|
|
|
@@ -854,6 +855,7 @@ function duplicatedGlobalTokenError(provider, modules) {
|
|
|
854
855
|
*/
|
|
855
856
|
const CONTEXT = new InjectionToken('context');
|
|
856
857
|
|
|
858
|
+
const alc = new async_hooks.AsyncLocalStorage();
|
|
857
859
|
function createContextBuilder({ appInjector, modulesMap, appLevelOperationProviders, singletonGlobalProvidersMap, operationGlobalProvidersMap, }) {
|
|
858
860
|
// This is very critical. It creates an execution context.
|
|
859
861
|
// It has to run on every operation.
|
|
@@ -882,11 +884,14 @@ function createContextBuilder({ appInjector, modulesMap, appLevelOperationProvid
|
|
|
882
884
|
},
|
|
883
885
|
});
|
|
884
886
|
appInjector.setExecutionContextGetter(function executionContextGetter() {
|
|
885
|
-
|
|
887
|
+
var _a;
|
|
888
|
+
return ((_a = alc.getStore()) === null || _a === void 0 ? void 0 : _a.getApplicationContext()) || appContext;
|
|
886
889
|
});
|
|
887
890
|
function createModuleExecutionContextGetter(moduleId) {
|
|
888
891
|
return function moduleExecutionContextGetter() {
|
|
889
|
-
|
|
892
|
+
var _a;
|
|
893
|
+
return (((_a = alc.getStore()) === null || _a === void 0 ? void 0 : _a.getModuleContext(moduleId)) ||
|
|
894
|
+
getModuleContext(moduleId, context));
|
|
890
895
|
};
|
|
891
896
|
}
|
|
892
897
|
modulesMap.forEach((mod, moduleId) => {
|
|
@@ -956,7 +961,7 @@ function createContextBuilder({ appInjector, modulesMap, appLevelOperationProvid
|
|
|
956
961
|
return getModuleContext(moduleId, sharedContext).injector;
|
|
957
962
|
},
|
|
958
963
|
});
|
|
959
|
-
|
|
964
|
+
const env = {
|
|
960
965
|
ɵdestroy: once(() => {
|
|
961
966
|
providersToDestroy.forEach(([injector, keyId]) => {
|
|
962
967
|
// If provider was instantiated
|
|
@@ -970,6 +975,19 @@ function createContextBuilder({ appInjector, modulesMap, appLevelOperationProvid
|
|
|
970
975
|
ɵinjector: operationAppInjector,
|
|
971
976
|
context: sharedContext,
|
|
972
977
|
};
|
|
978
|
+
return {
|
|
979
|
+
...env,
|
|
980
|
+
runWithContext(cb) {
|
|
981
|
+
return alc.run({
|
|
982
|
+
getApplicationContext() {
|
|
983
|
+
return appContext;
|
|
984
|
+
},
|
|
985
|
+
getModuleContext(moduleId) {
|
|
986
|
+
return getModuleContext(moduleId, context);
|
|
987
|
+
},
|
|
988
|
+
}, () => cb(env));
|
|
989
|
+
},
|
|
990
|
+
};
|
|
973
991
|
};
|
|
974
992
|
return contextBuilder;
|
|
975
993
|
}
|
|
@@ -979,31 +997,34 @@ function executionCreator({ contextBuilder, }) {
|
|
|
979
997
|
// Custom or original execute function
|
|
980
998
|
const executeFn = (options === null || options === void 0 ? void 0 : options.execute) || graphql.execute;
|
|
981
999
|
return (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, typeResolver) => {
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1000
|
+
function perform({ context, ɵdestroy: destroy, }) {
|
|
1001
|
+
const executionArgs = isNotSchema(argsOrSchema)
|
|
1002
|
+
? {
|
|
1003
|
+
...argsOrSchema,
|
|
1004
|
+
contextValue: context,
|
|
1005
|
+
}
|
|
1006
|
+
: {
|
|
1007
|
+
schema: argsOrSchema,
|
|
1008
|
+
document: document,
|
|
1009
|
+
rootValue,
|
|
1010
|
+
contextValue: context,
|
|
1011
|
+
variableValues,
|
|
1012
|
+
operationName,
|
|
1013
|
+
fieldResolver,
|
|
1014
|
+
typeResolver,
|
|
1015
|
+
};
|
|
1016
|
+
// It's important to wrap the executeFn within a promise
|
|
1017
|
+
// so we can easily control the end of execution (with finally)
|
|
1018
|
+
return Promise.resolve()
|
|
1019
|
+
.then(() => executeFn(executionArgs))
|
|
1020
|
+
.finally(destroy);
|
|
1021
|
+
}
|
|
1022
|
+
if (options === null || options === void 0 ? void 0 : options.controller) {
|
|
1023
|
+
return perform(options.controller);
|
|
1024
|
+
}
|
|
1025
|
+
return contextBuilder(isNotSchema(argsOrSchema)
|
|
985
1026
|
? argsOrSchema.contextValue
|
|
986
|
-
: contextValue);
|
|
987
|
-
const executionArgs = isNotSchema(argsOrSchema)
|
|
988
|
-
? {
|
|
989
|
-
...argsOrSchema,
|
|
990
|
-
contextValue: context,
|
|
991
|
-
}
|
|
992
|
-
: {
|
|
993
|
-
schema: argsOrSchema,
|
|
994
|
-
document: document,
|
|
995
|
-
rootValue,
|
|
996
|
-
contextValue: context,
|
|
997
|
-
variableValues,
|
|
998
|
-
operationName,
|
|
999
|
-
fieldResolver,
|
|
1000
|
-
typeResolver,
|
|
1001
|
-
};
|
|
1002
|
-
// It's important to wrap the executeFn within a promise
|
|
1003
|
-
// so we can easily control the end of execution (with finally)
|
|
1004
|
-
return Promise.resolve()
|
|
1005
|
-
.then(() => executeFn(executionArgs))
|
|
1006
|
-
.finally(destroy);
|
|
1027
|
+
: contextValue).runWithContext(perform);
|
|
1007
1028
|
};
|
|
1008
1029
|
};
|
|
1009
1030
|
return createExecution;
|
|
@@ -1014,43 +1035,46 @@ function subscriptionCreator({ contextBuilder, }) {
|
|
|
1014
1035
|
// Custom or original subscribe function
|
|
1015
1036
|
const subscribeFn = (options === null || options === void 0 ? void 0 : options.subscribe) || graphql.subscribe;
|
|
1016
1037
|
return (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, subscribeFieldResolver) => {
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1038
|
+
function perform({ context, ɵdestroy: destroy, }) {
|
|
1039
|
+
const subscriptionArgs = isNotSchema(argsOrSchema)
|
|
1040
|
+
? {
|
|
1041
|
+
...argsOrSchema,
|
|
1042
|
+
contextValue: context,
|
|
1043
|
+
}
|
|
1044
|
+
: {
|
|
1045
|
+
schema: argsOrSchema,
|
|
1046
|
+
document: document,
|
|
1047
|
+
rootValue,
|
|
1048
|
+
contextValue: context,
|
|
1049
|
+
variableValues,
|
|
1050
|
+
operationName,
|
|
1051
|
+
fieldResolver,
|
|
1052
|
+
subscribeFieldResolver,
|
|
1053
|
+
};
|
|
1054
|
+
let isIterable = false;
|
|
1055
|
+
// It's important to wrap the subscribeFn within a promise
|
|
1056
|
+
// so we can easily control the end of subscription (with finally)
|
|
1057
|
+
return Promise.resolve()
|
|
1058
|
+
.then(() => subscribeFn(subscriptionArgs))
|
|
1059
|
+
.then((sub) => {
|
|
1060
|
+
if (isAsyncIterable(sub)) {
|
|
1061
|
+
isIterable = true;
|
|
1062
|
+
return tapAsyncIterator(sub, destroy);
|
|
1063
|
+
}
|
|
1064
|
+
return sub;
|
|
1065
|
+
})
|
|
1066
|
+
.finally(() => {
|
|
1067
|
+
if (!isIterable) {
|
|
1068
|
+
destroy();
|
|
1069
|
+
}
|
|
1070
|
+
});
|
|
1071
|
+
}
|
|
1072
|
+
if (options === null || options === void 0 ? void 0 : options.controller) {
|
|
1073
|
+
return perform(options.controller);
|
|
1074
|
+
}
|
|
1075
|
+
return contextBuilder(isNotSchema(argsOrSchema)
|
|
1020
1076
|
? argsOrSchema.contextValue
|
|
1021
|
-
: contextValue);
|
|
1022
|
-
const subscriptionArgs = isNotSchema(argsOrSchema)
|
|
1023
|
-
? {
|
|
1024
|
-
...argsOrSchema,
|
|
1025
|
-
contextValue: context,
|
|
1026
|
-
}
|
|
1027
|
-
: {
|
|
1028
|
-
schema: argsOrSchema,
|
|
1029
|
-
document: document,
|
|
1030
|
-
rootValue,
|
|
1031
|
-
contextValue: context,
|
|
1032
|
-
variableValues,
|
|
1033
|
-
operationName,
|
|
1034
|
-
fieldResolver,
|
|
1035
|
-
subscribeFieldResolver,
|
|
1036
|
-
};
|
|
1037
|
-
let isIterable = false;
|
|
1038
|
-
// It's important to wrap the subscribeFn within a promise
|
|
1039
|
-
// so we can easily control the end of subscription (with finally)
|
|
1040
|
-
return Promise.resolve()
|
|
1041
|
-
.then(() => subscribeFn(subscriptionArgs))
|
|
1042
|
-
.then((sub) => {
|
|
1043
|
-
if (isAsyncIterable(sub)) {
|
|
1044
|
-
isIterable = true;
|
|
1045
|
-
return tapAsyncIterator(sub, destroy);
|
|
1046
|
-
}
|
|
1047
|
-
return sub;
|
|
1048
|
-
})
|
|
1049
|
-
.finally(() => {
|
|
1050
|
-
if (!isIterable) {
|
|
1051
|
-
destroy();
|
|
1052
|
-
}
|
|
1053
|
-
});
|
|
1077
|
+
: contextValue).runWithContext(perform);
|
|
1054
1078
|
};
|
|
1055
1079
|
};
|
|
1056
1080
|
return createSubscription;
|
|
@@ -1075,10 +1099,9 @@ function apolloSchemaCreator({ createSubscription, contextBuilder, schema, }) {
|
|
|
1075
1099
|
const createApolloSchema = () => {
|
|
1076
1100
|
const sessions = {};
|
|
1077
1101
|
const subscription = createSubscription();
|
|
1078
|
-
function getSession(ctx) {
|
|
1102
|
+
function getSession(ctx, { context, ɵdestroy: destroy }) {
|
|
1079
1103
|
if (!ctx[CONTEXT_ID]) {
|
|
1080
1104
|
ctx[CONTEXT_ID] = uniqueId((id) => !sessions[id]);
|
|
1081
|
-
const { context, ɵdestroy: destroy } = contextBuilder(ctx);
|
|
1082
1105
|
sessions[ctx[CONTEXT_ID]] = {
|
|
1083
1106
|
count: 0,
|
|
1084
1107
|
session: {
|
|
@@ -1110,20 +1133,22 @@ function apolloSchemaCreator({ createSubscription, contextBuilder, schema, }) {
|
|
|
1110
1133
|
operationName: input.operationName,
|
|
1111
1134
|
});
|
|
1112
1135
|
}
|
|
1113
|
-
// Create an execution context
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
.
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1136
|
+
// Create an execution context and run within it
|
|
1137
|
+
return contextBuilder(input.context).runWithContext((env) => {
|
|
1138
|
+
const { context, destroy } = getSession(input.context, env);
|
|
1139
|
+
// It's important to wrap the executeFn within a promise
|
|
1140
|
+
// so we can easily control the end of execution (with finally)
|
|
1141
|
+
return Promise.resolve()
|
|
1142
|
+
.then(() => graphql.execute({
|
|
1143
|
+
schema,
|
|
1144
|
+
document: input.document,
|
|
1145
|
+
contextValue: context,
|
|
1146
|
+
variableValues: input.variables,
|
|
1147
|
+
rootValue: input.rootValue,
|
|
1148
|
+
operationName: input.operationName,
|
|
1149
|
+
}))
|
|
1150
|
+
.finally(destroy);
|
|
1151
|
+
});
|
|
1127
1152
|
},
|
|
1128
1153
|
});
|
|
1129
1154
|
};
|
package/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { makeExecutableSchema } from '@graphql-tools/schema';
|
|
2
2
|
import { GraphQLSchema, execute as execute$1, subscribe, visit, Kind, GraphQLScalarType, concatAST, defaultFieldResolver, parse } from 'graphql';
|
|
3
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
3
4
|
import { wrapSchema } from '@graphql-tools/wrap';
|
|
4
5
|
import { mergeDeepWith } from 'ramda';
|
|
5
6
|
|
|
@@ -851,6 +852,7 @@ function duplicatedGlobalTokenError(provider, modules) {
|
|
|
851
852
|
*/
|
|
852
853
|
const CONTEXT = new InjectionToken('context');
|
|
853
854
|
|
|
855
|
+
const alc = new AsyncLocalStorage();
|
|
854
856
|
function createContextBuilder({ appInjector, modulesMap, appLevelOperationProviders, singletonGlobalProvidersMap, operationGlobalProvidersMap, }) {
|
|
855
857
|
// This is very critical. It creates an execution context.
|
|
856
858
|
// It has to run on every operation.
|
|
@@ -879,11 +881,14 @@ function createContextBuilder({ appInjector, modulesMap, appLevelOperationProvid
|
|
|
879
881
|
},
|
|
880
882
|
});
|
|
881
883
|
appInjector.setExecutionContextGetter(function executionContextGetter() {
|
|
882
|
-
|
|
884
|
+
var _a;
|
|
885
|
+
return ((_a = alc.getStore()) === null || _a === void 0 ? void 0 : _a.getApplicationContext()) || appContext;
|
|
883
886
|
});
|
|
884
887
|
function createModuleExecutionContextGetter(moduleId) {
|
|
885
888
|
return function moduleExecutionContextGetter() {
|
|
886
|
-
|
|
889
|
+
var _a;
|
|
890
|
+
return (((_a = alc.getStore()) === null || _a === void 0 ? void 0 : _a.getModuleContext(moduleId)) ||
|
|
891
|
+
getModuleContext(moduleId, context));
|
|
887
892
|
};
|
|
888
893
|
}
|
|
889
894
|
modulesMap.forEach((mod, moduleId) => {
|
|
@@ -953,7 +958,7 @@ function createContextBuilder({ appInjector, modulesMap, appLevelOperationProvid
|
|
|
953
958
|
return getModuleContext(moduleId, sharedContext).injector;
|
|
954
959
|
},
|
|
955
960
|
});
|
|
956
|
-
|
|
961
|
+
const env = {
|
|
957
962
|
ɵdestroy: once(() => {
|
|
958
963
|
providersToDestroy.forEach(([injector, keyId]) => {
|
|
959
964
|
// If provider was instantiated
|
|
@@ -967,6 +972,19 @@ function createContextBuilder({ appInjector, modulesMap, appLevelOperationProvid
|
|
|
967
972
|
ɵinjector: operationAppInjector,
|
|
968
973
|
context: sharedContext,
|
|
969
974
|
};
|
|
975
|
+
return {
|
|
976
|
+
...env,
|
|
977
|
+
runWithContext(cb) {
|
|
978
|
+
return alc.run({
|
|
979
|
+
getApplicationContext() {
|
|
980
|
+
return appContext;
|
|
981
|
+
},
|
|
982
|
+
getModuleContext(moduleId) {
|
|
983
|
+
return getModuleContext(moduleId, context);
|
|
984
|
+
},
|
|
985
|
+
}, () => cb(env));
|
|
986
|
+
},
|
|
987
|
+
};
|
|
970
988
|
};
|
|
971
989
|
return contextBuilder;
|
|
972
990
|
}
|
|
@@ -976,31 +994,34 @@ function executionCreator({ contextBuilder, }) {
|
|
|
976
994
|
// Custom or original execute function
|
|
977
995
|
const executeFn = (options === null || options === void 0 ? void 0 : options.execute) || execute$1;
|
|
978
996
|
return (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, typeResolver) => {
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
997
|
+
function perform({ context, ɵdestroy: destroy, }) {
|
|
998
|
+
const executionArgs = isNotSchema(argsOrSchema)
|
|
999
|
+
? {
|
|
1000
|
+
...argsOrSchema,
|
|
1001
|
+
contextValue: context,
|
|
1002
|
+
}
|
|
1003
|
+
: {
|
|
1004
|
+
schema: argsOrSchema,
|
|
1005
|
+
document: document,
|
|
1006
|
+
rootValue,
|
|
1007
|
+
contextValue: context,
|
|
1008
|
+
variableValues,
|
|
1009
|
+
operationName,
|
|
1010
|
+
fieldResolver,
|
|
1011
|
+
typeResolver,
|
|
1012
|
+
};
|
|
1013
|
+
// It's important to wrap the executeFn within a promise
|
|
1014
|
+
// so we can easily control the end of execution (with finally)
|
|
1015
|
+
return Promise.resolve()
|
|
1016
|
+
.then(() => executeFn(executionArgs))
|
|
1017
|
+
.finally(destroy);
|
|
1018
|
+
}
|
|
1019
|
+
if (options === null || options === void 0 ? void 0 : options.controller) {
|
|
1020
|
+
return perform(options.controller);
|
|
1021
|
+
}
|
|
1022
|
+
return contextBuilder(isNotSchema(argsOrSchema)
|
|
982
1023
|
? argsOrSchema.contextValue
|
|
983
|
-
: contextValue);
|
|
984
|
-
const executionArgs = isNotSchema(argsOrSchema)
|
|
985
|
-
? {
|
|
986
|
-
...argsOrSchema,
|
|
987
|
-
contextValue: context,
|
|
988
|
-
}
|
|
989
|
-
: {
|
|
990
|
-
schema: argsOrSchema,
|
|
991
|
-
document: document,
|
|
992
|
-
rootValue,
|
|
993
|
-
contextValue: context,
|
|
994
|
-
variableValues,
|
|
995
|
-
operationName,
|
|
996
|
-
fieldResolver,
|
|
997
|
-
typeResolver,
|
|
998
|
-
};
|
|
999
|
-
// It's important to wrap the executeFn within a promise
|
|
1000
|
-
// so we can easily control the end of execution (with finally)
|
|
1001
|
-
return Promise.resolve()
|
|
1002
|
-
.then(() => executeFn(executionArgs))
|
|
1003
|
-
.finally(destroy);
|
|
1024
|
+
: contextValue).runWithContext(perform);
|
|
1004
1025
|
};
|
|
1005
1026
|
};
|
|
1006
1027
|
return createExecution;
|
|
@@ -1011,43 +1032,46 @@ function subscriptionCreator({ contextBuilder, }) {
|
|
|
1011
1032
|
// Custom or original subscribe function
|
|
1012
1033
|
const subscribeFn = (options === null || options === void 0 ? void 0 : options.subscribe) || subscribe;
|
|
1013
1034
|
return (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, subscribeFieldResolver) => {
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1035
|
+
function perform({ context, ɵdestroy: destroy, }) {
|
|
1036
|
+
const subscriptionArgs = isNotSchema(argsOrSchema)
|
|
1037
|
+
? {
|
|
1038
|
+
...argsOrSchema,
|
|
1039
|
+
contextValue: context,
|
|
1040
|
+
}
|
|
1041
|
+
: {
|
|
1042
|
+
schema: argsOrSchema,
|
|
1043
|
+
document: document,
|
|
1044
|
+
rootValue,
|
|
1045
|
+
contextValue: context,
|
|
1046
|
+
variableValues,
|
|
1047
|
+
operationName,
|
|
1048
|
+
fieldResolver,
|
|
1049
|
+
subscribeFieldResolver,
|
|
1050
|
+
};
|
|
1051
|
+
let isIterable = false;
|
|
1052
|
+
// It's important to wrap the subscribeFn within a promise
|
|
1053
|
+
// so we can easily control the end of subscription (with finally)
|
|
1054
|
+
return Promise.resolve()
|
|
1055
|
+
.then(() => subscribeFn(subscriptionArgs))
|
|
1056
|
+
.then((sub) => {
|
|
1057
|
+
if (isAsyncIterable(sub)) {
|
|
1058
|
+
isIterable = true;
|
|
1059
|
+
return tapAsyncIterator(sub, destroy);
|
|
1060
|
+
}
|
|
1061
|
+
return sub;
|
|
1062
|
+
})
|
|
1063
|
+
.finally(() => {
|
|
1064
|
+
if (!isIterable) {
|
|
1065
|
+
destroy();
|
|
1066
|
+
}
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
if (options === null || options === void 0 ? void 0 : options.controller) {
|
|
1070
|
+
return perform(options.controller);
|
|
1071
|
+
}
|
|
1072
|
+
return contextBuilder(isNotSchema(argsOrSchema)
|
|
1017
1073
|
? argsOrSchema.contextValue
|
|
1018
|
-
: contextValue);
|
|
1019
|
-
const subscriptionArgs = isNotSchema(argsOrSchema)
|
|
1020
|
-
? {
|
|
1021
|
-
...argsOrSchema,
|
|
1022
|
-
contextValue: context,
|
|
1023
|
-
}
|
|
1024
|
-
: {
|
|
1025
|
-
schema: argsOrSchema,
|
|
1026
|
-
document: document,
|
|
1027
|
-
rootValue,
|
|
1028
|
-
contextValue: context,
|
|
1029
|
-
variableValues,
|
|
1030
|
-
operationName,
|
|
1031
|
-
fieldResolver,
|
|
1032
|
-
subscribeFieldResolver,
|
|
1033
|
-
};
|
|
1034
|
-
let isIterable = false;
|
|
1035
|
-
// It's important to wrap the subscribeFn within a promise
|
|
1036
|
-
// so we can easily control the end of subscription (with finally)
|
|
1037
|
-
return Promise.resolve()
|
|
1038
|
-
.then(() => subscribeFn(subscriptionArgs))
|
|
1039
|
-
.then((sub) => {
|
|
1040
|
-
if (isAsyncIterable(sub)) {
|
|
1041
|
-
isIterable = true;
|
|
1042
|
-
return tapAsyncIterator(sub, destroy);
|
|
1043
|
-
}
|
|
1044
|
-
return sub;
|
|
1045
|
-
})
|
|
1046
|
-
.finally(() => {
|
|
1047
|
-
if (!isIterable) {
|
|
1048
|
-
destroy();
|
|
1049
|
-
}
|
|
1050
|
-
});
|
|
1074
|
+
: contextValue).runWithContext(perform);
|
|
1051
1075
|
};
|
|
1052
1076
|
};
|
|
1053
1077
|
return createSubscription;
|
|
@@ -1072,10 +1096,9 @@ function apolloSchemaCreator({ createSubscription, contextBuilder, schema, }) {
|
|
|
1072
1096
|
const createApolloSchema = () => {
|
|
1073
1097
|
const sessions = {};
|
|
1074
1098
|
const subscription = createSubscription();
|
|
1075
|
-
function getSession(ctx) {
|
|
1099
|
+
function getSession(ctx, { context, ɵdestroy: destroy }) {
|
|
1076
1100
|
if (!ctx[CONTEXT_ID]) {
|
|
1077
1101
|
ctx[CONTEXT_ID] = uniqueId((id) => !sessions[id]);
|
|
1078
|
-
const { context, ɵdestroy: destroy } = contextBuilder(ctx);
|
|
1079
1102
|
sessions[ctx[CONTEXT_ID]] = {
|
|
1080
1103
|
count: 0,
|
|
1081
1104
|
session: {
|
|
@@ -1107,20 +1130,22 @@ function apolloSchemaCreator({ createSubscription, contextBuilder, schema, }) {
|
|
|
1107
1130
|
operationName: input.operationName,
|
|
1108
1131
|
});
|
|
1109
1132
|
}
|
|
1110
|
-
// Create an execution context
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
.
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1133
|
+
// Create an execution context and run within it
|
|
1134
|
+
return contextBuilder(input.context).runWithContext((env) => {
|
|
1135
|
+
const { context, destroy } = getSession(input.context, env);
|
|
1136
|
+
// It's important to wrap the executeFn within a promise
|
|
1137
|
+
// so we can easily control the end of execution (with finally)
|
|
1138
|
+
return Promise.resolve()
|
|
1139
|
+
.then(() => execute$1({
|
|
1140
|
+
schema,
|
|
1141
|
+
document: input.document,
|
|
1142
|
+
contextValue: context,
|
|
1143
|
+
variableValues: input.variables,
|
|
1144
|
+
rootValue: input.rootValue,
|
|
1145
|
+
operationName: input.operationName,
|
|
1146
|
+
}))
|
|
1147
|
+
.finally(destroy);
|
|
1148
|
+
});
|
|
1124
1149
|
},
|
|
1125
1150
|
});
|
|
1126
1151
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphql-modules",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.1-alpha-20241223144441-674927c3a29a8c57bbdad7eb31576cb88178f815",
|
|
4
4
|
"description": "Create reusable, maintainable, testable and extendable GraphQL modules",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|