import type { LogContext } from '@rocicorp/logger';
import type { AST } from '../../../../zero-protocol/src/ast.ts';
import type { ClientSchema } from '../../../../zero-protocol/src/client-schema.ts';
import type { Row } from '../../../../zero-protocol/src/data.ts';
import type { PrimaryKey } from '../../../../zero-protocol/src/primary-key.ts';
import { type Input } from '../../../../zql/src/ivm/operator.ts';
import type { ClientGroupStorage } from '../../../../zqlite/src/database-storage.ts';
import { type LoadedPermissions } from '../../auth/load-permissions.ts';
import type { LogConfig, ZeroConfig } from '../../config/zero-config.ts';
import type { LiteAndZqlSpec } from '../../db/specs.ts';
import type { InspectorDelegate } from '../../server/inspector-delegate.ts';
import { type RowKey } from '../../types/row-key.ts';
import { type ShardID } from '../../types/shards.ts';
import type { Snapshotter } from './snapshotter.ts';
export type RowAdd = {
    readonly type: 'add';
    readonly queryID: string;
    readonly table: string;
    readonly rowKey: Row;
    readonly row: Row;
};
export type RowRemove = {
    readonly type: 'remove';
    readonly queryID: string;
    readonly table: string;
    readonly rowKey: Row;
    readonly row: undefined;
};
export type RowEdit = {
    readonly type: 'edit';
    readonly queryID: string;
    readonly table: string;
    readonly rowKey: Row;
    readonly row: Row;
};
export type RowChange = RowAdd | RowRemove | RowEdit;
type QueryInfo = {
    readonly transformedAst: AST;
    readonly transformationHash: string;
};
export type Timer = {
    elapsedLap: () => number;
    totalElapsed: () => number;
};
/**
 * Manages the state of IVM pipelines for a given ViewSyncer (i.e. client group).
 */
export declare class PipelineDriver {
    #private;
    constructor(lc: LogContext, logConfig: LogConfig, snapshotter: Snapshotter, shardID: ShardID, storage: ClientGroupStorage, clientGroupID: string, inspectorDelegate: InspectorDelegate, yieldThresholdMs: () => number, enablePlanner?: boolean, config?: ZeroConfig);
    /**
     * Initializes the PipelineDriver to the current head of the database.
     * Queries can then be added (i.e. hydrated) with {@link addQuery()}.
     *
     * Must only be called once.
     */
    init(clientSchema: ClientSchema): void;
    /**
     * @returns Whether the PipelineDriver has been initialized.
     */
    initialized(): boolean;
    /**
     * Clears the current pipelines and TableSources, returning the PipelineDriver
     * to its initial state. This should be called in response to a schema change,
     * as TableSources need to be recomputed.
     */
    reset(clientSchema: ClientSchema): void;
    /** @returns The replica version. The PipelineDriver must have been initialized. */
    get replicaVersion(): string;
    /**
     * Returns the current version of the database. This will reflect the
     * latest version change when calling {@link advance()} once the
     * iteration has begun.
     */
    currentVersion(): string;
    /**
     * Returns the current upstream {app}.permissions, or `null` if none are defined.
     */
    currentPermissions(): LoadedPermissions | null;
    advanceWithoutDiff(): string;
    /**
     * Clears storage used for the pipelines. Call this when the
     * PipelineDriver will no longer be used.
     */
    destroy(): void;
    /** @return Map from query ID to PipelineInfo for all added queries. */
    queries(): ReadonlyMap<string, QueryInfo>;
    totalHydrationTimeMs(): number;
    /**
     * Adds a pipeline for the query. The method will hydrate the query using the
     * driver's current snapshot of the database and return a stream of results.
     * Henceforth, updates to the query will be returned when the driver is
     * {@link advance}d. The query and its pipeline can be removed with
     * {@link removeQuery()}.
     *
     * If a query with the same queryID is already added, the existing pipeline
     * will be removed and destroyed before adding the new pipeline.
     *
     * @param timer The caller-controlled {@link Timer} used to determine the
     *        final hydration time. (The caller may pause and resume the timer
     *        when yielding the thread for time-slicing).
     * @return The rows from the initial hydration of the query.
     */
    addQuery(transformationHash: string, queryID: string, query: AST, timer: Timer): Iterable<RowChange | 'yield'>;
    /**
     * Removes the pipeline for the query. This is a no-op if the query
     * was not added.
     */
    removeQuery(queryID: string): void;
    /**
     * Returns the value of the row with the given primary key `pk`,
     * or `undefined` if there is no such row. The pipeline must have been
     * initialized.
     */
    getRow(table: string, pk: RowKey): Row | undefined;
    /**
     * Advances to the new head of the database.
     *
     * @param timer The caller-controlled {@link Timer} that will be used to
     *        measure the progress of the advancement and abort with a
     *        {@link ResetPipelinesSignal} if it is estimated to take longer
     *        than a hydration.
     * @return The resulting row changes for all added queries. Note that the
     *         `changes` must be iterated over in their entirety in order to
     *         advance the database snapshot.
     */
    advance(timer: Timer): {
        version: string;
        numChanges: number;
        changes: Iterable<RowChange | 'yield'>;
    };
}
/**
 * Core hydration logic used by {@link PipelineDriver#addQuery}, extracted to a
 * function for reuse by bin-analyze so that bin-analyze's hydration logic
 * is as close as possible to zero-cache's real hydration logic.
 */
export declare function hydrate(input: Input, hash: string, clientSchema: ClientSchema, tableSpecs: Map<string, LiteAndZqlSpec>): Iterable<RowChange | 'yield'>;
export declare function hydrateInternal(input: Input, hash: string, primaryKeys: Map<string, PrimaryKey>, tableSpecs: Map<string, LiteAndZqlSpec>): Iterable<RowChange | 'yield'>;
export {};
//# sourceMappingURL=pipeline-driver.d.ts.map