fastevent 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/scope.ts","../src/utils/isPathMatched.ts","../src/utils/removeItem.ts","../src/event.ts"],"names":["FastEventScope","constructor","emitter","prefix","length","endsWith","options","delimiter","_getScopeListener","listener","scopePrefix","scopeListener","__name","payload","type","startsWith","substring","__wrappedListener","_getScopeType","undefined","on","args","arguments","once","onAny","offAll","off","clear","emit","retain","waitFor","timeout","scope","_FastEventScope","isPathMatched","path","pattern","fPattern","splice","Array","from","fill","i","removeItem","arr","condition","index","findIndex","item","push","FastEvent","listeners","__listeners","_options","_delimiter","_context","_retainedEvents","Map","Object","assign","context","ignoreErrors","_addListener","parts","count","_forEachNodes","node","onAddListener","callback","current","part","_removeListener","isArray","isRemove","onRemoveListener","Error","split","includes","_emitForLastEvent","hasWildcard","_traverseToPath","entryParts","_traverseListeners","entry","entryNode","_getListenerNode","_removeRetainedEvents","delete","key","keys","_getMeta","extra","meta","has","get","_executeListeners","lastFollowing","traverseNodes","parentPath","childNode","entries","_executeListener","call","e","_trigger","onListenerError","result","set","results","emitAsync","Promise","allSettled","map","status","value","reason","resolve","reject","tid","subscriber","clearTimeout","setTimeout","_FastEvent"],"mappings":"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","file":"index.mjs","sourcesContent":["import { FastEvent } from \"./event\";\nimport { FastEventListener, FastEvents, FastEventSubscriber } from \"./types\";\n\nexport class FastEventScope<\n Events extends FastEvents = FastEvents, \n Types extends keyof Events = keyof Events,\n Meta = unknown\n>{\n constructor(public emitter:FastEvent<Events,Types,Meta>,public prefix:string){\n if(prefix.length>0 && !prefix.endsWith(emitter.options.delimiter!)){\n this.prefix = prefix + emitter.options.delimiter\n } \n }\n private _getScopeListener(listener:FastEventListener):FastEventListener{\n const scopePrefix = this.prefix\n if(scopePrefix.length===0) return listener\n const scopeListener = function(payload:any,{type}:{type:string}){\n if(type.startsWith(scopePrefix)){ \n type = type.substring(scopePrefix.length)\n }\n return listener(payload,{type})\n } \n // 当启用scope时对监听器进行包装\n //@ts-ignore\n listener.__wrappedListener = scopeListener\n return listener\n }\n private _getScopeType(type:string){\n return type===undefined ? undefined : this.prefix + type\n } \n \n public on<T extends string>(type: T, listener: FastEventListener<T,Events[T],Meta>, count?:number ): FastEventSubscriber \n public on<T extends Types=Types>(type: T, listener: FastEventListener<T,Events[T],Meta>, count?:number ): FastEventSubscriber \n public on(type: '**', listener: FastEventListener<any,any,Meta>): FastEventSubscriber\n public on(): FastEventSubscriber{\n const args = [...arguments] as [any,any,any]\n args[0] = this._getScopeType(args[0])\n args[1] = this._getScopeListener(args[1])\n return this.emitter.on(...args)\n }\n\n public once<T extends string>(type: T, listener: FastEventListener<T,Events[T],Meta> ): FastEventSubscriber\n public once<T extends Types = Types>(type: T, listener: FastEventListener<Types,Events[T],Meta> ): FastEventSubscriber \n public once(): FastEventSubscriber{\n return this.on(arguments[0],arguments[1],1)\n }\n\n onAny<P=any>(listener: FastEventListener<Types,P,Meta>): FastEventSubscriber {\n const type = this.prefix + '**'\n return this.on(type as any,listener)\n } \n offAll(){\n this.emitter.offAll(this.prefix)\n } \n off(listener: FastEventListener<any, any,any>):void \n off(type: string, listener: FastEventListener<any, any, any>):void\n off(type: Types, listener: FastEventListener<any, any, any>):void\n off(type: string):void\n off(type: Types):void\n off(){\n const args = arguments as unknown as [any,any]\n if(typeof(args[0])==='string'){\n args[0] = this._getScopeType(args[0])\n }\n this.emitter.off(...args)\n } \n clear(){\n this.offAll()\n }\n public emit<R=any>(type:string,payload?:any,retain?:boolean):R[]\n public emit<R=any>(type:Types,payload?:Events[Types],retain?:boolean):R[]\n public emit<R=any>():R[]{\n const type = arguments[0] as string\n const payload = arguments[1] \n const retain = arguments[2] as boolean\n return this.emitter.emit(this._getScopeType(type)!,payload,retain)\n }\n public waitFor<R=any>(type:string,timeout?:number):Promise<R>\n public waitFor<R=any>(type:Types,timeout?:number):Promise<R>\n public waitFor<R=any>():Promise<R>{\n const type = arguments[0] as string\n const timeout = arguments[1] as number\n return this.emitter.waitFor(this._getScopeType(type)!,timeout)\n }\n public scope(prefix:string){\n return this.emitter.scope(this._getScopeType(prefix)!)\n }\n}","\n/**\n * \n * 判断path是否与pattern匹配\n * \n * isPathMatched(\"a.b.c\",\"a.b.c\") == true\n * isPathMatched(\"a.b.c\",\"a.b.*\") == true\n * isPathMatched(\"a.b.c\",\"a.*.*\") == true\n * isPathMatched(\"a.b.c\",\"*.*.*\") == true\n * isPathMatched(\"a.b.c\",\".b.*\") == true\n * isPathMatched(\"a.b.c.d\",\"a.**\") == true\n * \n * - '**' 匹配后续的\n * - '*' 匹配任意数量的字符,包括零个字符\n * \n * @param path \n * @param pattern \n */\nexport function isPathMatched(path:string[],pattern:string[]):boolean{\n if(path.length !== pattern.length && (path.length>0 && pattern[pattern.length-1]!=='**') ){\n return false;\n }\n let fPattern = [...pattern]\n if(pattern.length >0 && pattern[pattern.length-1] === '**'){\n fPattern.splice(pattern.length-1,1,...Array.from<string>({\n length: path.length-pattern.length+1\n }).fill('*'))\n }\n for(let i=0;i<path.length;i++){\n if(fPattern[i]==='*'){\n continue\n }\n if(fPattern[i]!==path[i]){\n return false\n }\n }\n return true\n}\n\n ","\n\nexport function removeItem(arr:any[],condition:(item:any)=>boolean){\n let index:number[] = []\n while (true) {\n const i = arr.findIndex((item)=>{ \n return condition(item)\n })\n if(i === -1) {\n index.push(i)\n break\n } \n arr.splice(i,1)\n }\n return index\n}","import { FastEventScope } from './scope';\nimport { \n FastEventListener, \n FastEventOptions, \n FastEvents, \n FastListeners, \n FastListenerNode, \n FastEventSubscriber, \n ScopeEvents,\n FastEventMeta\n} from './types'; \nimport { isPathMatched } from './utils/isPathMatched';\nimport { removeItem } from './utils/removeItem';\n \nexport class FastEvent<\n Events extends FastEvents = FastEvents, \n Types extends keyof Events = keyof Events,\n Meta = unknown\n>{\n public listeners : FastListeners = { __listeners: [] } as unknown as FastListeners\n private _options : FastEventOptions\n private _delimiter : string = '/'\n private _context : any\n private _retainedEvents : Map<string,any> = new Map<string,any>() \n constructor(options?:FastEventOptions<Meta>) { \n this._options = Object.assign({\n delimiter : '/',\n context : null,\n ignoreErrors : true\n }, options)\n this._delimiter = this._options.delimiter!\n this._context = this._options.context || this\n }\n get options(){ return this._options }\n private _addListener(parts:string[],listener:FastEventListener<any,any>,count?:number):FastListenerNode | undefined{\n return this._forEachNodes(parts,(node)=>{\n node.__listeners.push(count && count >0 ? [listener,count]: listener)\n if(typeof(this._options.onAddListener)==='function'){\n this._options.onAddListener(parts,listener)\n }\n }) \n }\n /**\n * \n * 根据parts路径遍历侦听器树,并在最后的节点上执行回调函数\n * \n * @param parts \n * @param callback \n * @returns \n */\n private _forEachNodes(parts:string[],callback:(node:FastListenerNode,parent:FastListenerNode)=>void):FastListenerNode | undefined{\n if(parts.length === 0) return \n let current = this.listeners\n for(let i=0;i<parts.length;i++){\n const part = parts[i]\n if(!(part in current)){\n current[part] = {\n __listeners: []\n } as unknown as FastListeners\n }\n if(i===parts.length-1){ \n const node = current[part]\n callback(node,current)\n return node\n }else{ \n current = current[part]\n }\n }\n return undefined\n } \n\n\n /**\n * 从监听器节点中移除指定的事件监听器\n * @private\n * @param node - 监听器节点\n * @param listener - 需要移除的事件监听器\n * @description 遍历节点的监听器列表,移除所有匹配的监听器。支持移除普通函数和数组形式的监听器\n */\n private _removeListener(node: FastListenerNode, path:string[],listener: FastEventListener<any,any,any>): void {\n if(!listener) return \n removeItem(node.__listeners,(item:any)=>{\n item = Array.isArray(item) ? item[0] : item \n const isRemove = item === listener \n if(isRemove && typeof(this._options.onRemoveListener)==='function'){\n this._options.onRemoveListener(path,listener)\n }\n return isRemove\n }) \n }\n public on<T extends string>(type: T, listener: FastEventListener<T,Events[T],Meta>, count?:number ): FastEventSubscriber\n public on<T extends Types=Types>(type: T, listener: FastEventListener<Types,Events[T],Meta>, count?:number ): FastEventSubscriber\n public on<P=any>(type: '**', listener: FastEventListener<Types,P,Meta>): FastEventSubscriber\n public on(): FastEventSubscriber{\n const type = arguments[0] as string\n const listener = arguments[1] as FastEventListener \n const count = arguments[2] as number\n if(type.length===0) throw new Error('event type cannot be empty')\n\n if(type==='**'){\n return this.onAny(listener)\n }\n\n const parts = type.split(this._delimiter);\n const node = this._addListener(parts,listener,count)\n \n // Retain不支持通配符\n if(node && !type.includes('*')) this._emitForLastEvent(type) \n\n return {\n off: ()=>node && this._removeListener(node,parts,listener)\n }\n } \n\n public once<T extends string>(type: T, listener: FastEventListener<T,Events[T],Meta> ): FastEventSubscriber\n public once<T extends Types=Types>(type: T, listener: FastEventListener<Types,Events[T],Meta> ): FastEventSubscriber\n public once(): FastEventSubscriber{\n return this.on(arguments[0],arguments[1],1)\n }\n\n /**\n * 注册一个监听器,用于监听所有事件\n * @param listener 事件监听器函数,可以接收任意类型的事件数据\n * @returns {FastEventSubscriber} 返回一个订阅者对象,包含 off 方法用于取消监听\n * @example\n * ```ts\n * const subscriber = emitter.onAny((eventName, data) => {\n * console.log(eventName, data);\n * });\n * \n * // 取消监听\n * subscriber.off();\n * ```\n */\n onAny<P=any>(listener: FastEventListener<string,P,Meta>): FastEventSubscriber {\n const listeners = this.listeners.__listeners\n listeners.push(listener)\n return {\n off:()=>this._removeListener(this.listeners,[],listener)\n }\n }\n\n off(listener: FastEventListener<any, any, any>):void \n off(type: string, listener: FastEventListener<any, any, any>):void\n off(type: Types, listener: FastEventListener<any, any, any>):void\n off(type: string):void\n off(type: Types):void\n off(){\n const args = arguments\n const type = typeof(args[0])==='function' ? undefined : args[0]\n const listener = typeof(args[0])==='function' ? args[0] : args[1]\n const parts = type ? type.split(this._delimiter) : []\n const hasWildcard= type ? type.includes('*') : false\n if(type && !hasWildcard){\n this._traverseToPath(this.listeners,parts,(node)=>{\n if(listener){ // 只删除指定的监听器\n this._removeListener(node,parts,listener)\n }else if(type){\n node.__listeners=[]\n }\n })\n }else{ // 仅删除指定的侦听器\n const entryParts:string[] = hasWildcard ? [] : parts\n this._traverseListeners(this.listeners,entryParts,(path,node)=>{ \n if(listener!==undefined || (hasWildcard && isPathMatched(path,parts))){\n if(listener){\n this._removeListener(node,parts,listener)\n }else{\n node.__listeners=[]\n } \n }\n })\n }\n }\n \n /**\n * 移除所有事件监听器\n * @param entry - 可选的事件前缀,如果提供则只移除指定前缀下的的监听器\n * @description \n * - 如果提供了prefix参数,则只清除该前缀下的所有监听器\n * - 如果没有提供prefix,则清除所有监听器\n * - 同时会清空保留的事件(_retainedEvents)\n * - 重置监听器对象为空\n\n * @example\n * \n * ```ts\n * emitter.offAll(); // 清除所有监听器\n * emitter.offAll('a/b'); // 清除a/b下的所有监听器\n * \n */\n offAll(entry?: string) { \n if(entry){\n const entryNode = this._getListenerNode(entry.split(this._delimiter))\n if(entryNode) entryNode.__listeners = []\n this._removeRetainedEvents(entry)\n }else{ \n this._retainedEvents.clear() \n this.listeners = { __listeners: [] } as unknown as FastListeners\n }\n }\n\n private _getListenerNode(parts:string[]):FastListenerNode | undefined{\n let entryNode: FastListenerNode | undefined\n this._forEachNodes(parts,(node)=>{\n entryNode = node\n })\n return entryNode\n }\n /**\n * 移除保留的事件\n * @param prefix - 事件前缀。如果不提供,将清除所有保留的事件。\n * 如果提供前缀,将删除所有以该前缀开头的事件。\n * 如果前缀不以分隔符结尾,会自动添加分隔符。\n * @private\n */\n private _removeRetainedEvents(prefix?: string) {\n if (!prefix) this._retainedEvents.clear()\n if(prefix?.endsWith(this._delimiter)){\n prefix+=this._delimiter\n } \n this._retainedEvents.delete(prefix!)\n for(let key of this._retainedEvents.keys()){\n if(key.startsWith(prefix!)){\n this._retainedEvents.delete(key)\n }\n }\n } \n clear(){\n this.offAll()\n }\n private _getMeta(extra:Record<string,any>){\n if(!this._options.meta) return extra\n return Object.assign({},this._options.meta,extra) as FastEventMeta<any,any> \n }\n private _emitForLastEvent(type:string){ \n if(this._retainedEvents.has(type)){\n const payload = this._retainedEvents.get(type)\n const parts = type.split(this._delimiter); \n this._traverseToPath(this.listeners,parts,(node)=>{ \n this._executeListeners(node,payload,this._getMeta({type}))\n }) \n // onAny侦听器保存在根节点中,所以需要执行\n this._executeListeners(this.listeners,payload,this._getMeta({type}))\n } \n }\n\n /**\n * 遍历监听器节点树\n * @param node 当前遍历的监听器节点\n * @param parts 事件名称按'.'分割的部分数组\n * @param callback 遍历到目标节点时的回调函数\n * @param index 当前遍历的parts数组索引,默认为0\n * @param lastFollowing 当命中**时该值为true, 注意**只能作在路径的最后面,如a.**有效,而a.**.b无效\n * @private\n * \n * 支持三种匹配模式:\n * - 精确匹配: 'a.b.c'\n * - 单层通配: 'a.*.c' \n * - 多层通配: 'a.**'\n */\n private _traverseToPath(node: FastListenerNode, parts: string[], callback: (node: FastListenerNode) => void, index: number = 0, lastFollowing?:boolean): void {\n\n if (index >= parts.length) {\n callback(node)\n return\n } \n const part = parts[index] \n\n if(lastFollowing===true){\n this._traverseToPath(node, parts, callback, index + 1,true)\n return\n }\n\n if (part in node) {\n this._traverseToPath(node[part], parts, callback, index + 1)\n }\n\n if ('*' in node) {\n this._traverseToPath(node['*'], parts, callback, index + 1)\n }\n // \n if ('**' in node) {\n this._traverseToPath(node['**'], parts, callback, index + 1,true)\n }\n }\n\n private _traverseListeners(node: FastListenerNode, entry:string[], callback: (path:string[],node: FastListenerNode) => void): void {\n let entryNode: FastListenerNode = node\n // 如果指定了entry路径,则按照路径遍历\n if (entry && entry.length > 0) { \n this._traverseToPath(node, entry,(node)=>{\n entryNode= node\n });\n }\n const traverseNodes = (node: FastListenerNode, callback: (path:string[],node: FastListenerNode) => void,parentPath:string[])=>{\n callback(parentPath, node); \n for(let [key,childNode] of Object.entries(node)){\n if(key.startsWith(\"__\")) continue\n if(childNode){\n traverseNodes(childNode as FastListenerNode, callback,[...parentPath,key]);\n }\n }\n }\n // 如果没有指定entry或entry为空数组,则递归遍历所有节点\n traverseNodes(entryNode, callback,[]);\n } \n\n private _executeListener(listener:any, payload: any,meta: FastEventMeta<any,any> ):any{\n try{\n if(typeof(listener.__wrappedListener)==='function'){\n return listener.__wrappedListener.call(this._context,payload,meta)\n }else{\n return listener.call(this._context,payload,meta)\n }\n }catch(e:any){\n e._trigger = meta.type\n if(typeof(this._options.onListenerError)==='function'){\n this._options.onListenerError.call(this,meta.type,e)\n }\n // 如果忽略错误,则返回错误对象\n if(this._options.ignoreErrors){\n return e\n }else{\n throw e\n }\n }\n }\n\n /**\n * 执行监听器节点中的所有监听函数\n * @param node - FastListenerNode类型的监听器节点\n * @param payload - 事件携带的数据\n * @param type - 事件类型\n * @returns 返回所有监听函数的执行结果数组\n * @private\n * \n * @description\n * 遍历执行节点中的所有监听函数:\n * - 对于普通监听器,直接执行并收集结果\n * - 对于带次数限制的监听器(数组形式),执行后递减次数,当次数为0时移除该监听器\n */\n private _executeListeners(node: FastListenerNode, payload: any, meta: Meta): any[] {\n if (!node || !node.__listeners) return []\n let i = 0\n const listeners = node.__listeners\n let result:any[] = []\n while(i<listeners.length){\n const listener = listeners[i]\n if(Array.isArray(listener)){\n result.push(this._executeListener(listener[0],payload,meta)) \n listener[1]-- \n if(listener[1]===0) {\n listeners.splice(i,1)\n i-- // 抵消后面的i++\n }\n }else{\n result.push(this._executeListener(listener,payload,meta)) \n } \n i++ \n }\n return result\n }\n\n public emit<R=any>(type:string,payload?:any,retain?:boolean,meta?:Meta):R[]\n public emit<R=any>(type:Types,payload?:Events[Types],retain?:boolean,meta?:Meta):R[]\n public emit<R=any>():R[]{\n const type = arguments[0] as string\n const payload = arguments[1] as any\n const retain = arguments[2] as boolean\n const meta = (arguments[3] || {}) as Meta\n\n const parts = type.split(this._delimiter); \n if(retain) {\n this._retainedEvents.set(type,payload)\n } \n const results:any[] = []\n this._traverseToPath(this.listeners,parts,(node)=>{ \n results.push(...this._executeListeners(node,payload,this._getMeta({...meta,type})))\n }) \n // onAny侦听器保存在根节点中,所以需要执行 \n results.push(...this._executeListeners(this.listeners,payload,this._getMeta({...meta,type})))\n return results\n }\n\n public async emitAsync<R=any>(type:string,payload?:any,retain?:boolean,meta?:Meta):Promise<[R|Error][]>\n public async emitAsync<R=any>(type:Types,payload?:Events[Types],retain?:boolean,meta?:Meta):Promise<[R|Error][]>\n public async emitAsync<P=any>():Promise<[P|Error][]>{\n const type = arguments[0] as string\n const payload = arguments[1] as any\n const retain = arguments[2] as boolean\n const meta = (arguments[3] || {}) as Meta\n\n const results = await Promise.allSettled(this.emit<P>(type,payload,retain,this._getMeta({...meta,type})))\n return results.map((result)=>{\n if(result.status==='fulfilled'){\n return result.value\n }else{\n return result.reason\n }\n })\n }\n\n /**\n * 等待指定事件发生\n * \n * @param type \n * @param timeout 超时时间,单位毫秒,默认为 0,表示无限等待\n */\n public waitFor<R=any>(type:string,timeout?:number):Promise<R>\n public waitFor<R=any>(type:Types,timeout?:number):Promise<R>\n public waitFor<R=any>():Promise<R>{\n const type = arguments[0] as string\n const timeout = arguments[1] as number\n return new Promise<R>((resolve,reject)=>{\n let tid:any\n let subscriber:FastEventSubscriber\n const listener = (payload:any)=>{\n clearTimeout(tid)\n subscriber.off() \n resolve(payload) \n }\n if(timeout && timeout>0){\n tid = setTimeout(()=>{\n subscriber && subscriber.off()\n reject(new Error('wait for event<'+ type +'> is timeout'))\n },timeout)\n }\n subscriber = this.on(type,listener) \n }) \n }\n\n /**\n * 创建事件域\n * \n * 注意:\n * \n * 事件域与当前事件对象共享相同的侦听器表\n * 也就是说,如果在事件域中触发事件,当前事件对象也会触发该事件\n * 两者工不是完全隔离的,仅是事件侦听和触发时的事件类型不同而已\n * \n * const emitter = new FastEvent()\n * \n * const scope= emitter.scope(\"a/b\")\n * \n * scope.on(\"x\",()=>{}) == emitter.on(\"a/b/x\",()=>{})\n * scope.emit(\"x\",1) == emitter.emit(\"a/b/x\",1) \n * scope.offAll() == emitter.offAll(\"a/b\")\n * \n */\n scope<T extends string>(prefix:T){ \n return new FastEventScope<ScopeEvents<Events,T>>(this as unknown as FastEvent<ScopeEvents<Events,T>>,prefix)\n }\n\n} "]}
1
+ {"version":3,"sources":["../src/scope.ts","../src/utils/isPathMatched.ts","../src/utils/removeItem.ts","../src/event.ts"],"names":["FastEventScope","constructor","emitter","prefix","length","endsWith","options","delimiter","_getScopeListener","listener","scopePrefix","scopeListener","__name","payload","type","startsWith","substring","__wrappedListener","_getScopeType","undefined","on","args","arguments","once","Object","assign","count","onAny","offAll","off","clear","emit","retain","waitFor","timeout","scope","_FastEventScope","isPathMatched","path","pattern","fPattern","splice","Array","from","fill","i","removeItem","arr","condition","index","findIndex","item","push","FastEvent","listeners","__listeners","_options","_delimiter","_context","_retainedEvents","Map","context","ignoreErrors","_addListener","parts","prepend","_forEachNodes","node","newListener","onAddListener","callback","current","part","_removeListener","isArray","isRemove","onRemoveListener","Error","split","includes","_emitForLastEvent","hasWildcard","_traverseToPath","entryParts","_traverseListeners","entry","entryNode","_getListenerNode","_removeRetainedEvents","delete","key","keys","_getMeta","extra","meta","has","get","_executeListeners","lastFollowing","traverseNodes","parentPath","childNode","entries","_executeListener","call","e","_trigger","onListenerError","result","set","results","emitAsync","Promise","allSettled","map","status","value","reason","resolve","reject","tid","subscriber","clearTimeout","setTimeout","_FastEvent"],"mappings":"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","file":"index.mjs","sourcesContent":["import { FastEvent } from \"./event\";\nimport { FastEventListener, FastEventListenOptions, FastEvents, FastEventSubscriber } from \"./types\";\n\nexport class FastEventScope<\n Events extends FastEvents = FastEvents, \n Types extends keyof Events = keyof Events,\n Meta = unknown\n>{\n constructor(public emitter:FastEvent<Events,Types,Meta>,public prefix:string){\n if(prefix.length>0 && !prefix.endsWith(emitter.options.delimiter!)){\n this.prefix = prefix + emitter.options.delimiter\n } \n }\n private _getScopeListener(listener:FastEventListener):FastEventListener{\n const scopePrefix = this.prefix\n if(scopePrefix.length===0) return listener\n const scopeListener = function(payload:any,{type}:{type:string}){\n if(type.startsWith(scopePrefix)){ \n type = type.substring(scopePrefix.length)\n }\n return listener(payload,{type})\n } \n // 当启用scope时对监听器进行包装\n //@ts-ignore\n listener.__wrappedListener = scopeListener\n return listener\n }\n private _getScopeType(type:string){\n return type===undefined ? undefined : this.prefix + type\n } \n \n public on<T extends string>(type: T, listener: FastEventListener<T,Events[T],Meta>, options?:FastEventListenOptions ): FastEventSubscriber \n public on<T extends Types=Types>(type: T, listener: FastEventListener<T,Events[T],Meta>, options?:FastEventListenOptions): FastEventSubscriber \n public on(type: '**', listener: FastEventListener<any,any,Meta>): FastEventSubscriber\n public on(): FastEventSubscriber{\n const args = [...arguments] as [any,any,any]\n args[0] = this._getScopeType(args[0])\n args[1] = this._getScopeListener(args[1])\n return this.emitter.on(...args)\n }\n\n public once<T extends string>(type: T, listener: FastEventListener<T,Events[T],Meta>, options?:FastEventListenOptions ): FastEventSubscriber\n public once<T extends Types = Types>(type: T, listener: FastEventListener<Types,Events[T],Meta>, options?:FastEventListenOptions ): FastEventSubscriber \n public once(): FastEventSubscriber{\n return this.on(arguments[0],arguments[1],Object.assign(arguments[2],{},{count:1}))\n }\n\n onAny<P=any>(listener: FastEventListener<Types,P,Meta>, options?:FastEventListenOptions): FastEventSubscriber {\n const type = this.prefix + '**'\n return this.on(type as any,listener,options)\n } \n offAll(){\n this.emitter.offAll(this.prefix)\n } \n off(listener: FastEventListener<any, any,any>):void \n off(type: string, listener: FastEventListener<any, any, any>):void\n off(type: Types, listener: FastEventListener<any, any, any>):void\n off(type: string):void\n off(type: Types):void\n off(){\n const args = arguments as unknown as [any,any]\n if(typeof(args[0])==='string'){\n args[0] = this._getScopeType(args[0])\n }\n this.emitter.off(...args)\n } \n clear(){\n this.offAll()\n }\n public emit<R=any>(type:string,payload?:any,retain?:boolean):R[]\n public emit<R=any>(type:Types,payload?:Events[Types],retain?:boolean):R[]\n public emit<R=any>():R[]{\n const type = arguments[0] as string\n const payload = arguments[1] \n const retain = arguments[2] as boolean\n return this.emitter.emit(this._getScopeType(type)!,payload,retain)\n }\n public waitFor<R=any>(type:string,timeout?:number):Promise<R>\n public waitFor<R=any>(type:Types,timeout?:number):Promise<R>\n public waitFor<R=any>():Promise<R>{\n const type = arguments[0] as string\n const timeout = arguments[1] as number\n return this.emitter.waitFor(this._getScopeType(type)!,timeout)\n }\n public scope(prefix:string){\n return this.emitter.scope(this._getScopeType(prefix)!)\n }\n}","\n/**\n * \n * 判断path是否与pattern匹配\n * \n * isPathMatched(\"a.b.c\",\"a.b.c\") == true\n * isPathMatched(\"a.b.c\",\"a.b.*\") == true\n * isPathMatched(\"a.b.c\",\"a.*.*\") == true\n * isPathMatched(\"a.b.c\",\"*.*.*\") == true\n * isPathMatched(\"a.b.c\",\".b.*\") == true\n * isPathMatched(\"a.b.c.d\",\"a.**\") == true\n * \n * - '**' 匹配后续的\n * - '*' 匹配任意数量的字符,包括零个字符\n * \n * @param path \n * @param pattern \n */\nexport function isPathMatched(path:string[],pattern:string[]):boolean{\n if(path.length !== pattern.length && (path.length>0 && pattern[pattern.length-1]!=='**') ){\n return false;\n }\n let fPattern = [...pattern]\n if(pattern.length >0 && pattern[pattern.length-1] === '**'){\n fPattern.splice(pattern.length-1,1,...Array.from<string>({\n length: path.length-pattern.length+1\n }).fill('*'))\n }\n for(let i=0;i<path.length;i++){\n if(fPattern[i]==='*'){\n continue\n }\n if(fPattern[i]!==path[i]){\n return false\n }\n }\n return true\n}\n\n ","\n\nexport function removeItem(arr:any[],condition:(item:any)=>boolean){\n let index:number[] = []\n while (true) {\n const i = arr.findIndex((item)=>{ \n return condition(item)\n })\n if(i === -1) {\n index.push(i)\n break\n } \n arr.splice(i,1)\n }\n return index\n}","import { FastEventScope } from './scope';\nimport { \n FastEventListener, \n FastEventOptions, \n FastEvents, \n FastListeners, \n FastListenerNode, \n FastEventSubscriber, \n ScopeEvents,\n FastEventMeta,\n FastEventListenOptions\n} from './types'; \nimport { isPathMatched } from './utils/isPathMatched';\nimport { removeItem } from './utils/removeItem';\n \nexport class FastEvent<\n Events extends FastEvents = FastEvents, \n Types extends keyof Events = keyof Events,\n Meta = unknown\n>{\n public listeners : FastListeners = { __listeners: [] } as unknown as FastListeners\n private _options : FastEventOptions\n private _delimiter : string = '/'\n private _context : any\n private _retainedEvents : Map<string,any> = new Map<string,any>() \n constructor(options?:FastEventOptions<Meta>) { \n this._options = Object.assign({\n delimiter : '/',\n context : null,\n ignoreErrors : true\n }, options)\n this._delimiter = this._options.delimiter!\n this._context = this._options.context || this\n }\n get options(){ return this._options }\n private _addListener(parts:string[],listener:FastEventListener<any,any>,options:Required<FastEventListenOptions>):FastListenerNode | undefined{\n const { count, prepend } = options\n return this._forEachNodes(parts,(node)=>{\n const newListener = count >0 ? [listener,count]: listener as any\n if(prepend){\n node.__listeners.splice(0,0,newListener)\n }else{\n node.__listeners.push(newListener)\n } \n if(typeof(this._options.onAddListener)==='function'){\n this._options.onAddListener(parts,listener)\n }\n }) \n }\n /**\n * \n * 根据parts路径遍历侦听器树,并在最后的节点上执行回调函数\n * \n * @param parts \n * @param callback \n * @returns \n */\n private _forEachNodes(parts:string[],callback:(node:FastListenerNode,parent:FastListenerNode)=>void):FastListenerNode | undefined{\n if(parts.length === 0) return \n let current = this.listeners\n for(let i=0;i<parts.length;i++){\n const part = parts[i]\n if(!(part in current)){\n current[part] = {\n __listeners: []\n } as unknown as FastListeners\n }\n if(i===parts.length-1){ \n const node = current[part]\n callback(node,current)\n return node\n }else{ \n current = current[part]\n }\n }\n return undefined\n } \n\n\n /**\n * 从监听器节点中移除指定的事件监听器\n * @private\n * @param node - 监听器节点\n * @param listener - 需要移除的事件监听器\n * @description 遍历节点的监听器列表,移除所有匹配的监听器。支持移除普通函数和数组形式的监听器\n */\n private _removeListener(node: FastListenerNode, path:string[],listener: FastEventListener<any,any,any>): void {\n if(!listener) return \n removeItem(node.__listeners,(item:any)=>{\n item = Array.isArray(item) ? item[0] : item \n const isRemove = item === listener \n if(isRemove && typeof(this._options.onRemoveListener)==='function'){\n this._options.onRemoveListener(path,listener)\n }\n return isRemove\n }) \n }\n public on<T extends string>(type: T, listener: FastEventListener<T,Events[T],Meta>, options?:FastEventListenOptions ): FastEventSubscriber\n public on<T extends Types=Types>(type: T, listener: FastEventListener<Types,Events[T],Meta>, options?:FastEventListenOptions): FastEventSubscriber\n public on<P=any>(type: '**', listener: FastEventListener<Types,P,Meta>): FastEventSubscriber\n public on(): FastEventSubscriber{\n const type = arguments[0] as string\n const listener = arguments[1] as FastEventListener \n const options = Object.assign({\n count : 0,\n prepend: false\n },arguments[2]) as Required<FastEventListenOptions>\n\n if(type.length===0) throw new Error('event type cannot be empty')\n\n if(type==='**'){\n return this.onAny(listener)\n }\n\n const parts = type.split(this._delimiter);\n const node = this._addListener(parts,listener,options)\n \n // Retain不支持通配符\n if(node && !type.includes('*')) this._emitForLastEvent(type) \n\n return {\n off: ()=>node && this._removeListener(node,parts,listener)\n }\n } \n\n public once<T extends string>(type: T, listener: FastEventListener<T,Events[T],Meta> ): FastEventSubscriber\n public once<T extends Types=Types>(type: T, listener: FastEventListener<Types,Events[T],Meta> ): FastEventSubscriber\n public once(): FastEventSubscriber{\n return this.on(arguments[0],arguments[1],{count:1})\n }\n\n /**\n * 注册一个监听器,用于监听所有事件\n * @param listener 事件监听器函数,可以接收任意类型的事件数据\n * @returns {FastEventSubscriber} 返回一个订阅者对象,包含 off 方法用于取消监听\n * @example\n * ```ts\n * const subscriber = emitter.onAny((eventName, data) => {\n * console.log(eventName, data);\n * });\n * \n * // 取消监听\n * subscriber.off();\n * ```\n */\n onAny<P=any>(listener: FastEventListener<string,P,Meta>, options?:Pick<FastEventListenOptions,'prepend'>): FastEventSubscriber {\n const listeners = this.listeners.__listeners\n if(options && options.prepend){\n listeners.splice(0,0,listener)\n }else{\n listeners.push(listener)\n } \n return {\n off:()=>this._removeListener(this.listeners,[],listener)\n }\n }\n\n off(listener: FastEventListener<any, any, any>):void \n off(type: string, listener: FastEventListener<any, any, any>):void\n off(type: Types, listener: FastEventListener<any, any, any>):void\n off(type: string):void\n off(type: Types):void\n off(){\n const args = arguments\n const type = typeof(args[0])==='function' ? undefined : args[0]\n const listener = typeof(args[0])==='function' ? args[0] : args[1]\n const parts = type ? type.split(this._delimiter) : []\n const hasWildcard= type ? type.includes('*') : false\n if(type && !hasWildcard){\n this._traverseToPath(this.listeners,parts,(node)=>{\n if(listener){ // 只删除指定的监听器\n this._removeListener(node,parts,listener)\n }else if(type){\n node.__listeners=[]\n }\n })\n }else{ // 仅删除指定的侦听器\n const entryParts:string[] = hasWildcard ? [] : parts\n this._traverseListeners(this.listeners,entryParts,(path,node)=>{ \n if(listener!==undefined || (hasWildcard && isPathMatched(path,parts))){\n if(listener){\n this._removeListener(node,parts,listener)\n }else{\n node.__listeners=[]\n } \n }\n })\n }\n }\n \n /**\n * 移除所有事件监听器\n * @param entry - 可选的事件前缀,如果提供则只移除指定前缀下的的监听器\n * @description \n * - 如果提供了prefix参数,则只清除该前缀下的所有监听器\n * - 如果没有提供prefix,则清除所有监听器\n * - 同时会清空保留的事件(_retainedEvents)\n * - 重置监听器对象为空\n\n * @example\n * \n * ```ts\n * emitter.offAll(); // 清除所有监听器\n * emitter.offAll('a/b'); // 清除a/b下的所有监听器\n * \n */\n offAll(entry?: string) { \n if(entry){\n const entryNode = this._getListenerNode(entry.split(this._delimiter))\n if(entryNode) entryNode.__listeners = []\n this._removeRetainedEvents(entry)\n }else{ \n this._retainedEvents.clear() \n this.listeners = { __listeners: [] } as unknown as FastListeners\n }\n }\n\n private _getListenerNode(parts:string[]):FastListenerNode | undefined{\n let entryNode: FastListenerNode | undefined\n this._forEachNodes(parts,(node)=>{\n entryNode = node\n })\n return entryNode\n }\n /**\n * 移除保留的事件\n * @param prefix - 事件前缀。如果不提供,将清除所有保留的事件。\n * 如果提供前缀,将删除所有以该前缀开头的事件。\n * 如果前缀不以分隔符结尾,会自动添加分隔符。\n * @private\n */\n private _removeRetainedEvents(prefix?: string) {\n if (!prefix) this._retainedEvents.clear()\n if(prefix?.endsWith(this._delimiter)){\n prefix+=this._delimiter\n } \n this._retainedEvents.delete(prefix!)\n for(let key of this._retainedEvents.keys()){\n if(key.startsWith(prefix!)){\n this._retainedEvents.delete(key)\n }\n }\n } \n clear(){\n this.offAll()\n }\n private _getMeta(extra:Record<string,any>){\n if(!this._options.meta) return extra\n return Object.assign({},this._options.meta,extra) as FastEventMeta<any,any> \n }\n private _emitForLastEvent(type:string){ \n if(this._retainedEvents.has(type)){\n const payload = this._retainedEvents.get(type)\n const parts = type.split(this._delimiter); \n this._traverseToPath(this.listeners,parts,(node)=>{ \n this._executeListeners(node,payload,this._getMeta({type}))\n }) \n // onAny侦听器保存在根节点中,所以需要执行\n this._executeListeners(this.listeners,payload,this._getMeta({type}))\n } \n }\n\n /**\n * 遍历监听器节点树\n * @param node 当前遍历的监听器节点\n * @param parts 事件名称按'.'分割的部分数组\n * @param callback 遍历到目标节点时的回调函数\n * @param index 当前遍历的parts数组索引,默认为0\n * @param lastFollowing 当命中**时该值为true, 注意**只能作在路径的最后面,如a.**有效,而a.**.b无效\n * @private\n * \n * 支持三种匹配模式:\n * - 精确匹配: 'a.b.c'\n * - 单层通配: 'a.*.c' \n * - 多层通配: 'a.**'\n */\n private _traverseToPath(node: FastListenerNode, parts: string[], callback: (node: FastListenerNode) => void, index: number = 0, lastFollowing?:boolean): void {\n\n if (index >= parts.length) {\n callback(node)\n return\n } \n const part = parts[index] \n\n if(lastFollowing===true){\n this._traverseToPath(node, parts, callback, index + 1,true)\n return\n }\n\n if (part in node) {\n this._traverseToPath(node[part], parts, callback, index + 1)\n }\n\n if ('*' in node) {\n this._traverseToPath(node['*'], parts, callback, index + 1)\n }\n // \n if ('**' in node) {\n this._traverseToPath(node['**'], parts, callback, index + 1,true)\n }\n }\n\n private _traverseListeners(node: FastListenerNode, entry:string[], callback: (path:string[],node: FastListenerNode) => void): void {\n let entryNode: FastListenerNode = node\n // 如果指定了entry路径,则按照路径遍历\n if (entry && entry.length > 0) { \n this._traverseToPath(node, entry,(node)=>{\n entryNode= node\n });\n }\n const traverseNodes = (node: FastListenerNode, callback: (path:string[],node: FastListenerNode) => void,parentPath:string[])=>{\n callback(parentPath, node); \n for(let [key,childNode] of Object.entries(node)){\n if(key.startsWith(\"__\")) continue\n if(childNode){\n traverseNodes(childNode as FastListenerNode, callback,[...parentPath,key]);\n }\n }\n }\n // 如果没有指定entry或entry为空数组,则递归遍历所有节点\n traverseNodes(entryNode, callback,[]);\n } \n\n private _executeListener(listener:any, payload: any,meta: FastEventMeta<any,any> ):any{\n try{\n if(typeof(listener.__wrappedListener)==='function'){\n return listener.__wrappedListener.call(this._context,payload,meta)\n }else{\n return listener.call(this._context,payload,meta)\n }\n }catch(e:any){\n e._trigger = meta.type\n if(typeof(this._options.onListenerError)==='function'){\n this._options.onListenerError.call(this,meta.type,e)\n }\n // 如果忽略错误,则返回错误对象\n if(this._options.ignoreErrors){\n return e\n }else{\n throw e\n }\n }\n }\n\n /**\n * 执行监听器节点中的所有监听函数\n * @param node - FastListenerNode类型的监听器节点\n * @param payload - 事件携带的数据\n * @param type - 事件类型\n * @returns 返回所有监听函数的执行结果数组\n * @private\n * \n * @description\n * 遍历执行节点中的所有监听函数:\n * - 对于普通监听器,直接执行并收集结果\n * - 对于带次数限制的监听器(数组形式),执行后递减次数,当次数为0时移除该监听器\n */\n private _executeListeners(node: FastListenerNode, payload: any, meta: Meta): any[] {\n if (!node || !node.__listeners) return []\n let i = 0\n const listeners = node.__listeners\n let result:any[] = []\n while(i<listeners.length){\n const listener = listeners[i]\n if(Array.isArray(listener)){\n result.push(this._executeListener(listener[0],payload,meta)) \n listener[1]-- \n if(listener[1]===0) {\n listeners.splice(i,1)\n i-- // 抵消后面的i++\n }\n }else{\n result.push(this._executeListener(listener,payload,meta)) \n } \n i++ \n }\n return result\n }\n\n public emit<R=any>(type:string,payload?:any,retain?:boolean,meta?:Meta):R[]\n public emit<R=any>(type:Types,payload?:Events[Types],retain?:boolean,meta?:Meta):R[]\n public emit<R=any>():R[]{\n const type = arguments[0] as string\n const payload = arguments[1] as any\n const retain = arguments[2] as boolean\n const meta = (arguments[3] || {}) as Meta\n\n const parts = type.split(this._delimiter); \n if(retain) {\n this._retainedEvents.set(type,payload)\n } \n const results:any[] = []\n this._traverseToPath(this.listeners,parts,(node)=>{ \n results.push(...this._executeListeners(node,payload,this._getMeta({...meta,type})))\n }) \n // onAny侦听器保存在根节点中,所以需要执行 \n results.push(...this._executeListeners(this.listeners,payload,this._getMeta({...meta,type})))\n return results\n }\n\n public async emitAsync<R=any>(type:string,payload?:any,retain?:boolean,meta?:Meta):Promise<[R|Error][]>\n public async emitAsync<R=any>(type:Types,payload?:Events[Types],retain?:boolean,meta?:Meta):Promise<[R|Error][]>\n public async emitAsync<P=any>():Promise<[P|Error][]>{\n const type = arguments[0] as string\n const payload = arguments[1] as any\n const retain = arguments[2] as boolean\n const meta = (arguments[3] || {}) as Meta\n\n const results = await Promise.allSettled(this.emit<P>(type,payload,retain,this._getMeta({...meta,type})))\n return results.map((result)=>{\n if(result.status==='fulfilled'){\n return result.value\n }else{\n return result.reason\n }\n })\n }\n\n /**\n * 等待指定事件发生\n * \n * @param type \n * @param timeout 超时时间,单位毫秒,默认为 0,表示无限等待\n */\n public waitFor<R=any>(type:string,timeout?:number):Promise<R>\n public waitFor<R=any>(type:Types,timeout?:number):Promise<R>\n public waitFor<R=any>():Promise<R>{\n const type = arguments[0] as string\n const timeout = arguments[1] as number\n return new Promise<R>((resolve,reject)=>{\n let tid:any\n let subscriber:FastEventSubscriber\n const listener = (payload:any)=>{\n clearTimeout(tid)\n subscriber.off() \n resolve(payload) \n }\n if(timeout && timeout>0){\n tid = setTimeout(()=>{\n subscriber && subscriber.off()\n reject(new Error('wait for event<'+ type +'> is timeout'))\n },timeout)\n }\n subscriber = this.on(type,listener) \n }) \n }\n\n /**\n * 创建事件域\n * \n * 注意:\n * \n * 事件域与当前事件对象共享相同的侦听器表\n * 也就是说,如果在事件域中触发事件,当前事件对象也会触发该事件\n * 两者工不是完全隔离的,仅是事件侦听和触发时的事件类型不同而已\n * \n * const emitter = new FastEvent()\n * \n * const scope= emitter.scope(\"a/b\")\n * \n * scope.on(\"x\",()=>{}) == emitter.on(\"a/b/x\",()=>{})\n * scope.emit(\"x\",1) == emitter.emit(\"a/b/x\",1) \n * scope.offAll() == emitter.offAll(\"a/b\")\n * \n */\n scope<T extends string>(prefix:T){ \n return new FastEventScope<ScopeEvents<Events,T>>(this as unknown as FastEvent<ScopeEvents<Events,T>>,prefix)\n }\n\n} "]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fastevent",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "fast event emitter",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/readme.md CHANGED
@@ -1,109 +1,109 @@
1
1
  # FastEvent
2
2
 
3
- FastEvent 是一个功能强大的`TypeScript`事件管理库,提供了灵活的事件订阅和发布机制,支持事件通配符、作用域、异步事件等特性。
3
+ FastEvent is a powerful TypeScript event management library that provides flexible event subscription and publishing mechanisms, supporting features such as event wildcards, scoping, and asynchronous events.
4
4
 
5
- 对比`EventEmitter2`,`FastEvent`具有以下优势:
5
+ Compared to `EventEmitter2`, `FastEvent` has the following advantages:
6
6
 
7
- - 在含通配符发布与订阅时,`FastEvent`的性能比`EventEmitter2`高 `1+`倍左右。
8
- - `FastEvent`包大小为 `6.3xkb`,而`EventEmitter2`为 `43.4kb`。
9
- - `FastEvent`拥有更丰富的功能。
7
+ - `FastEvent` performs about `1+` times better than `EventEmitter2` when publishing and subscribing with wildcards.
8
+ - `FastEvent` has a package size of `6.3kb`, while `EventEmitter2` is `43.4kb`.
9
+ - `FastEvent` offers more comprehensive features.
10
10
 
11
- # 安装
11
+ # Installation
12
12
 
13
- 使用 npm 安装:
13
+ Install using npm:
14
14
 
15
15
  ```bash
16
16
  npm install fastevent
17
17
  ```
18
18
 
19
- 或使用 yarn:
19
+ Or using yarn:
20
20
 
21
21
  ```bash
22
22
  yarn add fastevent
23
23
  ```
24
24
 
25
- # 快速入门
25
+ # Quick Start
26
26
 
27
- ## 基本使用
27
+ ## Basic Usage
28
28
 
29
29
  ```typescript
30
30
  import { FastEvent } from 'fastevent';
31
31
 
32
- // 创建事件实例
32
+ // Create event instance
33
33
  const events = new FastEvent();
34
34
 
35
- // 订阅事件
35
+ // Subscribe to event
36
36
  events.on('user/login', (user) => {
37
- console.log('用户登录:', user);
37
+ console.log('User login:', user);
38
38
  });
39
39
 
40
- // 发布事件
40
+ // Publish event
41
41
  events.emit('user/login', { id: 1, name: 'Alice' });
42
42
  ```
43
43
 
44
- # 指南
44
+ # Guide
45
45
 
46
- ## 事件通配符
46
+ ## Event Wildcards
47
47
 
48
- FastEvent 支持两种通配符:
49
- - `*`: 匹配单层路径
50
- - `**`: 匹配多层路径
48
+ FastEvent supports two types of wildcards:
49
+ - `*`: Matches a single path level
50
+ - `**`: Matches multiple path levels
51
51
 
52
52
  ```typescript
53
53
  const events = new FastEvent();
54
54
 
55
- // 匹配 user/*/login
55
+ // Matches user/*/login
56
56
  events.on('user/*/login', (data) => {
57
- console.log('任何用户类型的登录:', data);
57
+ console.log('Any user type login:', data);
58
58
  });
59
59
 
60
- // 匹配 user 下的所有事件
60
+ // Matches all events under user
61
61
  events.on('user/**', (data) => {
62
- console.log('所有用户相关事件:', data);
62
+ console.log('All user-related events:', data);
63
63
  });
64
64
 
65
- // 触发事件
66
- events.emit('user/admin/login', { id: 1 }); // 两个处理器都会被调用
67
- events.emit('user/admin/profile/update', { name: 'New' }); // 只有 ** 处理器会被调用
65
+ // Trigger events
66
+ events.emit('user/admin/login', { id: 1 }); // Both handlers will be called
67
+ events.emit('user/admin/profile/update', { name: 'New' }); // Only ** handler will be called
68
68
  ```
69
69
 
70
- ## 事件作用域
70
+ ## Event Scoping
71
71
 
72
- 作用域允许你在特定的命名空间下处理事件:
72
+ Scopes allow you to handle events within specific namespaces:
73
73
 
74
74
  ```typescript
75
75
  const events = new FastEvent();
76
76
 
77
- // 创建用户相关的作用域
77
+ // Create user-related scope
78
78
  const userScope = events.scope('user');
79
79
 
80
- // 在作用域中订阅事件
80
+ // Subscribe to events within the scope
81
81
  userScope.on('login', (data) => {
82
- console.log('用户登录:', data);
82
+ console.log('User login:', data);
83
83
  });
84
84
 
85
- // 等同于 events.emit('user/login', data)
85
+ // Equivalent to events.emit('user/login', data)
86
86
  userScope.emit('login', { id: 1 });
87
87
  ```
88
88
 
89
- ## 一次性事件
89
+ ## One-time Events
90
90
 
91
- 使用 `once` 订阅只触发一次的事件:
91
+ Use `once` to subscribe to events that trigger only once:
92
92
 
93
93
  ```typescript
94
94
  const events = new FastEvent();
95
95
 
96
96
  events.once('startup', () => {
97
- console.log('应用启动');
97
+ console.log('Application started');
98
98
  });
99
99
 
100
- events.emit('startup'); // 输出: 应用启动
101
- events.emit('startup'); // 无输出,监听器已被移除
100
+ events.emit('startup'); // Output: Application started
101
+ events.emit('startup'); // No output, listener has been removed
102
102
  ```
103
103
 
104
- ## 异步事件
104
+ ## Asynchronous Events
105
105
 
106
- 支持异步事件处理:
106
+ Support for asynchronous event handling:
107
107
 
108
108
  ```typescript
109
109
  const events = new FastEvent();
@@ -113,54 +113,54 @@ events.on('data/fetch', async () => {
113
113
  return await response.json();
114
114
  });
115
115
 
116
- // 异步发布事件
116
+ // Async event publishing
117
117
  const results = await events.emitAsync('data/fetch');
118
- console.log('所有处理器的结果:', results);
118
+ console.log('Results from all handlers:', results);
119
119
  ```
120
120
 
121
- ## 事件等待
121
+ ## Event Waiting
122
122
 
123
- 使用 `waitFor` 等待特定事件发生:
123
+ Use `waitFor` to wait for specific events:
124
124
 
125
125
  ```typescript
126
126
  const events = new FastEvent();
127
127
 
128
128
  async function waitForLogin() {
129
129
  try {
130
- // 等待登录事件,超时时间 5
130
+ // Wait for login event with 5 seconds timeout
131
131
  const userData = await events.waitFor('user/login', 5000);
132
- console.log('用户已登录:', userData);
132
+ console.log('User logged in:', userData);
133
133
  } catch (error) {
134
- console.log('登录等待超时');
134
+ console.log('Login wait timeout');
135
135
  }
136
136
  }
137
137
 
138
138
  waitForLogin();
139
- // 稍后触发登录事件
139
+ // Later trigger login event
140
140
  events.emit('user/login', { id: 1, name: 'Alice' });
141
141
  ```
142
142
 
143
- ## 保留事件数据
143
+ ## Retain Event Data
144
144
 
145
- 保留最后一次事件数据,新的订阅者会立即收到该数据:
145
+ Retain the last event data, new subscribers will receive it immediately:
146
146
 
147
147
  ```typescript
148
148
  const events = new FastEvent();
149
149
 
150
- // 发布事件并保留
150
+ // Publish event and retain
151
151
  events.emit('config/update', { theme: 'dark' }, true);
152
152
 
153
- // 之后的订阅者会立即收到保留的数据
153
+ // Later subscribers will immediately receive the retained data
154
154
  events.on('config/update', (config) => {
155
- console.log('配置:', config); // 立即输出: 配置: { theme: 'dark' }
155
+ console.log('Config:', config); // Immediately outputs: Config: { theme: 'dark' }
156
156
  });
157
157
  ```
158
158
 
159
- ## 多级事件
159
+ ## Multi-level Events
160
160
 
161
- 支持发布和订阅多级事件。
161
+ Support for publishing and subscribing to multi-level events.
162
162
 
163
- 默认使用 `/` 作为事件路径分隔符,你也可以使用自定义的分隔符:
163
+ By default, '/' is used as the event path delimiter, but you can use custom delimiters:
164
164
 
165
165
  ```typescript
166
166
  const events = new FastEvent({
@@ -168,28 +168,28 @@ const events = new FastEvent({
168
168
  });
169
169
  ```
170
170
 
171
- ## 全局事件监听
171
+ ## Global Event Listening
172
172
 
173
- 使用 `onAny` 监听所有事件:
173
+ Use `onAny` to listen to all events:
174
174
 
175
175
  ```typescript
176
176
  const events = new FastEvent();
177
177
 
178
178
  events.onAny((data, meta) => {
179
- console.log(`事件 ${meta.type} 被触发:`, data);
179
+ console.log(`Event ${meta.type} triggered:`, data);
180
180
  });
181
181
 
182
- events.emit('user/login', { id: 1 }); // 输出: 事件 user/login 被触发: { id: 1 }
183
- events.emit('system/error', 'Connection failed'); // 输出: 事件 system/error 被触发: Connection failed
182
+ events.emit('user/login', { id: 1 }); // Output: Event user/login triggered: { id: 1 }
183
+ events.emit('system/error', 'Connection failed'); // Output: Event system/error triggered: Connection failed
184
184
  ```
185
185
 
186
- ## 元数据(Meta)
186
+ ## Metadata (Meta)
187
187
 
188
- 元数据是一种为事件提供额外上下文信息的机制。你可以在全局范围内设置元数据,也可以为单个事件添加特定的元数据。
188
+ Metadata is a mechanism for providing additional context information for events. You can set metadata globally or add specific metadata for individual events.
189
189
 
190
- ### 全局元数据
190
+ ### Global Metadata
191
191
 
192
- 在创建 FastEvent 实例时设置全局元数据:
192
+ Set global metadata when creating a FastEvent instance:
193
193
 
194
194
  ```typescript
195
195
  const events = new FastEvent({
@@ -200,83 +200,83 @@ const events = new FastEvent({
200
200
  });
201
201
 
202
202
  events.on('user/login', (data, meta) => {
203
- console.log('事件数据:', data);
204
- console.log('元数据:', meta); // 包含 typeversion environment
203
+ console.log('Event data:', data);
204
+ console.log('Metadata:', meta); // Contains type, version, and environment
205
205
  });
206
206
  ```
207
207
 
208
- ### 事件特定元数据
208
+ ### Event-specific Metadata
209
209
 
210
- 在发布事件时可以传递额外的元数据,它会与全局元数据合并:
210
+ Additional metadata can be passed when publishing events, which will be merged with global metadata:
211
211
 
212
212
  ```typescript
213
213
  const events = new FastEvent({
214
214
  meta: { app: 'MyApp' }
215
215
  });
216
216
 
217
- // 在发布事件时添加特定的元数据
217
+ // Add specific metadata when publishing event
218
218
  events.emit('order/create',
219
- { orderId: '123' }, // 事件数据
220
- false, // 不保留
221
- { timestamp: Date.now() } // 事件特定的元数据
219
+ { orderId: '123' }, // Event data
220
+ false, // Don't retain
221
+ { timestamp: Date.now() } // Event-specific metadata
222
222
  );
223
223
 
224
- // 监听器接收合并后的元数据
224
+ // Listener receives merged metadata
225
225
  events.on('order/create', (data, meta) => {
226
- console.log('订单:', data); // { orderId: '123' }
227
- console.log('元数据:', meta); // { type: 'order/create', app: 'MyApp', timestamp: ... }
226
+ console.log('Order:', data); // { orderId: '123' }
227
+ console.log('Metadata:', meta); // { type: 'order/create', app: 'MyApp', timestamp: ... }
228
228
  });
229
229
  ```
230
230
 
231
- ## 错误处理
231
+ ## Error Handling
232
232
 
233
- FastEvent 提供了错误处理机制:
233
+ FastEvent provides error handling mechanisms:
234
234
 
235
235
  ```typescript
236
236
  const events = new FastEvent({
237
- ignoreErrors: true, // 默认为 true,不会抛出错误
237
+ ignoreErrors: true, // Default is true, won't throw errors
238
238
  onListenerError: (type, error) => {
239
- console.error(`处理事件 ${type} 时发生错误:`, error);
239
+ console.error(`Error handling event ${type}:`, error);
240
240
  }
241
241
  });
242
242
 
243
243
  events.on('process', () => {
244
- throw new Error('处理失败');
244
+ throw new Error('Processing failed');
245
245
  });
246
246
 
247
- // 不会抛出错误,而是触发 onListenerError
247
+ // Won't throw error, will trigger onListenerError instead
248
248
  events.emit('process');
249
249
  ```
250
250
 
251
- ## 自定义选项
251
+ ## Custom Options
252
252
 
253
- FastEvent 构造函数支持多个选项:
253
+ The FastEvent constructor supports multiple options:
254
254
 
255
255
  ```typescript
256
256
  const events = new FastEvent({
257
- // 事件路径分隔符,默认为 '/'
257
+ // Event path delimiter, default is '/'
258
258
  delimiter: '.',
259
- // 事件处理器的上下文
259
+ // Context for event handlers
260
260
  context: null,
261
- // 元数据,会传递给所有事件处理器
262
- meta: { version: '1.0' },
261
+ // Metadata, passed to all event handlers
262
+ meta: { ... },
263
263
 
264
- // 错误处理
264
+ // Error handling
265
265
  ignoreErrors: true,
266
266
  onListenerError: (type, error) => {
267
- console.error(`事件错误:`, type, error);
267
+ console.error(`Event error:`, type, error);
268
268
  },
269
269
 
270
- // 监听器添加/移除的回调
270
+ // Callbacks for listener addition/removal
271
271
  onAddListener: (path, listener) => {
272
- console.log('添加监听器:', path);
272
+ console.log('Listener added:', path);
273
273
  },
274
274
  onRemoveListener: (path, listener) => {
275
- console.log('移除监听器:', path);
275
+ console.log('Listener removed:', path);
276
276
  }
277
277
  });
278
278
  ```
279
279
 
280
- # 性能
280
+ # Performance
281
281
 
282
282
  ![](./bench.png)