import { Equal } from './Types.js'; /** Valid event names for the given events specifier. */ type EventNames = keyof Events & string; type Params = Equal extends true ? [] | [value: unknown] : Equal extends true ? [] | [value: T] : [value: T]; /** * Type of an event listener. * @typeParam T the type of the event value. If `T` is `void`, no value will be available. */ type EventCallback = (...values: Params) => void; /** A handle that allows de-registration from events. */ interface EventHandle { /** * Stops listening for the event associated with this handle. */ remove(): void; } /** Base class which provides default on/emit functions to child classes. */ interface EventedConstructor { /** Creates a new Evented instance. */ new (): Evented; } /** The signature of {@link Evented | Evented's} `on(...)` method. */ interface EventedOn { /** * Register event listener for specific events. * * @param eventName name of the event * @param callback the event handler callback will be invoked when the event has been emitted * @returns a handle to unregister from the event */ >(eventName: Name, callback: EventCallback): EventHandle; /** * Register event listener for any event. * * @param eventName must be `"*"` for this overload * @param callback the event handler callback will be invoked when any event has been emitted * @returns a handle to unregister from the events */ (eventName: "*", callback: EventCallback]>): EventHandle; /** * Register event listener for the events listed in `eventName`. * Comma separated event names are possible, for example `"eventA,eventB"`. * * @param eventName the event name or list of names * @param callback the event handler callback * @returns a handle to unregister from the event(s) */ (eventName: string | string[], callback: EventCallback): EventHandle; } /** * Like `Evented`, but only specifies the `on` function. * This is useful if clients of a class should not be able to invoke the `emit()` function * themselves. */ interface EventSource { on: EventedOn; } /** * A helper object that establishes TypeScript support for arbitrary event targets. * * Internally, the object simply calls the free functions `on`, `emit` or `emitSync`. */ interface TypedEvents { /** * Register event listener for specific events. * * @param target the object used as an event channel * @param eventName name of the event * @param callback the event handler callback will be invoked when the event has been emitted * @returns a handle to unregister from the event * * @see {@link on} */ on>(target: any, eventName: Name, callback: EventCallback): EventHandle; /** * Register event listener for any event. * * @param target the object used as an event channel * @param eventName must be `"*"` for this overload * @param callback the event handler callback will be invoked when any event has been emitted * @returns a handle to unregister from the events * * @see {@link on} */ on(target: any, eventName: "*", callback: EventCallback]>): EventHandle; /** * Register event listener for the events listed in `eventName`. * Comma separated event names are possible, for example `"eventA,eventB"`. * * @param target the object used as an event channel * @param eventName the event name or list of names * @param callback the event handler callback * @returns a handle to unregister from the event(s) * * @see {@link on} */ on(target: any, eventName: string | string[], callback: EventCallback): EventHandle; /** * Emits an event. * All associated event listeners registered for the given event name will be invoked asynchronously. * * @param target the object used as an event channel * @param eventName The name of the event. * @param value * The event value. Passed to all event listeners. * Note: no value can be passed if the event type is `void`. * * @see {@link emit} */ emit>(target: any, eventName: Name, ...value: Params): void; /** * Emits a synchronous event. * All associated event listeners registered for the given event name will be invoked synchronously. * * @param target the object used as an event channel * @param eventName The name of the event. * @param value * The event value. Passed to all event listeners. * Note: no value can be passed if the event type is `void`. * * @see {@link emitSync} */ emitSync>(target: any, eventName: Name, ...value: Params): void; } /** * Creates a {@link TypedEvents} instance that can be used to enforce event names and signatures via TypeScript. * * Internally, the object simply calls the free functions `on`, `emit` or `emitSync`. * * @example * * ```ts * * interface MyEvents { * eventName: number; * } * * // Create a shared helper object (once, for example at module scope): * const MY_EVENTS = createTypedEvents(); * * // The following expressions have type hints: * MY_EVENTS.on(target, ...); * MY_EVENTS.emit(target, ...); * ``` */ declare function createTypedEvents(): TypedEvents; interface Constructor { new (...args: Args): T; } type EventIdentifier = string | symbol; /** * Register event listener. * @param target the channel object. * @param eventName event name(s) * @param listener event listener * @returns handle with `remove` method * @example * ```ts * // object as event channel * const channel = {}; * // connect to event "changed" * on(channel, "changed", (msg)=> console.log(msg)); * * // it is possible to register to multiple events using ',' * on(channel, "changed,click", (msg)=> console.log(msg)); * * // it is possible to register to any events using '*' * on(channel, "*", (msg)=> console.log(msg)); * * // on provides handle to unregister * const handle = on(channel, "changed", (msg)=> console.log(msg)); * // unregister using "remove" * handle.remove(); * ``` */ declare function on(target: any, eventName: EventIdentifier | EventIdentifier[], listener: (value: T) => void): EventHandle; /** * Emits an event. Note events are always fired async. * @param target the channel object. * @param eventName event name * @param event the event arguments * @example * ```ts * // object as event channel * const channel = {}; * * // connect to event "changed" * on(channel, "changed", (msg)=> console.log(msg)); * * // fire changed event * emit(channel, "changed", "my event msg"); * ``` */ declare function emit(target: any, eventName: EventIdentifier, ...event: [] | [T]): void; /** * Emits an event synchronous. * @param target the channel object. * @param eventName event name * @param event the event arguments * @example * ```ts * // object as event channel * const channel = {}; * * // connect to event "changed" * on(channel, "changed", (msg)=> console.log(msg)); * * // fire changed event * emitSync(channel, "changed", "my event msg"); * ``` */ declare function emitSync(target: any, eventName: EventIdentifier, ...event: [] | [unknown]): void; /** * Cleans any event channel created on the given target. Un-registers any event listener. * @param target the channel object. * @example * ```ts * // object as event channel * const channel = {}; * * // connect to event "changed" * on(channel, "changed", (msg)=> console.log(msg)); * * // clean channel * cleanup(channel); * // the listener registered by on will never receive events. * ``` */ declare function cleanup(target: any): void; /** * Base class which provides default on/emit functions to child classes. * * Events are specified by providing a type or interface as a type parameter. * The type parameter should list the supported event names and the event value type (or void * if there is no value). * * @example * ```typescript * interface MyEvents { * numberChanged: number; // event handlers will receive a number value * print: void; // event handlers will receive no value * } * * class MyClass extends Evented { * // ... * } * * const object = new MyClass(); * object.on("numberChanged", (value) => { * // value is a number * }); * ``` */ interface Evented { on: EventedOn; /** * Emits an event. * All associated event listeners registered for the given event name will be invoked asynchronously. * * @param eventName The name of the event. * @param value * The event value. Passed to all event listeners. * Note: no value can be passed if the event type is `void`. */ emit>(eventName: Name, ...value: Params): void; } /** Base class which provides default on/emit functions to child classes. */ declare const Evented: EventedConstructor; /** * Evented Mixin function. Creates new clazz which inherits from a given clazz and extends it with on/emit * functions. * @param Base class to inherit from. * @returns class which inherits from `Base`. * @example * ```ts * import { EventedMixin } from "apprt-core/Events"; * * const MyClass = EventedMixin(class { * trigger() { * (this as any).emit("changed", true); * } * }); * const myClassInstance = new MyClass(); * myClassInstance.trigger(); * ``` */ declare function EventedMixin>(Base: BaseType): Constructor & Evented, ConstructorParameters>; export { Evented, EventedMixin, EventedMixin as Evented_Mixin, cleanup, createTypedEvents, emit, emitSync, on }; export type { EventCallback, EventHandle, EventNames, EventSource, EventedConstructor, EventedOn, TypedEvents };