@@ -25,51 +25,8 @@ import { GraphQLSchema } from '../type/schema';
25
25
import invariant from '../jsutils/invariant' ;
26
26
import mapAsyncIterator from './mapAsyncIterator' ;
27
27
28
- import type {
29
- ExecutionContext ,
30
- ExecutionResult ,
31
- } from '../execution/execute' ;
32
- import type {
33
- DocumentNode ,
34
- OperationDefinitionNode ,
35
- } from '../language/ast' ;
36
-
37
- /**
38
- * Implements the "CreateSourceEventStream" algorithm described in the
39
- * GraphQL specification, resolving the subscription source event stream.
40
- *
41
- * Returns an AsyncIterable
42
- *
43
- * A Source Stream represents the sequence of events, each of which is
44
- * expected to be used to trigger a GraphQL execution for that event.
45
- */
46
- export function createSourceEventStream (
47
- schema : GraphQLSchema ,
48
- document : DocumentNode ,
49
- rootValue ?: mixed ,
50
- contextValue ?: mixed ,
51
- variableValues ?: ?{ [ key : string ] : mixed } ,
52
- operationName ?: ?string ,
53
- ) : AsyncIterable < mixed > {
54
- // If a valid context cannot be created due to incorrect arguments,
55
- // this will throw an error.
56
- const exeContext = buildExecutionContext (
57
- schema ,
58
- document ,
59
- rootValue ,
60
- contextValue ,
61
- variableValues ,
62
- operationName
63
- ) ;
64
-
65
- // Call the `subscribe()` resolver or the default resolver to produce an
66
- // AsyncIterable yielding raw payloads.
67
- return resolveSubscription (
68
- exeContext ,
69
- exeContext . operation ,
70
- rootValue
71
- ) ;
72
- }
28
+ import type { ExecutionResult } from '../execution/execute' ;
29
+ import type { DocumentNode } from '../language/ast' ;
73
30
74
31
/**
75
32
* Implements the "Subscribe" algorithm described in the GraphQL specification.
@@ -97,6 +54,10 @@ export function subscribe(
97
54
98
55
// For each payload yielded from a subscription, map it over the normal
99
56
// GraphQL `execute` function, with `payload` as the rootValue.
57
+ // This implements the "MapSourceToResponseEvent" algorithm described in
58
+ // the GraphQL specification. The `execute` function provides the
59
+ // "ExecuteSubscriptionEvent" algorithm, as it is nearly identical to the
60
+ // "ExecuteQuery" algorithm, for which `execute` is also used.
100
61
return mapAsyncIterator (
101
62
subscription ,
102
63
payload => execute (
@@ -110,12 +71,40 @@ export function subscribe(
110
71
) ;
111
72
}
112
73
113
- function resolveSubscription (
114
- exeContext : ExecutionContext ,
115
- operation : OperationDefinitionNode ,
116
- rootValue : mixed
74
+ /**
75
+ * Implements the "CreateSourceEventStream" algorithm described in the
76
+ * GraphQL specification, resolving the subscription source event stream.
77
+ *
78
+ * Returns an AsyncIterable, may through a GraphQLError.
79
+ *
80
+ * A Source Stream represents the sequence of events, each of which is
81
+ * expected to be used to trigger a GraphQL execution for that event.
82
+ *
83
+ * This may be useful when hosting the stateful subscription service in a
84
+ * different process or machine than the stateless GraphQL execution engine,
85
+ * or otherwise separating these two steps. For more on this, see the
86
+ * "Supporting Subscriptions at Scale" information in the GraphQL specification.
87
+ */
88
+ export function createSourceEventStream (
89
+ schema : GraphQLSchema ,
90
+ document : DocumentNode ,
91
+ rootValue ?: mixed ,
92
+ contextValue ?: mixed ,
93
+ variableValues ?: ?{ [ key : string ] : mixed } ,
94
+ operationName ?: ?string ,
117
95
) : AsyncIterable < mixed > {
118
- const type = getOperationRootType ( exeContext . schema , exeContext . operation ) ;
96
+ // If a valid context cannot be created due to incorrect arguments,
97
+ // this will throw an error.
98
+ const exeContext = buildExecutionContext (
99
+ schema ,
100
+ document ,
101
+ rootValue ,
102
+ contextValue ,
103
+ variableValues ,
104
+ operationName
105
+ ) ;
106
+
107
+ const type = getOperationRootType ( schema , exeContext . operation ) ;
119
108
const fields = collectFields (
120
109
exeContext ,
121
110
type ,
@@ -131,12 +120,14 @@ function resolveSubscription(
131
120
const responseName = responseNames [ 0 ] ;
132
121
const fieldNodes = fields [ responseName ] ;
133
122
const fieldNode = fieldNodes [ 0 ] ;
134
- const fieldDef = getFieldDef ( exeContext . schema , type , fieldNode . name . value ) ;
123
+ const fieldDef = getFieldDef ( schema , type , fieldNode . name . value ) ;
135
124
invariant (
136
125
fieldDef ,
137
126
'This subscription is not defined by the schema.'
138
127
) ;
139
128
129
+ // Call the `subscribe()` resolver or the default resolver to produce an
130
+ // AsyncIterable yielding raw payloads.
140
131
const resolveFn = fieldDef . subscribe || defaultFieldResolver ;
141
132
142
133
const info = buildResolveInfo (
@@ -148,7 +139,7 @@ function resolveSubscription(
148
139
) ;
149
140
150
141
// resolveFieldValueOrError implements the "ResolveFieldEventStream"
151
- // algorithm from GraphQL specification. It differs from
142
+ // algorithm from GraphQL specification. It differs from
152
143
// "ResolveFieldValue" due to providing a different `resolveFn`.
153
144
const subscription = resolveFieldValueOrError (
154
145
exeContext ,
0 commit comments