import { Observer, Updater } from '../models/observable.model.js';

/**
 * Represents an observable object that can be observed by multiple observers.
 *
 * @class Observable
 * @template T - The type of data that observers will receive.
 */
declare class Observable<T> {
    protected _observers: Set<Observer<T>>;
    /**
     * Notifies all observers with optional data.
     *
     * @protected
     * @param {T} data - The new data to be sent to observers.
     * @memberof Observable
     */
    protected _notify(data: T): void;
    /**
     * Updates the observers with the new data.
     *
     * @param {T} data - The new data to be sent to observers.
     * @memberof Observable
     */
    update(data: T): void;
    /**
     * Subscribes an observer to the observable and returns an unsubscribe function.
     *
     * @param {Observer<T>} observer - The observer function to be added.
     * @returns {() => boolean} An unsubscribe function that removes the observer.
     * @memberof Observable
     */
    subscribe(observer: Observer<T>): () => boolean;
    /**
     * Unsubscribes an observer from the observable.
     * If no observer is provided, unsubscribes all observers.
     *
     * @param {Observer<T>} [observer] - The observer to be removed.
     * @returns {boolean} True if the observer(s) were successfully removed, false otherwise.
     * @memberof Observable
     */
    unsubscribe(observer?: Observer<T>): boolean;
}
/**
 * Represents an observable object with state that can be observed and updated.
 *
 * @class ObservableState
 * @extends {Observable<T>}
 * @template T - The type of the state.
 */
declare class ObservableState<T> extends Observable<T> {
    private readonly _mutable;
    private _state;
    /**
     * Notifies all observers with optional data and previous state.
     *
     * @protected
     * @param {T} data - The new data to be sent to observers.
     * @param  {T} prev - the previous data (defaults to this._state).
     * @memberof Observable
     */
    protected _notify(data: T, prev?: T): void;
    /**
     * Gets the current state of the observable.
     *
     * @readonly
     * @type {T} The current state.
     * @memberof ObservableState
     */
    get state(): T;
    /**
     * Creates an instance of ObservableState with an initial state and mutability option.
     *
     * @param {T} state - The initial state.
     * @param {boolean} [mutable=false] - Indicates whether the state is mutable.
     * @memberof ObservableState
     */
    constructor(state: T, mutable?: boolean);
    /**
     * Updates the state based on mutability and freezes it if necessary.
     *
     * @private
     * @param {T} state - The new state.
     * @memberof ObservableState
     */
    private _update;
    /**
     * Updates the state based on either a direct value or an update function.
     * Notifies observers with the new state.
     *
     * @param {T | UpdateFunction<T>} state - The new state or an update function.
     * @memberof ObservableState
     */
    update(state: Updater<T>): void;
}

export { Observable, ObservableState };
