/**
 * tansu is a lightweight, push-based state management library.
 * It borrows the ideas and APIs originally designed and implemented by {@link https://github.com/sveltejs/rfcs/blob/master/text/0002-reactive-stores.md | Svelte stores}.
 *
 * @packageDocumentation
 */
import { rawStoreSymbol, symbolObservable } from './internal/exposeRawStores';
import { RawStoreWritable } from './internal/storeWritable';
import type { AsyncDeriveFn, AsyncDeriveOptions, OnUseFn, Readable, ReadableSignal, StoreInput, StoreOptions, StoresInput, StoresInputValues, Subscriber, SyncDeriveFn, SyncDeriveOptions, UnsubscribeFunction, UnsubscribeObject, Unsubscriber, Updater, WritableSignal } from './types';
export { batch } from './internal/batch';
export { equal } from './internal/equal';
export { symbolObservable } from './internal/exposeRawStores';
export { untrack } from './internal/untrack';
export type * from './types';
/**
 * Returns a wrapper (for the given store) which only exposes the {@link ReadableSignal} interface.
 * This converts any {@link StoreInput} to a {@link ReadableSignal} and exposes the store as read-only.
 *
 * @param store - store to wrap
 * @returns A wrapper which only exposes the {@link ReadableSignal} interface.
 */
export declare function asReadable<T>(store: StoreInput<T>): ReadableSignal<T>;
/**
 * Returns a wrapper (for the given store) which only exposes the {@link ReadableSignal} interface and
 * also adds the given extra properties on the returned object.
 *
 * @param store - store to wrap
 * @param extraProp - extra properties to add on the returned object
 * @returns A wrapper which only exposes the {@link ReadableSignal} interface and the given extra properties.
 */
export declare function asReadable<T, U>(store: StoreInput<T>, extraProp: U): ReadableSignal<T> & Omit<U, keyof Readable<T>>;
/**
 * Returns a wrapper (for the given store) which only exposes the {@link WritableSignal} interface.
 * When the value is changed from the given wrapper, the provided set function is called.
 *
 * @param store - store to wrap
 * @param set - function that will be called when the value is changed from the wrapper
 * (through the {@link Writable.set|set} or the {@link Writable.update|update} function).
 * If set is not specified, a noop function is used (so the value of the store cannot be changed
 * from the returned wrapper).
 * @returns A wrapper which only exposes the {@link WritableSignal} interface.
 */
export declare function asWritable<T, W = T>(store: StoreInput<T>, set?: WritableSignal<T, W>['set']): WritableSignal<T, W>;
/**
 * Returns a wrapper (for the given store) which only exposes the {@link WritableSignal} interface and
 * also adds the given extra properties on the returned object.
 *
 * @param store - store to wrap
 * @param extraProps - object containing the extra properties to add on the returned object,
 * and optionally the {@link Writable.set|set} and the {@link Writable.update|update} function of the
 * {@link WritableSignal} interface.
 * If the set function is not specified, a noop function is used.
 *
 * If the update function is not specified, a default function that calls set is used.
 * @returns A wrapper which only exposes the {@link WritableSignal} interface and the given extra properties.
 */
export declare function asWritable<T, U, W = T>(store: StoreInput<T>, extraProps: U & Partial<Pick<WritableSignal<T, W>, 'set' | 'update'>>): WritableSignal<T, W> & Omit<U, keyof WritableSignal<T, W>>;
/**
 * A utility function to get the current value from a given store.
 * It works by subscribing to a store, capturing the value (synchronously) and unsubscribing just after.
 *
 * @param store - a store from which the current value is retrieved.
 *
 * @example
 * ```typescript
 * const myStore = writable(1);
 * console.log(get(myStore)); // logs 1
 * ```
 */
export declare const get: <T>(store: StoreInput<T>) => T;
/**
 * Base class that can be extended to easily create a custom {@link Readable} store.
 *
 * @example
 * ```typescript
 * class CounterStore extends Store {
 *    constructor() {
 *      super(1); // initial value
 *    }
 *
 *    reset() {
 *      this.set(0);
 *    }
 *
 *    increment() {
 *      this.update(value => value + 1);
 *    }
 * }
 *
 * const store = new CounterStore(1);
 *
 * // logs 1 (initial value) upon subscription
 * const unsubscribe = store.subscribe((value) => {
 *    console.log(value);
 * });
 * store.increment(); // logs 2
 * store.reset(); // logs 0
 *
 * unsubscribe(); // stops notifications and corresponding logging
 * ```
 */
export declare abstract class Store<T> implements Readable<T> {
    /**
     *
     * @param value - Initial value of the store
     */
    constructor(value: T);
    /** @internal */
    [rawStoreSymbol]: RawStoreWritable<T>;
    /**
     * Compares two values and returns true if they are equal.
     * It is called when setting a new value to avoid doing anything
     * (such as notifying subscribers) if the value did not change.
     * The default logic is to return false if `a` is a function or an object,
     * or if `a` and `b` are different according to `Object.is`.
     * This method can be overridden by subclasses to change the logic.
     *
     * @remarks
     * For backward compatibility, the default implementation calls the
     * deprecated {@link Store.notEqual} method and returns the negation
     * of its return value.
     *
     * @param a - First value to compare.
     * @param b - Second value to compare.
     * @returns true if a and b are considered equal.
     */
    protected equal(a: T, b: T): boolean;
    /**
     * Compares two values and returns true if they are different.
     * It is called when setting a new value to avoid doing anything
     * (such as notifying subscribers) if the value did not change.
     * The default logic is to return true if `a` is a function or an object,
     * or if `a` and `b` are different according to `Object.is`.
     * This method can be overridden by subclasses to change the logic.
     *
     * @remarks
     * This method is only called by the default implementation of
     * {@link Store.equal}, so overriding {@link Store.equal} takes
     * precedence over overriding notEqual.
     *
     * @deprecated Use {@link Store.equal} instead
     * @param a - First value to compare.
     * @param b - Second value to compare.
     * @returns true if a and b are considered different.
     */
    protected notEqual(a: T, b: T): boolean;
    /**
     * Replaces store's state with the provided value.
     * Equivalent of {@link Writable.set}, but internal to the store.
     *
     * @param value - value to be used as the new state of a store.
     */
    protected set(value: T): void;
    get(): T;
    /**
     * Updates store's state by using an {@link Updater} function.
     * Equivalent of {@link Writable.update}, but internal to the store.
     *
     * @param updater - a function that takes the current state as an argument and returns the new state.
     */
    protected update(updater: Updater<T>): void;
    /**
     * Function called when the number of subscribers changes from 0 to 1
     * (but not called when the number of subscribers changes from 1 to 2, ...).
     * If a function is returned, it will be called when the number of subscribers changes from 1 to 0.
     *
     * @example
     *
     * ```typescript
     * class CustomStore extends Store {
     *    onUse() {
     *      console.log('Got the fist subscriber!');
     *      return () => {
     *        console.log('All subscribers are gone...');
     *      };
     *    }
     * }
     *
     * const store = new CustomStore();
     * const unsubscribe1 = store.subscribe(() => {}); // logs 'Got the fist subscriber!'
     * const unsubscribe2 = store.subscribe(() => {}); // nothing is logged as we've got one subscriber already
     * unsubscribe1(); // nothing is logged as we still have one subscriber
     * unsubscribe2(); // logs 'All subscribers are gone...'
     * ```
     */
    protected onUse?(): Unsubscriber | void;
    /**
     * Default Implementation of the {@link SubscribableStore.subscribe}, not meant to be overridden.
     * @param subscriber - see {@link SubscribableStore.subscribe}
     */
    subscribe(subscriber: Subscriber<T>): UnsubscribeFunction & UnsubscribeObject;
    [symbolObservable](): this;
}
/**
 * A convenience function to create {@link Readable} store instances.
 * @param value - Initial value of a readable store.
 * @param options - Either an object with {@link StoreOptions | store options}, or directly the onUse function.
 *
 * The onUse function is a function called when the number of subscribers changes from 0 to 1
 * (but not called when the number of subscribers changes from 1 to 2, ...).
 *
 * If a function is returned, it will be called when the number of subscribers changes from 1 to 0.
 *
 * @example Sample with an onUse function
 * ```typescript
 * const clock = readable("00:00", setState => {
 *   const intervalID = setInterval(() => {
 *     const date = new Date();
 *     setState(`${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`);
 *   }, 1000);
 *
 *   return () => clearInterval(intervalID);
 * });
 * ```
 */
export declare function readable<T>(value: T, options?: StoreOptions<T> | OnUseFn<T>): ReadableSignal<T>;
/**
 * A convenience function to create {@link Writable} store instances.
 * @param value - initial value of a new writable store.
 * @param options - Either an object with {@link StoreOptions | store options}, or directly the onUse function.
 *
 * The onUse function is a function called when the number of subscribers changes from 0 to 1
 * (but not called when the number of subscribers changes from 1 to 2, ...).
 *
 * If a function is returned, it will be called when the number of subscribers changes from 1 to 0.
 *
 * @example
 * ```typescript
 * const x = writable(0);
 *
 * x.update(v => v + 1); // increment
 * x.set(0); // reset back to the default value
 * ```
 */
export declare function writable<T>(value: T, options?: StoreOptions<T> | OnUseFn<T>): WritableSignal<T>;
export declare abstract class DerivedStore<T, S extends StoresInput = StoresInput> extends Store<T> {
    constructor(stores: S, initialValue: T);
    protected abstract derive(values: StoresInputValues<S>): Unsubscriber | void;
}
/**
 * A convenience function to create a new store with a state computed from the latest values of dependent stores.
 * Each time the state of one of the dependent stores changes, a provided derive function is called to compute a new, derived state.
 *
 * @param stores - a single store or an array of dependent stores
 * @param options - either an object with store options, including a derive function, or the derive function itself directly.
 * The derive function is used to compute a new state based on the latest values of dependent stores.
 *
 * Alternatively, this function can accept a second argument, `set`, to manage asynchronous values.
 * If you return a function from the callback, it will be called when the callback runs again, or the last subscriber unsubscribes.
 *
 * @example synchronous
 * ```typescript
 * const x$ = writable(2);
 * const y$ = writable(3);
 * const sum$ = derived([x$, y$], ([x, y]) => x + y);
 *
 * // will log 5 upon subscription
 * sum$.subscribe((value) => {
 *    console.log(value)
 * });
 *
 * x$.set(3); // will re-evaluate the `([x, y]) => x + y` function and log 6 as this is the new state of the derived store
 *
 * ```
 *
 *  @example asynchronous
 * ```typescript
 * const x$ = writable(2);
 * const y$ = writable(3);
 *
 * const sum$ = derived([x$, $y], ([x, y], set) => {
 *    const timeoutId = setTimeout(() => set(x + y)));
 *    return () => clearTimeout(timeoutId);
 * }, <number>undefined);
 *
 * // will log undefined (the default value), then 5 asynchronously
 * sum$.subscribe((value) => {
 *    console.log(value)
 * });
 *
 * ```

 */
export declare function derived<T, S extends StoresInput>(stores: S, options: AsyncDeriveFn<T, S> | AsyncDeriveOptions<T, S>, initialValue: T): ReadableSignal<T>;
export declare function derived<T, S extends StoresInput>(stores: S, options: SyncDeriveFn<T, S> | SyncDeriveOptions<T, S>, initialValue?: T): ReadableSignal<T>;
/**
 * Creates a store whose value is computed by the provided function.
 *
 * @remarks
 *
 * The computation function is first called the first time the store is used.
 *
 * It can use the value of other stores or observables and the computation function is called again if the value of those dependencies
 * changed, as long as the store is still used.
 *
 * Dependencies are detected automatically as the computation function gets their value either by calling the stores
 * as a function (as it is possible with stores implementing {@link ReadableSignal}), or by calling the {@link get} function
 * (with a store or any observable). If some calls made by the function should not be tracked as dependencies, it is possible
 * to wrap them in a call to {@link untrack}.
 *
 * Note that dependencies can change between calls of the computation function. Internally, tansu will subscribe to new dependencies
 * when they are used and unsubscribe from dependencies that are no longer used after the call of the computation function.
 *
 * @param fn - computation function that returns the value of the store
 * @param options - store option. Allows to define the {@link StoreOptions.equal|equal} function, if needed
 * @returns store containing the value returned by the computation function
 */
export declare function computed<T>(fn: () => T, options?: Omit<StoreOptions<T>, 'onUse'>): ReadableSignal<T>;
