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>;
