import { StandardSchemaV1 } from '@standard-schema/spec';
import { CollectionConfig, CollectionErrorInfo, CollectionStatus, HealthProblem } from '../types.cjs';
import { CollectionEventsManager } from './events.cjs';
import { CollectionIndexesManager } from './indexes.cjs';
import { CollectionChangesManager } from './changes.cjs';
import { CollectionSyncManager } from './sync.cjs';
import { CollectionStateManager } from './state.cjs';
/**
 * Floor applied to the GC delay of a collection that started syncing before
 * anything subscribed. Adapters build their live query while rendering and
 * subscribe when that render commits. This grace period reduces cleanup
 * during that gap; a later subscriber can still restart sync. Adapters pass
 * a near-zero `gcTime` to make teardown on unmount immediate. Does not apply
 * to the timer armed when the last subscriber leaves, which still honours
 * `gcTime` exactly.
 */
export declare const UNSUBSCRIBED_GC_FLOOR_MS = 50;
/** A Collection's gcTime when its config names none (5 minutes). */
export declare const DEFAULT_GC_TIME_MS = 300000;
export declare class CollectionLifecycleManager<TOutput extends object = Record<string, unknown>, TKey extends string | number = string | number, TSchema extends StandardSchemaV1 = StandardSchemaV1, TInput extends object = TOutput> {
    private config;
    private id;
    private indexes;
    private events;
    private changes;
    private sync;
    private state;
    status: CollectionStatus;
    hasBeenReady: boolean;
    hasReceivedFirstCommit: boolean;
    private readyFailureSink;
    onFirstReadyCallbacks: Array<() => void>;
    private idleCallbackId;
    private failureReason;
    private failureReasonFromReload;
    private stoppedError;
    private statusError;
    private requestErrors;
    private requestErrorsFromReload;
    private adapterStopped;
    private reloadRun;
    private recovering;
    private gcGraceUntil;
    private cleanupConfig;
    private statusRevision;
    private cleaningUp;
    private cleanupPromise;
    private readonly cleanupStartCallbacks;
    /**
     * Creates a new CollectionLifecycleManager instance
     */
    constructor(config: CollectionConfig<TOutput, TKey, TSchema, any>, id: string, cleanupConfig?: () => void);
    setDeps(deps: {
        indexes: CollectionIndexesManager<TOutput, TKey, TSchema, TInput>;
        events: CollectionEventsManager;
        changes: CollectionChangesManager<TOutput, TKey, TSchema, TInput>;
        sync: CollectionSyncManager<TOutput, TKey, TSchema, TInput>;
        state: CollectionStateManager<TOutput, TKey, TSchema, TInput>;
    }): void;
    /**
     * Validates state transitions to prevent invalid status changes
     */
    validateStatusTransition(from: CollectionStatus, to: CollectionStatus): void;
    /**
     * Safely update the collection status with validation
     * @private
     */
    setStatus(newStatus: CollectionStatus, allowReady?: boolean, beforeEmit?: () => void): void;
    /**
     * Validates that the collection is in a usable state for data operations
     * @private
     */
    validateCollectionUsable(operation: string): void;
    /**
     * Mark the collection as ready for use
     * This is called by sync implementations to explicitly signal that the collection is ready,
     * providing a more intuitive alternative to using commits for readiness signaling
     * @private - Should only be called by sync implementations
     *
     * `beforeEffects` runs after the status reads `ready` and before status
     * listeners and ready callbacks, so their writes follow it.
     */
    markReady(beforeEffects?: () => void): void;
    /**
     * @internal Hold ready-effect failures while a sync function runs, whether
     * it calls markReady or commits a truncate. The returned function stops
     * holding them and returns the first one.
     */
    deferReadyFailures(): () => {
        error: unknown;
    } | undefined;
    private applyReadyTransition;
    /**
     * The sync adapter stopped. Before the first ready this fails the sync
     * run's first load; after it, the rows stay and the error shows until a
     * reload. A second fail() in the same sync run changes nothing: the adapter
     * already stopped, and the first error stays.
     */
    fail(error: unknown): void;
    /** Whether the current sync run's adapter called `fail()`. */
    get stoppedThisRun(): boolean;
    /**
     * Whether the current sync run is in its first load: `loading`, or a reload
     * of a failed first load that is not ready yet. A failure now fails that
     * first load.
     */
    get inFirstLoad(): boolean;
    /** Whether a reload's new sync run is in flight. */
    get reloading(): boolean;
    /**
     * A reload starts a new sync run while everything visible stays: the rows,
     * the status, and the current problem. The node shows `reloading`.
     */
    beginReload(): Promise<void>;
    /**
     * The reload's new run replaced the rows with a snapshot or a truncate, or
     * marked ready: the retired run's problems clear, the new run's stay, and a
     * failed first load becomes ready.
     */
    completeReload(beforeEffects?: () => void): void;
    /** A reload retired the sync run; subscriptions detach its demand. */
    retireSubscriptionDemand(): void;
    /** The reload ended without a commit, for example by cleanup. */
    abandonReload(error: unknown): void;
    private endReload;
    /**
     * Local storage or an internal invariant broke. The Collection can no
     * longer serve reads or accept writes, from any active status. Nothing
     * recovers a crash in place: only cleanup, which discards all state, leaves
     * it.
     */
    crash(error?: unknown): void;
    /** The Collection's own problems, as health tree detail. */
    get problems(): {
        failureReason: HealthProblem | null;
        error: HealthProblem | null;
    };
    /** The cause of status `error` or `crashed`, as health tree detail. */
    get statusProblem(): HealthProblem | null;
    /** The sync adapter still tries after a problem. Status and rows do not change. */
    reportError(error: unknown): void;
    /**
     * The source synced successfully again. With no error it clears the
     * failure reason; with one it removes the failure whose cause is that
     * value, and the failure reason clears once none is left. With nothing to
     * remove it does nothing. `undefined` is no error: it clears every
     * failure, also one that `reportError(undefined)` listed.
     */
    reportHealthy(error?: unknown): void;
    /**
     * @internal A live query's request failed after initial-query readiness,
     * with each of its failures in failure order.
     */
    reportRequestError(key: string, errors: Array<unknown>): void;
    /** @internal The failed request settled or was released. */
    clearRequestError(key: string): void;
    /** fail() ends the sync adapter's reporting for its sync run. */
    private assertAdapterActive;
    private assertReady;
    /** Return the cause of status `error` or `crashed` in this sync run, if any. */
    getSyncError(): unknown;
    /** Cleanup discards the current projection until a new sync run starts. */
    hasStartedCleanup(): boolean;
    assertCanStartSync(): void;
    isCleaningUp(): boolean;
    /**
     * Observe the synchronous start of cleanup without treating it as terminal
     * resource settlement. Internal dependents use this to retire work before
     * an asynchronous adapter cleanup publishes `cleaned-up`.
     */
    onCleanupStart(callback: () => void): () => void;
    /**
     * Start the garbage collection timer for a collection with no subscribers
     * Called when sync starts outside a subscription
     */
    startGCTimerIfUnsubscribed(): void;
    private canGarbageCollect;
    /**
     * Renew inactive retention. Settlement keeps the remaining startup/preload
     * handoff; a real last unsubscribe clears it and uses gcTime exactly.
     */
    startGCTimer(preserveHandoff?: boolean): void;
    /**
     * Cancel the garbage collection timer
     * Called when the collection becomes active again
     */
    cancelGCTimer(): void;
    /**
     * Schedule cleanup to run during browser idle time
     * This prevents blocking the UI thread during cleanup operations
     */
    private scheduleIdleCleanup;
    private beginCleanup;
    /**
     * Register a callback to be executed when the collection first becomes ready
     * Useful for preloading collections
     * @param callback Function to call when the collection first becomes ready
     */
    onFirstReady(callback: () => void): () => void;
    cleanup(): Promise<void>;
}
/** @internal Requests that failed after initial-query readiness, by issuer. */
export declare class RequestErrors {
    private readonly failed;
    private readonly open;
    problem: HealthProblem | null;
    /** Returns whether the problem changed. */
    fail(key: string, errors: Array<unknown>): boolean;
    /** Returns whether the problem changed. */
    settle(key: string): boolean;
    private release;
    private show;
}
/**
 * @internal A health problem: its newest failure's fields, with every
 * failure of its frame listed, oldest first.
 */
export declare function problemOf(errors: ReadonlyArray<CollectionErrorInfo>): HealthProblem;
/** @internal Health tree detail for a problem value. */
export declare function describeProblem(error: unknown): CollectionErrorInfo;
