@asaidimu/utils-events 1.1.1 → 1.2.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.
package/index.d.mts CHANGED
@@ -76,14 +76,18 @@ interface EventBus<TEventMap extends Record<string, any>> {
76
76
  * subscription
77
77
  * @returns A function to unsubscribe from the event.
78
78
  */
79
- subscribe: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions) => () => void;
79
+ subscribe<TEventName extends keyof TEventMap | "*">(eventName: TEventName, callback: TEventName extends "*" ? (payload: TEventMap[keyof TEventMap] & {
80
+ __event__: keyof TEventMap;
81
+ }) => void : (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions): () => void;
80
82
  /**
81
83
  * Subscribes to an event and automatically unsubscribes after it fires once.
82
84
  * @param eventName - The name of the event to subscribe to.
83
85
  * @param callback - The function to call when the event is emitted.
84
86
  * @returns A function to cancel the one-shot subscription before it fires.
85
87
  */
86
- once: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions) => () => void;
88
+ once<TEventName extends keyof TEventMap | "*">(eventName: TEventName, callback: TEventName extends "*" ? (payload: TEventMap[keyof TEventMap] & {
89
+ __event__: keyof TEventMap;
90
+ }) => void : (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions): () => void;
87
91
  /**
88
92
  * Emits an event with a payload to all subscribed listeners.
89
93
  * @param event - An object containing the event name and payload.
@@ -99,10 +103,18 @@ interface EventBus<TEventMap extends Record<string, any>> {
99
103
  metrics: () => EventMetrics;
100
104
  /**
101
105
  * Clears all subscriptions and resets metrics.
102
- * After calling clear(), the bus is fully reset and can be reused —
106
+ *
107
+ * After calling `clear()`, the bus is fully reset and can be reused
103
108
  * cross-tab communication is re-established if it was previously enabled.
109
+ *
110
+ * @param options - Optional configuration object.
111
+ * @param options.permanent - If `true`, the bus becomes permanently unusable after clearing.
112
+ * Defaults to `false`.
113
+ * @returns {void}
104
114
  */
105
- clear: () => void;
115
+ clear: (options?: {
116
+ permanent?: boolean;
117
+ }) => void;
106
118
  }
107
119
  /**
108
120
  * Interface defining the metrics tracked by the EventBus.
@@ -141,6 +153,9 @@ interface SubscribeOptions {
141
153
  *
142
154
  * Options are validated eagerly so misconfiguration surfaces at construction
143
155
  * time rather than silently producing wrong behaviour at runtime.
156
+ *
157
+ * The bus now supports a universal wildcard event named `*`. Subscribing to
158
+ * `*` will receive all event payloads. Emitting to `*` is forbidden.
144
159
  */
145
160
  declare function createEventBus<TEventMap extends Record<string, any>>(options?: EventBusOptions): EventBus<TEventMap>;
146
161
 
@@ -153,14 +168,18 @@ declare class Events<TEventMap extends Record<string, any>> implements EventBus<
153
168
  * @param callback - The function to call when the event is emitted.
154
169
  * @returns A function to unsubscribe from the event.
155
170
  */
156
- subscribe<TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void): () => void;
171
+ subscribe<TEventName extends keyof TEventMap | "*">(eventName: TEventName, callback: TEventName extends "*" ? (payload: TEventMap[keyof TEventMap] & {
172
+ __event__: keyof TEventMap;
173
+ }) => void : (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions): () => void;
157
174
  /**
158
175
  * Subscribes to an event and automatically unsubscribes after it fires once.
159
176
  * @param eventName - The name of the event to subscribe to.
160
177
  * @param callback - The function to call when the event is emitted.
161
178
  * @returns A function to cancel the one-shot subscription before it fires.
162
179
  */
163
- once<TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void): () => void;
180
+ once<TEventName extends keyof TEventMap | "*">(eventName: TEventName, callback: TEventName extends "*" ? (payload: TEventMap[keyof TEventMap] & {
181
+ __event__: keyof TEventMap;
182
+ }) => void : (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions): () => void;
164
183
  /**
165
184
  * Emits an event with a payload to all subscribed listeners.
166
185
  * @param event - An object containing the event name and payload.
package/index.d.ts CHANGED
@@ -76,14 +76,18 @@ interface EventBus<TEventMap extends Record<string, any>> {
76
76
  * subscription
77
77
  * @returns A function to unsubscribe from the event.
78
78
  */
79
- subscribe: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions) => () => void;
79
+ subscribe<TEventName extends keyof TEventMap | "*">(eventName: TEventName, callback: TEventName extends "*" ? (payload: TEventMap[keyof TEventMap] & {
80
+ __event__: keyof TEventMap;
81
+ }) => void : (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions): () => void;
80
82
  /**
81
83
  * Subscribes to an event and automatically unsubscribes after it fires once.
82
84
  * @param eventName - The name of the event to subscribe to.
83
85
  * @param callback - The function to call when the event is emitted.
84
86
  * @returns A function to cancel the one-shot subscription before it fires.
85
87
  */
86
- once: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions) => () => void;
88
+ once<TEventName extends keyof TEventMap | "*">(eventName: TEventName, callback: TEventName extends "*" ? (payload: TEventMap[keyof TEventMap] & {
89
+ __event__: keyof TEventMap;
90
+ }) => void : (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions): () => void;
87
91
  /**
88
92
  * Emits an event with a payload to all subscribed listeners.
89
93
  * @param event - An object containing the event name and payload.
@@ -99,10 +103,18 @@ interface EventBus<TEventMap extends Record<string, any>> {
99
103
  metrics: () => EventMetrics;
100
104
  /**
101
105
  * Clears all subscriptions and resets metrics.
102
- * After calling clear(), the bus is fully reset and can be reused —
106
+ *
107
+ * After calling `clear()`, the bus is fully reset and can be reused
103
108
  * cross-tab communication is re-established if it was previously enabled.
109
+ *
110
+ * @param options - Optional configuration object.
111
+ * @param options.permanent - If `true`, the bus becomes permanently unusable after clearing.
112
+ * Defaults to `false`.
113
+ * @returns {void}
104
114
  */
105
- clear: () => void;
115
+ clear: (options?: {
116
+ permanent?: boolean;
117
+ }) => void;
106
118
  }
107
119
  /**
108
120
  * Interface defining the metrics tracked by the EventBus.
@@ -141,6 +153,9 @@ interface SubscribeOptions {
141
153
  *
142
154
  * Options are validated eagerly so misconfiguration surfaces at construction
143
155
  * time rather than silently producing wrong behaviour at runtime.
156
+ *
157
+ * The bus now supports a universal wildcard event named `*`. Subscribing to
158
+ * `*` will receive all event payloads. Emitting to `*` is forbidden.
144
159
  */
145
160
  declare function createEventBus<TEventMap extends Record<string, any>>(options?: EventBusOptions): EventBus<TEventMap>;
146
161
 
@@ -153,14 +168,18 @@ declare class Events<TEventMap extends Record<string, any>> implements EventBus<
153
168
  * @param callback - The function to call when the event is emitted.
154
169
  * @returns A function to unsubscribe from the event.
155
170
  */
156
- subscribe<TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void): () => void;
171
+ subscribe<TEventName extends keyof TEventMap | "*">(eventName: TEventName, callback: TEventName extends "*" ? (payload: TEventMap[keyof TEventMap] & {
172
+ __event__: keyof TEventMap;
173
+ }) => void : (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions): () => void;
157
174
  /**
158
175
  * Subscribes to an event and automatically unsubscribes after it fires once.
159
176
  * @param eventName - The name of the event to subscribe to.
160
177
  * @param callback - The function to call when the event is emitted.
161
178
  * @returns A function to cancel the one-shot subscription before it fires.
162
179
  */
163
- once<TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void): () => void;
180
+ once<TEventName extends keyof TEventMap | "*">(eventName: TEventName, callback: TEventName extends "*" ? (payload: TEventMap[keyof TEventMap] & {
181
+ __event__: keyof TEventMap;
182
+ }) => void : (payload: TEventMap[TEventName]) => void, options?: SubscribeOptions): () => void;
164
183
  /**
165
184
  * Emits an event with a payload to all subscribed listeners.
166
185
  * @param event - An object containing the event name and payload.
package/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=class{_delay;_leading;_timer;_pendingFn;_pendingResolvers=[];_leadingFired=!1;constructor(e){this._delay=e?.delay??300,this._leading=e?.leading??!1}do(e){return new Promise((t=>{this._enqueue(e,t)}))}fire(e){this._enqueue(e,void 0)}_enqueue(e,t){if(this._pendingFn=e,t&&this._pendingResolvers.push(t),this._leading&&!this._leadingFired)return this._leadingFired=!0,this._fire(),clearTimeout(this._timer),void(this._timer=setTimeout((()=>{this._leadingFired=!1,void 0!==this._pendingFn&&this._fire()}),this._delay));clearTimeout(this._timer),this._timer=setTimeout((()=>{this._leadingFired=!1,this._fire()}),this._delay)}cancel(){clearTimeout(this._timer),this._timer=void 0,this._pendingFn=void 0,this._leadingFired=!1;const e=this._pendingResolvers.splice(0);for(const t of e)t({status:"cancelled"})}async flush(){return this._pendingFn?(clearTimeout(this._timer),this._timer=void 0,this._leadingFired=!1,this._fire()):null}pending(){return void 0!==this._pendingFn}async _fire(){const e=this._pendingFn,t=this._pendingResolvers.splice(0);let n;this._pendingFn=void 0;try{n={status:"ok",value:await e()}}catch(e){n={status:"error",error:e}}for(const e of t)e(n);return n}};function t(t){const n=t??{},s=n.errorHandler??(e=>console.error("EventBus Error:",e)),i=null!=n.batch?.size,r=n.batch?.size,a=n.batch?.delay??16;if(i&&(r<=0||!Number.isFinite(r)))throw new Error(`EventBus: batch.size must be a positive finite number, got ${r}.`);if(i&&(a<0||!Number.isFinite(a)))throw new Error(`EventBus: batch.delay must be a non-negative finite number, got ${a}.`);const o=n.broadcast?.channel,c=null!=o&&o.length>0,l=new Map;let u=[];const d=i?new e({delay:a}):null;let h=0,m=0;const _=new Map,f=()=>{if(!c)return null;if("undefined"==typeof BroadcastChannel)return console.warn("EventBus: BroadcastChannel is not supported in this environment. Cross-tab notifications are disabled."),null;const e=new BroadcastChannel(o);return e.onmessage=e=>{const{name:t,payload:n}=e.data;b(t,n)},e};let g=f();const p=(e,t)=>{h++,m+=t,_.set(e,(_.get(e)??0)+1)},b=(e,t)=>{const n=l.get(e);if(n&&0!==n.size)for(const{callback:i}of Array.from(n.values()))try{i(t)}catch(n){const i=n instanceof Error?n:Object.assign(new Error(String(n)),{cause:n}),r=Object.assign(i,{eventName:e,payload:t});s(r)}},v=(t,n,s)=>{l.has(t)||l.set(t,new Map);const i=l.get(t);let r,a;return void 0!==s&&s>0?(a=new e({delay:s,leading:!1}),r=e=>{a.fire((()=>{n(e)}))}):r=n,i.set(n,{callback:r,debouncer:a}),()=>{const e=i.get(n);e&&(e.debouncer?.cancel(),i.delete(n),0===i.size&&l.delete(t))}},y=()=>{const e=u;u=[];for(const{name:t,payload:n}of e){const e=performance.now();b(t,n),p(t,performance.now()-e)}};return{subscribe:(e,t,n)=>v(e,t,n?.debounce),once:(e,t,n)=>{let s;return s=v(e,(e=>{s(),t(e)}),n?.debounce),s},emit:({name:e,payload:t})=>{if(i)return u.push({name:e,payload:t}),u.length>=r?(d.cancel(),void y()):(d.fire((()=>y())),void g?.postMessage({name:e,payload:t}));const n=performance.now();b(e,t),p(e,performance.now()-n),g?.postMessage({name:e,payload:t})},metrics:()=>({totalEvents:h,activeSubscriptions:Array.from(l.values()).reduce(((e,t)=>e+t.size),0),eventCounts:new Map(_),averageEmitDuration:h>0?m/h:0}),clear:()=>{d?.cancel(),u=[];for(const e of l.values())for(const{debouncer:t}of e.values())t?.cancel();l.clear(),h=0,m=0,_.clear(),g?.close(),g=f()}}}exports.Events=class{bus;constructor(e){this.bus=t(e)}subscribe(e,t){return this.bus.subscribe(e,t)}once(e,t){return this.bus.once(e,t)}emit(e){return this.bus.emit(e)}metrics(){return this.bus.metrics()}clear(){return this.bus.clear()}},exports.createEventBus=t;
1
+ "use strict";var e=class{_delay;_leading;_timer;_pendingFn;_pendingResolvers=[];_leadingFired=!1;constructor(e){this._delay=e?.delay??300,this._leading=e?.leading??!1}do(e){return new Promise(t=>{this._enqueue(e,t)})}fire(e){this._enqueue(e,void 0)}_enqueue(e,t){if(this._pendingFn=e,t&&this._pendingResolvers.push(t),this._leading&&!this._leadingFired)return this._leadingFired=!0,this._fire(),clearTimeout(this._timer),void(this._timer=setTimeout(()=>{this._leadingFired=!1,void 0!==this._pendingFn&&this._fire()},this._delay));clearTimeout(this._timer),this._timer=setTimeout(()=>{this._leadingFired=!1,this._fire()},this._delay)}cancel(){clearTimeout(this._timer),this._timer=void 0,this._pendingFn=void 0,this._leadingFired=!1;const e=this._pendingResolvers.splice(0);for(const t of e)t({status:"cancelled"})}async flush(){return this._pendingFn?(clearTimeout(this._timer),this._timer=void 0,this._leadingFired=!1,this._fire()):null}pending(){return void 0!==this._pendingFn}async _fire(){const e=this._pendingFn,t=this._pendingResolvers.splice(0);let n;this._pendingFn=void 0;try{n={status:"ok",value:await e()}}catch(e){n={status:"error",error:e}}for(const e of t)e(n);return n}};function t(t){const n=t??{},s=n.errorHandler??(e=>console.error("EventBus Error:",e)),r=null!=n.batch?.size,i=n.batch?.size,a=n.batch?.delay??16;if(r&&(i<=0||!Number.isFinite(i)))throw new Error(`EventBus: batch.size must be a positive finite number, got ${i}.`);if(r&&(a<0||!Number.isFinite(a)))throw new Error(`EventBus: batch.delay must be a non-negative finite number, got ${a}.`);const o=n.broadcast?.channel,c=null!=o&&o.length>0,l=new Map,u=new Map;let d=[];const h=r?new e({delay:a}):null;let f=0,m=0;const _=new Map,g=()=>{if(!c)return null;if("undefined"==typeof BroadcastChannel)return console.warn("EventBus: BroadcastChannel is not supported in this environment. Cross-tab notifications are disabled."),null;const e=new BroadcastChannel(o);return e.onmessage=e=>{const{name:t,payload:n}=e.data;v(t,n)},e};let p=g();const b=(e,t)=>{f++,m+=t,_.set(e,(_.get(e)??0)+1)},v=(e,t)=>{const n=l.get(e);if(n&&n.size>0)for(const{callback:r}of Array.from(n.values()))try{r(t)}catch(n){const r=n instanceof Error?n:Object.assign(new Error(String(n)),{cause:n}),i=Object.assign(r,{eventName:e,payload:t});s(i)}if(u.size>0)for(const{callback:n}of Array.from(u.values()))try{n({...t,__event__:e})}catch(e){const n=e instanceof Error?e:Object.assign(new Error(String(e)),{cause:e}),r=Object.assign(n,{eventName:"*",payload:t});s(r)}},y=(t,n,s)=>{let r,i;void 0!==s&&s>0?(i=new e({delay:s,leading:!1}),r=e=>{i.fire(()=>{n(e)})}):r=n;const a={callback:r,debouncer:i};if("*"===t)return u.set(n,a),()=>{const e=u.get(n);e&&(e.debouncer?.cancel(),u.delete(n))};{l.has(t)||l.set(t,new Map);const e=l.get(t);return e.set(n,a),()=>{const s=e.get(n);s&&(s.debouncer?.cancel(),e.delete(n),0===e.size&&l.delete(t))}}},w=()=>{const e=d;d=[];for(const{name:t,payload:n}of e){const e=performance.now();v(t,n),b(t,performance.now()-e)}};return{subscribe:(e,t,n)=>y(e,t,n?.debounce),once(e,t,n){let s;return s=y(e,e=>{s(),t(e)},n?.debounce),s},emit:({name:e,payload:t})=>{if("*"===e)throw new Error('EventBus: Emitting to wildcard event "*" is forbidden.');if(r)return d.push({name:e,payload:t}),d.length>=i?(h.cancel(),void w()):(h.fire(()=>w()),void p?.postMessage({name:e,payload:t}));const n=performance.now();v(e,t),b(e,performance.now()-n),p?.postMessage({name:e,payload:t})},metrics:()=>({totalEvents:f,activeSubscriptions:Array.from(l.values()).reduce((e,t)=>e+t.size,0)+u.size,eventCounts:new Map(_),averageEmitDuration:f>0?m/f:0}),clear:e=>{h?.cancel(),d=[];for(const e of l.values())for(const{debouncer:t}of e.values())t?.cancel();l.clear();for(const{debouncer:e}of u.values())e?.cancel();u.clear(),f=0,m=0,_.clear(),p?.close(),p=e?.permanent?null:g()}}}exports.Events=class{bus;constructor(e){this.bus=t(e)}subscribe(e,t,n){return this.bus.subscribe(e,t,n)}once(e,t,n){return this.bus.once(e,t,n)}emit(e){return this.bus.emit(e)}metrics(){return this.bus.metrics()}clear(){return this.bus.clear()}},exports.createEventBus=t;
package/index.mjs CHANGED
@@ -1 +1 @@
1
- var e=class{_delay;_leading;_timer;_pendingFn;_pendingResolvers=[];_leadingFired=!1;constructor(e){this._delay=e?.delay??300,this._leading=e?.leading??!1}do(e){return new Promise((n=>{this._enqueue(e,n)}))}fire(e){this._enqueue(e,void 0)}_enqueue(e,n){if(this._pendingFn=e,n&&this._pendingResolvers.push(n),this._leading&&!this._leadingFired)return this._leadingFired=!0,this._fire(),clearTimeout(this._timer),void(this._timer=setTimeout((()=>{this._leadingFired=!1,void 0!==this._pendingFn&&this._fire()}),this._delay));clearTimeout(this._timer),this._timer=setTimeout((()=>{this._leadingFired=!1,this._fire()}),this._delay)}cancel(){clearTimeout(this._timer),this._timer=void 0,this._pendingFn=void 0,this._leadingFired=!1;const e=this._pendingResolvers.splice(0);for(const n of e)n({status:"cancelled"})}async flush(){return this._pendingFn?(clearTimeout(this._timer),this._timer=void 0,this._leadingFired=!1,this._fire()):null}pending(){return void 0!==this._pendingFn}async _fire(){const e=this._pendingFn,n=this._pendingResolvers.splice(0);let t;this._pendingFn=void 0;try{t={status:"ok",value:await e()}}catch(e){t={status:"error",error:e}}for(const e of n)e(t);return t}};function n(n){const t=n??{},i=t.errorHandler??(e=>console.error("EventBus Error:",e)),s=null!=t.batch?.size,r=t.batch?.size,a=t.batch?.delay??16;if(s&&(r<=0||!Number.isFinite(r)))throw new Error(`EventBus: batch.size must be a positive finite number, got ${r}.`);if(s&&(a<0||!Number.isFinite(a)))throw new Error(`EventBus: batch.delay must be a non-negative finite number, got ${a}.`);const o=t.broadcast?.channel,c=null!=o&&o.length>0,l=new Map;let u=[];const d=s?new e({delay:a}):null;let h=0,m=0;const _=new Map,f=()=>{if(!c)return null;if("undefined"==typeof BroadcastChannel)return console.warn("EventBus: BroadcastChannel is not supported in this environment. Cross-tab notifications are disabled."),null;const e=new BroadcastChannel(o);return e.onmessage=e=>{const{name:n,payload:t}=e.data;b(n,t)},e};let g=f();const p=(e,n)=>{h++,m+=n,_.set(e,(_.get(e)??0)+1)},b=(e,n)=>{const t=l.get(e);if(t&&0!==t.size)for(const{callback:s}of Array.from(t.values()))try{s(n)}catch(t){const s=t instanceof Error?t:Object.assign(new Error(String(t)),{cause:t}),r=Object.assign(s,{eventName:e,payload:n});i(r)}},v=(n,t,i)=>{l.has(n)||l.set(n,new Map);const s=l.get(n);let r,a;return void 0!==i&&i>0?(a=new e({delay:i,leading:!1}),r=e=>{a.fire((()=>{t(e)}))}):r=t,s.set(t,{callback:r,debouncer:a}),()=>{const e=s.get(t);e&&(e.debouncer?.cancel(),s.delete(t),0===s.size&&l.delete(n))}},y=()=>{const e=u;u=[];for(const{name:n,payload:t}of e){const e=performance.now();b(n,t),p(n,performance.now()-e)}};return{subscribe:(e,n,t)=>v(e,n,t?.debounce),once:(e,n,t)=>{let i;return i=v(e,(e=>{i(),n(e)}),t?.debounce),i},emit:({name:e,payload:n})=>{if(s)return u.push({name:e,payload:n}),u.length>=r?(d.cancel(),void y()):(d.fire((()=>y())),void g?.postMessage({name:e,payload:n}));const t=performance.now();b(e,n),p(e,performance.now()-t),g?.postMessage({name:e,payload:n})},metrics:()=>({totalEvents:h,activeSubscriptions:Array.from(l.values()).reduce(((e,n)=>e+n.size),0),eventCounts:new Map(_),averageEmitDuration:h>0?m/h:0}),clear:()=>{d?.cancel(),u=[];for(const e of l.values())for(const{debouncer:n}of e.values())n?.cancel();l.clear(),h=0,m=0,_.clear(),g?.close(),g=f()}}}var t=class{bus;constructor(e){this.bus=n(e)}subscribe(e,n){return this.bus.subscribe(e,n)}once(e,n){return this.bus.once(e,n)}emit(e){return this.bus.emit(e)}metrics(){return this.bus.metrics()}clear(){return this.bus.clear()}};export{t as Events,n as createEventBus};
1
+ var e=class{_delay;_leading;_timer;_pendingFn;_pendingResolvers=[];_leadingFired=!1;constructor(e){this._delay=e?.delay??300,this._leading=e?.leading??!1}do(e){return new Promise(n=>{this._enqueue(e,n)})}fire(e){this._enqueue(e,void 0)}_enqueue(e,n){if(this._pendingFn=e,n&&this._pendingResolvers.push(n),this._leading&&!this._leadingFired)return this._leadingFired=!0,this._fire(),clearTimeout(this._timer),void(this._timer=setTimeout(()=>{this._leadingFired=!1,void 0!==this._pendingFn&&this._fire()},this._delay));clearTimeout(this._timer),this._timer=setTimeout(()=>{this._leadingFired=!1,this._fire()},this._delay)}cancel(){clearTimeout(this._timer),this._timer=void 0,this._pendingFn=void 0,this._leadingFired=!1;const e=this._pendingResolvers.splice(0);for(const n of e)n({status:"cancelled"})}async flush(){return this._pendingFn?(clearTimeout(this._timer),this._timer=void 0,this._leadingFired=!1,this._fire()):null}pending(){return void 0!==this._pendingFn}async _fire(){const e=this._pendingFn,n=this._pendingResolvers.splice(0);let t;this._pendingFn=void 0;try{t={status:"ok",value:await e()}}catch(e){t={status:"error",error:e}}for(const e of n)e(t);return t}};function n(n){const t=n??{},r=t.errorHandler??(e=>console.error("EventBus Error:",e)),s=null!=t.batch?.size,i=t.batch?.size,a=t.batch?.delay??16;if(s&&(i<=0||!Number.isFinite(i)))throw new Error(`EventBus: batch.size must be a positive finite number, got ${i}.`);if(s&&(a<0||!Number.isFinite(a)))throw new Error(`EventBus: batch.delay must be a non-negative finite number, got ${a}.`);const o=t.broadcast?.channel,c=null!=o&&o.length>0,l=new Map,u=new Map;let d=[];const h=s?new e({delay:a}):null;let f=0,m=0;const _=new Map,g=()=>{if(!c)return null;if("undefined"==typeof BroadcastChannel)return console.warn("EventBus: BroadcastChannel is not supported in this environment. Cross-tab notifications are disabled."),null;const e=new BroadcastChannel(o);return e.onmessage=e=>{const{name:n,payload:t}=e.data;v(n,t)},e};let b=g();const p=(e,n)=>{f++,m+=n,_.set(e,(_.get(e)??0)+1)},v=(e,n)=>{const t=l.get(e);if(t&&t.size>0)for(const{callback:s}of Array.from(t.values()))try{s(n)}catch(t){const s=t instanceof Error?t:Object.assign(new Error(String(t)),{cause:t}),i=Object.assign(s,{eventName:e,payload:n});r(i)}if(u.size>0)for(const{callback:t}of Array.from(u.values()))try{t({...n,__event__:e})}catch(e){const t=e instanceof Error?e:Object.assign(new Error(String(e)),{cause:e}),s=Object.assign(t,{eventName:"*",payload:n});r(s)}},y=(n,t,r)=>{let s,i;void 0!==r&&r>0?(i=new e({delay:r,leading:!1}),s=e=>{i.fire(()=>{t(e)})}):s=t;const a={callback:s,debouncer:i};if("*"===n)return u.set(t,a),()=>{const e=u.get(t);e&&(e.debouncer?.cancel(),u.delete(t))};{l.has(n)||l.set(n,new Map);const e=l.get(n);return e.set(t,a),()=>{const r=e.get(t);r&&(r.debouncer?.cancel(),e.delete(t),0===e.size&&l.delete(n))}}},w=()=>{const e=d;d=[];for(const{name:n,payload:t}of e){const e=performance.now();v(n,t),p(n,performance.now()-e)}};return{subscribe:(e,n,t)=>y(e,n,t?.debounce),once(e,n,t){let r;return r=y(e,e=>{r(),n(e)},t?.debounce),r},emit:({name:e,payload:n})=>{if("*"===e)throw new Error('EventBus: Emitting to wildcard event "*" is forbidden.');if(s)return d.push({name:e,payload:n}),d.length>=i?(h.cancel(),void w()):(h.fire(()=>w()),void b?.postMessage({name:e,payload:n}));const t=performance.now();v(e,n),p(e,performance.now()-t),b?.postMessage({name:e,payload:n})},metrics:()=>({totalEvents:f,activeSubscriptions:Array.from(l.values()).reduce((e,n)=>e+n.size,0)+u.size,eventCounts:new Map(_),averageEmitDuration:f>0?m/f:0}),clear:e=>{h?.cancel(),d=[];for(const e of l.values())for(const{debouncer:n}of e.values())n?.cancel();l.clear();for(const{debouncer:e}of u.values())e?.cancel();u.clear(),f=0,m=0,_.clear(),b?.close(),b=e?.permanent?null:g()}}}var t=class{bus;constructor(e){this.bus=n(e)}subscribe(e,n,t){return this.bus.subscribe(e,n,t)}once(e,n,t){return this.bus.once(e,n,t)}emit(e){return this.bus.emit(e)}metrics(){return this.bus.metrics()}clear(){return this.bus.clear()}};export{t as Events,n as createEventBus};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaidimu/utils-events",
3
- "version": "1.1.1",
3
+ "version": "1.2.1",
4
4
  "description": "A lightweight, type-safe event bus implementation for TypeScript applications.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -34,7 +34,9 @@
34
34
  }
35
35
  }
36
36
  },
37
- "dependencies": {},
37
+ "dependencies": {
38
+ "uuid": "^14.0.0"
39
+ },
38
40
  "publishConfig": {
39
41
  "registry": "https://registry.npmjs.org/",
40
42
  "tag": "latest",