UNPKG

@resk/core

Version:

An innovative TypeScript framework that empowers developers to build applications with a fully decorator-based architecture for efficient resource management. By combining the power of decorators with a resource-oriented design, DecorRes enhances code cla

317 lines (316 loc) 13.3 kB
/** * @interface IObservableCallback * Represents the callback options for observable events. * * This type defines a function that can be used as a callback for observable events. * It accepts a variable number of arguments of any type and returns a value of any type. * * Callbacks of this type can be utilized in various event-driven scenarios, allowing * flexibility in the number and types of parameters passed to the callback. * * @example * ```typescript * const callback: IObservableCallback = (arg1: string, arg2: number) => { * console.log(arg1, arg2); // Outputs the string and number passed to the callback * }; * * // Invoking the callback with different types of arguments * callback("Event triggered", 42); // Outputs: Event triggered 42 * callback("Another event", 100); // Outputs: Another event 100 * ``` */ export type IObservableCallback = (...args: any[]) => any; /** * Represents a collection of observable callbacks mapped to their respective event types, * allowing for optional event handling. * * This type defines a record structure where each key corresponds to a specific event type, * and the value is an array of callback functions associated with that event. The use of * `Partial` allows for flexibility, meaning that not all event types need to have registered * callbacks, making it suitable for scenarios where some events may not be utilized. * * @template EventType - A generic type parameter that extends from `string`, representing * the event types. By default, it is set to `string`, allowing for * any string-based event name. * * @example * // Defining specific event types * type MyEvent = 'click' | 'hover' | 'scroll'; * * // Creating a record of callbacks for the defined events * const callbacks: IObservableCallbacks<MyEvent> = { * click: [ * (event) => console.log('Click event handler 1', event), * (event) => console.log('Click event handler 2', event), * ], * hover: [ * (event) => console.log('Hover event handler', event), * ], * // 'scroll' event has no callbacks registered * }; * * // Accessing the callbacks for a specific event * const clickHandlers = callbacks.click; * if (clickHandlers) { * clickHandlers.forEach(handler => handler('click')); // Logs: Click event handler 1 click * // Logs: Click event handler 2 click * } * * @remarks * This type is particularly useful in event-driven architectures where multiple callbacks * need to be associated with different events. The use of `Partial` allows for a more * flexible design, enabling developers to define only the events they are interested in * without requiring all possible events to be present. */ export type IObservableCallbacks<EventType extends string = string> = Partial<Record<EventType | IObservableAllEventType, IObservableCallback[]>>; /** * Represents a wildcard event type for observable systems. * * This type is used to signify that a callback should be triggered for all events within * an observable system. It acts as a catch-all for any event, allowing developers to * register handlers that respond to every event emitted by the observable. * * @example * // Using the wildcard event type to listen for all events * observable.on('*', (event, ...args) => { * console.log(`An event occurred: ${event}`, 'Arguments:', args); * }); * * @remarks * The use of a wildcard event type can be useful for logging, debugging, or handling * global events that are not specific to a single event type. However, it should be used * judiciously, as it may lead to performance concerns if many events are emitted frequently. */ export type IObservableAllEventType = '*'; export interface IObservable<EventType extends string = string> { _____isObservable?: boolean; on: (event: EventType, fn: IObservableCallback) => { remove: () => any; }; finally: (event: EventType, fn: IObservableCallback) => IObservable<EventType>; off: (event: EventType, fn: IObservableCallback) => IObservable<EventType>; trigger: (event: EventType | IObservableAllEventType, ...args: any[]) => IObservable<EventType>; offAll: () => IObservable<EventType>; once: (event: EventType, fn: IObservableCallback) => { remove: () => any; }; getEventCallBacks: () => IObservableCallbacks<EventType>; } /** * Returns an instance of the IObservable interface. * The `observableFactory` function creates a new observable object with methods to manage * event listeners and trigger events. The returned observable object allows for adding, * removing, and triggering event callbacks, as well as managing final callbacks that execute * after all other callbacks for an event. * * @returns {IObservable<EventType>} A new instance of the observable object. * * @example * ```typescript * const observable = observableFactory(); * observable.on("event", (arg1, arg2) => { * console.log(arg1, arg2); * }); * observable.trigger("event", "Hello", "World"); // Outputs: Hello World * observable.on("event",function(){ * console.log("event triggered"); * }) * ``` * @see {@link IObservable} for more information on the observable interface. * @see {@link IObservableCallbacks} for more information on the observable callbacks interface. * @see {@link IObservableAllEventType} for more information on the observable all event type. * @see {@link isObservable} for more information on the observable check function. */ export declare const observableFactory: <EventType extends string = string>() => IObservable<EventType>; /** * Creates an observable object based on the provided element. * * The `observable` function checks if the given element is already observable. If it is, * the function returns the existing observable instance. If not, it creates a new observable * instance and extends the provided element with observable methods. This allows the element * to listen for events, trigger callbacks, and manage event listeners. * * @template EventType - The type of the event. This can be any string or a custom type. * @param {any} element - The element to make observable. This can be any object or value. * @returns {IObservable<EventType>} The observable object, which includes methods for event handling. * * @example * ```typescript * import observable from "@resk/core"; * const context = observable({}); * const testCb = (e) => console.log("test"); * context.on("test", testCb); * context.trigger("test"); * context.off("test", testCb); * context.offAll(); * ``` * @see {@link IObservable} for more information on the observable interface. * @see {@link IObservableCallbacks} for more information on the observable callbacks interface. * @see {@link IObservableAllEventType} for more information on the observable all event type. * @see {@link isObservable} for more information on the observable check function. */ export declare const observable: <EventType extends string = string>(element: any) => IObservable<EventType>; /** * Exports the ObservableClass that implements the IObservable interface. * * This class provides a way to create observable objects that can emit events and have * listeners attached to them. It encapsulates the observable functionality, allowing * users to manage events and their corresponding callbacks in a structured manner. * * The ObservableClass is particularly useful in scenarios where you need to implement * an event-driven architecture, enabling decoupled communication between different parts * of an application. * @template EventType - The type of the event. This can be any string or a custom type. */ export declare class ObservableClass<EventType extends string = string> implements IObservable<EventType> { /** * Flag indicating whether the object is observable. * * This property is used internally to identify instances of observable objects. * It is set to true for all instances of this class. */ readonly _____isObservable?: boolean | undefined; /** * The internal observable object that provides the observable functionality. * * This object is created using the observableFactory function and contains * the core methods for managing event listeners and triggering events. */ readonly _observable: IObservable<EventType>; /** * Listen to the given `event` and execute the `callback` each time an event is triggered. * * @param {EventType} event - The event to listen to. * @param {IObservableCallback} fn - The callback function to execute. * @returns {{ remove: () => any }} An object with a `remove` method to remove the callback. * * @example * ```typescript * const observable = new ObservableClass(); * const subscription = observable.on("dataReceived", (data) => { * console.log("Data received:", data); * }); * ``` */ on(event: EventType, fn: IObservableCallback): { remove: () => any; }; /** * Add a callback function to an event that will be triggered once. * * This method ensures that the callback is executed only the first time the event is triggered. * * @param {EventType} event - The event to listen to. * @param {IObservableCallback} fn - The callback function to execute. * @returns {IObservable<EventType>} The observable object. * * @example * ```typescript * observable.finally("dataProcessed", () => { * console.log("Data has been processed."); * }); * ``` */ finally(event: EventType, fn: IObservableCallback): IObservable<EventType>; /** * Removes the given `event` listener. * * If `fn` is provided, this method removes the specific callback function from the event. * If `fn` is not provided, it removes all callback functions associated with the event. * * @param {EventType} event - The event to remove the listener from. * @param {IObservableCallback} [fn] - The callback function to remove. * @returns {IObservable<EventType>} The observable object. * * @example * ```typescript * observable.off("dataReceived", subscription.remove); * ``` */ off(event: EventType, fn: IObservableCallback): IObservable<EventType>; /** * Execute all callback functions that listen to the given `event`. * * If the last argument is a function, it will be treated as the final callback function * to be executed after all other callbacks. * * @param {EventType} event - The event to trigger. * @param {...any[]} args - The arguments to pass to the callback functions. * @returns {IObservable<EventType>} The observable object. * * @example * ```typescript * observable.trigger("dataReceived", { id: 1, value: "Hello" }); * ``` */ trigger(event: EventType | IObservableAllEventType, ...args: any[]): IObservable<EventType>; /** * Remove all event bindings. * * This method clears all event listeners for the observable object. * * @returns {IObservable<EventType>} The observable object. * * @example * ```typescript * observable.offAll(); * ``` */ offAll(): IObservable<EventType>; /** * Listen to the given `event` and execute the `callback` at most once. * * This method ensures that the callback is executed only once, even if the event is triggered multiple times. * * @param {EventType} event - The event to listen to. * @param {IObservableCallback} fn - The callback function to execute. * @returns {{ remove: () => any }} An object with a `remove` method to remove the callback. * * @example * ```typescript * const subscription = observable.once("dataLoaded", () => { * console.log("Data has been loaded."); * }); * ``` */ once(event: EventType, fn: IObservableCallback): { remove: () => any; }; /** * Get all event callbacks. * * This method returns an object with event names as keys and arrays of callback functions as values. * * @returns {IObservableCallbacks<EventType>} An object with event names as keys and arrays of callback functions as values. * * @example * ```typescript * const callbacks = observable.getEventCallBacks(); * console.log(callbacks); * ``` */ getEventCallBacks(): IObservableCallbacks<EventType>; } /** * Checks if the given object is an observable element. * * An object is considered observable if it implements the IObservable interface and has * the following properties and methods: * - `_____isObservable` set to `true` * - `on` method * - `trigger` method * - `off` method * * @param {any} obj - The object to check. * @returns {boolean} `true` if the object is observable, `false` otherwise. * * @example * ```typescript * const observable = new ObservableClass(); * console.log(isObservable(observable)); // true * * const nonObservable = {}; * console.log(isObservable(nonObservable)); // false * ``` */ export declare function isObservable(obj: any): boolean;