fluids
Version:
Glue layer for reactivity
92 lines (91 loc) • 4.24 kB
TypeScript
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<any>;
/**
* 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<E extends FluidEvent>(observer: FluidObserver<E>, event: E): void;
declare function callFluidObserver(observer: FluidObserver, event: UnsafeFluidEvent): void;
/** Send an event to all observers. */
declare function callFluidObservers<E extends FluidEvent>(target: FluidObservable<E>, event: E): void;
declare function callFluidObservers(target: object, event: UnsafeFluidEvent): void;
declare type GetFluidValue = {
<T>(target: T | FluidValue<T>): T;
};
declare type GetFluidObservers = {
<E extends FluidEvent>(target: FluidObservable<E>): ReadonlySet<FluidObserver<E>> | null;
(target: object): ReadonlySet<FluidObserver> | null;
};
/** An event from a `fluids` compatible object */
export interface FluidEvent<T extends object = any> {
type: string;
parent: T;
}
/** An unknown event from a `fluids` compatible object */
export interface UnsafeFluidEvent<T extends object = any> extends FluidEvent<T> {
[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<FooEvent> {}
*
* 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<E extends FluidEvent = any> {
[$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<T = any> {
constructor(get?: () => T);
/** Get the current value. */
protected get?(): T;
/** Called after an observer is added. */
protected observerAdded?(count: number, observer: FluidObserver<any>): void;
/** Called after an observer is removed. */
protected observerRemoved?(count: number, observer: FluidObserver<any>): void;
}
/** Extract the value type from a `FluidValue` type */
export declare type FluidUnwrap<T> = T extends FluidValue<infer U> ? U : T;
/** Extract the event type from a `FluidObservable` type */
export declare type FluidEvents<T> = T extends FluidObservable<infer U> ? U : never;
/** An observer of `FluidValue` objects. */
export declare type FluidObserver<E extends UnsafeFluidEvent = UnsafeFluidEvent> = {
eventObserved(event: E): void;
} | {
(event: E): void;
};
/** Add the `FluidValue` type to every property. */
export declare type FluidProps<T> = T extends object ? {
[P in keyof T]: T[P] | FluidValue<Exclude<T[P], void>>;
} : unknown;
/** Remove the `FluidValue` type from every property. */
export declare type StaticProps<T extends object> = {
[P in keyof T]: FluidUnwrap<T[P]>;
};
/** Define the getter called by `getFluidValue`. */
declare const setFluidGetter: (target: object, get: () => any) => any;
/** Observe a `fluids`-compatible object. */
declare function addFluidObserver<E extends FluidEvent>(target: FluidObservable<E>, observer: FluidObserver<E>): typeof observer;
declare function addFluidObserver<E extends UnsafeFluidEvent>(target: object, observer: FluidObserver<E>): typeof observer;
/** Stop observing a `fluids`-compatible object. */
declare function removeFluidObserver<E extends FluidEvent>(target: FluidObservable<E>, observer: FluidObserver<E>): void;
declare function removeFluidObserver<E extends UnsafeFluidEvent>(target: object, observer: FluidObserver<E>): void;