@xyo-network/module-events 2.75.0 → 2.75.2

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.
Files changed (48) hide show
  1. package/dist/browser/Events/Events.d.cts +63 -0
  2. package/dist/browser/Events/Events.d.cts.map +1 -0
  3. package/dist/browser/Events/Events.js +29 -30
  4. package/dist/browser/Events/Events.js.map +1 -1
  5. package/dist/browser/Events/index.d.cts +2 -0
  6. package/dist/browser/Events/index.d.cts.map +1 -0
  7. package/dist/browser/Events/index.js +1 -261
  8. package/dist/browser/Events/index.js.map +1 -1
  9. package/dist/browser/index.d.cts +3 -0
  10. package/dist/browser/index.d.cts.map +1 -0
  11. package/dist/browser/index.js +2 -261
  12. package/dist/browser/index.js.map +1 -1
  13. package/dist/browser/model/Event.d.cts +22 -0
  14. package/dist/browser/model/Event.d.cts.map +1 -0
  15. package/dist/browser/model/index.d.cts +2 -0
  16. package/dist/browser/model/index.d.cts.map +1 -0
  17. package/dist/browser/model/index.js +1 -0
  18. package/dist/browser/model/index.js.map +1 -1
  19. package/dist/docs.json +5785 -0
  20. package/dist/node/Events/Events.d.cts +63 -0
  21. package/dist/node/Events/Events.d.cts.map +1 -0
  22. package/dist/node/Events/Events.js +45 -36
  23. package/dist/node/Events/Events.js.map +1 -1
  24. package/dist/node/Events/Events.mjs +44 -36
  25. package/dist/node/Events/Events.mjs.map +1 -1
  26. package/dist/node/Events/index.d.cts +2 -0
  27. package/dist/node/Events/index.d.cts.map +1 -0
  28. package/dist/node/Events/index.js +276 -3
  29. package/dist/node/Events/index.js.map +1 -1
  30. package/dist/node/Events/index.mjs +268 -1
  31. package/dist/node/Events/index.mjs.map +1 -1
  32. package/dist/node/index.d.cts +3 -0
  33. package/dist/node/index.d.cts.map +1 -0
  34. package/dist/node/index.js +276 -5
  35. package/dist/node/index.js.map +1 -1
  36. package/dist/node/index.mjs +268 -2
  37. package/dist/node/index.mjs.map +1 -1
  38. package/dist/node/model/Event.d.cts +22 -0
  39. package/dist/node/model/Event.d.cts.map +1 -0
  40. package/dist/node/model/Event.js +2 -0
  41. package/dist/node/model/Event.js.map +1 -1
  42. package/dist/node/model/index.d.cts +2 -0
  43. package/dist/node/model/index.d.cts.map +1 -0
  44. package/dist/node/model/index.js +2 -6
  45. package/dist/node/model/index.js.map +1 -1
  46. package/dist/node/model/index.mjs +0 -1
  47. package/dist/node/model/index.mjs.map +1 -1
  48. package/package.json +10 -10
@@ -0,0 +1,63 @@
1
+ import { Base, BaseParams } from '@xyo-network/core';
2
+ import { EventAnyListener, EventArgs, EventData, EventFunctions, EventListener, EventName } from '../model';
3
+ /**
4
+ Emittery can collect and log debug information.
5
+
6
+ To enable this feature set the `DEBUG` environment variable to `emittery` or `*`. Additionally, you can set the static `isDebugEnabled` variable to true on the Emittery class, or `myEmitter.debug.enabled` on an instance of it for debugging a single instance.
7
+
8
+ See API for more information on how debugging works.
9
+ */
10
+ export type DebugLogger = (type: string, debugName: string, eventName?: EventName, eventData?: EventArgs) => void;
11
+ export type EventListenerInfo<TEventArgs extends EventArgs = EventArgs> = {
12
+ filter?: TEventArgs;
13
+ listener: EventListener<TEventArgs>;
14
+ };
15
+ /**
16
+ Configure debug options of an instance.
17
+ */
18
+ export type DebugOptions = {
19
+ enabled?: boolean;
20
+ logger?: DebugLogger;
21
+ readonly name: string;
22
+ };
23
+ export type MetaEventData<TEventData extends EventData> = {
24
+ listenerAdded: {
25
+ eventName?: keyof TEventData;
26
+ listener: EventListener<TEventData[keyof TEventData]> | EventAnyListener<TEventData[keyof TEventData]>;
27
+ };
28
+ listenerRemoved: {
29
+ eventName?: keyof TEventData;
30
+ listener: EventListener<TEventData[keyof TEventData]> | EventAnyListener<TEventData[keyof TEventData]>;
31
+ };
32
+ };
33
+ export type EventsParams = BaseParams<{
34
+ readonly debug?: DebugOptions;
35
+ }>;
36
+ export declare class Events<TEventData extends EventData = EventData> extends Base<EventsParams> implements EventFunctions<TEventData> {
37
+ protected static anyMap: WeakMap<object, Set<EventAnyListener>>;
38
+ protected static eventsMap: WeakMap<object, Map<PropertyKey, Set<EventListenerInfo<EventArgs>>>>;
39
+ private static canEmitMetaEvents;
40
+ private static isGlobalDebugEnabled;
41
+ eventData: TEventData;
42
+ constructor(params?: EventsParams);
43
+ static get isDebugEnabled(): boolean;
44
+ static set isDebugEnabled(newValue: boolean);
45
+ get debug(): DebugOptions | undefined;
46
+ clearListeners(eventNames: keyof TEventData | (keyof TEventData)[]): void;
47
+ emit<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]): Promise<void>;
48
+ emitMetaEvent<TEventName extends keyof MetaEventData<TEventData>>(eventName: TEventName, eventArgs: MetaEventData<TEventData>[TEventName]): Promise<void>;
49
+ emitSerial<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]): Promise<void>;
50
+ listenerCount(eventNames?: keyof TEventData | (keyof TEventData)[]): number;
51
+ logIfDebugEnabled<TEventName extends EventName>(type: string, eventName?: TEventName, eventArgs?: EventArgs): void;
52
+ off<TEventName extends keyof TEventData, TEventListener = EventListener<TEventData[TEventName]>>(eventNames: TEventName | TEventName[], listener: TEventListener): void;
53
+ offAny(listener: EventAnyListener): void;
54
+ on<TEventName extends keyof TEventData = keyof TEventData>(eventNames: TEventName | TEventName[], listener: EventListener<TEventData[TEventName]>, filter?: TEventData[TEventName]): () => void;
55
+ onAny(listener: EventAnyListener): () => void;
56
+ once<TEventName extends keyof TEventData>(eventName: TEventName, listener: EventListener<TEventData[TEventName]>): () => void;
57
+ private emitInternal;
58
+ private emitMetaEventInternal;
59
+ private getListeners;
60
+ private safeCallAnyListener;
61
+ private safeCallListener;
62
+ }
63
+ //# sourceMappingURL=Events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Events.d.ts","sourceRoot":"","sources":["../../../src/Events/Events.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,10 @@
1
- // src/Events/Events.ts
2
1
  import { assertEx } from "@xylabs/assert";
3
2
  import { forget } from "@xylabs/forget";
4
3
  import { Base } from "@xyo-network/core";
5
4
  import { handleError } from "@xyo-network/error";
6
- var resolvedPromise = Promise.resolve();
7
- var isMetaEvent = (eventName) => eventName === "listenerAdded" || eventName === "listenerRemoved";
8
- var Events = class _Events extends Base {
5
+ const resolvedPromise = Promise.resolve();
6
+ const isMetaEvent = (eventName) => eventName === "listenerAdded" || eventName === "listenerRemoved";
7
+ class Events extends Base {
9
8
  static anyMap = /* @__PURE__ */ new WeakMap();
10
9
  static eventsMap = /* @__PURE__ */ new WeakMap();
11
10
  static canEmitMetaEvents = false;
@@ -35,18 +34,18 @@ var Events = class _Events extends Base {
35
34
  });
36
35
  }
37
36
  super(mutatedParams);
38
- _Events.anyMap.set(this, /* @__PURE__ */ new Set());
39
- _Events.eventsMap.set(this, /* @__PURE__ */ new Map());
37
+ Events.anyMap.set(this, /* @__PURE__ */ new Set());
38
+ Events.eventsMap.set(this, /* @__PURE__ */ new Map());
40
39
  }
41
40
  static get isDebugEnabled() {
42
41
  if (typeof globalThis.process?.env !== "object") {
43
- return _Events.isGlobalDebugEnabled;
42
+ return Events.isGlobalDebugEnabled;
44
43
  }
45
44
  const { env } = globalThis.process ?? { env: {} };
46
- return env.DEBUG === "events" || env.DEBUG === "*" || _Events.isGlobalDebugEnabled;
45
+ return env.DEBUG === "events" || env.DEBUG === "*" || Events.isGlobalDebugEnabled;
47
46
  }
48
47
  static set isDebugEnabled(newValue) {
49
- _Events.isGlobalDebugEnabled = newValue;
48
+ Events.isGlobalDebugEnabled = newValue;
50
49
  }
51
50
  get debug() {
52
51
  return this.params.debug;
@@ -61,10 +60,10 @@ var Events = class _Events extends Base {
61
60
  set.clear();
62
61
  }
63
62
  } else {
64
- _Events.anyMap.get(this)?.clear();
65
- for (const [eventName2, listeners] of assertEx(_Events.eventsMap.get(this)).entries()) {
63
+ Events.anyMap.get(this)?.clear();
64
+ for (const [eventName2, listeners] of assertEx(Events.eventsMap.get(this)).entries()) {
66
65
  listeners.clear();
67
- _Events.eventsMap.get(this)?.delete(eventName2);
66
+ Events.eventsMap.get(this)?.delete(eventName2);
68
67
  }
69
68
  }
70
69
  }
@@ -75,15 +74,15 @@ var Events = class _Events extends Base {
75
74
  async emitMetaEvent(eventName, eventArgs) {
76
75
  if (isMetaEvent(eventName)) {
77
76
  try {
78
- _Events.canEmitMetaEvents = true;
77
+ Events.canEmitMetaEvents = true;
79
78
  await this.emitMetaEventInternal(eventName, eventArgs);
80
79
  } finally {
81
- _Events.canEmitMetaEvents = false;
80
+ Events.canEmitMetaEvents = false;
82
81
  }
83
82
  }
84
83
  }
85
84
  async emitSerial(eventName, eventArgs) {
86
- if (isMetaEvent(eventName) && !_Events.canEmitMetaEvents) {
85
+ if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {
87
86
  throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`");
88
87
  }
89
88
  const filterMatch = (args, filter) => {
@@ -100,7 +99,7 @@ var Events = class _Events extends Base {
100
99
  this.logIfDebugEnabled("emitSerial", eventName, eventArgs);
101
100
  const listeners = this.getListeners(eventName) ?? /* @__PURE__ */ new Set();
102
101
  const filteredListeners = [...listeners.values()].filter((value) => value.filter ? filterMatch(eventArgs, value.filter) : true).map((info) => info.listener);
103
- const anyListeners = assertEx(_Events.anyMap.get(this));
102
+ const anyListeners = assertEx(Events.anyMap.get(this));
104
103
  const staticListeners = [...filteredListeners];
105
104
  const staticAnyListeners = [...anyListeners];
106
105
  await resolvedPromise;
@@ -117,18 +116,18 @@ var Events = class _Events extends Base {
117
116
  let count = 0;
118
117
  for (const eventName of eventNamesArray) {
119
118
  if (typeof eventName === "string") {
120
- count += assertEx(_Events.anyMap.get(this)).size + (this.getListeners(eventName)?.size ?? 0);
119
+ count += assertEx(Events.anyMap.get(this)).size + (this.getListeners(eventName)?.size ?? 0);
121
120
  continue;
122
121
  }
123
- count += assertEx(_Events.anyMap.get(this)).size;
124
- for (const value of assertEx(_Events.eventsMap.get(this)).values()) {
122
+ count += assertEx(Events.anyMap.get(this)).size;
123
+ for (const value of assertEx(Events.eventsMap.get(this)).values()) {
125
124
  count += value.size;
126
125
  }
127
126
  }
128
127
  return count;
129
128
  }
130
129
  logIfDebugEnabled(type, eventName, eventArgs) {
131
- if (_Events.isDebugEnabled || this.debug?.enabled) {
130
+ if (Events.isDebugEnabled || this.debug?.enabled) {
132
131
  this.debug?.logger?.(type, this.debug.name, eventName, eventArgs);
133
132
  }
134
133
  }
@@ -139,7 +138,7 @@ var Events = class _Events extends Base {
139
138
  if (set) {
140
139
  set.delete(listener);
141
140
  if (set.size === 0) {
142
- const events = _Events.eventsMap.get(this);
141
+ const events = Events.eventsMap.get(this);
143
142
  events?.delete(eventName);
144
143
  }
145
144
  }
@@ -151,7 +150,7 @@ var Events = class _Events extends Base {
151
150
  }
152
151
  offAny(listener) {
153
152
  this.logIfDebugEnabled("unsubscribeAny", void 0, void 0);
154
- const typedMap = _Events.anyMap.get(this);
153
+ const typedMap = Events.anyMap.get(this);
155
154
  typedMap?.delete(listener);
156
155
  forget(this.emitMetaEvent("listenerRemoved", { listener }));
157
156
  }
@@ -161,7 +160,7 @@ var Events = class _Events extends Base {
161
160
  let set = this.getListeners(eventName);
162
161
  if (!set) {
163
162
  set = /* @__PURE__ */ new Set();
164
- const events = _Events.eventsMap.get(this);
163
+ const events = Events.eventsMap.get(this);
165
164
  events?.set(eventName, set);
166
165
  }
167
166
  set.add({ filter, listener });
@@ -174,7 +173,7 @@ var Events = class _Events extends Base {
174
173
  }
175
174
  onAny(listener) {
176
175
  this.logIfDebugEnabled("subscribeAny", void 0, void 0);
177
- _Events.anyMap.get(this)?.add(listener);
176
+ Events.anyMap.get(this)?.add(listener);
178
177
  forget(this.emitMetaEvent("listenerAdded", { listener }));
179
178
  return this.offAny.bind(this, listener);
180
179
  }
@@ -187,13 +186,13 @@ var Events = class _Events extends Base {
187
186
  return this.off.bind(this, eventName, subListener);
188
187
  }
189
188
  async emitInternal(eventName, eventArgs, filter) {
190
- if (isMetaEvent(eventName) && !_Events.canEmitMetaEvents) {
189
+ if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {
191
190
  throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`");
192
191
  }
193
192
  this.logIfDebugEnabled("emit", eventName, eventArgs);
194
193
  const listeners = this.getListeners(eventName) ?? /* @__PURE__ */ new Set();
195
194
  const filteredListeners = [...listeners.values()].filter((value) => filter ? value.listener : true).map((info) => info.listener);
196
- const anyListeners = assertEx(_Events.anyMap.get(this));
195
+ const anyListeners = assertEx(Events.anyMap.get(this));
197
196
  const staticListeners = [...filteredListeners];
198
197
  const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners];
199
198
  await resolvedPromise;
@@ -209,13 +208,13 @@ var Events = class _Events extends Base {
209
208
  ]);
210
209
  }
211
210
  async emitMetaEventInternal(eventName, eventArgs) {
212
- if (isMetaEvent(eventName) && !_Events.canEmitMetaEvents) {
211
+ if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {
213
212
  throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`");
214
213
  }
215
214
  this.logIfDebugEnabled("emit", eventName, eventArgs);
216
215
  const listeners = this.getListeners(eventName) ?? /* @__PURE__ */ new Set();
217
216
  const filteredListeners = [...listeners.values()].map((info) => info.listener);
218
- const anyListeners = assertEx(_Events.anyMap.get(this));
217
+ const anyListeners = assertEx(Events.anyMap.get(this));
219
218
  const staticListeners = [...filteredListeners];
220
219
  const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners];
221
220
  await resolvedPromise;
@@ -231,7 +230,7 @@ var Events = class _Events extends Base {
231
230
  ]);
232
231
  }
233
232
  getListeners(eventName) {
234
- const events = assertEx(_Events.eventsMap.get(this));
233
+ const events = assertEx(Events.eventsMap.get(this));
235
234
  if (!events.has(eventName)) {
236
235
  return;
237
236
  }
@@ -255,7 +254,7 @@ var Events = class _Events extends Base {
255
254
  });
256
255
  }
257
256
  }
258
- };
257
+ }
259
258
  export {
260
259
  Events
261
260
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/Events/Events.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { forget } from '@xylabs/forget'\nimport { Base, BaseParams } from '@xyo-network/core'\nimport { handleError } from '@xyo-network/error'\n\nimport { EventAnyListener, EventArgs, EventData, EventFunctions, EventListener, EventName } from '../model'\n\n/**\nEmittery can collect and log debug information.\n\nTo enable this feature set the `DEBUG` environment variable to `emittery` or `*`. Additionally, you can set the static `isDebugEnabled` variable to true on the Emittery class, or `myEmitter.debug.enabled` on an instance of it for debugging a single instance.\n\nSee API for more information on how debugging works.\n*/\nexport type DebugLogger = (type: string, debugName: string, eventName?: EventName, eventData?: EventArgs) => void\n\nexport type EventListenerInfo<TEventArgs extends EventArgs = EventArgs> = {\n filter?: TEventArgs\n listener: EventListener<TEventArgs>\n}\n\n/**\nConfigure debug options of an instance.\n*/\nexport type DebugOptions = {\n enabled?: boolean\n logger?: DebugLogger\n readonly name: string\n}\n\nconst resolvedPromise = Promise.resolve()\n\nexport type MetaEventData<TEventData extends EventData> = {\n listenerAdded: {\n eventName?: keyof TEventData\n listener: EventListener<TEventData[keyof TEventData]> | EventAnyListener<TEventData[keyof TEventData]>\n }\n listenerRemoved: {\n eventName?: keyof TEventData\n listener: EventListener<TEventData[keyof TEventData]> | EventAnyListener<TEventData[keyof TEventData]>\n }\n}\n\nconst isMetaEvent = (eventName: EventName) => eventName === 'listenerAdded' || eventName === 'listenerRemoved'\n\nexport type EventsParams = BaseParams<{ readonly debug?: DebugOptions }>\n\nexport class Events<TEventData extends EventData = EventData> extends Base<EventsParams> implements EventFunctions<TEventData> {\n protected static anyMap = new WeakMap<object, Set<EventAnyListener>>()\n protected static eventsMap = new WeakMap<object, Map<EventName, Set<EventListenerInfo>>>()\n\n private static canEmitMetaEvents = false\n private static isGlobalDebugEnabled = false\n\n //this is here to be able to query the type, not use\n eventData = {} as TEventData\n\n constructor(params: EventsParams = {}) {\n const mutatedParams = { ...params }\n if (mutatedParams.debug) {\n mutatedParams.debug.logger =\n mutatedParams.debug.logger ??\n ((type: string, debugName: string, eventName?: EventName, eventData?: EventArgs) => {\n let eventDataString: string\n let eventNameString: string | undefined\n try {\n eventDataString = JSON.stringify(eventData)\n } catch {\n eventDataString = `Object with the following keys failed to stringify: ${Object.keys(eventData ?? {}).join(',')}`\n }\n\n if (typeof eventName === 'symbol' || typeof eventName === 'number') {\n eventNameString = eventName.toString()\n } else {\n eventNameString = eventName\n }\n\n const currentTime = new Date()\n const logTime = `${currentTime.getHours()}:${currentTime.getMinutes()}:${currentTime.getSeconds()}.${currentTime.getMilliseconds()}`\n this.logger.log(`[${logTime}][events:${type}][${debugName}] Event Name: ${eventNameString}\\n\\tdata: ${eventDataString}`)\n })\n }\n super(mutatedParams)\n Events.anyMap.set(this, new Set<EventAnyListener>())\n Events.eventsMap.set(this, new Map<keyof TEventData, Set<EventListenerInfo>>())\n }\n\n static get isDebugEnabled() {\n // In a browser environment, `globalThis.process` can potentially reference a DOM Element with a `#process` ID,\n // so instead of just type checking `globalThis.process`, we need to make sure that `globalThis.process.env` exists.\n\n if (typeof globalThis.process?.env !== 'object') {\n return Events.isGlobalDebugEnabled\n }\n\n const { env } = globalThis.process ?? { env: {} }\n return env.DEBUG === 'events' || env.DEBUG === '*' || Events.isGlobalDebugEnabled\n }\n\n static set isDebugEnabled(newValue) {\n Events.isGlobalDebugEnabled = newValue\n }\n\n get debug() {\n return this.params.debug\n }\n\n clearListeners(eventNames: keyof TEventData | (keyof TEventData)[]) {\n const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]\n\n for (const eventName of eventNamesArray) {\n this.logIfDebugEnabled('clear', eventName, undefined)\n\n if (typeof eventName === 'string' || typeof eventName === 'symbol' || typeof eventName === 'number') {\n const set = this.getListeners(eventName)\n if (set) {\n set.clear()\n }\n } else {\n Events.anyMap.get(this)?.clear()\n\n for (const [eventName, listeners] of assertEx(Events.eventsMap.get(this)).entries()) {\n listeners.clear()\n Events.eventsMap.get(this)?.delete(eventName)\n }\n }\n }\n }\n\n async emit<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]) {\n await this.emitInternal(eventName, eventArgs)\n }\n\n async emitMetaEvent<TEventName extends keyof MetaEventData<TEventData>>(eventName: TEventName, eventArgs: MetaEventData<TEventData>[TEventName]) {\n if (isMetaEvent(eventName)) {\n try {\n Events.canEmitMetaEvents = true\n await this.emitMetaEventInternal(eventName, eventArgs)\n } finally {\n Events.canEmitMetaEvents = false\n }\n }\n }\n\n async emitSerial<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]) {\n if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {\n throw new TypeError('`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`')\n }\n\n const filterMatch = (args: TEventData[TEventName], filter: TEventData[TEventName]) => {\n if (filter) {\n switch (typeof filter) {\n case 'object':\n return Object.entries(args).reduce((prev, [key, value]) => ((filter as Record<PropertyKey, unknown>)[key] === value ? true : prev), false)\n default:\n return args === filter\n }\n }\n return true\n }\n\n this.logIfDebugEnabled('emitSerial', eventName, eventArgs)\n\n const listeners = this.getListeners(eventName) ?? new Set()\n const filteredListeners = [...listeners.values()]\n .filter((value) => (value.filter ? filterMatch(eventArgs, value.filter as TEventData[TEventName]) : true))\n .map((info) => info.listener)\n const anyListeners = assertEx(Events.anyMap.get(this))\n const staticListeners = [...filteredListeners]\n const staticAnyListeners = [...anyListeners]\n\n await resolvedPromise\n\n for (const listener of staticListeners) {\n await this.safeCallListener(eventName, eventArgs, listener)\n }\n\n for (const listener of staticAnyListeners) {\n await this.safeCallAnyListener(eventName, eventArgs, listener)\n }\n }\n\n //TODO: Make test for this\n listenerCount(eventNames?: keyof TEventData | (keyof TEventData)[]) {\n const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]\n let count = 0\n\n for (const eventName of eventNamesArray) {\n if (typeof eventName === 'string') {\n count += assertEx(Events.anyMap.get(this)).size + (this.getListeners(eventName)?.size ?? 0)\n\n continue\n }\n\n count += assertEx(Events.anyMap.get(this)).size\n\n for (const value of assertEx(Events.eventsMap.get(this)).values()) {\n count += value.size\n }\n }\n\n return count\n }\n\n logIfDebugEnabled<TEventName extends EventName>(type: string, eventName?: TEventName, eventArgs?: EventArgs) {\n if (Events.isDebugEnabled || this.debug?.enabled) {\n this.debug?.logger?.(type, this.debug.name, eventName, eventArgs)\n }\n }\n\n off<TEventName extends keyof TEventData, TEventListener = EventListener<TEventData[TEventName]>>(\n eventNames: TEventName | TEventName[],\n listener: TEventListener,\n ) {\n const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]\n for (const eventName of eventNamesArray) {\n const set = this.getListeners(eventName) as Set<TEventListener>\n if (set) {\n set.delete(listener)\n if (set.size === 0) {\n const events = Events.eventsMap.get(this)\n events?.delete(eventName)\n }\n }\n\n this.logIfDebugEnabled('unsubscribe', eventName, undefined)\n\n if (!isMetaEvent(eventName)) {\n forget(this.emitMetaEvent('listenerRemoved', { eventName, listener: listener as EventListener }))\n }\n }\n }\n\n offAny(listener: EventAnyListener) {\n this.logIfDebugEnabled('unsubscribeAny', undefined, undefined)\n\n const typedMap = Events.anyMap.get(this) as Set<EventAnyListener<TEventData[keyof TEventData]>>\n typedMap?.delete(listener)\n forget(this.emitMetaEvent('listenerRemoved', { listener: listener as EventAnyListener }))\n }\n\n on<TEventName extends keyof TEventData = keyof TEventData>(\n eventNames: TEventName | TEventName[],\n listener: EventListener<TEventData[TEventName]>,\n filter?: TEventData[TEventName],\n ) {\n const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]\n for (const eventName of eventNamesArray) {\n let set = this.getListeners(eventName)\n if (!set) {\n set = new Set()\n const events = Events.eventsMap.get(this)\n events?.set(eventName, set)\n }\n\n set.add({ filter, listener: listener as EventListener })\n\n this.logIfDebugEnabled('subscribe', eventName, undefined)\n\n if (!isMetaEvent(eventName)) {\n forget(this.emitMetaEvent('listenerAdded', { eventName, listener: listener as EventListener }))\n }\n }\n\n return this.off.bind(this, eventNames, listener as EventListener)\n }\n\n onAny(listener: EventAnyListener) {\n this.logIfDebugEnabled('subscribeAny', undefined, undefined)\n\n Events.anyMap.get(this)?.add(listener as EventAnyListener)\n forget(this.emitMetaEvent('listenerAdded', { listener: listener as EventAnyListener }))\n return this.offAny.bind(this, listener as EventAnyListener)\n }\n\n once<TEventName extends keyof TEventData>(eventName: TEventName, listener: EventListener<TEventData[TEventName]>) {\n const subListener = async (args: TEventData[TEventName]) => {\n this.off(eventName, subListener)\n await this.safeCallListener(eventName, args, listener)\n }\n this.on(eventName, subListener)\n return this.off.bind(this, eventName, subListener as EventListener)\n }\n\n private async emitInternal<TEventName extends keyof TEventData, TEventArgs extends TEventData[TEventName]>(\n eventName: TEventName,\n eventArgs: TEventArgs,\n filter?: TEventArgs,\n ) {\n if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {\n throw new TypeError('`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`')\n }\n\n this.logIfDebugEnabled('emit', eventName, eventArgs)\n\n const listeners = this.getListeners(eventName) ?? new Set()\n const filteredListeners = [...listeners.values()].filter((value) => (filter ? value.listener : true)).map((info) => info.listener)\n const anyListeners = assertEx(Events.anyMap.get(this))\n const staticListeners = [...filteredListeners]\n const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners]\n\n await resolvedPromise\n await Promise.all([\n ...staticListeners.map(async (listener) => {\n await this.safeCallListener(eventName, eventArgs, listener)\n }),\n ...staticAnyListeners.map(async (listener) => {\n if (anyListeners.has(listener)) {\n await this.safeCallAnyListener(eventName, eventArgs, listener)\n }\n }),\n ])\n }\n\n private async emitMetaEventInternal<TEventName extends keyof MetaEventData<TEventData>>(\n eventName: TEventName,\n eventArgs: MetaEventData<TEventData>[TEventName],\n ) {\n if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {\n throw new TypeError('`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`')\n }\n\n this.logIfDebugEnabled('emit', eventName, eventArgs)\n\n const listeners = this.getListeners(eventName) ?? new Set()\n const filteredListeners = [...listeners.values()].map((info) => info.listener)\n const anyListeners = assertEx(Events.anyMap.get(this))\n const staticListeners = [...filteredListeners]\n const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners]\n\n await resolvedPromise\n await Promise.all([\n ...staticListeners.map(async (listener) => {\n await this.safeCallListener(eventName, eventArgs, listener)\n }),\n ...staticAnyListeners.map(async (listener) => {\n if (anyListeners.has(listener)) {\n await this.safeCallAnyListener(eventName, eventArgs, listener)\n }\n }),\n ])\n }\n\n private getListeners<TEventName extends keyof TEventData>(eventName: TEventName) {\n const events = assertEx(Events.eventsMap.get(this))\n if (!events.has(eventName)) {\n return\n }\n\n return events.get(eventName)\n }\n\n private async safeCallAnyListener<TEventData extends EventData, TEventName extends keyof EventData>(\n eventName: TEventName,\n eventArgs: TEventData[TEventName],\n listener: EventAnyListener<TEventData[TEventName]>,\n ) {\n try {\n return await listener(eventName, eventArgs)\n } catch (ex) {\n handleError(ex, (error) => {\n this.logger?.error(`Listener[${String(eventName)}] Excepted: ${error.message}`)\n })\n }\n }\n\n private async safeCallListener<TEventData extends EventData, TEventName extends keyof EventData>(\n eventName: TEventName,\n eventArgs: TEventData[TEventName],\n listener: EventListener<TEventData[TEventName]>,\n ) {\n try {\n return await listener(eventArgs)\n } catch (ex) {\n handleError(ex, (error) => {\n this.logger?.error(`Listener[${String(eventName)}] Excepted: ${error.message}`)\n })\n }\n }\n}\n"],"mappings":"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","names":["eventName"]}
1
+ {"version":3,"sources":["../../../src/Events/Events.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { forget } from '@xylabs/forget'\nimport { Base, BaseParams } from '@xyo-network/core'\nimport { handleError } from '@xyo-network/error'\n\nimport { EventAnyListener, EventArgs, EventData, EventFunctions, EventListener, EventName } from '../model'\n\n/**\nEmittery can collect and log debug information.\n\nTo enable this feature set the `DEBUG` environment variable to `emittery` or `*`. Additionally, you can set the static `isDebugEnabled` variable to true on the Emittery class, or `myEmitter.debug.enabled` on an instance of it for debugging a single instance.\n\nSee API for more information on how debugging works.\n*/\nexport type DebugLogger = (type: string, debugName: string, eventName?: EventName, eventData?: EventArgs) => void\n\nexport type EventListenerInfo<TEventArgs extends EventArgs = EventArgs> = {\n filter?: TEventArgs\n listener: EventListener<TEventArgs>\n}\n\n/**\nConfigure debug options of an instance.\n*/\nexport type DebugOptions = {\n enabled?: boolean\n logger?: DebugLogger\n readonly name: string\n}\n\nconst resolvedPromise = Promise.resolve()\n\nexport type MetaEventData<TEventData extends EventData> = {\n listenerAdded: {\n eventName?: keyof TEventData\n listener: EventListener<TEventData[keyof TEventData]> | EventAnyListener<TEventData[keyof TEventData]>\n }\n listenerRemoved: {\n eventName?: keyof TEventData\n listener: EventListener<TEventData[keyof TEventData]> | EventAnyListener<TEventData[keyof TEventData]>\n }\n}\n\nconst isMetaEvent = (eventName: EventName) => eventName === 'listenerAdded' || eventName === 'listenerRemoved'\n\nexport type EventsParams = BaseParams<{ readonly debug?: DebugOptions }>\n\nexport class Events<TEventData extends EventData = EventData> extends Base<EventsParams> implements EventFunctions<TEventData> {\n protected static anyMap = new WeakMap<object, Set<EventAnyListener>>()\n protected static eventsMap = new WeakMap<object, Map<EventName, Set<EventListenerInfo>>>()\n\n private static canEmitMetaEvents = false\n private static isGlobalDebugEnabled = false\n\n //this is here to be able to query the type, not use\n eventData = {} as TEventData\n\n constructor(params: EventsParams = {}) {\n const mutatedParams = { ...params }\n if (mutatedParams.debug) {\n mutatedParams.debug.logger =\n mutatedParams.debug.logger ??\n ((type: string, debugName: string, eventName?: EventName, eventData?: EventArgs) => {\n let eventDataString: string\n let eventNameString: string | undefined\n try {\n eventDataString = JSON.stringify(eventData)\n } catch {\n eventDataString = `Object with the following keys failed to stringify: ${Object.keys(eventData ?? {}).join(',')}`\n }\n\n if (typeof eventName === 'symbol' || typeof eventName === 'number') {\n eventNameString = eventName.toString()\n } else {\n eventNameString = eventName\n }\n\n const currentTime = new Date()\n const logTime = `${currentTime.getHours()}:${currentTime.getMinutes()}:${currentTime.getSeconds()}.${currentTime.getMilliseconds()}`\n this.logger.log(`[${logTime}][events:${type}][${debugName}] Event Name: ${eventNameString}\\n\\tdata: ${eventDataString}`)\n })\n }\n super(mutatedParams)\n Events.anyMap.set(this, new Set<EventAnyListener>())\n Events.eventsMap.set(this, new Map<keyof TEventData, Set<EventListenerInfo>>())\n }\n\n static get isDebugEnabled() {\n // In a browser environment, `globalThis.process` can potentially reference a DOM Element with a `#process` ID,\n // so instead of just type checking `globalThis.process`, we need to make sure that `globalThis.process.env` exists.\n\n if (typeof globalThis.process?.env !== 'object') {\n return Events.isGlobalDebugEnabled\n }\n\n const { env } = globalThis.process ?? { env: {} }\n return env.DEBUG === 'events' || env.DEBUG === '*' || Events.isGlobalDebugEnabled\n }\n\n static set isDebugEnabled(newValue) {\n Events.isGlobalDebugEnabled = newValue\n }\n\n get debug() {\n return this.params.debug\n }\n\n clearListeners(eventNames: keyof TEventData | (keyof TEventData)[]) {\n const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]\n\n for (const eventName of eventNamesArray) {\n this.logIfDebugEnabled('clear', eventName, undefined)\n\n if (typeof eventName === 'string' || typeof eventName === 'symbol' || typeof eventName === 'number') {\n const set = this.getListeners(eventName)\n if (set) {\n set.clear()\n }\n } else {\n Events.anyMap.get(this)?.clear()\n\n for (const [eventName, listeners] of assertEx(Events.eventsMap.get(this)).entries()) {\n listeners.clear()\n Events.eventsMap.get(this)?.delete(eventName)\n }\n }\n }\n }\n\n async emit<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]) {\n await this.emitInternal(eventName, eventArgs)\n }\n\n async emitMetaEvent<TEventName extends keyof MetaEventData<TEventData>>(eventName: TEventName, eventArgs: MetaEventData<TEventData>[TEventName]) {\n if (isMetaEvent(eventName)) {\n try {\n Events.canEmitMetaEvents = true\n await this.emitMetaEventInternal(eventName, eventArgs)\n } finally {\n Events.canEmitMetaEvents = false\n }\n }\n }\n\n async emitSerial<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]) {\n if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {\n throw new TypeError('`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`')\n }\n\n const filterMatch = (args: TEventData[TEventName], filter: TEventData[TEventName]) => {\n if (filter) {\n switch (typeof filter) {\n case 'object':\n return Object.entries(args).reduce((prev, [key, value]) => ((filter as Record<PropertyKey, unknown>)[key] === value ? true : prev), false)\n default:\n return args === filter\n }\n }\n return true\n }\n\n this.logIfDebugEnabled('emitSerial', eventName, eventArgs)\n\n const listeners = this.getListeners(eventName) ?? new Set()\n const filteredListeners = [...listeners.values()]\n .filter((value) => (value.filter ? filterMatch(eventArgs, value.filter as TEventData[TEventName]) : true))\n .map((info) => info.listener)\n const anyListeners = assertEx(Events.anyMap.get(this))\n const staticListeners = [...filteredListeners]\n const staticAnyListeners = [...anyListeners]\n\n await resolvedPromise\n\n for (const listener of staticListeners) {\n await this.safeCallListener(eventName, eventArgs, listener)\n }\n\n for (const listener of staticAnyListeners) {\n await this.safeCallAnyListener(eventName, eventArgs, listener)\n }\n }\n\n //TODO: Make test for this\n listenerCount(eventNames?: keyof TEventData | (keyof TEventData)[]) {\n const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]\n let count = 0\n\n for (const eventName of eventNamesArray) {\n if (typeof eventName === 'string') {\n count += assertEx(Events.anyMap.get(this)).size + (this.getListeners(eventName)?.size ?? 0)\n\n continue\n }\n\n count += assertEx(Events.anyMap.get(this)).size\n\n for (const value of assertEx(Events.eventsMap.get(this)).values()) {\n count += value.size\n }\n }\n\n return count\n }\n\n logIfDebugEnabled<TEventName extends EventName>(type: string, eventName?: TEventName, eventArgs?: EventArgs) {\n if (Events.isDebugEnabled || this.debug?.enabled) {\n this.debug?.logger?.(type, this.debug.name, eventName, eventArgs)\n }\n }\n\n off<TEventName extends keyof TEventData, TEventListener = EventListener<TEventData[TEventName]>>(\n eventNames: TEventName | TEventName[],\n listener: TEventListener,\n ) {\n const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]\n for (const eventName of eventNamesArray) {\n const set = this.getListeners(eventName) as Set<TEventListener>\n if (set) {\n set.delete(listener)\n if (set.size === 0) {\n const events = Events.eventsMap.get(this)\n events?.delete(eventName)\n }\n }\n\n this.logIfDebugEnabled('unsubscribe', eventName, undefined)\n\n if (!isMetaEvent(eventName)) {\n forget(this.emitMetaEvent('listenerRemoved', { eventName, listener: listener as EventListener }))\n }\n }\n }\n\n offAny(listener: EventAnyListener) {\n this.logIfDebugEnabled('unsubscribeAny', undefined, undefined)\n\n const typedMap = Events.anyMap.get(this) as Set<EventAnyListener<TEventData[keyof TEventData]>>\n typedMap?.delete(listener)\n forget(this.emitMetaEvent('listenerRemoved', { listener: listener as EventAnyListener }))\n }\n\n on<TEventName extends keyof TEventData = keyof TEventData>(\n eventNames: TEventName | TEventName[],\n listener: EventListener<TEventData[TEventName]>,\n filter?: TEventData[TEventName],\n ) {\n const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]\n for (const eventName of eventNamesArray) {\n let set = this.getListeners(eventName)\n if (!set) {\n set = new Set()\n const events = Events.eventsMap.get(this)\n events?.set(eventName, set)\n }\n\n set.add({ filter, listener: listener as EventListener })\n\n this.logIfDebugEnabled('subscribe', eventName, undefined)\n\n if (!isMetaEvent(eventName)) {\n forget(this.emitMetaEvent('listenerAdded', { eventName, listener: listener as EventListener }))\n }\n }\n\n return this.off.bind(this, eventNames, listener as EventListener)\n }\n\n onAny(listener: EventAnyListener) {\n this.logIfDebugEnabled('subscribeAny', undefined, undefined)\n\n Events.anyMap.get(this)?.add(listener as EventAnyListener)\n forget(this.emitMetaEvent('listenerAdded', { listener: listener as EventAnyListener }))\n return this.offAny.bind(this, listener as EventAnyListener)\n }\n\n once<TEventName extends keyof TEventData>(eventName: TEventName, listener: EventListener<TEventData[TEventName]>) {\n const subListener = async (args: TEventData[TEventName]) => {\n this.off(eventName, subListener)\n await this.safeCallListener(eventName, args, listener)\n }\n this.on(eventName, subListener)\n return this.off.bind(this, eventName, subListener as EventListener)\n }\n\n private async emitInternal<TEventName extends keyof TEventData, TEventArgs extends TEventData[TEventName]>(\n eventName: TEventName,\n eventArgs: TEventArgs,\n filter?: TEventArgs,\n ) {\n if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {\n throw new TypeError('`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`')\n }\n\n this.logIfDebugEnabled('emit', eventName, eventArgs)\n\n const listeners = this.getListeners(eventName) ?? new Set()\n const filteredListeners = [...listeners.values()].filter((value) => (filter ? value.listener : true)).map((info) => info.listener)\n const anyListeners = assertEx(Events.anyMap.get(this))\n const staticListeners = [...filteredListeners]\n const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners]\n\n await resolvedPromise\n await Promise.all([\n ...staticListeners.map(async (listener) => {\n await this.safeCallListener(eventName, eventArgs, listener)\n }),\n ...staticAnyListeners.map(async (listener) => {\n if (anyListeners.has(listener)) {\n await this.safeCallAnyListener(eventName, eventArgs, listener)\n }\n }),\n ])\n }\n\n private async emitMetaEventInternal<TEventName extends keyof MetaEventData<TEventData>>(\n eventName: TEventName,\n eventArgs: MetaEventData<TEventData>[TEventName],\n ) {\n if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {\n throw new TypeError('`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`')\n }\n\n this.logIfDebugEnabled('emit', eventName, eventArgs)\n\n const listeners = this.getListeners(eventName) ?? new Set()\n const filteredListeners = [...listeners.values()].map((info) => info.listener)\n const anyListeners = assertEx(Events.anyMap.get(this))\n const staticListeners = [...filteredListeners]\n const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners]\n\n await resolvedPromise\n await Promise.all([\n ...staticListeners.map(async (listener) => {\n await this.safeCallListener(eventName, eventArgs, listener)\n }),\n ...staticAnyListeners.map(async (listener) => {\n if (anyListeners.has(listener)) {\n await this.safeCallAnyListener(eventName, eventArgs, listener)\n }\n }),\n ])\n }\n\n private getListeners<TEventName extends keyof TEventData>(eventName: TEventName) {\n const events = assertEx(Events.eventsMap.get(this))\n if (!events.has(eventName)) {\n return\n }\n\n return events.get(eventName)\n }\n\n private async safeCallAnyListener<TEventData extends EventData, TEventName extends keyof EventData>(\n eventName: TEventName,\n eventArgs: TEventData[TEventName],\n listener: EventAnyListener<TEventData[TEventName]>,\n ) {\n try {\n return await listener(eventName, eventArgs)\n } catch (ex) {\n handleError(ex, (error) => {\n this.logger?.error(`Listener[${String(eventName)}] Excepted: ${error.message}`)\n })\n }\n }\n\n private async safeCallListener<TEventData extends EventData, TEventName extends keyof EventData>(\n eventName: TEventName,\n eventArgs: TEventData[TEventName],\n listener: EventListener<TEventData[TEventName]>,\n ) {\n try {\n return await listener(eventArgs)\n } catch (ex) {\n handleError(ex, (error) => {\n this.logger?.error(`Listener[${String(eventName)}] Excepted: ${error.message}`)\n })\n }\n }\n}\n"],"mappings":"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","names":["eventName"]}
@@ -0,0 +1,2 @@
1
+ export * from './Events';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Events/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA"}
@@ -1,262 +1,2 @@
1
- // src/Events/Events.ts
2
- import { assertEx } from "@xylabs/assert";
3
- import { forget } from "@xylabs/forget";
4
- import { Base } from "@xyo-network/core";
5
- import { handleError } from "@xyo-network/error";
6
- var resolvedPromise = Promise.resolve();
7
- var isMetaEvent = (eventName) => eventName === "listenerAdded" || eventName === "listenerRemoved";
8
- var Events = class _Events extends Base {
9
- static anyMap = /* @__PURE__ */ new WeakMap();
10
- static eventsMap = /* @__PURE__ */ new WeakMap();
11
- static canEmitMetaEvents = false;
12
- static isGlobalDebugEnabled = false;
13
- //this is here to be able to query the type, not use
14
- eventData = {};
15
- constructor(params = {}) {
16
- const mutatedParams = { ...params };
17
- if (mutatedParams.debug) {
18
- mutatedParams.debug.logger = mutatedParams.debug.logger ?? ((type, debugName, eventName, eventData) => {
19
- let eventDataString;
20
- let eventNameString;
21
- try {
22
- eventDataString = JSON.stringify(eventData);
23
- } catch {
24
- eventDataString = `Object with the following keys failed to stringify: ${Object.keys(eventData ?? {}).join(",")}`;
25
- }
26
- if (typeof eventName === "symbol" || typeof eventName === "number") {
27
- eventNameString = eventName.toString();
28
- } else {
29
- eventNameString = eventName;
30
- }
31
- const currentTime = /* @__PURE__ */ new Date();
32
- const logTime = `${currentTime.getHours()}:${currentTime.getMinutes()}:${currentTime.getSeconds()}.${currentTime.getMilliseconds()}`;
33
- this.logger.log(`[${logTime}][events:${type}][${debugName}] Event Name: ${eventNameString}
34
- data: ${eventDataString}`);
35
- });
36
- }
37
- super(mutatedParams);
38
- _Events.anyMap.set(this, /* @__PURE__ */ new Set());
39
- _Events.eventsMap.set(this, /* @__PURE__ */ new Map());
40
- }
41
- static get isDebugEnabled() {
42
- if (typeof globalThis.process?.env !== "object") {
43
- return _Events.isGlobalDebugEnabled;
44
- }
45
- const { env } = globalThis.process ?? { env: {} };
46
- return env.DEBUG === "events" || env.DEBUG === "*" || _Events.isGlobalDebugEnabled;
47
- }
48
- static set isDebugEnabled(newValue) {
49
- _Events.isGlobalDebugEnabled = newValue;
50
- }
51
- get debug() {
52
- return this.params.debug;
53
- }
54
- clearListeners(eventNames) {
55
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames];
56
- for (const eventName of eventNamesArray) {
57
- this.logIfDebugEnabled("clear", eventName, void 0);
58
- if (typeof eventName === "string" || typeof eventName === "symbol" || typeof eventName === "number") {
59
- const set = this.getListeners(eventName);
60
- if (set) {
61
- set.clear();
62
- }
63
- } else {
64
- _Events.anyMap.get(this)?.clear();
65
- for (const [eventName2, listeners] of assertEx(_Events.eventsMap.get(this)).entries()) {
66
- listeners.clear();
67
- _Events.eventsMap.get(this)?.delete(eventName2);
68
- }
69
- }
70
- }
71
- }
72
- async emit(eventName, eventArgs) {
73
- await this.emitInternal(eventName, eventArgs);
74
- }
75
- async emitMetaEvent(eventName, eventArgs) {
76
- if (isMetaEvent(eventName)) {
77
- try {
78
- _Events.canEmitMetaEvents = true;
79
- await this.emitMetaEventInternal(eventName, eventArgs);
80
- } finally {
81
- _Events.canEmitMetaEvents = false;
82
- }
83
- }
84
- }
85
- async emitSerial(eventName, eventArgs) {
86
- if (isMetaEvent(eventName) && !_Events.canEmitMetaEvents) {
87
- throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`");
88
- }
89
- const filterMatch = (args, filter) => {
90
- if (filter) {
91
- switch (typeof filter) {
92
- case "object":
93
- return Object.entries(args).reduce((prev, [key, value]) => filter[key] === value ? true : prev, false);
94
- default:
95
- return args === filter;
96
- }
97
- }
98
- return true;
99
- };
100
- this.logIfDebugEnabled("emitSerial", eventName, eventArgs);
101
- const listeners = this.getListeners(eventName) ?? /* @__PURE__ */ new Set();
102
- const filteredListeners = [...listeners.values()].filter((value) => value.filter ? filterMatch(eventArgs, value.filter) : true).map((info) => info.listener);
103
- const anyListeners = assertEx(_Events.anyMap.get(this));
104
- const staticListeners = [...filteredListeners];
105
- const staticAnyListeners = [...anyListeners];
106
- await resolvedPromise;
107
- for (const listener of staticListeners) {
108
- await this.safeCallListener(eventName, eventArgs, listener);
109
- }
110
- for (const listener of staticAnyListeners) {
111
- await this.safeCallAnyListener(eventName, eventArgs, listener);
112
- }
113
- }
114
- //TODO: Make test for this
115
- listenerCount(eventNames) {
116
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames];
117
- let count = 0;
118
- for (const eventName of eventNamesArray) {
119
- if (typeof eventName === "string") {
120
- count += assertEx(_Events.anyMap.get(this)).size + (this.getListeners(eventName)?.size ?? 0);
121
- continue;
122
- }
123
- count += assertEx(_Events.anyMap.get(this)).size;
124
- for (const value of assertEx(_Events.eventsMap.get(this)).values()) {
125
- count += value.size;
126
- }
127
- }
128
- return count;
129
- }
130
- logIfDebugEnabled(type, eventName, eventArgs) {
131
- if (_Events.isDebugEnabled || this.debug?.enabled) {
132
- this.debug?.logger?.(type, this.debug.name, eventName, eventArgs);
133
- }
134
- }
135
- off(eventNames, listener) {
136
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames];
137
- for (const eventName of eventNamesArray) {
138
- const set = this.getListeners(eventName);
139
- if (set) {
140
- set.delete(listener);
141
- if (set.size === 0) {
142
- const events = _Events.eventsMap.get(this);
143
- events?.delete(eventName);
144
- }
145
- }
146
- this.logIfDebugEnabled("unsubscribe", eventName, void 0);
147
- if (!isMetaEvent(eventName)) {
148
- forget(this.emitMetaEvent("listenerRemoved", { eventName, listener }));
149
- }
150
- }
151
- }
152
- offAny(listener) {
153
- this.logIfDebugEnabled("unsubscribeAny", void 0, void 0);
154
- const typedMap = _Events.anyMap.get(this);
155
- typedMap?.delete(listener);
156
- forget(this.emitMetaEvent("listenerRemoved", { listener }));
157
- }
158
- on(eventNames, listener, filter) {
159
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames];
160
- for (const eventName of eventNamesArray) {
161
- let set = this.getListeners(eventName);
162
- if (!set) {
163
- set = /* @__PURE__ */ new Set();
164
- const events = _Events.eventsMap.get(this);
165
- events?.set(eventName, set);
166
- }
167
- set.add({ filter, listener });
168
- this.logIfDebugEnabled("subscribe", eventName, void 0);
169
- if (!isMetaEvent(eventName)) {
170
- forget(this.emitMetaEvent("listenerAdded", { eventName, listener }));
171
- }
172
- }
173
- return this.off.bind(this, eventNames, listener);
174
- }
175
- onAny(listener) {
176
- this.logIfDebugEnabled("subscribeAny", void 0, void 0);
177
- _Events.anyMap.get(this)?.add(listener);
178
- forget(this.emitMetaEvent("listenerAdded", { listener }));
179
- return this.offAny.bind(this, listener);
180
- }
181
- once(eventName, listener) {
182
- const subListener = async (args) => {
183
- this.off(eventName, subListener);
184
- await this.safeCallListener(eventName, args, listener);
185
- };
186
- this.on(eventName, subListener);
187
- return this.off.bind(this, eventName, subListener);
188
- }
189
- async emitInternal(eventName, eventArgs, filter) {
190
- if (isMetaEvent(eventName) && !_Events.canEmitMetaEvents) {
191
- throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`");
192
- }
193
- this.logIfDebugEnabled("emit", eventName, eventArgs);
194
- const listeners = this.getListeners(eventName) ?? /* @__PURE__ */ new Set();
195
- const filteredListeners = [...listeners.values()].filter((value) => filter ? value.listener : true).map((info) => info.listener);
196
- const anyListeners = assertEx(_Events.anyMap.get(this));
197
- const staticListeners = [...filteredListeners];
198
- const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners];
199
- await resolvedPromise;
200
- await Promise.all([
201
- ...staticListeners.map(async (listener) => {
202
- await this.safeCallListener(eventName, eventArgs, listener);
203
- }),
204
- ...staticAnyListeners.map(async (listener) => {
205
- if (anyListeners.has(listener)) {
206
- await this.safeCallAnyListener(eventName, eventArgs, listener);
207
- }
208
- })
209
- ]);
210
- }
211
- async emitMetaEventInternal(eventName, eventArgs) {
212
- if (isMetaEvent(eventName) && !_Events.canEmitMetaEvents) {
213
- throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`");
214
- }
215
- this.logIfDebugEnabled("emit", eventName, eventArgs);
216
- const listeners = this.getListeners(eventName) ?? /* @__PURE__ */ new Set();
217
- const filteredListeners = [...listeners.values()].map((info) => info.listener);
218
- const anyListeners = assertEx(_Events.anyMap.get(this));
219
- const staticListeners = [...filteredListeners];
220
- const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners];
221
- await resolvedPromise;
222
- await Promise.all([
223
- ...staticListeners.map(async (listener) => {
224
- await this.safeCallListener(eventName, eventArgs, listener);
225
- }),
226
- ...staticAnyListeners.map(async (listener) => {
227
- if (anyListeners.has(listener)) {
228
- await this.safeCallAnyListener(eventName, eventArgs, listener);
229
- }
230
- })
231
- ]);
232
- }
233
- getListeners(eventName) {
234
- const events = assertEx(_Events.eventsMap.get(this));
235
- if (!events.has(eventName)) {
236
- return;
237
- }
238
- return events.get(eventName);
239
- }
240
- async safeCallAnyListener(eventName, eventArgs, listener) {
241
- try {
242
- return await listener(eventName, eventArgs);
243
- } catch (ex) {
244
- handleError(ex, (error) => {
245
- this.logger?.error(`Listener[${String(eventName)}] Excepted: ${error.message}`);
246
- });
247
- }
248
- }
249
- async safeCallListener(eventName, eventArgs, listener) {
250
- try {
251
- return await listener(eventArgs);
252
- } catch (ex) {
253
- handleError(ex, (error) => {
254
- this.logger?.error(`Listener[${String(eventName)}] Excepted: ${error.message}`);
255
- });
256
- }
257
- }
258
- };
259
- export {
260
- Events
261
- };
1
+ export * from "./Events";
262
2
  //# sourceMappingURL=index.js.map