declare const $observers: unique symbol; export { FluidValue, hasFluidValue, getFluidValue, getFluidObservers, callFluidObserver, callFluidObservers, setFluidGetter, addFluidObserver, removeFluidObserver, }; /** Returns true if `arg` can be observed. */ declare const hasFluidValue: (arg: any) => arg is FluidValue; /** * Get the current value. * If `arg` is not observable, `arg` is returned. */ declare const getFluidValue: GetFluidValue; /** Get the current observer set. Never mutate it directly! */ declare const getFluidObservers: GetFluidObservers; /** Send an event to an observer. */ declare function callFluidObserver(observer: FluidObserver, event: E): void; declare function callFluidObserver(observer: FluidObserver, event: UnsafeFluidEvent): void; /** Send an event to all observers. */ declare function callFluidObservers(target: FluidObservable, event: E): void; declare function callFluidObservers(target: object, event: UnsafeFluidEvent): void; declare type GetFluidValue = { (target: T | FluidValue): T; }; declare type GetFluidObservers = { (target: FluidObservable): ReadonlySet> | null; (target: object): ReadonlySet | null; }; /** An event from a `fluids` compatible object */ export interface FluidEvent { type: string; parent: T; } /** An unknown event from a `fluids` compatible object */ export interface UnsafeFluidEvent extends FluidEvent { [key: string]: any; } /** * A source of `FluidEvent` objects that can be observed with * the `addFluidObserver` function. * * Use "interface merging" to mark your class as observable: * * class Foo {} * interface Foo extends FluidObservable {} * * Once that's done, you get the following benefits: * - observers added with `addFluidObserver` are type-checked * - events passed to `callFluidObservers` are type-checked */ export interface FluidObservable { [$observers]?: E | null; } /** * `FluidValue` objects can be unwrapped with `getFluidValue` to access * their current value. * * Libraries may support observable values by handling `FluidValue` objects * in their functions and classes. */ declare abstract class FluidValue { constructor(get?: () => T); /** Get the current value. */ protected get?(): T; /** Called after an observer is added. */ protected observerAdded?(count: number, observer: FluidObserver): void; /** Called after an observer is removed. */ protected observerRemoved?(count: number, observer: FluidObserver): void; } /** Extract the value type from a `FluidValue` type */ export declare type FluidUnwrap = T extends FluidValue ? U : T; /** Extract the event type from a `FluidObservable` type */ export declare type FluidEvents = T extends FluidObservable ? U : never; /** An observer of `FluidValue` objects. */ export declare type FluidObserver = { eventObserved(event: E): void; } | { (event: E): void; }; /** Add the `FluidValue` type to every property. */ export declare type FluidProps = T extends object ? { [P in keyof T]: T[P] | FluidValue>; } : unknown; /** Remove the `FluidValue` type from every property. */ export declare type StaticProps = { [P in keyof T]: FluidUnwrap; }; /** Define the getter called by `getFluidValue`. */ declare const setFluidGetter: (target: object, get: () => any) => any; /** Observe a `fluids`-compatible object. */ declare function addFluidObserver(target: FluidObservable, observer: FluidObserver): typeof observer; declare function addFluidObserver(target: object, observer: FluidObserver): typeof observer; /** Stop observing a `fluids`-compatible object. */ declare function removeFluidObserver(target: FluidObservable, observer: FluidObserver): void; declare function removeFluidObserver(target: object, observer: FluidObserver): void;