interface HandleMethods { destroy?(): void; dispose?(): void; remove?(): void; unregister?(): void; unsubscribe?(): void; } type RequiredKey = Required> & T; /** * Type of supported cleanup handles. * * Handle must implement one of the following methods: * - destroy() * - dispose() * - remove() * - unregister() * - unsubscribe() */ type Handle = RequiredKey | RequiredKey | RequiredKey | RequiredKey | RequiredKey | null | undefined; /** Type of the rebind callback supported by {@link Observers} and {@link ObserverGroup}. */ type RebindCallback = (self: Observers | ObserverGroup, ...args: unknown[]) => void; /** * ObserverGroups contain a series of handles. */ interface ObserverGroup { /** * Add observer handles. */ add(...handles: Handle[]): ObserverGroup; /** * Removes observer handles. */ remove(...handles: Handle[]): ObserverGroup; /** * True if no observer is registered. */ isEmpty(): boolean; /** * The amount of registered observers. */ count(): number; /** * Invokes and removes all handles of this group. */ clean(): ObserverGroup; /** * Sets the rebind callback. */ onRebind(rebind: RebindCallback): ObserverGroup; /** * Invokes the rebind callback. */ bind(...args: unknown[]): ObserverGroup; } /** * Observers encapsulates a collection of connections to event emitters, like Evented, Mutable, Watches and the * like. * It therefor helps you to manage multiple event connections by grouping them - e.g. for cleaning all connections at * once. */ interface Observers { /** * Cleans any registered observer. * Or, if names are defined, then only the given groups are cleaned. */ clean(...names: string[]): void; /** * Destroys this Observable. * It works like clean with the addition of clearing all set rebind functions. */ destroy(): void; /** * Gets a group to scope observers. */ group(name: string): ObserverGroup; /** * Add observer handles to default group. */ add(...handles: Handle[]): Observers; /** * Removes observer handles from default group. */ remove(...handles: Handle[]): Observers; /** * True if no observer is registered at default group. */ isEmpty(): boolean; /** * The amount of registered observers at default group. */ count(): number; /** * True if no observer is registered in any group. */ isAllEmpty(): boolean; /** * The amount of registered observers in all groups. */ countAll(): number; /** * Registers the rebind callback, which will be executed if bind is called. * This is an alternative to the constructor parameter 'rebind'. */ onRebind(rebind: RebindCallback): Observers; /** * Binds to new target observables, by invoking the rebind callback. * See the class description for a sample. */ bind(...args: unknown[]): Observers; } /** Options for the {@link createObservers} function. */ interface ObserverOptions { rebind?: RebindCallback; } /** * Observers encapsulates a collection of connections to event emitters, like Evented, Mutable, Watches and the * like. * It therefor helps you to manage multiple event connections by grouping them - e.g. for cleaning all connections at * once. * * @param options optional parameters to customize the creation * * @example _track a event connection_ * ```ts * import Observers from "apprt-core/Observers"; * import { Evented } from "apprt-core/Events"; * * const eventSource = new Evented(); * const observers = Observers(); * // track connection to eventSource * observers.add(eventSource.on("event", ()=>{ ... })); * // if the connection needs to be cleaned call * observers.clean(); * ``` * * @example _group event connections_ * ```ts * const eventSourceA = new Evented(); * const eventSourceB = new Evented(); * const observers = Observers(); * // track connection to eventSourceA, but in group "a" * observers.group("a").add(eventSourceA.on("event", ()=>{ ... })); * // track connection to eventSourceB, but in group "b" * observers.group("b").add(eventSourceB.on("event", ()=>{ ... })); * // if "a" is not longer required * observers.group("a").clean(); * // if "b" is not longer required (shows alternative) * observers.clean("b"); * // if none of the connections are required anymore clean all * observers.clean(); * ``` * * @example _use the rebind functionality_ * ```ts * // The bind/rebind functionality helps to encapsulate the code to connect to an observable. * // When the observable target changes a simple call to 'bind' * // rexecutes the connection code and clears the old connection. * * import createObservers, { Observers } from "apprt-core/Observers"; * import { Evented } from "apprt-core/Events"; * * interface CustomEvents { * "changed": boolean * } * * class Controller { * private observers: Observers | undefined; * private events: any[] = []; * constructor() { * this.events = []; * this.observers = createObservers({ * // rebind is executed if Observers.bind is called, and used to reconnect to a new source instance * rebind: (observers, source) => { * const eventSource = source as Evented; * observers.add(eventSource.on("change", (evt) => { * this.events.push(evt); * })); * } * }); * } * connect(eventSource: Evented) { * // observe new event source * this.observers!.bind(eventSource); * } * disconnect() { * // disconnect from event source * this.observers!.clean(); * } * } * ``` */ declare function createObservers(options?: ObserverOptions): Observers; export { createObservers, createObservers as default }; export type { Handle, HandleMethods, ObserverGroup, ObserverOptions, Observers, RebindCallback };