@graphql-tools/executor
Version:
Fork of GraphQL.js' execute function
126 lines (125 loc) • 5.45 kB
TypeScript
import { GraphQLError } from 'graphql';
import { Path, type IncrementalSpec } from '@graphql-tools/utils';
import { type MaybePromise } from '@whatwg-node/promise-helpers';
import type { SubsequentIncrementalExecutionResult } from './execute.js';
import type { DeferUsage } from './incrementalCollect.js';
export interface PendingResult {
id: string;
path: ReadonlyArray<string | number>;
label?: string;
}
export interface CompletedResult {
id: string;
errors?: ReadonlyArray<GraphQLError>;
}
export interface IncrementalPublisherState {
nextId: number;
ids: Map<object, string>;
announced: Set<object>;
}
export declare function createIncrementalPublisherState(): IncrementalPublisherState;
/** Minimal context the incremental publisher and payload records need. */
export interface IncrementalPublisherContext {
subsequentPayloads: Set<AsyncPayloadRecord>;
incrementalSpec: IncrementalSpec;
publisher?: IncrementalPublisherState;
signalPromise?: Promise<never>;
/**
* Paths that were set to null by error bubbling. Present only on the
* incremental collect path so default execution does not allocate.
*/
nulledPaths?: Array<ReadonlyArray<string | number>>;
}
export declare class StreamGroup {
path: Array<string | number>;
label: string | undefined;
parentContext: AsyncPayloadRecord | undefined;
hasIterator: boolean;
iteratorCompleted: boolean;
openCount: number;
constructor(opts: {
path: Path | undefined;
label: string | undefined;
parentContext: AsyncPayloadRecord | undefined;
hasIterator?: boolean;
});
retain(): void;
release(): void;
isStillPending(): boolean;
}
export declare function createStreamGroupIfV02(exeContext: IncrementalPublisherContext, opts: {
path: Path | undefined;
label: string | undefined;
parentContext: AsyncPayloadRecord | undefined;
hasIterator?: boolean;
}): StreamGroup | undefined;
export declare function deleteAsyncPayload(exeContext: IncrementalPublisherContext, record: AsyncPayloadRecord): void;
export declare function pathStartsWith(path: ReadonlyArray<string | number>, prefix: ReadonlyArray<string | number>): boolean;
export declare function isAtOrUnderNulledPath(path: ReadonlyArray<string | number>, nulledPaths: ReadonlyArray<ReadonlyArray<string | number>> | undefined): boolean;
/**
* Drop keys that would write into a subtree already nulled by error bubbling.
* Ancestor deferred records can still deliver sibling fields (e.g. `someField`
* next to a nulled `b.c`).
*/
export declare function pruneUnmergeableIncrementalData(data: unknown, basePath: ReadonlyArray<string | number>, nulledPaths: ReadonlyArray<ReadonlyArray<string | number>> | undefined): unknown;
/**
* Cancel a subsequent record whose path is at or under a nulled position
* (graphql-js 17 `hasNulledPosition`). v0.2 records that were already
* announced stay in the set so the publisher can emit `completed` without
* incremental data.
*/
export declare function cancelAsyncPayload(exeContext: IncrementalPublisherContext, record: AsyncPayloadRecord): void;
export declare class DeferredFragmentRecord {
type: 'defer';
errors: Array<GraphQLError>;
label: string | undefined;
path: Array<string | number>;
promise: Promise<void>;
data: Record<string, unknown> | null;
parentContext: AsyncPayloadRecord | undefined;
deliveryParent: AsyncPayloadRecord | undefined;
deferUsage: DeferUsage | undefined;
isCompleted: boolean;
cancelled: boolean;
_exeContext: IncrementalPublisherContext;
_resolve?: (arg: MaybePromise<Record<string, unknown> | null>) => void;
constructor(opts: {
label: string | undefined;
path: Path | undefined;
parentContext: AsyncPayloadRecord | undefined;
deliveryParent?: AsyncPayloadRecord | undefined;
exeContext: IncrementalPublisherContext;
deferUsage?: DeferUsage;
});
addData(data: MaybePromise<Record<string, unknown> | null>): void;
}
export declare class StreamRecord {
type: 'stream';
errors: Array<GraphQLError>;
label: string | undefined;
path: Array<string | number>;
items: Array<unknown> | null;
promise: Promise<void>;
parentContext: AsyncPayloadRecord | undefined;
iterator: AsyncIterator<unknown> | undefined;
isCompletedIterator?: boolean;
isCompleted: boolean;
cancelled: boolean;
streamGroup: StreamGroup | undefined;
_exeContext: IncrementalPublisherContext;
_resolve?: (arg: MaybePromise<Array<unknown> | null>) => void;
constructor(opts: {
label: string | undefined;
path: Path | undefined;
iterator?: AsyncIterator<unknown>;
parentContext: AsyncPayloadRecord | undefined;
exeContext: IncrementalPublisherContext;
streamGroup?: StreamGroup;
});
addItems(items: MaybePromise<Array<unknown> | null>): void;
setIsCompletedIterator(): void;
}
export type AsyncPayloadRecord = DeferredFragmentRecord | StreamRecord;
export declare function isStreamPayload(asyncPayload: AsyncPayloadRecord): asyncPayload is StreamRecord;
export declare function collectInitialPending(exeContext: IncrementalPublisherContext): Array<PendingResult>;
export declare function yieldSubsequentPayloads(exeContext: IncrementalPublisherContext): AsyncGenerator<SubsequentIncrementalExecutionResult, void, void>;