/**
 * Enables custom formatting for Readable and Writable objects in Chrome DevTools.
 * It is enabled in development by default.
 *
 * @see {@link https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html}
 */
declare function customFormatter(): void;

interface Scheduler {
}

type Disposer = () => void;
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;
}
/**
 * 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 Subscriber<TValue = any> = (newValue: TValue) => void;
type Version = number;

interface ComputeFn<TValue = any> {
    (get: Get): TValue;
}

interface WatchEffect {
    (get: Get, dispose: Disposer): (() => void) | undefined | void;
}

interface TraceConfig {
    name?: string;
    /** @default true */
    printStack?: boolean;
    /** @default true */
    defaultExpand?: boolean;
}
interface Trace {
    <T extends Readable>($: T, config?: TraceConfig): T;
    (effect: WatchEffect, config?: TraceConfig): WatchEffect;
    (fn: ComputeFn, config?: TraceConfig): ComputeFn;
}
/**
 * Console logs trace information about the provided Readable or WatchEffect.
 * @example
 * ```ts
 * import { writable, watch } from "@embra/reactivity";
 * import { trace } from "@embra/reactivity/debug";
 * const count$ = writable(0);
 *
 * trace(count$);
 *
 * watch(() => count$.value++);
 *
 * count$.set(1);
 * ```
 */
declare const trace: Trace;

export { type Trace, type TraceConfig, customFormatter, trace };
