interface Scheduler {
}
/**
 * A function that flushes all scheduled Readables (All subscribers of the Readables will be called).
 */
interface SchedulerFlush {
    (): void;
}

/**
 * Creates an async {@link Scheduler}.
 *
 * @category Schedulers
 * @param defer - A function that defers the execution of the {@link SchedulerFlush} function.
 * @returns A {@link Scheduler}
 *
 * @example
 * ```ts
 * import { asyncScheduler } from "@embra/reactivity";
 * const MicroTaskScheduler = asyncScheduler(flush => Promise.resolve().then(flush));
 * const AnimationFrameScheduler = asyncScheduler(requestAnimationFrame);
 * ```
 */
declare const asyncScheduler: (defer: (flush: SchedulerFlush) => unknown) => Scheduler;

/**
 * The default {@link Scheduler} that runs updates synchronously.
 *
 * @category Schedulers
 */
declare const SyncScheduler: Scheduler;

/**
 * A {@link Scheduler} that runs updates at most once per microtask (Promise).
 *
 * @category Schedulers
 *
 * @example
 * ```ts
 * import { writable, compute, MicrotaskScheduler } from "@embra/reactivity";
 *
 * const v1$ = writable(1);
 * const v2$ = writable(2);
 * const computed$ = compute((get) => get(v1$) + get(v2$));
 *
 * computed$.reaction(
 *   (value) => {
 *     console.log(value)
 *   },
 *   MicrotaskScheduler,
 * );
 * ```
 */
declare const MicrotaskScheduler: Scheduler;

/**
 * Custom config for the Readable/Writable.
 */
interface Config<TValue = any> {
    /**
     * Compare two values. Default `Object.is`.
     * `false` to disable equality check.
     */
    readonly equal?: Equal<TValue> | false;
    /**
     * Name for debugging.
     */
    readonly name?: string;
    /**
     * A callback invoked when a value is needed to be disposed.
     *
     * A value is considered for disposal when:
     * - it is replaced by another value (a new value is set).
     * - the Readable is disposed.
     *
     * @param oldValue The value that is needed to be disposed.
     */
    readonly onDisposeValue?: (oldValue: TValue) => void;
}
type Disposer = () => void;
type Equal<TValue = any> = (newValue: TValue, oldValue: TValue) => boolean;
interface Get {
    <T = any>($: ReadableLike<T>): T;
    <T = any, U = any>($: ReadableLike<T> | U): T | U;
}
/**
 * A Readable is a reactive value that can be read and subscribed to.
 *
 * @category Readable
 */
interface Readable<TValue = any> {
    readonly name?: string;
    /**
     * A version representation of the value.
     * If two versions of a $ is not equal(`Object.is`), it means the `value` has changed (event if the `value` is equal).
     */
    readonly version: Version;
    /**
     * Indicates whether the Readable has been disposed.
     */
    readonly disposed: boolean;
    /**
     * Current value of the $.
     */
    readonly value: TValue;
    /**
     * Get current value.
     */
    get: () => TValue;
    /**
     * Subscribe to value changes without immediate emission.
     * @param subscriber
     * @param scheduler Optional scheduler to control when the subscriber is called.
     * @returns a disposer function that cancels the subscription
     */
    reaction(subscriber: Subscriber<TValue>, scheduler?: Scheduler): Disposer;
    /**
     * Subscribe to value changes with immediate emission.
     * @param subscriber
     * @param scheduler Optional scheduler to control when the subscriber is called.
     * @returns a disposer function that cancels the subscription
     */
    subscribe(subscriber: Subscriber<TValue>, scheduler?: Scheduler): Disposer;
    /**
     * Remove the given subscriber or all subscribers if no subscriber is provided.
     * @param subscriber Optional subscriber function to remove.
     * @param scheduler Optional scheduler associated with the subscriber.
     * If not provided, all subscribers will be removed.
     */
    unsubscribe(subscriber?: (...args: any[]) => any, scheduler?: Scheduler): void;
}
/**
 * An OwnedReadable is a {@link Readable} with a `dispose` method that removes all subscribers and locks the Readable.
 *
 * @category Readable
 */
interface OwnedReadable<TValue = any> extends Readable<TValue> {
    /**
     * Remove all subscribers and lock.
     */
    dispose(): void;
}
/**
 * A Readable provider is an object that provides a {@link Readable} `$` property.
 *
 * @category Readable
 */
interface ReadableProvider<TValue = any> {
    readonly $: Readable<TValue>;
}
/**
 * A {@link Readable} or a {@link ReadableProvider}.
 *
 * @category Readable
 */
type ReadableLike<TValue = any> = Readable<TValue> | ReadableProvider<TValue>;
type SetValue<TValue = any> = (value: TValue) => void;
type Subscriber<TValue = any> = (newValue: TValue) => void;
type Unwrap<T> = T extends ReadableLike<infer TValue> ? TValue : T;
type Version = number;
/**
 * A Writable is a {@link Readable} with a writable `value` property and a `set` method that updates the value.
 *
 * @category Writable
 */
interface Writable<TValue = any> extends Readable<TValue> {
    /** Current value of the Writable */
    value: TValue;
    /** Set new value */
    set: (value: TValue) => void;
}
/**
 * An OwnedWritable is a {@link Writable} with a `dispose` method that removes all subscribers and locks the Writable.
 *
 * @category Writable
 */
interface OwnedWritable<TValue = any> extends Writable<TValue> {
    /**
     * Remove all subscribers and lock.
     */
    dispose(): void;
}

type Listener<T = any> = (data: T) => void;
/**
 * Unsubscribes the bound listener.
 * @returns Returns true if the listener existed and has been removed,
 *          or false if the listener does not exist.
 */
type RemoveListener = () => boolean;
interface EventObject<T = any> {
}

type BatchTask<O extends object = object> = O & {
    batchTask_: () => void;
};
/**
 * Manually starts a batch of updates without auto-flushing.
 * Use {@link batchFlush} to finish the batch.
 *
 * It is preferred to use the {@link batch} function instead.
 *
 * @category Batch
 * @returns A boolean indicating if this is the first batch trigger.
 *          If true, the caller should call {@link batchFlush} to finish the batch.
 *
 * @example
 * ```ts
 * import { batchStart, batchFlush, writable, compute} from "@embra/reactivity";
 *
 * const count$ = writable(0);
 * const double$ = compute(get => get(count$) * 2);
 *
 * const isFirst = batchStart();
 *
 * count$.set(1);
 * count$.set(2);
 *
 * if (isFirst) {
 *   batchFlush();
 * }
 * ```
 */
declare const batchStart: () => boolean;
/**
 * Finishes a {@link batchStart} updates.
 *
 * It is preferred to use the {@link batch} function instead.
 *
 * @category Batch
 */
declare const batchFlush: () => void;
/**
 * Creates a batch of updates. Computations within the batch are deferred until the batch completes.
 *
 * @category Batch
 * @param fn - The function containing updates to batch.
 * @param thisArg - The value to use as `this` when executing `fn`.
 * @returns The result of the function `fn`.
 *
 * @example
 * ```ts
 * import { batch, writable, compute } from "@embra/reactivity";
 *
 * const count$ = writable(0);
 * const double$ = compute(get => get(count$) * 2);
 *
 * batch(() => {
 *   count$.set(1);
 *   count$.set(2);
 * });
 * ```
 */
declare const batch: <T>(fn: () => T, thisArg?: any) => T;

interface ComputeFn<TValue = any> {
    (get: Get): TValue;
}
/**
 * Computes a derived value based on other Readables.
 *
 * @category Derivations
 * @param fn - The function that computes the value.
 * @param config - Optional custom {@link Config}.
 * @returns An {@link OwnedReadable} that computes its value based on other Readables.
 *
 * @example
 * ```ts
 * import { compute, writable, reactiveMap } from "@embra/reactivity";
 *
 * const v1$ = writable(0);
 * const v2$ = writable(1);
 * const map$ = reactiveMap([["s", 42]]);
 *
 * const sum$ = compute(get => get(v1$) + get(v2$) + get(map$).get("s") || 0);
 * ```
 */
declare const compute: <TValue>(fn: ComputeFn<TValue>, config?: Config<TValue>) => OwnedReadable<TValue>;

interface Derive {
    /**
     * Derive a new {@link Readable} with same value from the given {@link ReadableLike}.
     * @param dep - The {@link ReadableLike} to derive from.
     * @returns A {@link Readable} with same value as the given {@link ReadableLike}.
     */
    <TDepValue, TValue>(dep: ReadableLike<TDepValue>): OwnedReadable<TValue>;
    /**
     * Derive a new {@link Readable} with transformed value from the given {@link ReadableLike}.
     * @param dep - The {@link ReadableLike} to derive from.
     * @param transform A pure function that takes an input value and returns a new value.
     * @param config custom config for the combined {@link Readable}.
     * @returns A {@link Readable} with transformed value from the given {@link ReadableLike}.
     */
    <TDepValue, TValue>(dep: ReadableLike<TDepValue>, transform: (depValue: TDepValue) => TValue, config?: Config<TValue>): OwnedReadable<TValue>;
}
/**
 * Derive a new {@link Readable} with transformed value from the given {@link ReadableLike}.
 *
 * Unlike {@link compute}, the signature of the `transform` function is pure,
 * which makes it easier to use functions that are not aware of the reactive system.
 *
 * @function
 * @category Derivations
 * @param dep - The {@link ReadableLike} to derive from.
 * @param transform - Optional pure function that takes an input value and returns a new value.
 * @param config - Optional custom {@link Config}.
 * @returns A {@link OwnedReadable} with transformed value from the given {@link ReadableLike}.
 */
declare const derive: Derive;

type MapReadablesToValues<TDepValues extends readonly ReadableLike[]> = {
    [K in keyof TDepValues]: TDepValues[K] extends ReadableLike<infer V> ? V : never;
};
interface Combine {
    /**
     * Combines an array of {@link ReadableLike}s into a single {@link Readable} with the array of values.
     * @param deps An array of {@link ReadableLike}s to combine.
     * @returns A {@link Readable} with the combined values.
     */
    <TDeps extends readonly ReadableLike[] = ReadableLike[]>(deps: [...TDeps]): OwnedReadable<MapReadablesToValues<TDeps>>;
    /**
     * Combines an array of {@link ReadableLike}s into a single {@link Readable} with transformed value.
     * @param deps - An array of {@link ReadableLike}s to combine.
     * @param transform - A pure function that takes multiple values and returns a new value.
     * @param config - Optional custom {@link Config}.
     * @returns A {@link Readable} with the transformed values.
     */
    <TDeps extends readonly ReadableLike[] = ReadableLike[], TValue = any>(deps: [...TDeps], transform: (...deps: MapReadablesToValues<TDeps>) => TValue, config?: Config<TValue>): OwnedReadable<TValue>;
}
/**
 * Combine an array of {@link ReadableLike}s into a single {@link Readable} with transformed value.
 *
 * Unlike {@link compute}, the signature of the `transform` function is pure,
 * which makes it easier to use functions that are not aware of the reactive system.
 *
 * @function
 * @category Derivations
 * @param deps - An array of {@link ReadableLike}s to combine.
 * @param transform - Optional pure function that takes multiple values and returns a new value.
 * @param config - Optional custom {@link Config}.
 * @returns A {@link OwnedReadable} with transformed value.
 *
 * @example
 * ```ts
 * import { combine, writable } from "@embra/reactivity";
 *
 * const v1$ = writable(0);
 * const v2$ = writable(0);
 *
 * const combined$ = combine([v1$, v2$], (v1, v2) => v1 + v2);
 * ````
 */
declare const combine: Combine;

interface CreateReadable {
    /**
     * Creates a Readonly with the given value.
     *
     * @returns A tuple with the Readonly and a function to set the value.
     */
    <TValue = any>(): [OwnedReadable<TValue | undefined>, SetValue<TValue | undefined>];
    /**
     * Creates a Readonly with the given value.
     *
     * @param value
     * @param config Optional custom config.
     * @returns A tuple with the Readonly and a function to set the value.
     */
    (value: [], config?: Config<any[]>): [OwnedReadable<any[]>, SetValue<any[]>];
    /**
     * Creates a Readonly with the given value.
     *
     * @param value
     * @param config Optional custom config.
     * @returns A tuple with the Readonly and a function to set the value.
     */
    <TValue = any>(value: TValue, config?: Config<TValue>): [OwnedReadable<TValue>, SetValue<TValue>];
    /**
     * Creates a Readonly with the given value.
     *
     * @param value
     * @param config Optional custom config.
     * @returns A tuple with the Readonly and a function to set the value.
     */
    <TValue = any>(value?: TValue, config?: Config<TValue>): [OwnedReadable<TValue | undefined>, SetValue<TValue | undefined>];
}
/**
 * Creates an {@link OwnedReadable}.
 *
 * @function
 * @category Readable
 * @param value - Initial value.
 * @param config - Optional custom {@link Config}.
 * @returns A tuple containing the {@link OwnedReadable} and a setter function.
 */
declare const readable: CreateReadable;
interface ToWritable {
    <TValue>($: OwnedReadable<TValue>, set: (this: void, value: TValue) => void): OwnedWritable<TValue>;
    <TValue>($: Readable<TValue>, set: (this: void, value: TValue) => void): Writable<TValue>;
}
/**
 * Converts a Readable to a Writable By adding a setter function.
 *
 * @function
 * @category Writable
 * @param $
 * @param set a function that sets the value of Readable.
 * @returns The same Readable with the new setter.
 */
declare const toWritable: ToWritable;
interface CreateWritable {
    /**
     * Creates a Writable.
     * @returns A Writable with undefined value.
     */
    <TValue = any>(): OwnedWritable<TValue | undefined>;
    /**
     * Creates a Writable.
     * @param value Initial value.
     * @param config Optional custom config.
     */
    (value: [], config?: Config<any[]>): OwnedWritable<any[]>;
    /**
     * Creates a Writable.
     * @param value Initial value.
     * @param config Optional custom config.
     */
    <TValue = any>(value: TValue, config?: Config<TValue>): OwnedWritable<TValue>;
    /**
     * Creates a Writable.
     * @param value Initial value.
     * @param config Optional custom config.
     */
    <TValue = any>(value?: TValue, config?: Config<TValue | undefined>): OwnedWritable<TValue>;
}
/**
 * Creates an {@link OwnedWritable}.
 *
 * @function
 * @category Writable
 * @param value - Initial value.
 * @param config - Optional custom {@link Config}.
 * @returns The created {@link OwnedWritable}.
 */
declare const writable: CreateWritable;

interface WatchEffect {
    (get: Get, dispose: Disposer): (() => void) | undefined | void;
}
/**
 * Watch a reactive effect and re-run it when its dependencies change.
 *
 * @category SideEffects
 * @param effect - The reactive effect to watch.
 * @returns A disposer function to stop watching the effect.
 *
 * @example
 * ```ts
 * import { watch, writable, reactiveMap } from "./watch";
 *
 * const count$ = writable(0);
 * const map$ = reactiveMap();
 *
 * watch((get) => {
 *   console.log(get(count$));
 *   console.log(get(map$).get("key"));
 * });
 * ```
 */
declare const watch: (effect: WatchEffect) => Disposer;

/**
 * Remove the given subscriber.
 * Remove all if no subscriber provided.
 *
 * @category Readable
 * @param $
 * @param subscriber
 */
declare const unsubscribe: ($: Iterable<Readable> | Readable | null | undefined, subscriber?: (...args: any[]) => any) => void;
/**
 * `Object.is`
 *
 * @category Comparers
 */
declare const strictEqual: (value1: any, value2: any) => boolean;
/**
 * Shallow compare two arrays.
 *
 * @category Comparers
 * @param arrA - any value
 * @param arrB - any value
 * @returns `false` if any of:
 *          1. one of arrA or arrB is an array and the other is not
 *          2. arrA and arrB have different lengths
 *          3. arrA and arrB have different values at any index
 */
declare const arrayShallowEqual: (arrA: any, arrB: any) => boolean;
interface IsReadable {
    ($: unknown): $ is Readable;
    ($: any): $ is Readable;
    <T extends Readable>($: T): $ is T extends Readable ? T : never;
}
/**
 * Checks if $ is is a {@link Readable}.
 *
 * Note that a {@link Writable} is also a {@link Readable}.
 *
 * @function
 * @category Readable
 * @returns `true` if $ is {@link Readable}.
 */
declare const isReadable: IsReadable;
interface IsWritable {
    ($: unknown): $ is Writable;
    ($: any): $ is Writable;
    <T extends Writable>($: T): $ is T extends Writable ? T : never;
}
/**
 * Checks if $ is is a {@link Writable}.
 *
 * @function
 * @category Writable
 * @returns `true` if $ is {@link Writable}.
 */
declare const isWritable: IsWritable;
/**
 * Check if $ is a {@link ReadableProvider}.
 *
 * @category Readable
 * @param $ - The value to check.
 * @returns `true` if $ is a {@link ReadableProvider}.
 */
declare const isReadableProvider: <T = any>($: any) => $ is ReadableProvider<T>;
/**
 * Check if $ is a {@link ReadableLike}.
 *
 * @category Readable
 * @param $ - The value to check.
 * @returns `true` if $ is a {@link ReadableLike}.
 */
declare const isReadableLike: <T = any>($: any) => $ is ReadableLike<T>;
/**
 * Get the {@link Readable} from a possible {@link ReadableLike}.
 *
 * @category Readable
 * @param $ - The value to extract the Readable from.
 * @returns The extracted {@link Readable} or `undefined` if not found.
 */
declare const getReadable: <T = any>($: ReadableLike<T> | any) => Readable<T> | undefined;

/** When a value should be disposed */
interface OnDisposeValue<V> extends BatchTask<EventObject<V>> {
    readonly delete_: Set<V>;
}
declare function onDisposeValue<V>(this: {
    onDisposeValue_?: null | OnDisposeValue<V>;
}, fn: (value: V) => void): RemoveListener;

interface ReactiveMapChanged<K, V> {
    readonly upsert: readonly [K, V][];
    readonly delete: readonly K[];
}
/**
 * OwnedReactiveMap extends the standard Map interface with reactive capabilities.
 *
 * @category ReactiveMap
 */
declare class OwnedReactiveMap<K, V> extends Map<K, V> implements ReadableProvider<ReadonlyReactiveMap<K, V>> {
    /**
     * A Readable that emits the Map itself whenever it changes.
     *
     * @group Readable
     */
    get $(): Readable<ReadonlyReactiveMap<K, V>>;
    /**
     * Subscribe to changes in the map.
     *
     * @group Events
     * @param fn - The function to call when the map is changed.
     * @returns A disposer function to unsubscribe from the event.
     *
     * @example
     * ```ts
     * import { reactiveMap } from "@embra/reactivity";
     *
     * const map = reactiveMap<number, string>();
     * const disposer = map.onChanged((changed) => {
     *   console.log("Map changed:", changed);
     * });
     * ```
     */
    onChanged(fn: (changed: ReactiveMapChanged<K, V>) => void): RemoveListener;
    /**
     * Subscribe to events when a value is needed to be disposed.
     *
     * A value is considered for disposal when:
     * - it is deleted from the map.
     * - it is replaced by another value (the old value is removed).
     * - it is cleared from the map.
     * - the map is disposed.
     *
     * Note that for performance reasons, it does not handle the case where multiple keys map to the same value.
     *
     * @function
     * @group Events
     * @param fn - The function to call when a value is needed to be disposed.
     * @returns A disposer function to unsubscribe from the event.
     *
     * @example
     * ```ts
     * import { reactiveMap } from "@embra/reactivity";
     *
     * const map = reactiveMap<number, string>();
     * const disposer = map.onDisposeValue((value) => {
     *   console.log("Value disposed:", value);
     * });
     * ```
     */
    readonly onDisposeValue: typeof onDisposeValue;
    constructor(entries?: Iterable<readonly [K, V]> | null);
    dispose(): void;
    set(key: K, value: V): this;
    delete(key: K): boolean;
    clear(): void;
    rename(key: K, newKey: K): void;
    /**
     * Replace the contents of the map with the given entries.
     * @param entries - The new entries to replace the map with.
     * @returns The map itself.
     */
    replace(entries: Iterable<readonly [K, V]>): this;
}
/**
 * ReactiveMap is {@link OwnedReactiveMap} without the `dispose` method.
 *
 * @category ReactiveMap
 */
type ReactiveMap<K, V> = Omit<OwnedReactiveMap<K, V>, "dispose">;
/**
 * ReadonlyReactiveMap is a readonly interface for {@link ReactiveMap}.
 *
 * @category ReactiveMap
 */
interface ReadonlyReactiveMap<K, V> extends ReadonlyMap<K, V> {
    /**
     * A Readable that emits the Map itself whenever it changes.
     *
     * @group Readable
     */
    readonly $: Readable<ReadonlyMap<K, V>>;
    /**
     * Subscribe to changes in the map.
     *
     * @group Events
     * @param fn - The function to call when the map is changed.
     * @returns A disposer function to unsubscribe from the event.
     *
     * @example
     * ```ts
     * import { reactiveMap } from "@embra/reactivity";
     *
     * const map = reactiveMap<number, string>();
     * const disposer = map.onChanged((changed) => {
     *   console.log("Map changed:", changed);
     * });
     * ```
     */
    onChanged(fn: (changed: ReactiveMapChanged<K, V>) => void): RemoveListener;
    /**
     * Subscribe to events when a value is needed to be disposed.
     *
     * A value is considered for disposal when:
     * - it is deleted from the map.
     * - it is replaced by another value (the old value is removed).
     * - it is cleared from the map.
     * - the map is disposed.
     *
     * Note that for performance reasons, it does not handle the case where multiple keys map to the same value.
     *
     * @function
     * @group Events
     * @param fn - The function to call when a value is needed to be disposed.
     * @returns A disposer function to unsubscribe from the event.
     *
     * @example
     * ```ts
     * import { reactiveMap } from "@embra/reactivity";
     *
     * const map = reactiveMap<number, string>();
     * const disposer = map.onDisposeValue((value) => {
     *   console.log("Value disposed:", value);
     * });
     * ```
     */
    readonly onDisposeValue: (fn: (value: V) => void) => RemoveListener;
}
/**
 * Creates a new {@link OwnedReactiveMap}.
 *
 * @category ReactiveMap
 * @param entries - Initial entries for the reactive map.
 * @returns A new instance of {@link OwnedReactiveMap}.
 *
 * @example
 * ```ts
 * import { reactiveMap } from "@embra/reactivity";
 *
 * const map$ = reactiveMap([["key", "value"]]);
 * ```
 */
declare const reactiveMap: <K, V>(entries?: Iterable<readonly [K, V]> | null) => OwnedReactiveMap<K, V>;

interface ReactiveSetChanged<V> {
    readonly upsert: readonly V[];
    readonly delete: readonly V[];
}
/**
 * OwnedReactiveSet extends the standard Set interface with reactive capabilities.
 *
 * @category ReactiveSet
 */
declare class OwnedReactiveSet<V> extends Set<V> implements ReadableProvider<ReadonlyReactiveSet<V>> {
    /**
     * A Readable that emits the Set itself whenever it changes.
     *
     * @group Readable
     */
    get $(): Readable<ReadonlyReactiveSet<V>>;
    /**
     * Subscribe to changes in the set.
     *
     * @group Events
     * @param fn - The function to call when the set is changed.
     * @returns A disposer function to unsubscribe from the event.
     *
     * @example
     * ```ts
     * import { reactiveSet } from "@embra/reactivity";
     *
     * const set = reactiveSet<number>();
     * const disposer = set.onChanged((changed) => {
     *   console.log("Set changed:", changed);
     * });
     * ```
     */
    onChanged(fn: (changed: ReactiveSetChanged<V>) => void): RemoveListener;
    /**
     * Subscribe to events when a value is needed to be disposed.
     *
     * A value is considered for disposal when:
     * - it is deleted from the set.
     * - it is replaced by another value (the old value is removed).
     * - it is cleared from the set.
     * - the set is disposed.
     *
     * @function
     * @group Events
     * @param fn - The function to call when a value is needed to be disposed.
     * @returns A disposer function to unsubscribe from the event.
     *
     * @example
     * ```ts
     * import { reactiveSet } from "@embra/reactivity";
     *
     * const set = reactiveSet<number>();
     * const disposer = set.onDisposeValue((value) => {
     *   console.log("Value disposed:", value);
     * });
     * ```
     */
    readonly onDisposeValue: typeof onDisposeValue;
    constructor(values?: Iterable<V> | null);
    dispose(): void;
    add(value: V): this;
    delete(value: V): boolean;
    clear(): void;
    /**
     * Replace the contents of the set with the given values.
     * @param values - The new values to replace the set with.
     * @returns The set itself.
     */
    replace(values: Iterable<V>): this;
}
/**
 * ReactiveSet is {@link OwnedReactiveSet} without the `dispose` method.
 *
 * @category ReactiveSet
 */
type ReactiveSet<V> = Omit<OwnedReactiveSet<V>, "dispose">;
/**
 * ReadonlyReactiveSet is a readonly interface for {@link ReactiveSet}.
 *
 * @category ReactiveSet
 */
interface ReadonlyReactiveSet<V> extends ReadonlySet<V> {
    /**
     * A Readable that emits the Set itself whenever it changes.
     *
     * @group Readable
     */
    readonly $: Readable<ReadonlySet<V>>;
    /**
     * Subscribe to changes in the set.
     *
     * @group Events
     * @param fn - The function to call when the set is changed.
     * @returns A disposer function to unsubscribe from the event.
     *
     * @example
     * ```ts
     * import { reactiveSet } from "@embra/reactivity";
     *
     * const set = reactiveSet<number>();
     * const disposer = set.onChanged((changed) => {
     *   console.log("Set changed:", changed);
     * });
     * ```
     */
    onChanged(fn: (changed: ReactiveSetChanged<V>) => void): RemoveListener;
    /**
     * Subscribe to events when a value is needed to be disposed.
     *
     * A value is considered for disposal when:
     * - it is deleted from the set.
     * - it is replaced by another value (the old value is removed).
     * - it is cleared from the set.
     * - the set is disposed.
     *
     * @function
     * @group Events
     * @param fn - The function to call when a value is needed to be disposed.
     * @returns A disposer function to unsubscribe from the event.
     *
     * @example
     * ```ts
     * import { reactiveSet } from "@embra/reactivity";
     *
     * const set = reactiveSet<number>();
     * const disposer = set.onDisposeValue((value) => {
     *   console.log("Value disposed:", value);
     * });
     * ```
     */
    readonly onDisposeValue: (fn: (value: V) => void) => RemoveListener;
}
/**
 * Creates a new {@link OwnedReactiveSet}.
 *
 * @category ReactiveSet
 * @param values - Initial values for the reactive set.
 * @returns A new instance of {@link OwnedReactiveSet}.
 *
 * @example
 * ```ts
 * import { reactiveSet } from "@embra/reactivity";
 *
 * const set$ = reactiveSet([1, 2, 3]);
 * ```
 */
declare const reactiveSet: <V>(values?: Iterable<V> | null) => OwnedReactiveSet<V>;

/**
 * OwnedReactiveArray extends the standard Array interface with reactive capabilities.
 *
 * @category ReactiveArray
 */
declare class OwnedReactiveArray<V> extends Array<V> implements ReadableProvider<ReadonlyReactiveArray<V>> {
    readonly [n: number]: V;
    /**
     * Gets the length of the array.
     * This is a number one higher than the highest index in the array.
     *
     * Use `.setLength(length)` to change the length of the array.
     */
    readonly length: number;
    /**
     * A Readable that emits the Array itself whenever it changes.
     *
     * @group Readable
     */
    get $(): Readable<ReadonlyReactiveArray<V>>;
    /**
     * Subscribe to events when a value is needed to be disposed.
     *
     * A value is considered for disposal when:
     * - it is deleted from the array.
     * - it is replaced by another value (the old value is removed).
     * - it is cleared from the array.
     * - the array is disposed.
     *
     * @group Events
     * @function
     * @param fn - The function to call when a value is needed to be disposed.
     * @returns A disposer function to unsubscribe from the event.
     *
     * @example
     * ```ts
     * import { reactiveArray } from "@embra/reactivity";
     *
     * const arr = reactiveArray<number>();
     * const disposer = arr.onDisposeValue((value) => {
     *   console.log("Value disposed:", value);
     * });
     * ```
     */
    readonly onDisposeValue: (fn: (value: V) => void) => RemoveListener;
    constructor(arrayLength?: number);
    constructor(arrayLength: number);
    constructor(...items: V[]);
    /**
     * Overwrites the value at the provided index with the given value.
     * If the index is negative, then it replaces from the end of the array.
     * @param index The index of the value to overwrite. If the index is
     * negative, then it replaces from the end of the array.
     * @param value The value to write into the array.
     */
    set(index: number, value: V): this;
    setLength(value: number): void;
    fill(value: V, start?: number, end?: number): this;
    push(...items: V[]): number;
    pop(): V | undefined;
    shift(): V | undefined;
    unshift(...items: V[]): number;
    splice(start: number, deleteCount?: number): V[];
    splice(start: number, deleteCount: number, ...items: V[]): V[];
    reverse(): this;
    sort(compareFn?: (a: V, b: V) => number): this;
    copyWithin(target: number, start: number, end?: number): this;
    /**
     * Replaces the contents of the array with the provided items.
     * @param items The new items to replace the contents of the array with.
     * @returns The array itself.
     */
    replace(items: Iterable<V>): this;
    dispose(): void;
}
/**
 * ReactiveArray is {@link OwnedReactiveArray} without the `dispose` method.
 *
 * @category ReactiveArray
 */
type ReactiveArray<V> = Omit<OwnedReactiveArray<V>, "dispose">;
/**
 * ReadonlyReactiveArray is a readonly interface for {@link ReactiveArray}.
 *
 * @category ReactiveArray
 */
interface ReadonlyReactiveArray<V> extends ReadonlyArray<V> {
    /**
     * A Readable that emits the Array itself whenever it changes.
     *
     * @group Readable
     */
    readonly $: Readable<readonly V[]>;
    /**
     * Gets the length of the array.
     * This is a number one higher than the highest index in the array.
     *
     * Use `.setLength(length)` to change the length of the array.
     */
    readonly length: number;
    /**
     * Overwrites the value at the provided index with the given value.
     * If the index is negative, then it replaces from the end of the array.
     * @param index The index of the value to overwrite. If the index is
     * negative, then it replaces from the end of the array.
     * @param value The value to write into the array.
     */
    set(index: number, value: V): this;
    /**
     * Updates the length of the array.
     * @param value The new length of the array.
     */
    setLength(value: number): void;
    /**
     * Subscribe to events when a value is needed to be disposed.
     *
     * A value is considered for disposal when:
     * - it is deleted from the array.
     * - it is replaced by another value (the old value is removed).
     * - it is cleared from the array.
     * - the array is disposed.
     *
     * @group Events
     * @function
     * @param fn - The function to call when a value is needed to be disposed.
     * @returns A disposer function to unsubscribe from the event.
     *
     * @example
     * ```ts
     * import { reactiveArray } from "@embra/reactivity";
     *
     * const arr = reactiveArray<number>();
     * const disposer = arr.onDisposeValue((value) => {
     *   console.log("Value disposed:", value);
     * });
     * ```
     */
    readonly onDisposeValue: (fn: (value: V) => void) => RemoveListener;
}
/**
 * Creates a new {@link OwnedReactiveArray}.
 *
 * @category ReactiveArray
 * @param values - Initial values for the reactive array.
 * @returns A new instance of {@link OwnedReactiveArray}.
 *
 * @example
 * ```ts
 * import { reactiveArray } from "@embra/reactivity";
 *
 * const arr$ = reactiveArray([1, 2, 3]);
 * ```
 */
declare const reactiveArray: <V>(values?: Iterable<V> | null) => OwnedReactiveArray<V>;

export { type Combine, type ComputeFn, type Config, type CreateReadable, type CreateWritable, type Derive, type Disposer, type Equal, type Get, type IsReadable, type IsWritable, type Listener, type MapReadablesToValues, MicrotaskScheduler, type OnDisposeValue, OwnedReactiveArray, OwnedReactiveMap, OwnedReactiveSet, type OwnedReadable, type OwnedWritable, type ReactiveArray, type ReactiveMap, type ReactiveMapChanged, type ReactiveSet, type ReactiveSetChanged, type Readable, type ReadableLike, type ReadableProvider, type ReadonlyReactiveArray, type ReadonlyReactiveMap, type ReadonlyReactiveSet, type RemoveListener, type Scheduler, type SchedulerFlush, type SetValue, type Subscriber, SyncScheduler, type ToWritable, type Unwrap, type Version, type WatchEffect, type Writable, arrayShallowEqual, asyncScheduler, batch, batchFlush, batchStart, combine, compute, derive, getReadable, isReadable, isReadableLike, isReadableProvider, isWritable, reactiveArray, reactiveMap, reactiveSet, readable, strictEqual, toWritable, unsubscribe, watch, writable };
