From 969743f9b9ec67c9248cdf0e9b58d6d5ec5b4784 Mon Sep 17 00:00:00 2001 From: wxzhang Date: Sat, 21 Oct 2023 15:01:28 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat(events/flexEvent):=20=20flexEvent?= =?UTF-8?q?=E6=96=B0EEOEE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/events/flexEvent.ts | 66 ++++++++++++++++++++--------------------- src/events/liteEvent.ts | 36 +++++++++++----------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/events/flexEvent.ts b/src/events/flexEvent.ts index 7eb519e..d08b629 100644 --- a/src/events/flexEvent.ts +++ b/src/events/flexEvent.ts @@ -42,26 +42,26 @@ export type FlexListenerRegistry = Map> /** * Event: 指定一个通用事件类型 */ -export class FlexEvent{ +export class FlexEvent= Record>{ // {"<事件名称>":{:[Callback,<侦听次数>]}} - #listeners:FlexListenerRegistry= new Map() - #options:Required + private _listeners:FlexListenerRegistry= new Map() + private _options:Required // 保留最后一次触发的消息,key=事件名称,value=消息 - #lastMessage:Record = {} + private _lastMessage:Record = {} static listenerSeqId:number = 0 constructor(options:FlexEventOptions = {ignoreError:true,context:null}){ - this.#options = assignObject({ + this._options = assignObject({ ignoreError:true, wildcard: true, delimiter:"/", context:null - },options) as Required + },options) as Required } - get options(){return this.#options} - get delimiter(){return this.#options.delimiter} + get options(){return this._options} + get delimiter(){return this._options.delimiter} get context(){ return this.options.context} - get listeners(){return this.#listeners} - get retainedMessages(){return this.#lastMessage} + get listeners(){return this._listeners} + get retainedMessages(){return this._lastMessage} /** * 检测事件是否匹配 * @@ -80,7 +80,7 @@ export class FlexEvent{ */ private isEventMatched(pattern:string,event:string):boolean{ if(pattern == event) return true - if(this.#options.wildcard && pattern.includes("*")){ + if(this._options.wildcard && pattern.includes("*")){ // 由于通配符**与*冲突,所以先将**替换成一个特殊的字符 const regex =new RegExp("^"+pattern.replaceAll("**",`__###__`).replaceAll("*","[\\w\\*]*").replaceAll("__###__",`[\\w\\\\*${this.delimiter}]*`)+"$") return regex.test(event) @@ -104,11 +104,11 @@ export class FlexEvent{ */ on(event:Events,callback:FlexEventListener,options?:SubscribeOptions):FlexEventSubscriber | number{ const { objectify = false,count=-1 } =Object.assign({},options) as Required - if(!this.#listeners.has(event)){ - this.#listeners.set(event,new Map()) + if(!this._listeners.has(event)){ + this._listeners.set(event,new Map()) } const listenerId = ++ FlexEvent.listenerSeqId - const eventListeners = this.#listeners.get(event) as FlexEventListenerRegistry + const eventListeners = this._listeners.get(event) as FlexEventListenerRegistry eventListeners?.set(listenerId,[callback,count]) // 如果启用了retain,则应该马上触发最后保存的事件 this.emitRetainEvent(event,listenerId,eventListeners) @@ -117,7 +117,7 @@ export class FlexEvent{ off:()=>{ eventListeners?.delete(listenerId) if(eventListeners?.size==0){ - this.#listeners.delete(event) + this._listeners.delete(event) } } } @@ -131,12 +131,12 @@ export class FlexEvent{ */ private emitRetainEvent(event:Events,listenerId:number,eventListeners:FlexEventListenerRegistry){ //setTimeout(()=>{ - if(event in this.#lastMessage){ - this.executeListener(listenerId,eventListeners,this.#lastMessage[event]) + if(event in this._lastMessage){ + this.executeListener(listenerId,eventListeners,this._lastMessage[event]) }else if(this.options.wildcard){ // 检查是否有通配符 - for(const [key] of Object.entries(this.#lastMessage)){ + for(const [key] of Object.entries(this._lastMessage)){ if(this.isEventMatched(event,key) || this.isEventMatched(key,event) ){ - this.executeListener(listenerId,eventListeners,this.#lastMessage[key]) + this.executeListener(listenerId,eventListeners,this._lastMessage[key]) } } } @@ -161,7 +161,7 @@ export class FlexEvent{ private forEachListeners(callback:({event,listenerId,listener,count,eventListeners}:{event:Events,listenerId:number,listener:FlexEventListener,count:number,eventListeners:FlexEventListenerRegistry})=>boolean | void){ // {"<事件名称>":{:[Callback,<侦听次数>]}} let isAbort = false - for(let [event,eventListeners] of this.#listeners.entries()){ + for(let [event,eventListeners] of this._listeners.entries()){ if(isAbort) break for(let [listenerId,[listener,count]] of eventListeners.entries()){ if(isAbort) break @@ -200,9 +200,9 @@ export class FlexEvent{ */ private getMatchedListeners(event:Events):[Events,FlexEventListenerRegistry | undefined][] { if(this.options.wildcard){ // 启用通配符 - return [...this.#listeners.entries()].filter(([eventName])=>(this.isEventMatched(eventName,event)) || this.isEventMatched(event,eventName)) + return [...this._listeners.entries()].filter(([eventName])=>(this.isEventMatched(eventName,event)) || this.isEventMatched(event,eventName)) }else{ - return [[event,this.#listeners.get(event)]] + return [[event,this._listeners.get(event)]] } } @@ -234,7 +234,7 @@ export class FlexEvent{ this.forEachListeners(({listenerId,eventListeners,event})=>{ if(listenerId == arguments[0]){ eventListeners.delete(listenerId) - if(this.#listeners.get(event)?.size==0) this.#listeners.delete(event) + if(this._listeners.get(event)?.size==0) this._listeners.delete(event) return false } }) @@ -243,7 +243,7 @@ export class FlexEvent{ this.forEachListeners(({listenerId,listener,eventListeners,event})=>{ if(listener == callback){ eventListeners.delete(listenerId) - if(this.#listeners.get(event)?.size==0) this.#listeners.delete(event) + if(this._listeners.get(event)?.size==0) this._listeners.delete(event) } }) } @@ -252,7 +252,7 @@ export class FlexEvent{ this.forEachEventListeners(arguments[0] as Events,({event,listenerId,listener,eventListeners})=>{ if(event == arguments[0] && listener == arguments[1] ){ eventListeners.delete(listenerId) - if(this.#listeners.get(event)?.size==0) this.#listeners.delete(event) + if(this._listeners.get(event)?.size==0) this._listeners.delete(event) } }) } @@ -320,14 +320,14 @@ export class FlexEvent{ }) } clear(){ - this.#lastMessage={} + this._lastMessage={} this.offAll() } offAll(event?:Events){ if(event){ - this.#listeners.delete(event) + this._listeners.delete(event) }else{ - this.#listeners.clear() + this._listeners.clear() } } /** @@ -379,7 +379,7 @@ export class FlexEvent{ results.push(this.executeListener(listenerId,eventListeners,message)) if(typeof(callback)=='function') callback(listenerId) if(eventListeners.size==0){ - this.#listeners.delete(eventName) + this._listeners.delete(eventName) } }) return results @@ -394,7 +394,7 @@ export class FlexEvent{ */ emit(event:Events,message?:Message,retain?:boolean){ if(retain){ - this.#lastMessage[event] = message + this._lastMessage[event] = message } return this.executeListeners(event,message) } @@ -408,7 +408,7 @@ export class FlexEvent{ async emitAsync(event:Events,message?:Message,retain?:boolean){ const listeners = this.getListeners(event) if(retain){ - this.#lastMessage[event] = message + this._lastMessage[event] = message } let results = await Promise.allSettled(listeners.map((listener:Function) =>{ return listener.call(this,message) @@ -424,8 +424,8 @@ export class FlexEvent{ } } } - if(this.#listeners.get(eventName)?.size==0){ - this.#listeners.delete(eventName) + if(this._listeners.get(eventName)?.size==0){ + this._listeners.delete(eventName) } }) diff --git a/src/events/liteEvent.ts b/src/events/liteEvent.ts index a2ca527..7ffb08e 100644 --- a/src/events/liteEvent.ts +++ b/src/events/liteEvent.ts @@ -27,11 +27,11 @@ export type LiteListenerRegistry = Map> export class LiteEvent{ // {"<事件名称>":{:[Callback,<侦听次数>]}} - #listeners:LiteListenerRegistry= new Map() + private _listeners:LiteListenerRegistry= new Map() // 保留最后一次触发的消息,key=事件名称,value=消息 - #lastMessage:Record = {} + private _lastMessage:Record = {} static listenerSeqId:number = 0 - get listeners(){return this.#listeners} + get listeners(){return this._listeners} /** * 订阅事件并返回一个事件订阅ID * @@ -42,11 +42,11 @@ export class LiteEvent{ */ on(event:Events,callback:LiteEventListener,options?:LiteEventSubscribeOptions):LiteEventSubscriber | number{ const { objectify = false,count=-1 } = Object.assign({},options) as Required - if(!this.#listeners.has(event)){ - this.#listeners.set(event,new Map()) + if(!this._listeners.has(event)){ + this._listeners.set(event,new Map()) } const listenerId = ++LiteEvent.listenerSeqId - const eventListeners = this.#listeners.get(event) as LiteEventListenerRegistry + const eventListeners = this._listeners.get(event) as LiteEventListenerRegistry eventListeners?.set(listenerId,[callback,count]) // 如果启用了retain,则应该马上触发最后保存的事件 this.emitRetainEvent(event,listenerId,eventListeners) @@ -55,7 +55,7 @@ export class LiteEvent{ off:()=>{ eventListeners?.delete(listenerId) if(eventListeners?.size==0){ - this.#listeners.delete(event) + this._listeners.delete(event) } } } @@ -68,8 +68,8 @@ export class LiteEvent{ * @param event */ private emitRetainEvent(event:Events,listenerId:number,eventListeners:LiteEventListenerRegistry){ - if(event in this.#lastMessage){ - this.executeListener(listenerId,eventListeners,this.#lastMessage[event]) + if(event in this._lastMessage){ + this.executeListener(listenerId,eventListeners,this._lastMessage[event]) } } /** @@ -91,7 +91,7 @@ export class LiteEvent{ private forEachListeners(callback:({event,listenerId,listener,count,eventListeners}:{event:Events,listenerId:number,listener:LiteEventListener,count:number,eventListeners:LiteEventListenerRegistry})=>boolean | void){ // {"<事件名称>":{:[Callback,<侦听次数>]}} let isAbort = false - for(let [event,eventListeners] of this.#listeners.entries()){ + for(let [event,eventListeners] of this._listeners.entries()){ if(isAbort) break for(let [listenerId,[listener,count]] of eventListeners.entries()){ if(isAbort) break @@ -113,7 +113,7 @@ export class LiteEvent{ private forEachEventListeners(event:Events,callback:ForEachLiteEventListenerCallback){ // {"<事件名称>":{:[Callback,<侦听次数>]}} let isAbort = false - let matchedListeners = [[event,this.#listeners.get(event)]] as [Events,LiteEventListenerRegistry | undefined][] + let matchedListeners = [[event,this._listeners.get(event)]] as [Events,LiteEventListenerRegistry | undefined][] for(let [eventName,eventListeners] of matchedListeners){ if(!eventListeners) continue for(let [listenerId,[listener,count]] of eventListeners){ @@ -150,7 +150,7 @@ export class LiteEvent{ this.forEachListeners(({listenerId,eventListeners,event})=>{ if(listenerId == arguments[0]){ eventListeners.delete(listenerId) - if(this.#listeners.get(event)?.size==0) this.#listeners.delete(event) + if(this._listeners.get(event)?.size==0) this._listeners.delete(event) return false } }) @@ -159,7 +159,7 @@ export class LiteEvent{ this.forEachListeners(({listenerId,listener,eventListeners,event})=>{ if(listener == callback){ eventListeners.delete(listenerId) - if(this.#listeners.get(event)?.size==0) this.#listeners.delete(event) + if(this._listeners.get(event)?.size==0) this._listeners.delete(event) } }) } @@ -168,7 +168,7 @@ export class LiteEvent{ this.forEachEventListeners(arguments[0] as Events,({event,listenerId,listener,eventListeners})=>{ if(event == arguments[0] && listener == arguments[1] ){ eventListeners.delete(listenerId) - if(this.#listeners.get(event)?.size==0) this.#listeners.delete(event) + if(this._listeners.get(event)?.size==0) this._listeners.delete(event) } }) } @@ -199,9 +199,9 @@ export class LiteEvent{ } offAll(event?:Events){ if(event){ - this.#listeners.delete(event) + this._listeners.delete(event) }else{ - this.#listeners.clear() + this._listeners.clear() } } /** @@ -234,7 +234,7 @@ export class LiteEvent{ results.push(this.executeListener(listenerId,eventListeners,message)) if(typeof(callback)=='function') callback(listenerId) if(eventListeners.size==0){ - this.#listeners.delete(eventName) + this._listeners.delete(eventName) } }) return results @@ -246,7 +246,7 @@ export class LiteEvent{ */ emit(event:Events,message?:Message,retain?:boolean){ if(retain){ - this.#lastMessage[event] = message + this._lastMessage[event] = message } return this.executeListeners(event,message) } From 99a8268a5d5dd476f30fb3dbafe4d497fc987dd7 Mon Sep 17 00:00:00 2001 From: wxzhang Date: Sat, 21 Oct 2023 15:01:49 +0800 Subject: [PATCH 2/6] 1.3.39 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 74bf8a1..61758f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flex-tools", - "version": "1.3.38", + "version": "1.3.39", "description": "modular utilities.", "main": "dist/index.js", "module": "dist/index.mjs", From d8147986cdca63ab45f596fc582fa447b91f8f62 Mon Sep 17 00:00:00 2001 From: wxzhang Date: Sat, 21 Oct 2023 17:12:28 +0800 Subject: [PATCH 3/6] =?UTF-8?q?feat(types):=20=E6=96=B0=E5=A2=9E=E5=8A=A0O?= =?UTF-8?q?ptional=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/guide/types.md | 26 ++++++++++++++++++++++++++ src/types/optional.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/types/optional.ts diff --git a/docs/guide/types.md b/docs/guide/types.md index 6304822..5f066e1 100644 --- a/docs/guide/types.md +++ b/docs/guide/types.md @@ -340,3 +340,29 @@ Overloads == (a: string)=>string | (a: number)=>number | (a: any)=> - `Overloads` 只能获取最多8个重载的类型。 +## Optional + +将类型中的所有属性变为可选属性,排除指定的键名。 + +```typescript +export interface SiteOptions{ + id:string + icon:string + logo:string + title:string + path:string +} + +type mysite = Optional + +// type mysite == { +// id:string +// icon?:string +// logo?:string +// title?:string +// path:string +// } + +``` + +- `Optional`等价于`Partial`,但`Optional`可以排除指定的键名。 diff --git a/src/types/optional.ts b/src/types/optional.ts new file mode 100644 index 0000000..634aa82 --- /dev/null +++ b/src/types/optional.ts @@ -0,0 +1,31 @@ + + +export type Optional = Partial & Required>; + + + +// export interface SiteOptions{ +// id:string // 站点ID +// icon:string // 站点图标 +// logo:string // 站点logo +// title:string // +// path:string // 站点路径 +// } + + +// type mysite = Optional + + +// let site:mysite = { +// id:"1", +// path:"ddd" +// } + + +// type mysite2 = Optional + + +// let site2:mysite2 = { +// id:"1" +// } + From 855aca213592e75a6a2048ac22adf955a340fc13 Mon Sep 17 00:00:00 2001 From: wxzhang Date: Sat, 21 Oct 2023 17:12:44 +0800 Subject: [PATCH 4/6] 1.3.40 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 61758f4..4659eab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flex-tools", - "version": "1.3.39", + "version": "1.3.40", "description": "modular utilities.", "main": "dist/index.js", "module": "dist/index.mjs", From 1286d2be361982cb68cde23d68149da3870544d1 Mon Sep 17 00:00:00 2001 From: wxzhang Date: Sat, 21 Oct 2023 17:18:08 +0800 Subject: [PATCH 5/6] =?UTF-8?q?fix(types):=20=E4=BF=AE=E5=A4=8Doptional?= =?UTF-8?q?=E6=9C=AA=E5=AF=BC=E5=87=BA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/types/index.ts b/src/types/index.ts index eab1b51..7309e9e 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -18,4 +18,5 @@ export * from "./objectPath" export * from "./allowEmpty" export * from "./asyncFunction" export * from "./arrayMember" -export * from "./overloads" \ No newline at end of file +export * from "./overloads" +export * from "./optional" \ No newline at end of file From 818755f37514344bba3f78100dcc5551f71deb26 Mon Sep 17 00:00:00 2001 From: wxzhang Date: Sat, 21 Oct 2023 17:18:14 +0800 Subject: [PATCH 6/6] 1.3.41 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4659eab..0a4677d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flex-tools", - "version": "1.3.40", + "version": "1.3.41", "description": "modular utilities.", "main": "dist/index.js", "module": "dist/index.mjs",