/** * Type definitions for TC39 Signals API * * These types align with the signal-polyfill implementation and TC39 proposal. * Note: Signal is Stage 1 - API may change in future spec updates. * * @see {@link https://github.com/tc39/proposal-signals | TC39 Signals Proposal} */ /** * Options for creating Signal.State * * @param equals - Optional custom equality function for determining if value changed * * @example * ```typescript * import { Signal } from "@xmachines/play-signals"; * import type { SignalOptions } from "@xmachines/play-signals"; * * const options: SignalOptions = { * equals: (a, b) => a === b * }; * const count = new Signal.State(0, options); * ``` */ export interface SignalOptions { /** * Custom equality function for determining if value changed * @param a - Previous value * @param b - New value * @returns true if values are equal (no notification needed) */ equals?: (a: T, b: T) => boolean; } /** * Writable state signal holding a single reactive value * * Signal.State is the fundamental primitive for reactive state. Calling `get()` within * a computed signal or watcher automatically tracks the state as a dependency. Calling * `set()` notifies all dependent computations and watchers. * * @example * ```typescript * import { Signal } from "@xmachines/play-signals"; * * const name = new Signal.State('Alice'); * console.log(name.get()); // 'Alice' * name.set('Bob'); * console.log(name.get()); // 'Bob' * ``` */ export interface SignalState { /** * Read current value and track as dependency * * @returns Current value of the signal */ get(): T; /** * Write new value and notify watchers if changed * * @param value - New value to set */ set(value: T): void; } /** * Options for creating Signal.Computed * * @param equals - Optional custom equality function for memoization * * @example * ```typescript * import { Signal } from "@xmachines/play-signals"; * import type { ComputedOptions } from "@xmachines/play-signals"; * * const options: ComputedOptions = { * equals: (a, b) => a.toLowerCase() === b.toLowerCase() * }; * ``` */ export interface ComputedOptions { /** * Custom equality function for memoization */ equals?: (a: T, b: T) => boolean; } /** * Lazily-evaluated, memoized computed signal * * Signal.Computed automatically tracks dependencies when its callback is executed. * The computation is memoized and only re-runs when dependencies change. This enables * automatic dependency tracking without manual subscription management. * * @example * ```typescript * import { Signal } from "@xmachines/play-signals"; * * const count = new Signal.State(0); * const doubled = new Signal.Computed(() => count.get() * 2); * * console.log(doubled.get()); // 0 * count.set(5); * console.log(doubled.get()); // 10 (recomputed) * console.log(doubled.get()); // 10 (memoized, not recomputed) * ``` */ export interface SignalComputed { /** * Read computed value (recalculates only if dependencies changed) * * @returns Computed value based on current dependencies */ get(): T; } /** * Notification callback for Signal.subtle.Watcher * * Invoked when watched signals change. Use microtask batching pattern to coalesce * rapid updates (see signal-polyfill README for best practices). * * @example * ```typescript * import { Signal } from "@xmachines/play-signals"; * * const notify: WatcherNotify = () => { * queueMicrotask(() => { * const pending = watcher.getPending(); * // Process pending signal changes * }); * }; * const watcher = new Signal.subtle.Watcher(notify); * ``` */ export type WatcherNotify = () => void; /** * Watcher for observing signal changes and scheduling effects * * Signal.subtle.Watcher enables observing multiple signals and batching updates. * This is the low-level primitive used by frameworks to implement reactive effects. * * @example * ```typescript * import { Signal } from "@xmachines/play-signals"; * * const count = new Signal.State(0); * const doubled = new Signal.Computed(() => count.get() * 2); * * const watcher = new Signal.subtle.Watcher(() => { * queueMicrotask(() => { * const pending = watcher.getPending(); * console.log('Signals changed:', pending.length); * }); * }); * * watcher.watch(count); * watcher.watch(doubled); * * count.set(5); // Notification scheduled via microtask * ``` */ export interface SignalWatcher { /** * Start watching a signal for changes * * @param signal - Signal to observe (State or Computed) */ watch(signal: SignalState | SignalComputed): void; /** * Stop watching a signal * * @param signal - Signal to stop observing */ unwatch(signal: SignalState | SignalComputed): void; /** * Get signals that changed since last check * * @returns Array of signals that have pending updates */ getPending(): Array | SignalComputed>; } //# sourceMappingURL=types.d.ts.map