Skip to content

Commit d6e6ac1

Browse files
committed
extract PayloadPublisher
1 parent 4612e99 commit d6e6ac1

File tree

5 files changed

+414
-191
lines changed

5 files changed

+414
-191
lines changed

src/execution/Executor.ts

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ import {
4848
cancellablePromise,
4949
} from './AbortSignalListener.js';
5050
import type { DeferUsageSet, ExecutionPlan } from './buildExecutionPlan.js';
51-
import { buildExecutionPlan } from './buildExecutionPlan.js';
5251
import { buildResolveInfo } from './buildResolveInfo.js';
5352
import type {
5453
DeferUsage,
@@ -57,17 +56,20 @@ import type {
5756
GroupedFieldSet,
5857
} from './collectFields.js';
5958
import { collectFields, collectSubfields } from './collectFields.js';
59+
import type { ExperimentalIncrementalExecutionResults } from './IncrementalPublisher.js';
6060
import { buildIncrementalResponse } from './IncrementalPublisher.js';
61+
import type { PayloadPublisher } from './PayloadPublisher.js';
6162
import type {
6263
CancellableStreamRecord,
6364
CompletedExecutionGroup,
6465
ExecutionResult,
65-
ExperimentalIncrementalExecutionResults,
6666
IncrementalDataRecord,
67+
InitialIncrementalExecutionResult,
6768
PendingExecutionGroup,
6869
StreamItemRecord,
6970
StreamItemResult,
7071
StreamRecord,
72+
SubsequentIncrementalExecutionResult,
7173
} from './types.js';
7274
import { DeferredFragmentRecord } from './types.js';
7375
import type { VariableValues } from './values.js';
@@ -150,8 +152,22 @@ interface GraphQLWrappedResult<T> {
150152
}
151153

152154
/** @internal */
153-
export class Executor {
155+
export class Executor<
156+
TInitialPayload = InitialIncrementalExecutionResult,
157+
TSubsequentPayload = SubsequentIncrementalExecutionResult,
158+
> {
154159
validatedExecutionArgs: ValidatedExecutionArgs;
160+
161+
buildExecutionPlan: (
162+
originalGroupedFieldSet: GroupedFieldSet,
163+
parentDeferUsages?: DeferUsageSet | undefined,
164+
) => ExecutionPlan;
165+
166+
getPayloadPublisher: () => PayloadPublisher<
167+
TInitialPayload,
168+
TSubsequentPayload
169+
>;
170+
155171
exeContext: ExecutionContext;
156172

157173
/**
@@ -167,8 +183,21 @@ export class Executor {
167183
newDeferUsages: ReadonlyArray<DeferUsage>;
168184
};
169185

170-
constructor(validatedExecutionArgs: ValidatedExecutionArgs) {
186+
constructor(
187+
validatedExecutionArgs: ValidatedExecutionArgs,
188+
buildExecutionPlan: (
189+
originalGroupedFieldSet: GroupedFieldSet,
190+
parentDeferUsages?: DeferUsageSet | undefined,
191+
) => ExecutionPlan,
192+
getPayloadPublisher: () => PayloadPublisher<
193+
TInitialPayload,
194+
TSubsequentPayload
195+
>,
196+
) {
171197
this.validatedExecutionArgs = validatedExecutionArgs;
198+
this.buildExecutionPlan = buildExecutionPlan;
199+
this.getPayloadPublisher = getPayloadPublisher;
200+
172201
const abortSignal = validatedExecutionArgs.abortSignal;
173202
this.exeContext = {
174203
errors: undefined,
@@ -196,7 +225,11 @@ export class Executor {
196225
}
197226

198227
executeQueryOrMutationOrSubscriptionEvent(): PromiseOrValue<
199-
ExecutionResult | ExperimentalIncrementalExecutionResults
228+
| ExecutionResult
229+
| ExperimentalIncrementalExecutionResults<
230+
TInitialPayload,
231+
TSubsequentPayload
232+
>
200233
> {
201234
try {
202235
const {
@@ -277,19 +310,36 @@ export class Executor {
277310

278311
buildDataResponse(
279312
graphqlWrappedResult: GraphQLWrappedResult<ObjMap<unknown>>,
280-
): ExecutionResult | ExperimentalIncrementalExecutionResults {
313+
):
314+
| ExecutionResult
315+
| ExperimentalIncrementalExecutionResults<
316+
TInitialPayload,
317+
TSubsequentPayload
318+
> {
281319
const { rawResult: data, incrementalDataRecords } = graphqlWrappedResult;
282320
const errors = this.exeContext.errors;
283321
if (incrementalDataRecords === undefined) {
284322
this.exeContext.abortSignalListener?.disconnect();
285323
return errors !== undefined ? { errors, data } : { data };
286324
}
287325

326+
return this.buildIncrementalResponse(data, errors, incrementalDataRecords);
327+
}
328+
329+
buildIncrementalResponse(
330+
data: ObjMap<unknown>,
331+
errors: ReadonlyArray<GraphQLError> | undefined,
332+
incrementalDataRecords: ReadonlyArray<IncrementalDataRecord>,
333+
): ExperimentalIncrementalExecutionResults<
334+
TInitialPayload,
335+
TSubsequentPayload
336+
> {
288337
return buildIncrementalResponse(
289338
this.exeContext,
290339
data,
291340
errors,
292341
incrementalDataRecords,
342+
this.getPayloadPublisher(),
293343
);
294344
}
295345

@@ -315,7 +365,7 @@ export class Executor {
315365
undefined,
316366
);
317367

318-
const { groupedFieldSet, newGroupedFieldSets } = buildExecutionPlan(
368+
const { groupedFieldSet, newGroupedFieldSets } = this.buildExecutionPlan(
319369
originalGroupedFieldSet,
320370
);
321371

@@ -1582,13 +1632,7 @@ export class Executor {
15821632
);
15831633
const { groupedFieldSet, newDeferUsages } = collectedSubfields;
15841634

1585-
if (newDeferUsages.length > 0) {
1586-
invariant(
1587-
this.validatedExecutionArgs.operation.operation !==
1588-
OperationTypeNode.SUBSCRIPTION,
1589-
'`@defer` directive not supported on subscription operations. Disable `@defer` by setting the `if` argument to `false`.',
1590-
);
1591-
}
1635+
this.assertValidOperationTypeForDefer(newDeferUsages);
15921636

15931637
return this.executeSubExecutionPlan(
15941638
returnType,
@@ -1601,6 +1645,18 @@ export class Executor {
16011645
);
16021646
}
16031647

1648+
assertValidOperationTypeForDefer(
1649+
newDeferUsages: ReadonlyArray<DeferUsage>,
1650+
): void {
1651+
if (newDeferUsages.length > 0) {
1652+
invariant(
1653+
this.validatedExecutionArgs.operation.operation !==
1654+
OperationTypeNode.SUBSCRIPTION,
1655+
'`@defer` directive not supported on subscription operations. Disable `@defer` by setting the `if` argument to `false`.',
1656+
);
1657+
}
1658+
}
1659+
16041660
executeSubExecutionPlan(
16051661
returnType: GraphQLObjectType,
16061662
sourceValue: unknown,
@@ -1665,7 +1721,10 @@ export class Executor {
16651721
if (executionPlan !== undefined) {
16661722
return executionPlan;
16671723
}
1668-
executionPlan = buildExecutionPlan(originalGroupedFieldSet, deferUsageSet);
1724+
executionPlan = this.buildExecutionPlan(
1725+
originalGroupedFieldSet,
1726+
deferUsageSet,
1727+
);
16691728
(
16701729
originalGroupedFieldSet as unknown as { _executionPlan: ExecutionPlan }
16711730
)._executionPlan = executionPlan;

0 commit comments

Comments
 (0)