import { IBaseObservable, IEquals, IObservable, IObservableKey, IObservableNextOptions, IObservableOptions, IValueList, Observable } from "@guanghechen/observable";
import { ISubscribable, ISubscriber, IUnsubscribable } from "@guanghechen/subscriber";
import { IBatchDisposable, IDisposable } from "@guanghechen/types";
import { BatchDisposable } from "@guanghechen/disposable";
interface IComputed<T> extends IBaseObservable<T> {
  getServerSnapshot?: () => T;
  subscribeStateChange: (onStoreChange: () => void) => () => void;
}
declare class Computed<T> implements IComputed<T> {
  protected readonly _observable: IBaseObservable<T>;
  constructor(observable: IBaseObservable<T>);
  static fromObservables<S extends Array<IBaseObservable<any>>, T>(observables: S, transform: (values: IValueList<S>) => T, options?: IObservableOptions<T>): Computed<T>;
  get disposed(): boolean;
  dispose(): void;
  registerDisposable<T extends IDisposable>(disposable: T): void;
  subscribe(subscriber: ISubscriber<T>): IUnsubscribable;
  readonly getSnapshot: () => T;
  readonly getServerSnapshot: () => T;
  readonly subscribeStateChange: (onStateChange: () => void) => (() => void);
}
interface IImmutableCollection<K, V> {
  has(key: K): boolean;
  get(key: K): V | undefined;
  keys(): Iterable<K>;
  values(): Iterable<V>;
  entries(): Iterable<[K, V]>;
  withMutations(mutator: (mutable: this) => void): this;
}
interface IImmutableMap<K, V> extends IImmutableCollection<K, V> {
  set(key: K, value: V): this;
  delete(key: K): this;
  deleteAll(keys: Iterable<K>): this;
  merge(entries: Iterable<[K, V]>): this;
}
interface IImmutableSet<V> extends IImmutableCollection<V, V> {
  add(value: V): this;
  delete(key: V): this;
}
interface IObservableCollectionOptions<V> {
  valueEquals?: IEquals<V | undefined>;
}
interface IObservableCollection<K, V, C extends IImmutableCollection<K, V>> extends IObservable<C> {
  has(key: K): boolean;
  get(key: K): V | undefined;
  keys(): Iterable<K>;
  values(): Iterable<V>;
  entries(): Iterable<[K, V]>;
  observeKey(key: K): IObservable<V | undefined>;
  subscribeKey(key: K, subscriber: ISubscriber<V | undefined>): IUnsubscribable;
}
interface IObservableMap<K, V, C extends IImmutableMap<K, V>> extends IObservableCollection<K, V, C> {
  set(key: K, value: V, options?: IObservableNextOptions): void;
  delete(key: K, options?: IObservableNextOptions): void;
  deleteAll(keys: Iterable<K>, options?: IObservableNextOptions): void;
  merge(entries: Iterable<[K, V]>, options?: IObservableNextOptions): void;
}
interface IObservableSet<V, C extends IImmutableSet<V>> extends IObservableCollection<V, V, C> {
  add(value: V, options?: IObservableNextOptions): void;
  addAll(values: Iterable<V>, options?: IObservableNextOptions): void;
  delete(value: V, options?: IObservableNextOptions): void;
  deleteAll(values: Iterable<V>, options?: IObservableNextOptions): void;
}
interface IObservableSubscriber<T> {
  readonly subscriber: ISubscriber<T>;
  inactive: boolean;
}
declare class ObservableCollection<K, V, C extends IImmutableCollection<K, V>> extends BatchDisposable implements IObservableCollection<K, V, C> {
  readonly equals: IEquals<C>;
  readonly valueEquals: IEquals<V | undefined>;
  protected readonly _subscribers: Array<IObservableSubscriber<C>>;
  protected readonly _keySubscribersMap: Map<K, Array<IObservableSubscriber<V | undefined>>>;
  protected _value: C;
  protected _lastNotifiedValue: C | undefined;
  constructor(defaultValue: C, options?: IObservableCollectionOptions<V>);
  dispose(): void;
  has(key: K): boolean;
  get(key: K): V | undefined;
  keys(): Iterable<K>;
  values(): Iterable<V>;
  entries(): Iterable<[K, V]>;
  getSnapshot(): C;
  next(value: C, options?: IObservableNextOptions): void;
  subscribe(subscriber: ISubscriber<C>): IUnsubscribable;
  observeKey(key: K): IObservable<V | undefined>;
  subscribeKey(key: K, subscriber: ISubscriber<V | undefined>): IUnsubscribable;
  protected _notify(): void;
}
declare class DisposedObservable<T> implements IObservable<T> {
  readonly equals: IEquals<T>;
  protected _value: T;
  constructor(defaultValue: T, options?: IObservableOptions<T>);
  get disposed(): boolean;
  dispose(): void;
  registerDisposable<T extends IDisposable>(disposable: T): void;
  getSnapshot(): T;
  next(value: T, options?: IObservableNextOptions): void;
  subscribe(subscriber: ISubscriber<T>): IUnsubscribable;
}
declare class ObservableMap<K, V, C extends IImmutableMap<K, V>> extends ObservableCollection<K, V, C> implements IObservableMap<K, V, C> {
  set(key: K, value: V, options?: IObservableNextOptions): void;
  delete(key: K, options?: IObservableNextOptions): void;
  deleteAll(keys: Iterable<K>, options?: IObservableNextOptions): void;
  merge(entries: Iterable<[K, V]>, options?: IObservableNextOptions): void;
}
declare class ObservableSet<V, C extends IImmutableSet<V>> extends ObservableCollection<V, V, C> implements IObservableSet<V, C> {
  add(value: V, options?: IObservableNextOptions): void;
  addAll(values: Iterable<V>, options?: IObservableNextOptions): void;
  delete(value: V, options?: IObservableNextOptions): void;
  deleteAll(values: Iterable<V>, options?: IObservableNextOptions): void;
}
type IValuePatcher<T> = (prev: T) => T;
interface IState<T> extends IComputed<T> {
  /**
   *
   * @param nextValue
   */
  next(nextValue: T): void;
  /**
   *
   * @param patch
   */
  setState(patch: IValuePatcher<T>): void;
  /**
   *
   * @param patch
   */
  updateState(patch: T | IValuePatcher<T>): void;
}
declare class State<T> extends Observable<T> implements IState<T> {
  readonly getSnapshot: () => T;
  readonly getServerSnapshot: () => T;
  readonly setState: (patch: IValuePatcher<T>) => void;
  readonly updateState: (patch: T | IValuePatcher<T>) => void;
  readonly subscribeStateChange: (onStateChange: () => void) => (() => void);
}
interface IViewModelTicker {
  readonly keys: ReadonlyArray<string>;
  readonly ticker: ISubscribable<number> & IDisposable;
}
interface IViewModel extends IBatchDisposable {
  /**
   * Create a tick observable to watch changes in keys of this.
   * @param keys
   */
  ticker<K extends IObservableKey<this>>(keys: K[] | undefined): Readonly<IViewModelTicker>;
}
declare abstract class ViewModel extends BatchDisposable implements IViewModel {
  protected readonly _tickerMap: Map<string, IViewModelTicker>;
  constructor();
  dispose(): void;
  ticker<K extends IObservableKey<this>>(observableKeys: K[]): Readonly<IViewModelTicker>;
}
export { Computed, DisposedObservable, IComputed, IImmutableCollection, IImmutableMap, IImmutableSet, IObservableCollection, IObservableCollectionOptions, IObservableMap, IObservableSet, IState, IValuePatcher, IViewModel, IViewModelTicker, ObservableCollection, ObservableMap, ObservableSet, State, ViewModel };