UNPKG

@ue-too/board

Version:

<h1 align="center"> uē-tôo </h1> <p align="center"> pan, zoom, rotate, and more with your html canvas. </p>

198 lines (197 loc) 6.28 kB
/** * Type definition for an observer callback function. * * @typeParam T - Tuple type of arguments passed to the observer * * @remarks * Observers are callbacks that get notified when an Observable emits data. * The generic type T is a tuple representing the arguments passed to the callback. * * @example * ```typescript * // Observer that receives a single string * const stringObserver: Observer<[string]> = (message) => { * console.log(message); * }; * * // Observer that receives multiple arguments * const multiObserver: Observer<[number, string, boolean]> = (num, str, flag) => { * console.log(num, str, flag); * }; * ``` * * @category Observable Pattern */ export type Observer<T extends any[]> = (...data: T) => void; /** * Options for subscribing to an Observable. * * @property signal - Optional AbortSignal for automatic unsubscription * * @remarks * Subscription options allow for automatic cleanup of subscriptions using * the AbortController API. When the signal is aborted, the subscription * is automatically removed. * * @example * ```typescript * const controller = new AbortController(); * * observable.subscribe( * (data) => console.log(data), * { signal: controller.signal } * ); * * // Later, abort to unsubscribe * controller.abort(); * ``` * * @category Observable Pattern */ export interface SubscriptionOptions { signal?: AbortSignal; } /** * Interface for the Observable pattern implementation. * * @typeParam T - Tuple type of data emitted to observers * * @remarks * Observables allow multiple observers to subscribe and receive notifications * when data is emitted. This is the pub-sub pattern for event handling. * * Implementations can be synchronous or asynchronous: * - {@link SynchronousObservable}: Notifies observers immediately * - {@link AsyncObservable}: Notifies observers via microtasks * * @category Observable Pattern */ export interface Observable<T extends any[]> { subscribe(observer: Observer<T>, options?: SubscriptionOptions): () => void; notify(...data: T): void; } /** * Asynchronous Observable implementation that notifies observers via microtasks. * * @typeParam T - Tuple type of data emitted to observers * * @remarks * This Observable uses `queueMicrotask` to defer observer notifications, * ensuring they execute after the current execution context completes but * before the next task. This prevents recursive notification issues and * allows the notifier to complete before observers run. * * Use AsyncObservable when: * - You want to prevent recursion issues in notifications * - Observer execution should not block the notifier * - You need guaranteed async behavior * * @example * ```typescript * const observable = new AsyncObservable<[string]>(); * * observable.subscribe((message) => { * console.log('Observer received:', message); * }); * * console.log('Before notify'); * observable.notify('Hello'); * console.log('After notify'); * * // Output: * // Before notify * // After notify * // Observer received: Hello * ``` * * @category Observable Pattern * @see {@link SynchronousObservable} for synchronous notifications */ export declare class AsyncObservable<T extends any[]> implements Observable<T> { private observers; /** * Subscribes an observer to receive notifications. * * @param observer - The callback function to be notified * @param options - Optional subscription options including AbortSignal * @returns Unsubscribe function to remove this observer * * @remarks * If an AbortSignal is provided and is already aborted, the observer * is not added and the returned unsubscribe function is a no-op. */ subscribe(observer: Observer<T>, options?: SubscriptionOptions): () => void; /** * Notifies all observers with the provided data asynchronously. * * @param data - The data to pass to all observers * * @remarks * Each observer is called via `queueMicrotask`, ensuring async execution. * This method returns immediately; observers run later in the event loop. */ notify(...data: T): void; } /** * Synchronous Observable implementation that notifies observers immediately. * * @typeParam T - Tuple type of data emitted to observers * * @remarks * This Observable calls all observers synchronously and immediately when * `notify()` is called. The notify method doesn't return until all observers * have executed. * * Use SynchronousObservable when: * - You need immediate, guaranteed execution of observers * - Observer execution order matters and must be predictable * - You're in a performance-critical path (no async overhead) * * Caution: Can lead to recursion issues if observers trigger notifications. * * @example * ```typescript * const observable = new SynchronousObservable<[string]>(); * * observable.subscribe((message) => { * console.log('Observer received:', message); * }); * * console.log('Before notify'); * observable.notify('Hello'); * console.log('After notify'); * * // Output: * // Before notify * // Observer received: Hello * // After notify * ``` * * @category Observable Pattern * @see {@link AsyncObservable} for asynchronous notifications */ export declare class SynchronousObservable<T extends any[]> implements Observable<T> { private observers; /** * Subscribes an observer to receive notifications. * * @param observer - The callback function to be notified * @param options - Optional subscription options including AbortSignal * @returns Unsubscribe function to remove this observer * * @remarks * If an AbortSignal is provided and is already aborted, the observer * is not added and the returned unsubscribe function is a no-op. */ subscribe(observer: Observer<T>, options?: SubscriptionOptions): () => void; /** * Notifies all observers with the provided data synchronously. * * @param data - The data to pass to all observers * * @remarks * Each observer is called immediately in order. This method blocks until * all observers have completed execution. */ notify(...data: T): void; }