API reference
Every public class, method, and event in @codexo/exojs. Generated from source.
classSignal
Lightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or Signal.once, removed with Signal.remove, and notified with Signal.dispatch. `Args` is the tuple of arguments passed to listeners - type-checked end to end so a `new Signal<[number, string]>()` enforces both `dispatch(1, 'x')` and the listener signature `(n: number, s: string) => ...`. Handlers are stored as direct function references (no wrapper objects). `dispatch` tracks re-entrancy with a depth counter instead of a snapshot copy, so no allocation occurs per dispatch and a listener that dispatches this same Signal again nests safely. Handlers added or removed during dispatch take effect on the next call, never the dispatch in progress - both `add` and `remove` mid-dispatch defer their mutation until after the outermost dispatch finishes, and reconcile per handler (the *last* `add`/`remove` requested for a given handler during one outermost dispatch wins, resolved against whether `_handlers` - never mutated while any dispatch is in progress - actually contained that handler when dispatch started) rather than each call consulting the other's un-flushed queue as if it were already-applied state. Signal.destroy is safe to call from inside a listener: it terminates the dispatch that triggered it (and every dispatch nested inside it on the same call stack) immediately, without invoking any further listener at any nesting level.
import { Signal } from '@codexo/exojs'Lightweight typed event emitter. Each `Signal` represents one named notification channel (e.g. `onResize`, `onFrame`). Listeners are added with Signal.add or Signal.once, removed with Signal.remove, and notified with Signal.dispatch.
`Args` is the tuple of arguments passed to listeners - type-checked end to end so a `new Signal<[number, string]>()` enforces both `dispatch(1, 'x')` and the listener signature `(n: number, s: string) => ...`.
Handlers are stored as direct function references (no wrapper objects). `dispatch` tracks re-entrancy with a depth counter instead of a snapshot copy, so no allocation occurs per dispatch and a listener that dispatches this same Signal again nests safely. Handlers added or removed during dispatch take effect on the next call, never the dispatch in progress - both `add` and `remove` mid-dispatch defer their mutation until after the outermost dispatch finishes, and reconcile per handler (the *last* `add`/`remove` requested for a given handler during one outermost dispatch wins, resolved against whether `_handlers` - never mutated while any dispatch is in progress - actually contained that handler when dispatch started) rather than each call consulting the other's un-flushed queue as if it were already-applied state. Signal.destroy is safe to call from inside a listener: it terminates the dispatch that triggered it (and every dispatch nested inside it on the same call stack) immediately, without invoking any further listener at any nesting level.
new(): Signal<Args>add(handler: SignalHandler<Args>): thisclear(): thisdestroy(): voiddispatch(params: Args): thisdispatchIsolated(onError: (error: unknown) => void, params: Args): thishas(handler: SignalHandler<Args>): booleanonce(handler: SignalHandler<Args>): thisremove(handler: SignalHandler<Args>): thiscount: number