/** * @license * Copyright 2022-2024 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ import "../polyfills/disposable.js"; import { MaybePromise } from "./Promises.js"; /** * A callback function for observables. * * The observer return value effects how an {@link Observable} emits: * * - If an observer returns undefined the {@link Observable} invokes the next observer immediately. * * - If an observer returns a {@link Promise}, the {@link Observable} awaits the return value then continues as * described here. The emitter must then await the {@link Promise} returned by {@link Observable.emit}. * * - Any other return value is returned by {@link Observable.emit} and subsequent observers do not see emission. * * @param payload a list of arguments to be emitted */ export interface Observer { (...payload: T): MaybePromise; [observant]?: boolean; } /** * A discrete event that may be monitored via callback. Could call it "event" but that could be confused with Matter * cluster events and/or DOM events. * * @param T arguments, should be a named tuple */ export interface Observable extends AsyncIterable, PromiseLike { /** * Notify observers. */ emit(...args: T): R | undefined; /** * Add an observer. */ on(observer: Observer): void; /** * Remove an observer. */ off(observer: Observer): void; /** * Add an observer that emits once then is unregistered. */ once(observer: Observer): void; /** * True if there is at least one observer registered. */ isObserved: boolean; /** * Determine whether an observer is registered. */ isObservedBy(observer: Observer): boolean; /** * This flag indicates whether the observable is asynchronous. Any observable that accepts promise returns may * be asynchronous but this information is not available at runtime unless you specify here, typically via * {@link AsyncObservable}. */ isAsync?: boolean; /** * Observable supports standard "for await (const value of observable"). * * Using an observer in this manner limits your listener to the first parameter normally emitted and your observer * cannot return a value. */ [Symbol.asyncIterator](): AsyncIterator; /** * Release resources associated with the observable. */ [Symbol.dispose](): void; } /** * An observer may designate itself as "not observant" for the purposes of {@link Observable.isObserved} by returning * false from this field. */ export declare const observant: unique symbol; /** * An {@link Observable} that explicitly supports asynchronous observers. */ export interface AsyncObservable extends Observable> { isAsync: true; } export type ObserverErrorHandler = (error: Error, observer: Observer) => void; /** * A concrete {@link Observable} implementation. */ export declare class BasicObservable implements Observable { #private; constructor(errorHandler?: ObserverErrorHandler, isAsync?: boolean); [Symbol.dispose](): void; get isAsync(): boolean | undefined; set isAsync(isAsync: boolean | undefined); get isObserved(): boolean; isObservedBy(observer: Observer): boolean; emit(...payload: T): R | undefined; on(observer: Observer): void; off(observer: Observer): void; once(observer: Observer): void; then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): PromiseLike; [Symbol.asyncIterator](): AsyncIterator; } /** * Create an {@link Observable}. */ export declare const Observable: { new (errorHandler?: ObserverErrorHandler): Observable; (errorHandler?: ObserverErrorHandler): Observable; }; /** * Create an {@link AsyncObservable} that explicitly supports asynchronous results */ export declare const AsyncObservable: { new (errorHandler?: ObserverErrorHandler): AsyncObservable; (errorHandler?: ObserverErrorHandler): AsyncObservable; }; /** * A set of observables. You can bind events using individual observables or the methods emulating a subset Node's * EventEmitter. * * To maintain type safety, implementers define events as observable child properties. */ export declare class EventEmitter { emit>(this: This, name: N, ...payload: EventEmitter.PayloadOf): void; addListener>(this: This, name: N, handler: EventEmitter.ObserverOf): void; removeListener>(this: This, name: N, handler: EventEmitter.ObserverOf): void; get eventNames(): string[]; [Symbol.dispose](): void; } export declare namespace EventEmitter { /** * Legal event names. If there are no events defined, assume this is an * untyped instance and allow any argument. */ type NamesOf = [EventNames] extends [never] ? string : EventNames; type EventNames = string & keyof { [K in keyof This as This[K] extends Observable ? K : never]: true; }; /** * Arguments for an event. If there are no events defined, assume this is * an untyped emitter and allow any argument. */ type PayloadOf = [EventPayload] extends [never] ? any[] : EventPayload; type EventPayload = This extends { [K in E]: Observable; } ? T : never; type ObserverOf = Observable>; } /** * An {@link Observable} that proxies to another {@link Observable}. * * Emits emitted here instead emit on the target {@link Observable}. Events emitted on the target emit locally via * a listener installed by the proxy. * * This is useful for managing a subset of {@link Observer}s for an {@link Observable}. * * Note that this "proxy" acts as a proxy but is not a JS {@link Proxy}. */ export declare class ObservableProxy extends BasicObservable { #private; constructor(target: Observable); [Symbol.dispose](): void; get isAsync(): boolean | undefined; get isObserved(): boolean; emit: (...payload: any) => any | undefined; } //# sourceMappingURL=Observable.d.ts.map