Skip to content

Commit

Permalink
remove Target term
Browse files Browse the repository at this point in the history
  • Loading branch information
yaacovCR committed Dec 15, 2023
1 parent 40f07e2 commit 24784b3
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 58 deletions.
106 changes: 56 additions & 50 deletions src/execution/buildFieldPlan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,12 @@ import { isSameSet } from '../jsutils/isSameSet.js';

import type { DeferUsage, FieldDetails } from './collectFields.js';

export const NON_DEFERRED_TARGET_SET: TargetSet = new Set<Target>([undefined]);

export type Target = DeferUsage | undefined;
export type TargetSet = ReadonlySet<Target>;
export type DeferUsageSet = ReadonlySet<DeferUsage>;

export interface FieldGroup {
fields: ReadonlyArray<FieldDetails>;
targets?: TargetSet | undefined;
knownTargets?: TargetSet | undefined;
deferUsages?: DeferUsageSet | undefined;
knownDeferUsages?: DeferUsageSet | undefined;
}

export type GroupedFieldSet = Map<string, FieldGroup>;
Expand All @@ -24,19 +20,23 @@ export interface NewGroupedFieldSetDetails {

export function buildFieldPlan(
fields: Map<string, ReadonlyArray<FieldDetails>>,
parentTargets = NON_DEFERRED_TARGET_SET,
knownTargets = NON_DEFERRED_TARGET_SET,
parentDeferUsages: DeferUsageSet = new Set<DeferUsage>(),
knownDeferUsages: DeferUsageSet = new Set<DeferUsage>(),
): {
groupedFieldSet: GroupedFieldSet;
newGroupedFieldSetDetailsMap: Map<DeferUsageSet, NewGroupedFieldSetDetails>;
newDeferUsages: ReadonlyArray<DeferUsage>;
} {
const newDeferUsages: Set<DeferUsage> = new Set<DeferUsage>();
const newKnownTargets = new Set<Target>(knownTargets);
const newKnownDeferUsages = new Set<DeferUsage>(knownDeferUsages);

const groupedFieldSet = new Map<
string,
{ fields: Array<FieldDetails>; targets: TargetSet; knownTargets: TargetSet }
{
fields: Array<FieldDetails>;
deferUsages: DeferUsageSet;
knownDeferUsages: DeferUsageSet;
}
>();

const newGroupedFieldSetDetailsMap = new Map<
Expand All @@ -46,8 +46,8 @@ export function buildFieldPlan(
string,
{
fields: Array<FieldDetails>;
targets: TargetSet;
knownTargets: TargetSet;
deferUsages: DeferUsageSet;
knownDeferUsages: DeferUsageSet;
}
>;
shouldInitiateDefer: boolean;
Expand All @@ -56,41 +56,50 @@ export function buildFieldPlan(

const map = new Map<
string,
{ targetSet: TargetSet; fieldDetailsList: ReadonlyArray<FieldDetails> }
{
deferUsageSet: DeferUsageSet;
fieldDetailsList: ReadonlyArray<FieldDetails>;
}
>();

for (const [responseKey, fieldDetailsList] of fields) {
const targetSet = new Set<Target>();
const deferUsageSet = new Set<DeferUsage>();
let inOriginalResult = false;
for (const fieldDetails of fieldDetailsList) {
const target = fieldDetails.deferUsage;
targetSet.add(target);
if (!knownTargets.has(target)) {
// all targets that are not known must be defined
newDeferUsages.add(target as DeferUsage);
const deferUsage = fieldDetails.deferUsage;
if (deferUsage === undefined) {
inOriginalResult = true;
continue;
}
newKnownTargets.add(target);
}
map.set(responseKey, { targetSet, fieldDetailsList });
}

for (const [responseKey, { targetSet, fieldDetailsList }] of map) {
const maskingTargetList: Array<Target> = [];
for (const target of targetSet) {
if (
target === undefined ||
getAncestors(target).every((ancestor) => !targetSet.has(ancestor))
) {
maskingTargetList.push(target);
deferUsageSet.add(deferUsage);
if (!knownDeferUsages.has(deferUsage)) {
newDeferUsages.add(deferUsage);
newKnownDeferUsages.add(deferUsage);
}
}
if (inOriginalResult) {
deferUsageSet.clear();
} else {
deferUsageSet.forEach((deferUsage) => {
const ancestors = getAncestors(deferUsage);
for (const ancestor of ancestors) {
if (deferUsageSet.has(ancestor)) {
deferUsageSet.delete(deferUsage);
}
}
});
}
map.set(responseKey, { deferUsageSet, fieldDetailsList });
}

const maskingTargets: TargetSet = new Set<Target>(maskingTargetList);
if (isSameSet(maskingTargets, parentTargets)) {
for (const [responseKey, { deferUsageSet, fieldDetailsList }] of map) {
if (isSameSet(deferUsageSet, parentDeferUsages)) {
let fieldGroup = groupedFieldSet.get(responseKey);
if (fieldGroup === undefined) {
fieldGroup = {
fields: [],
targets: maskingTargets,
knownTargets: newKnownTargets,
deferUsages: deferUsageSet,
knownDeferUsages: newKnownDeferUsages,
};
groupedFieldSet.set(responseKey, fieldGroup);
}
Expand All @@ -100,28 +109,27 @@ export function buildFieldPlan(

let newGroupedFieldSetDetails = getBySet(
newGroupedFieldSetDetailsMap,
maskingTargets,
deferUsageSet,
);
let newGroupedFieldSet;
if (newGroupedFieldSetDetails === undefined) {
newGroupedFieldSet = new Map<
string,
{
fields: Array<FieldDetails>;
targets: TargetSet;
knownTargets: TargetSet;
deferUsages: DeferUsageSet;
knownDeferUsages: DeferUsageSet;
}
>();

newGroupedFieldSetDetails = {
groupedFieldSet: newGroupedFieldSet,
shouldInitiateDefer: maskingTargetList.some(
(deferUsage) => !parentTargets.has(deferUsage),
shouldInitiateDefer: Array.from(deferUsageSet).some(
(deferUsage) => !parentDeferUsages.has(deferUsage),
),
};
newGroupedFieldSetDetailsMap.set(
// all new grouped field sets must not contain the initial result as a target
maskingTargets as DeferUsageSet,
deferUsageSet,
newGroupedFieldSetDetails,
);
} else {
Expand All @@ -131,8 +139,8 @@ export function buildFieldPlan(
if (fieldGroup === undefined) {
fieldGroup = {
fields: [],
targets: maskingTargets,
knownTargets: newKnownTargets,
deferUsages: deferUsageSet,
knownDeferUsages: newKnownDeferUsages,
};
newGroupedFieldSet.set(responseKey, fieldGroup);
}
Expand All @@ -146,14 +154,12 @@ export function buildFieldPlan(
};
}

function getAncestors(
deferUsage: DeferUsage,
): ReadonlyArray<DeferUsage | undefined> {
function getAncestors(deferUsage: DeferUsage): ReadonlyArray<DeferUsage> {
const ancestors: Array<DeferUsage> = [];
let parentDeferUsage: DeferUsage | undefined = deferUsage.parentDeferUsage;
const ancestors: Array<DeferUsage | undefined> = [parentDeferUsage];
while (parentDeferUsage !== undefined) {
parentDeferUsage = parentDeferUsage.parentDeferUsage;
ancestors.unshift(parentDeferUsage);
parentDeferUsage = parentDeferUsage.parentDeferUsage;
}
return ancestors;
}
14 changes: 6 additions & 8 deletions src/execution/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ const buildSubFieldPlan = memoize3(
);
return buildFieldPlan(
subFields,
fieldGroup.targets,
fieldGroup.knownTargets,
fieldGroup.deferUsages,
fieldGroup.knownDeferUsages,
);
},
);
Expand Down Expand Up @@ -1464,17 +1464,15 @@ function addNewDeferredFragments(

// For each new deferUsage object:
for (const newDeferUsage of newDeferUsages) {
const parentTarget = newDeferUsage.parentDeferUsage;
const parentDeferUsage = newDeferUsage.parentDeferUsage;

// If the parent target is defined, the parent target is a DeferUsage object and
// the parent result record is the DeferredFragmentRecord corresponding to that DeferUsage.
// If the parent target is not defined, the parent result record is either:
// If the parent defer usage is not defined, the parent result record is either:
// - the InitialResultRecord, or
// - a StreamItemsRecord, as `@defer` may be nested under `@stream`.
const parent =
parentTarget === undefined
parentDeferUsage === undefined
? (incrementalDataRecord as InitialResultRecord | StreamItemsRecord)
: deferredFragmentRecordFromDeferUsage(parentTarget, newDeferMap);
: deferredFragmentRecordFromDeferUsage(parentDeferUsage, newDeferMap);

// Instantiate the new record.
const deferredFragmentRecord = new DeferredFragmentRecord({
Expand Down

0 comments on commit 24784b3

Please sign in to comment.