import { StandardSchemaV1 } from '@standard-schema/spec';
import { Collection } from './collection/index.js';
import { CollectionOptionsIdentity } from './collection-options.js';
import { CollectionConfig, InferSchemaInput, InferSchemaOutput, NonSingleResult, SingleResult, TransactionConfig, UtilsRecord } from './types.js';
import { LiveQueryOptions } from './live-query-options.js';
declare const collectionConfigFactory: unique symbol;
type AnyCollectionConfig = CollectionConfig<any, any, any, any>;
export type CollectionOptions<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TSchema extends StandardSchemaV1 = never, TUtils extends UtilsRecord = UtilsRecord> = CollectionOptionsIdentity<T, TKey, TSchema, TUtils, DbClient>;
type DescriptorFromConfig<TConfig extends AnyCollectionConfig> = TConfig extends {
    getKey: (item: infer T) => infer TKey;
} ? CollectionOptions<Extract<T, object>, Extract<TKey, string | number>, TConfig extends {
    schema: infer TSchema extends StandardSchemaV1;
} ? TSchema : never, TConfig extends {
    utils: infer TUtils extends UtilsRecord;
} ? TUtils : UtilsRecord> & (TConfig extends SingleResult ? SingleResult : NonSingleResult) : never;
type CollectionConfigWithFactory<TConfig extends AnyCollectionConfig> = TConfig & {
    readonly [collectionConfigFactory]: (client: DbClient) => TConfig;
};
/**
 * Adds a fresh-config materializer to an adapter options object.
 *
 * Adapter option creators should use this so a module-scoped descriptor can be
 * materialized safely by more than one DbClient.
 */
export declare function withCollectionConfigFactory<TConfig extends AnyCollectionConfig>(config: TConfig, factory: (client: DbClient) => TConfig): CollectionConfigWithFactory<TConfig>;
export type CollectionMaterializeOptions<T extends object> = {
    initialData?: Array<T>;
};
export type DehydratedCollectionRow<T extends object = Record<string, unknown>, TKey extends string | number = string | number> = {
    key: TKey;
    value: T;
    metadata?: unknown;
};
export type DehydratedCollectionChunk<T extends object = Record<string, unknown>, TKey extends string | number = string | number> = {
    collectionId: string;
    rows: Array<DehydratedCollectionRow<T, TKey>>;
    syncMeta?: unknown;
};
export type DehydratedLiveQuery = {
    queryHash: string;
    dehydratedAt: number;
    snapshot?: DehydratedLiveQueryResult;
    promise?: Promise<DehydratedLiveQueryResult>;
};
export type DehydratedLiveQueryResult<T extends object = object, TKey extends string | number = string | number> = {
    rows: Array<DehydratedCollectionRow<T, TKey>>;
};
export type DehydratedDbState = {
    collections: Array<DehydratedCollectionChunk>;
    liveQueries?: Array<DehydratedLiveQuery>;
};
export type DbClientLiveQueryState = `pending` | `success` | `error`;
export type DbClientLiveQuery = {
    readonly queryHash: string;
    readonly dehydratedAt: number;
    readonly status: DbClientLiveQueryState;
    readonly promise: Promise<void>;
    readonly snapshot?: DehydratedLiveQueryResult;
    readonly error?: unknown;
};
export type DbClientEvent = {
    type: `liveQueryAdded` | `liveQueryUpdated`;
    query: DbClientLiveQuery;
} | {
    type: `liveQueryStreamError`;
    error: unknown;
};
export type DehydrateDbClientOptions = {
    shouldDehydrateCollection?: (collection: Collection) => boolean;
    shouldDehydrateLiveQuery?: (query: DbClientLiveQuery) => boolean;
};
export type DbClientOptions = Record<string, unknown>;
export declare function collectionOptions<T extends StandardSchemaV1, TKey extends string | number, TUtils extends UtilsRecord>(options: CollectionConfig<InferSchemaOutput<T>, TKey, T, TUtils> & {
    schema: T;
} & NonSingleResult): CollectionOptions<InferSchemaOutput<T>, TKey, T, TUtils> & NonSingleResult;
export declare function collectionOptions<T extends StandardSchemaV1, TKey extends string | number, TUtils extends UtilsRecord>(options: CollectionConfig<InferSchemaOutput<T>, TKey, T, TUtils> & {
    schema: T;
} & SingleResult): CollectionOptions<InferSchemaOutput<T>, TKey, T, TUtils> & SingleResult;
export declare function collectionOptions<T extends object, TKey extends string | number = string | number, TUtils extends UtilsRecord = UtilsRecord>(options: CollectionConfig<T, TKey, never, TUtils> & {
    schema?: never;
} & NonSingleResult): CollectionOptions<T, TKey, never, TUtils> & NonSingleResult;
export declare function collectionOptions<T extends object, TKey extends string | number = string | number, TUtils extends UtilsRecord = UtilsRecord>(options: CollectionConfig<T, TKey, never, TUtils> & {
    schema?: never;
} & SingleResult): CollectionOptions<T, TKey, never, TUtils> & SingleResult;
export declare function collectionOptions<TConfig extends AnyCollectionConfig>(id: string, factory: (client: DbClient) => TConfig): DescriptorFromConfig<TConfig>;
export declare function isCollectionOptions(value: unknown): value is CollectionOptions<any, string | number, any, UtilsRecord>;
export declare class DbClient {
    private readonly options;
    private collectionsByOptions;
    private collectionsById;
    private pendingHydration;
    private liveQueries;
    private preloadedLiveQueries;
    private liveQueryResources;
    private listeners;
    private ssrStreamingEnabled;
    private ssrServerCleanupEnabled;
    private lastLiveQueryTimestamp;
    private readonly transactionScope;
    constructor(options?: DbClientOptions);
    getDependency<T>(key: string): T | undefined;
    requireDependency<T>(key: string): T;
    get activeTransaction(): import('./transactions.js').Transaction<Record<string, unknown>> | undefined;
    createTransaction<T extends object = Record<string, unknown>>(config: TransactionConfig<T>): import('./transactions.js').Transaction<T>;
    preloadLiveQuery(options: LiveQueryOptions): Promise<void>;
    collection<T extends StandardSchemaV1, TKey extends string | number, TUtils extends UtilsRecord>(options: CollectionOptions<InferSchemaOutput<T>, TKey, T, TUtils> & NonSingleResult, materializeOptions?: CollectionMaterializeOptions<InferSchemaInput<T>>): Collection<InferSchemaOutput<T>, TKey, TUtils, T, InferSchemaInput<T>> & NonSingleResult;
    collection<T extends StandardSchemaV1, TKey extends string | number, TUtils extends UtilsRecord>(options: CollectionOptions<InferSchemaOutput<T>, TKey, T, TUtils> & SingleResult, materializeOptions?: CollectionMaterializeOptions<InferSchemaInput<T>>): Collection<InferSchemaOutput<T>, TKey, TUtils, T, InferSchemaInput<T>> & SingleResult;
    collection<T extends object, TKey extends string | number = string | number, TUtils extends UtilsRecord = UtilsRecord>(options: CollectionOptions<T, TKey, never, TUtils> & NonSingleResult, materializeOptions?: CollectionMaterializeOptions<T>): Collection<T, TKey, TUtils, never, T> & NonSingleResult;
    collection<T extends object, TKey extends string | number = string | number, TUtils extends UtilsRecord = UtilsRecord>(options: CollectionOptions<T, TKey, never, TUtils> & SingleResult, materializeOptions?: CollectionMaterializeOptions<T>): Collection<T, TKey, TUtils, never, T> & SingleResult;
    /** @internal */
    _materializeCollectionForRender<T extends object, TKey extends string | number, TSchema extends StandardSchemaV1, TUtils extends UtilsRecord>(options: CollectionOptions<T, TKey, TSchema, TUtils>): Collection<T, TKey, TUtils, TSchema, [
        TSchema
    ] extends [never] ? T : InferSchemaInput<TSchema>>;
    private materializeCollection;
    dehydrate(options?: DehydrateDbClientOptions): DehydratedDbState;
    hydrate(state: DehydratedDbState): void;
    applyCollectionChunk(chunk: DehydratedCollectionChunk): void;
    subscribe(listener: (event: DbClientEvent) => void): () => void;
    /** @internal */
    _setSsrStreamingEnabled(enabled: boolean): void;
    /** @internal */
    _isSsrStreamingEnabled(): boolean;
    /** @internal */
    _setSsrServerCleanupEnabled(enabled: boolean): void;
    /** @internal */
    _isSsrServerCleanupEnabled(): boolean;
    /** @internal */
    _getLiveQuery(queryHash: string): DbClientLiveQuery | undefined;
    /** @internal */
    _consumeLiveQueryResult(queryHash: string, dehydratedAt: number): void;
    /** @internal */
    _registerLiveQuery(queryHash: string, promise: Promise<DehydratedLiveQueryResult>): Promise<void>;
    /** @internal */
    _registerLiveQueryResource(owner: object, cleanup: () => Promise<void>): () => void;
    /** @internal */
    _failPendingLiveQueries(error: unknown): void;
    cleanup(): Promise<void>;
    private hydrateLiveQuery;
    private nextLiveQueryTimestamp;
    private createLiveQueryRecord;
    private emit;
    private applyRows;
}
export {};
