UNPKG

cozyevent

Version:

World's fastest, Lightweight Async/Sync Event Emitter, also for React

1 lines 11 kB
{"version":3,"file":"index.cjs","sources":["../src/core/CozyEvent.ts","../src/react/context.tsx","../src/react/instanceRegistry.ts","../src/react/CozyEventProvider.tsx","../src/react/useCozyEvent.tsx"],"sourcesContent":["/**\n * A lightweight event emitter class for handling event-driven programming.\n * Supports synchronous and asynchronous event emission, along with event management methods.\n */\ntype Callback<T = unknown> = (args: T) => void;\n\nclass CozyEvent {\n private _events: Record<string, Callback<any>[]> = {};\n\n /**\n * Registers an event listener that will be called every time the event is emitted.\n *\n * @param event - The name of the event.\n * @param callback - The function to be executed when the event is emitted.\n */\n public on<T>(event: string, callback: Callback<T>): void {\n (this._events[event] ??= []).push(callback);\n }\n\n /**\n * Registers an event listener that will be called only once when the event is emitted.\n *\n * @param event - The name of the event.\n * @param callback - The function to be executed once when the event is emitted.\n */\n public once<T>(event: string, callback: Callback<T>): void {\n const onceCallback: Callback<T> = (args: T) => {\n callback(args);\n this.off(event, onceCallback); // Automatically remove the listener after it runs once\n };\n this.on(event, onceCallback); // Register the once listener\n }\n\n /**\n * Removes a specific event listener.\n *\n * @param event - The name of the event.\n * @param callback - The function to remove from the event listeners.\n */\n public off<T>(event: string, callback: Callback<T>): void {\n if (!this._events[event]) return;\n\n this._events[event] = this._events[event].filter((cb) => cb !== callback);\n\n if (this._events[event].length === 0) {\n delete this._events[event];\n }\n }\n\n /**\n * Emits an event synchronously, executing all registered listeners with the provided parameters.\n *\n * @param event - The name of the event to emit.\n * @param params - Optional parameters to pass to the listeners.\n */\n public emit<T>(event: string, params?: T): void {\n this._events[event]?.forEach((callback) => callback(params));\n }\n\n /**\n * Emits an event asynchronously using the microtask queue.\n *\n * @param event - The name of the event to emit.\n * @param params - Optional parameters to pass to the listeners.\n */\n public emitAsync<T>(event: string, params?: T): void {\n if (!this._events[event]) return;\n queueMicrotask(() => {\n this._events[event].forEach((callback) => callback(params));\n });\n }\n\n /**\n * Removes all event listeners. Optionally, removes only the listeners for a specific event.\n *\n * @param event - (Optional) The name of the event to remove listeners for.\n */\n public removeAllListeners(event?: string): void {\n event ? delete this._events[event] : this._events = {};\n }\n}\n\nexport { CozyEvent };\n","import { createContext } from 'react';\nimport { CozyEvent } from '../core/CozyEvent';\n\n/**\n * React context for providing a CozyEvent instance to components.\n * \n * This context allows components to access a CozyEvent instance, enabling\n * event-driven communication within the application. If no instance is provided,\n * the context will default to `null`.\n * \n * @see CozyEventProvider - The provider component that supplies the context value.\n * @see useCozyEvent - A hook for consuming the context and subscribing to events.\n */\nexport const CozyEventContext = createContext<CozyEvent | null>(null);\n\n","import { CozyEvent } from '../core/CozyEvent';\n\nconst instanceRegistry: Record<string, CozyEvent> = {};\n\n/**\n * Registers a CozyEvent instance with a given ID.\n * @param id - The unique identifier for the instance.\n * @param instance - The CozyEvent instance to register.\n */\nexport const registerCozyEventInstance = (id: string, instance: CozyEvent) => {\n instanceRegistry[id] = instance;\n};\n\n/**\n * Unregisters a CozyEvent instance by its ID.\n * @param id - The unique identifier for the instance.\n */\nexport const unregisterCozyEventInstance = (id: string) => {\n delete instanceRegistry[id];\n};\n\n/**\n * Retrieves a CozyEvent instance by its ID. If no instance is found, returns undefined.\n * @param id - The unique identifier for the instance.\n * @returns The CozyEvent instance associated with the ID, or undefined if not found.\n */\nexport const getCozyEventInstanceById = (id: string): CozyEvent | undefined => {\n return instanceRegistry[id];\n};\n","import { FC, useMemo, useEffect } from 'react';\nimport { CozyEvent } from '../core/CozyEvent';\nimport { CozyEventContext } from './context';\nimport { CozyEventProviderProps } from './types';\nimport { registerCozyEventInstance, unregisterCozyEventInstance } from './instanceRegistry';\n\n\n/**\n * CozyEventProvider is a React context provider that supplies a CozyEvent instance\n * to its child components. It ensures that the provided instance is valid and accessible\n * throughout the component tree.\n *\n * @param {CozyEvent} [instance=globalCozyEventInstance] - An optional instance of CozyEvent. \n * If not provided, a global instance is used by default.\n * @param {React.ReactNode} children - The child components that will have access to the CozyEvent instance.\n * @returns {JSX.Element} A React context provider wrapping the children with the CozyEvent instance.\n * @throws {Error} If the provided instance is not a valid CozyEvent instance.\n */\nexport const globalCozyEventInstance = new CozyEvent(); \nexport const CozyEventProvider: FC<CozyEventProviderProps> = ({\n instance = globalCozyEventInstance,\n children,\n id = 'default'\n}) => {\n \n if (!(instance instanceof CozyEvent)) {\n throw new Error('Invalid CozyEvent instance provided to CozyEventProvider');\n }\n\n \n useEffect(() => {\n registerCozyEventInstance(id, instance);\n return () => {\n unregisterCozyEventInstance(id);\n };\n }, [id, instance]);\n \n \n const contextValue = useMemo(() => instance, [instance]);\n\n return (\n <CozyEventContext.Provider value={contextValue}>\n {children}\n </CozyEventContext.Provider>\n );\n};","import { useEffect, useContext, useMemo, useCallback } from 'react';\nimport { CozyEventContext } from './context';\nimport { globalCozyEventInstance } from './CozyEventProvider';\nimport { getCozyEventInstanceById } from './instanceRegistry';\nimport { UseCozyEventOptions } from './types';\n\n/**\n * A custom React hook for subscribing to and handling events in the CozyEvent system.\n *\n * @param {string} eventName - The name of the event to listen for. Must be a non-empty string.\n * @param {(data: any) => void} callback - The function to be called when the event is triggered.\n * @param {UseCozyEventOptions} [options] - Optional parameters to scope the event.\n * \n * @returns {CozyEventEmitter} - The event emitter instance used for managing events.\n *\n * @throws {Error} If `eventName` is not a valid non-empty string.\n * @throws {Error} If `callback` is not a valid function.\n *\n * @example\n * // Usage example\n * useCozyEvent('user:login', (data) => {\n * console.log('User logged in:', data);\n * });\n *\n * @example\n * // Usage with namespace\n * useCozyEvent('update', (data) => {\n * console.log('Update event:', data);\n * }, { namespace: 'app' });\n * \n * @example\n * // Usage with namespace and ID\n * useCozyEvent('update', (data) => {\n * console.log('Update event:', data);\n * }, { namespace: 'app', id: 'unique-id' });\n */\nexport const useCozyEvent = <T = any>(\n eventName: string,\n callback: (data: any) => void,\n options?: UseCozyEventOptions\n) => {\n\n const { namespace, id } = options || {};\n const emitter = id\n ? getCozyEventInstanceById(id)\n : useContext(CozyEventContext) || globalCozyEventInstance;\n\n\n if (!emitter) {\n throw new Error(`No CozyEvent instance found for id: ${id}`);\n }\n\n\n if (typeof eventName !== 'string' || eventName.trim() === '') {\n throw new Error('Invalid eventName provided to useCozyEvent. It must be a non-empty string.');\n }\n\n\n if (typeof callback !== 'function') {\n throw new Error('Invalid callback provided to useCozyEvent. It must be a function.');\n }\n\n\n const fullEventName = useMemo(\n () => (namespace ? `${namespace}:${eventName}` : eventName),\n [namespace, eventName]\n );\n\n\n const stableCallback = useCallback(callback, [callback]);\n\n useEffect(() => {\n emitter.on(fullEventName, stableCallback);\n return () => {\n emitter.off(fullEventName, stableCallback);\n };\n }, [emitter, fullEventName, stableCallback]);\n\n return emitter;\n};\n"],"names":["CozyEvent","_events","on","event","callback","this","push","once","onceCallback","args","off","filter","cb","length","emit","params","forEach","emitAsync","queueMicrotask","removeAllListeners","CozyEventContext","createContext","instanceRegistry","registerCozyEventInstance","id","instance","getCozyEventInstanceById","globalCozyEventInstance","children","Error","useEffect","unregisterCozyEventInstance","contextValue","useMemo","_jsx","jsx","Provider","value","eventName","options","namespace","emitter","useContext","trim","fullEventName","stableCallback","useCallback"],"mappings":"mEAMA,MAAMA,EACIC,QAA2C,CAAE,EAQ9C,EAAAC,CAAMC,EAAeC,IACzBC,KAAKJ,QAAQE,KAAW,IAAIG,KAAKF,GAS7B,IAAAG,CAAQJ,EAAeC,GAC5B,MAAMI,EAA6BC,IACjCL,EAASK,GACTJ,KAAKK,IAAIP,EAAOK,EAAa,EAE/BH,KAAKH,GAAGC,EAAOK,GASV,GAAAE,CAAOP,EAAeC,GACtBC,KAAKJ,QAAQE,KAElBE,KAAKJ,QAAQE,GAASE,KAAKJ,QAAQE,GAAOQ,QAAQC,GAAOA,IAAOR,IAE7B,IAA/BC,KAAKJ,QAAQE,GAAOU,eACfR,KAAKJ,QAAQE,IAUjB,IAAAW,CAAQX,EAAeY,GAC5BV,KAAKJ,QAAQE,IAAQa,SAASZ,GAAaA,EAASW,KAS/C,SAAAE,CAAad,EAAeY,GAC5BV,KAAKJ,QAAQE,IAClBe,gBAAe,KACbb,KAAKJ,QAAQE,GAAOa,SAASZ,GAAaA,EAASW,IAAQ,IASxD,kBAAAI,CAAmBhB,GACxBA,SAAeE,KAAKJ,QAAQE,GAASE,KAAKJ,QAAU,CAAE,SCjE7CmB,EAAmBC,EAAaA,cAAmB,MCX1DC,EAA8C,CAAE,EAOzCC,EAA4B,CAACC,EAAYC,KACpDH,EAAiBE,GAAMC,CAAQ,EAgBpBC,EAA4BF,GAChCF,EAAiBE,GCTbG,EAA0B,IAAI3B,2EACkB,EAC3DyB,WAAWE,EACXC,WACAJ,KAAK,cAGL,KAAMC,aAAoBzB,GACxB,MAAM,IAAI6B,MAAM,4DAIjBC,EAAAA,WAAU,KACTP,EAA0BC,EAAIC,GACvB,KDfgC,CAACD,WACnCF,EAAiBE,EAAG,ECevBO,CAA4BP,EAAG,IAEhC,CAACA,EAAIC,IAGR,MAAMO,EAAeC,EAAOA,SAAC,IAAMR,GAAU,CAACA,IAE9C,OACES,EAAAC,IAACf,EAAiBgB,SAAQ,CAACC,MAAOL,EAAYJ,SAC3CA,GACyB,8FCPJ,CAC1BU,EACAlC,EACAmC,KAGA,MAAMC,UAAEA,EAAShB,GAAEA,GAAOe,GAAW,CAAE,EACjCE,EAAUjB,EACZE,EAAyBF,GACzBkB,EAAUA,WAACtB,IAAqBO,EAGpC,IAAKc,EACH,MAAM,IAAIZ,MAAM,uCAAuCL,KAIzD,GAAyB,iBAAdc,GAA+C,KAArBA,EAAUK,OAC7C,MAAM,IAAId,MAAM,8EAIlB,GAAwB,mBAAbzB,EACT,MAAM,IAAIyB,MAAM,qEAIlB,MAAMe,EAAgBX,EAAOA,SAC3B,IAAOO,EAAY,GAAGA,KAAaF,IAAcA,GACjD,CAACE,EAAWF,IAIRO,EAAiBC,EAAWA,YAAC1C,EAAU,CAACA,IAS9C,OAPA0B,EAAAA,WAAU,KACRW,EAAQvC,GAAG0C,EAAeC,GACnB,KACLJ,EAAQ/B,IAAIkC,EAAeC,EAAe,IAE3C,CAACJ,EAASG,EAAeC,IAErBJ,CAAO"}