/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { Dependee, Dependent } from "./dependencies";
/**
 * A {@link Dependee} which runs a callback once it removes its last dependent.
 * See {@link DisposingDependee.endInitialization}.
 *
 * @alpha
 */
export declare class DisposingDependee implements Dependee {
    readonly computationName: string;
    private readonly dependents;
    private state;
    /**
     * Called on dispose.
     * Only set while state is State.Initialized.
     */
    private onDispose;
    /**
     * Constructs a DisposingDependee in "initialization mode".
     * After adding any initial dependencies,
     * {@link DisposingDependee.endInitialization} can be called to provide an onDispose callback.
     */
    constructor(computationName: string);
    registerDependent(dependent: Dependent): boolean;
    removeDependent(dependent: Dependent): void;
    invalidateDependents(): void;
    /**
     * Ends "initialization mode", meaning this will now be disposed (and thus run the `onDispose` callback)
     * the next time it has zero dependents (which will be before this returns if it currently has zero dependents).
     *
     * Note that once there are zero dependents (before running the `onDispose` callback),
     * this object is no longer usable as a Dependee,
     * and thus it is an error to call `registerDependent`.
     * This means `onDispose` will be invoked at most once.
     *
     * It is an error to call `endInitialization` more than once.
     * If called, it should be called by the creator of this DisposingDependee after adding initial dependencies.
     *
     * "initialization mode" exists to handle a couple of edge cases where the simpler approach of just
     * disposing when last dependee is removed would not work:
     * - No dependents were added in initialization: would never get disposed.
     * - A dependent was added, then removed, then a second one added during initialization:
     * the second dependent would be added after this was disposed, which is invalid.
     *
     * This first case is actually pretty easy to hit on accident even in a lazy system,
     * since sometimes the context which takes the dependency does not need dependency tracking
     * (ex: its a one time event and not a projection).
     * This scenario is the main motivating factor behind this particular API design.
     *
     * Another way to think about this is "initialization mode" effectively holds an extra ref count to this Dependee,
     * keeping it alive while its in-scope for its creator to add dependents to.
     *
     * @param onDispose - run once there are no dependents.
     * Will be during this call to endInitialization if there are currently no dependents.
     */
    endInitialization(onDispose: (dependee: DisposingDependee) => void): void;
    /**
     * Dispose if there are no dependents.
     */
    private disposeIfEmpty;
    /**
     * @returns true iff this is disposed, and this can no longer be used.
     */
    isDisposed(): boolean;
}
//# sourceMappingURL=disposingDependee.d.ts.map