Skip to content

Commit 7ca7c93

Browse files
committed
update to match new spec changes
graphql/graphql-spec#1034
1 parent 272c52e commit 7ca7c93

File tree

2 files changed

+207
-205
lines changed

2 files changed

+207
-205
lines changed

src/execution/IncrementalPublisher.ts

Lines changed: 64 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,7 @@ import type {
88
GraphQLFormattedError,
99
} from '../error/GraphQLError.js';
1010

11-
import type {
12-
DeferUsage,
13-
DeferUsageSet,
14-
GroupedFieldSet,
15-
GroupedFieldSetDetails,
16-
} from './collectFields.js';
17-
import type { StreamUsage } from './execute.js';
11+
import type { GroupedFieldSet } from './collectFields.js';
1812

1913
interface IncrementalUpdate<TData = unknown, TExtensions = ObjMap<unknown>> {
2014
incremental: ReadonlyArray<IncrementalResult<TData, TExtensions>>;
@@ -188,112 +182,38 @@ export class IncrementalPublisher {
188182
this._reset();
189183
}
190184

191-
prepareInitialResultRecord(): InitialResultRecord {
192-
return new InitialResultRecord();
185+
reportNewDeferFragmentRecord(
186+
deferredFragmentRecord: DeferredFragmentRecord,
187+
parentIncrementalResultRecord:
188+
| InitialResultRecord
189+
| DeferredFragmentRecord
190+
| StreamItemsRecord,
191+
): void {
192+
parentIncrementalResultRecord.children.add(deferredFragmentRecord);
193193
}
194194

195-
prepareNewDeferRecords(
196-
newGroupedFieldSetDetails: Map<DeferUsageSet, GroupedFieldSetDetails>,
197-
newDeferUsages: ReadonlyArray<DeferUsage>,
198-
incrementalDataRecord: IncrementalDataRecord,
199-
deferMap?: ReadonlyMap<DeferUsage, DeferredFragmentRecord>,
200-
path?: Path | undefined,
201-
): {
202-
newDeferMap: ReadonlyMap<DeferUsage, DeferredFragmentRecord>;
203-
newDeferredGroupedFieldSetRecords: ReadonlyArray<DeferredGroupedFieldSetRecord>;
204-
} {
205-
let newDeferMap;
206-
if (newDeferUsages.length === 0) {
207-
newDeferMap = deferMap ?? new Map<DeferUsage, DeferredFragmentRecord>();
208-
} else {
209-
newDeferMap =
210-
deferMap === undefined
211-
? new Map<DeferUsage, DeferredFragmentRecord>()
212-
: new Map<DeferUsage, DeferredFragmentRecord>(deferMap);
213-
for (const deferUsage of newDeferUsages) {
214-
const deferredFragmentRecord = new DeferredFragmentRecord({
215-
path,
216-
label: deferUsage.label,
217-
});
218-
219-
const parentDeferUsage = deferUsage.ancestors[0];
220-
221-
const parent =
222-
parentDeferUsage === undefined
223-
? (incrementalDataRecord as InitialResultRecord | StreamItemsRecord)
224-
: this._deferredFragmentRecordFromDeferUsage(
225-
parentDeferUsage,
226-
newDeferMap,
227-
);
228-
parent.children.add(deferredFragmentRecord);
229-
230-
newDeferMap.set(deferUsage, deferredFragmentRecord);
231-
}
232-
}
233-
234-
const newDeferredGroupedFieldSetRecords: Array<DeferredGroupedFieldSetRecord> =
235-
[];
236-
237-
for (const [
238-
newGroupedFieldSetDeferUsages,
239-
{ groupedFieldSet, shouldInitiateDefer },
240-
] of newGroupedFieldSetDetails) {
241-
const deferredFragmentRecords = this._getDeferredFragmentRecords(
242-
newGroupedFieldSetDeferUsages,
243-
newDeferMap,
195+
reportNewDeferredGroupedFieldSetRecord(
196+
deferredGroupedFieldSetRecord: DeferredGroupedFieldSetRecord,
197+
): void {
198+
for (const deferredFragmentRecord of deferredGroupedFieldSetRecord.deferredFragmentRecords) {
199+
deferredFragmentRecord._pending.add(deferredGroupedFieldSetRecord);
200+
deferredFragmentRecord.deferredGroupedFieldSetRecords.add(
201+
deferredGroupedFieldSetRecord,
244202
);
245-
const deferredGroupedFieldSetRecord = new DeferredGroupedFieldSetRecord({
246-
path,
247-
deferredFragmentRecords,
248-
groupedFieldSet,
249-
shouldInitiateDefer,
250-
});
251-
for (const deferredFragmentRecord of deferredFragmentRecords) {
252-
deferredFragmentRecord._pending.add(deferredGroupedFieldSetRecord);
253-
deferredFragmentRecord.deferredGroupedFieldSetRecords.add(
254-
deferredGroupedFieldSetRecord,
255-
);
256-
}
257-
newDeferredGroupedFieldSetRecords.push(deferredGroupedFieldSetRecord);
258203
}
259-
260-
return {
261-
newDeferMap,
262-
newDeferredGroupedFieldSetRecords,
263-
};
264204
}
265205

266-
prepareNewStreamRecord(
267-
streamUsage: StreamUsage,
268-
path: Path,
269-
asyncIterator?: AsyncIterator<unknown> | undefined,
270-
): StreamRecord {
271-
return new StreamRecord({
272-
label: streamUsage.label,
273-
path,
274-
asyncIterator,
275-
});
276-
}
277-
278-
prepareNewStreamItemsRecord(
279-
streamRecord: StreamRecord,
280-
path: Path | undefined,
281-
incrementalDataRecord: IncrementalDataRecord,
282-
): StreamItemsRecord {
283-
const streamItemsRecord = new StreamItemsRecord({
284-
streamRecord,
285-
path,
286-
});
287-
288-
if (isDeferredGroupedFieldSetRecord(incrementalDataRecord)) {
289-
for (const parent of incrementalDataRecord.deferredFragmentRecords) {
206+
reportNewStreamItemsRecord(
207+
streamItemsRecord: StreamItemsRecord,
208+
parentIncrementalDataRecord: IncrementalDataRecord,
209+
): void {
210+
if (isDeferredGroupedFieldSetRecord(parentIncrementalDataRecord)) {
211+
for (const parent of parentIncrementalDataRecord.deferredFragmentRecords) {
290212
parent.children.add(streamItemsRecord);
291213
}
292214
} else {
293-
incrementalDataRecord.children.add(streamItemsRecord);
215+
parentIncrementalDataRecord.children.add(streamItemsRecord);
294216
}
295-
296-
return streamItemsRecord;
297217
}
298218

299219
completeDeferredGroupedFieldSet(
@@ -341,6 +261,9 @@ export class IncrementalPublisher {
341261
streamItemsRecord.streamRecord.errors.push(error);
342262
this.setIsFinalRecord(streamItemsRecord);
343263
streamItemsRecord.isCompleted = true;
264+
streamItemsRecord.streamRecord.earlyReturn?.().catch(() => {
265+
// ignore error
266+
});
344267
this._release(streamItemsRecord);
345268
}
346269

@@ -418,7 +341,7 @@ export class IncrementalPublisher {
418341
}
419342

420343
streams.forEach((stream) => {
421-
stream.asyncIterator?.return?.().catch(() => {
344+
stream.earlyReturn?.().catch(() => {
422345
// ignore error
423346
});
424347
});
@@ -469,10 +392,10 @@ export class IncrementalPublisher {
469392
streams.add(subsequentResultRecord.streamRecord);
470393
}
471394
}
472-
const promises: Array<Promise<IteratorResult<unknown>>> = [];
395+
const promises: Array<Promise<unknown>> = [];
473396
streams.forEach((streamRecord) => {
474-
if (streamRecord.asyncIterator?.return) {
475-
promises.push(streamRecord.asyncIterator.return());
397+
if (streamRecord.earlyReturn) {
398+
promises.push(streamRecord.earlyReturn());
476399
}
477400
});
478401
await Promise.all(promises);
@@ -569,31 +492,26 @@ export class IncrementalPublisher {
569492
this._publish(child);
570493
}
571494
if (isStreamItemsRecord(subsequentResultRecord)) {
572-
if (!subsequentResultRecord.sent) {
573-
subsequentResultRecord.sent = true;
574-
if (subsequentResultRecord.isFinalRecord) {
575-
completedResults.push(
576-
this._completedRecordToResult(
577-
subsequentResultRecord.streamRecord,
578-
),
579-
);
580-
}
581-
if (subsequentResultRecord.isCompletedAsyncIterator) {
582-
// async iterable resolver just finished but there may be pending payloads
583-
continue;
584-
}
585-
if (subsequentResultRecord.streamRecord.errors.length > 0) {
586-
continue;
587-
}
588-
const incrementalResult: IncrementalStreamResult = {
589-
items: subsequentResultRecord.items,
590-
path: subsequentResultRecord.streamRecord.path,
591-
};
592-
if (subsequentResultRecord.errors.length > 0) {
593-
incrementalResult.errors = subsequentResultRecord.errors;
594-
}
595-
incrementalResults.push(incrementalResult);
495+
if (subsequentResultRecord.isFinalRecord) {
496+
completedResults.push(
497+
this._completedRecordToResult(subsequentResultRecord.streamRecord),
498+
);
499+
}
500+
if (subsequentResultRecord.isCompletedAsyncIterator) {
501+
// async iterable resolver just finished but there may be pending payloads
502+
continue;
596503
}
504+
if (subsequentResultRecord.streamRecord.errors.length > 0) {
505+
continue;
506+
}
507+
const incrementalResult: IncrementalStreamResult = {
508+
items: subsequentResultRecord.items,
509+
path: subsequentResultRecord.streamRecord.path,
510+
};
511+
if (subsequentResultRecord.errors.length > 0) {
512+
incrementalResult.errors = subsequentResultRecord.errors;
513+
}
514+
incrementalResults.push(incrementalResult);
597515
} else {
598516
completedResults.push(
599517
this._completedRecordToResult(subsequentResultRecord),
@@ -639,23 +557,6 @@ export class IncrementalPublisher {
639557
return result;
640558
}
641559

642-
private _getDeferredFragmentRecords(
643-
deferUsages: DeferUsageSet,
644-
deferMap: ReadonlyMap<DeferUsage, DeferredFragmentRecord>,
645-
): ReadonlyArray<DeferredFragmentRecord> {
646-
return Array.from(deferUsages).map((deferUsage) =>
647-
this._deferredFragmentRecordFromDeferUsage(deferUsage, deferMap),
648-
);
649-
}
650-
651-
private _deferredFragmentRecordFromDeferUsage(
652-
deferUsage: DeferUsage,
653-
deferMap: ReadonlyMap<DeferUsage, DeferredFragmentRecord>,
654-
): DeferredFragmentRecord {
655-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
656-
return deferMap.get(deferUsage)!;
657-
}
658-
659560
private _publish(subsequentResultRecord: SubsequentResultRecord): void {
660561
if (isStreamItemsRecord(subsequentResultRecord)) {
661562
if (subsequentResultRecord.isCompleted) {
@@ -734,6 +635,18 @@ export class IncrementalPublisher {
734635
}
735636
}
736637

638+
function isDeferredGroupedFieldSetRecord(
639+
incrementalDataRecord: unknown,
640+
): incrementalDataRecord is DeferredGroupedFieldSetRecord {
641+
return incrementalDataRecord instanceof DeferredGroupedFieldSetRecord;
642+
}
643+
644+
function isStreamItemsRecord(
645+
subsequentResultRecord: unknown,
646+
): subsequentResultRecord is StreamItemsRecord {
647+
return subsequentResultRecord instanceof StreamItemsRecord;
648+
}
649+
737650
/** @internal */
738651
export class InitialResultRecord {
739652
errors: Array<GraphQLError>;
@@ -795,16 +708,16 @@ export class StreamRecord {
795708
label: string | undefined;
796709
path: ReadonlyArray<string | number>;
797710
errors: Array<GraphQLError>;
798-
asyncIterator?: AsyncIterator<unknown> | undefined;
711+
earlyReturn?: (() => Promise<unknown>) | undefined;
799712
constructor(opts: {
800713
label: string | undefined;
801714
path: Path;
802-
asyncIterator?: AsyncIterator<unknown> | undefined;
715+
earlyReturn?: (() => Promise<unknown>) | undefined;
803716
}) {
804717
this.label = opts.label;
805718
this.path = pathToArray(opts.path);
806719
this.errors = [];
807-
this.asyncIterator = opts.asyncIterator;
720+
this.earlyReturn = opts.earlyReturn;
808721
}
809722
}
810723

@@ -819,7 +732,6 @@ export class StreamItemsRecord {
819732
isCompletedAsyncIterator?: boolean;
820733
isCompleted: boolean;
821734
filtered: boolean;
822-
sent: boolean;
823735

824736
constructor(opts: { streamRecord: StreamRecord; path: Path | undefined }) {
825737
this.streamRecord = opts.streamRecord;
@@ -829,7 +741,6 @@ export class StreamItemsRecord {
829741
this.isCompleted = false;
830742
this.filtered = false;
831743
this.items = [];
832-
this.sent = false;
833744
}
834745
}
835746

@@ -839,15 +750,3 @@ export type IncrementalDataRecord =
839750
| StreamItemsRecord;
840751

841752
type SubsequentResultRecord = DeferredFragmentRecord | StreamItemsRecord;
842-
843-
function isDeferredGroupedFieldSetRecord(
844-
incrementalDataRecord: unknown,
845-
): incrementalDataRecord is DeferredGroupedFieldSetRecord {
846-
return incrementalDataRecord instanceof DeferredGroupedFieldSetRecord;
847-
}
848-
849-
function isStreamItemsRecord(
850-
subsequentResultRecord: unknown,
851-
): subsequentResultRecord is StreamItemsRecord {
852-
return subsequentResultRecord instanceof StreamItemsRecord;
853-
}

0 commit comments

Comments
 (0)