@xyo-network/module-events 3.15.6 → 3.15.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,259 +1,7 @@
1
- // src/Events/Events.ts
2
- import { assertEx } from "@xylabs/assert";
3
- import { Base } from "@xylabs/base";
4
- import { handleError } from "@xylabs/error";
5
- import { forget } from "@xylabs/forget";
6
- var NO_META_EVENT_ERROR_MESSAGE = "`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`";
7
- var resolvedPromise = Promise.resolve();
8
- var isMetaEvent = (eventName) => eventName === "listenerAdded" || eventName === "listenerRemoved";
9
- var Events = class _Events extends Base {
10
- static anyMap = /* @__PURE__ */ new WeakMap();
11
- static eventsMap = /* @__PURE__ */ new WeakMap();
12
- static canEmitMetaEvents = false;
13
- static isGlobalDebugEnabled = false;
14
- // this is here to be able to query the type, not use
15
- eventData = {};
16
- constructor(params = {}) {
17
- const mutatedParams = { ...params };
18
- if (mutatedParams.debug) {
19
- mutatedParams.debug.logger = mutatedParams.debug.logger ?? ((type, debugName, eventName, eventData) => {
20
- let eventDataString;
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
- const eventNameString = typeof eventName === "symbol" || typeof eventName === "number" ? eventName.toString() : eventName;
27
- const currentTime = /* @__PURE__ */ new Date();
28
- const logTime = `${currentTime.getHours()}:${currentTime.getMinutes()}:${currentTime.getSeconds()}.${currentTime.getMilliseconds()}`;
29
- this.logger?.log(`[${logTime}][events:${type}][${debugName}] Event Name: ${eventNameString}
30
- data: ${eventDataString}`);
31
- });
32
- }
33
- super(mutatedParams);
34
- _Events.anyMap.set(this, /* @__PURE__ */ new Set());
35
- _Events.eventsMap.set(this, /* @__PURE__ */ new Map());
36
- }
37
- static get isDebugEnabled() {
38
- if (typeof globalThis.process?.env !== "object") {
39
- return _Events.isGlobalDebugEnabled;
40
- }
41
- const { env } = globalThis.process ?? { env: {} };
42
- return env.DEBUG === "events" || env.DEBUG === "*" || _Events.isGlobalDebugEnabled;
43
- }
44
- static set isDebugEnabled(newValue) {
45
- _Events.isGlobalDebugEnabled = newValue;
46
- }
47
- get debug() {
48
- return this.params.debug;
49
- }
50
- clearListeners(eventNames) {
51
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames];
52
- for (const eventName of eventNamesArray) {
53
- this.logIfDebugEnabled("clear", eventName);
54
- if (typeof eventName === "string" || typeof eventName === "symbol" || typeof eventName === "number") {
55
- const set = this.getListeners(eventName);
56
- if (set) {
57
- set.clear();
58
- }
59
- } else {
60
- _Events.anyMap.get(this)?.clear();
61
- for (const [eventName2, listeners] of assertEx(_Events.eventsMap.get(this)).entries()) {
62
- listeners.clear();
63
- _Events.eventsMap.get(this)?.delete(eventName2);
64
- }
65
- }
66
- }
67
- }
68
- async emit(eventName, eventArgs) {
69
- await this.emitInternal(eventName, eventArgs);
70
- }
71
- async emitMetaEvent(eventName, eventArgs) {
72
- if (isMetaEvent(eventName)) {
73
- try {
74
- _Events.canEmitMetaEvents = true;
75
- await this.emitMetaEventInternal(eventName, eventArgs);
76
- } finally {
77
- _Events.canEmitMetaEvents = false;
78
- }
79
- }
80
- }
81
- async emitSerial(eventName, eventArgs) {
82
- if (isMetaEvent(eventName) && !_Events.canEmitMetaEvents) {
83
- throw new TypeError(NO_META_EVENT_ERROR_MESSAGE);
84
- }
85
- const filterMatch = (args, filter) => {
86
- if (filter) {
87
- switch (typeof filter) {
88
- case "object": {
89
- return Object.entries(args).reduce((prev, [key, value]) => filter[key] === value ? true : prev, false);
90
- }
91
- default: {
92
- return args === filter;
93
- }
94
- }
95
- }
96
- return true;
97
- };
98
- this.logIfDebugEnabled("emitSerial", eventName, eventArgs);
99
- const listeners = this.getListeners(eventName) ?? /* @__PURE__ */ new Set();
100
- const filteredListeners = [...listeners.values()].filter((value) => value.filter ? filterMatch(eventArgs, value.filter) : true).map((info) => info.listener);
101
- const anyListeners = assertEx(_Events.anyMap.get(this));
102
- const staticListeners = [...filteredListeners];
103
- const staticAnyListeners = [...anyListeners];
104
- await resolvedPromise;
105
- for (const listener of staticListeners) {
106
- await this.safeCallListener(eventName, eventArgs, listener);
107
- }
108
- for (const listener of staticAnyListeners) {
109
- await this.safeCallAnyListener(eventName, eventArgs, listener);
110
- }
111
- }
112
- // TODO: Make test for this
113
- listenerCount(eventNames) {
114
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames];
115
- let count = 0;
116
- for (const eventName of eventNamesArray) {
117
- if (typeof eventName === "string") {
118
- count += assertEx(_Events.anyMap.get(this)).size + (this.getListeners(eventName)?.size ?? 0);
119
- continue;
120
- }
121
- count += assertEx(_Events.anyMap.get(this)).size;
122
- for (const value of assertEx(_Events.eventsMap.get(this)).values()) {
123
- count += value.size;
124
- }
125
- }
126
- return count;
127
- }
128
- logIfDebugEnabled(type, eventName, eventArgs) {
129
- if (_Events.isDebugEnabled || this.debug?.enabled) {
130
- this.debug?.logger?.(type, this.debug.name, eventName, eventArgs);
131
- }
132
- }
133
- off(eventNames, listener) {
134
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames];
135
- for (const eventName of eventNamesArray) {
136
- const set = this.getListeners(eventName);
137
- if (set) {
138
- set.delete(listener);
139
- if (set.size === 0) {
140
- const events = _Events.eventsMap.get(this);
141
- events?.delete(eventName);
142
- }
143
- }
144
- this.logIfDebugEnabled("unsubscribe", eventName);
145
- if (!isMetaEvent(eventName)) {
146
- forget(this.emitMetaEvent("listenerRemoved", { eventName, listener }));
147
- }
148
- }
149
- }
150
- offAny(listener) {
151
- this.logIfDebugEnabled("unsubscribeAny");
152
- const typedMap = _Events.anyMap.get(this);
153
- typedMap?.delete(listener);
154
- forget(this.emitMetaEvent("listenerRemoved", { listener }));
155
- }
156
- on(eventNames, listener, filter) {
157
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames];
158
- for (const eventName of eventNamesArray) {
159
- let set = this.getListeners(eventName);
160
- if (!set) {
161
- set = /* @__PURE__ */ new Set();
162
- const events = _Events.eventsMap.get(this);
163
- events?.set(eventName, set);
164
- }
165
- set.add({ filter, listener });
166
- this.logIfDebugEnabled("subscribe", eventName);
167
- if (!isMetaEvent(eventName)) {
168
- forget(this.emitMetaEvent("listenerAdded", { eventName, listener }));
169
- }
170
- }
171
- return this.off.bind(this, eventNames, listener);
172
- }
173
- onAny(listener) {
174
- this.logIfDebugEnabled("subscribeAny");
175
- _Events.anyMap.get(this)?.add(listener);
176
- forget(this.emitMetaEvent("listenerAdded", { listener }));
177
- return this.offAny.bind(this, listener);
178
- }
179
- once(eventName, listener) {
180
- const subListener = async (args) => {
181
- this.off(eventName, subListener);
182
- await this.safeCallListener(eventName, args, listener);
183
- };
184
- this.on(eventName, subListener);
185
- return this.off.bind(this, eventName, subListener);
186
- }
187
- async emitInternal(eventName, eventArgs, filter) {
188
- if (isMetaEvent(eventName) && !_Events.canEmitMetaEvents) {
189
- throw new TypeError(NO_META_EVENT_ERROR_MESSAGE);
190
- }
191
- this.logIfDebugEnabled("emit", eventName, eventArgs);
192
- const listeners = this.getListeners(eventName) ?? /* @__PURE__ */ new Set();
193
- const filteredListeners = [...listeners.values()].filter((value) => filter ? value.listener : true).map((info) => info.listener);
194
- const anyListeners = assertEx(_Events.anyMap.get(this));
195
- const staticListeners = [...filteredListeners];
196
- const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners];
197
- await resolvedPromise;
198
- await Promise.all([
199
- ...staticListeners.map(async (listener) => {
200
- await this.safeCallListener(eventName, eventArgs, listener);
201
- }),
202
- ...staticAnyListeners.map(async (listener) => {
203
- if (anyListeners.has(listener)) {
204
- await this.safeCallAnyListener(eventName, eventArgs, listener);
205
- }
206
- })
207
- ]);
208
- }
209
- async emitMetaEventInternal(eventName, eventArgs) {
210
- if (isMetaEvent(eventName) && !_Events.canEmitMetaEvents) {
211
- throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`");
212
- }
213
- this.logIfDebugEnabled("emit", eventName, eventArgs);
214
- const listeners = this.getListeners(eventName) ?? /* @__PURE__ */ new Set();
215
- const filteredListeners = [...listeners.values()].map((info) => info.listener);
216
- const anyListeners = assertEx(_Events.anyMap.get(this));
217
- const staticListeners = [...filteredListeners];
218
- const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners];
219
- await resolvedPromise;
220
- await Promise.all([
221
- ...staticListeners.map(async (listener) => {
222
- await this.safeCallListener(eventName, eventArgs, listener);
223
- }),
224
- ...staticAnyListeners.map(async (listener) => {
225
- if (anyListeners.has(listener)) {
226
- await this.safeCallAnyListener(eventName, eventArgs, listener);
227
- }
228
- })
229
- ]);
230
- }
231
- getListeners(eventName) {
232
- const events = assertEx(_Events.eventsMap.get(this));
233
- if (!events.has(eventName)) {
234
- return;
235
- }
236
- return events.get(eventName);
237
- }
238
- async safeCallAnyListener(eventName, eventArgs, listener) {
239
- try {
240
- return await listener(eventName, eventArgs);
241
- } catch (ex) {
242
- handleError(ex, (error) => {
243
- this.logger?.error(`Listener[${String(eventName)}] Excepted: ${error.message}`);
244
- });
245
- }
246
- }
247
- async safeCallListener(eventName, eventArgs, listener) {
248
- try {
249
- return await listener(eventArgs);
250
- } catch (ex) {
251
- handleError(ex, (error) => {
252
- this.logger?.error(`Listener[${String(eventName)}] Excepted: ${error.message}`);
253
- });
254
- }
255
- }
256
- };
1
+ // src/index.ts
2
+ import {
3
+ Events
4
+ } from "@xylabs/events";
257
5
  export {
258
6
  Events
259
7
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Events/Events.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport type { BaseParams } from '@xylabs/base'\nimport { Base } from '@xylabs/base'\nimport { handleError } from '@xylabs/error'\nimport { forget } from '@xylabs/forget'\n\nimport type {\n EventAnyListener, EventArgs, EventData, EventFunctions, EventListener, EventName,\n} from '../model/index.ts'\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\non 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\nconst NO_META_EVENT_ERROR_MESSAGE = '`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`'\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 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 const eventNameString = typeof eventName === 'symbol' || typeof eventName === 'number' ? eventName.toString() : eventName\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)\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(NO_META_EVENT_ERROR_MESSAGE)\n }\n\n const filterMatch = (args: TEventData[TEventName], filter: TEventData[TEventName]) => {\n if (filter) {\n switch (typeof filter) {\n case 'object': {\n // eslint-disable-next-line unicorn/no-array-reduce\n return Object.entries(args).reduce((prev, [key, value]) => ((filter as Record<PropertyKey, unknown>)[key] === value ? true : prev), false)\n }\n default: {\n return args === filter\n }\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)\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')\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)\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')\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(NO_META_EVENT_ERROR_MESSAGE)\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/index.ts"],"sourcesContent":["export type {\n /** @deprecated use from @xylabs/events instead */\n DebugLogger,\n /** @deprecated use from @xylabs/events instead */\n DebugOptions,\n /** @deprecated use from @xylabs/events instead */\n EventAnyListener,\n /** @deprecated use from @xylabs/events instead */\n EventArgs,\n /** @deprecated use from @xylabs/events instead */\n EventData,\n /** @deprecated use from @xylabs/events instead */\n EventFunctions,\n /** @deprecated use from @xylabs/events instead */\n EventListener,\n /** @deprecated use from @xylabs/events instead */\n EventListenerInfo,\n /** @deprecated use from @xylabs/events instead */\n EventName,\n /** @deprecated use from @xylabs/events instead */\n EventsParams,\n /** @deprecated use from @xylabs/events instead */\n EventUnsubscribeFunction,\n /** @deprecated use from @xylabs/events instead */\n MetaEventData,\n} from '@xylabs/events'\nexport {\n /** @deprecated use from @xylabs/events instead */\n Events,\n} from '@xylabs/events'\n"],"mappings":";AA0BA;AAAA,EAEE;AAAA,OACK;","names":[]}
@@ -1,3 +1,29 @@
1
- export * from './Events/index.ts';
2
- export * from './model/index.ts';
1
+ export type {
2
+ /** @deprecated use from @xylabs/events instead */
3
+ DebugLogger,
4
+ /** @deprecated use from @xylabs/events instead */
5
+ DebugOptions,
6
+ /** @deprecated use from @xylabs/events instead */
7
+ EventAnyListener,
8
+ /** @deprecated use from @xylabs/events instead */
9
+ EventArgs,
10
+ /** @deprecated use from @xylabs/events instead */
11
+ EventData,
12
+ /** @deprecated use from @xylabs/events instead */
13
+ EventFunctions,
14
+ /** @deprecated use from @xylabs/events instead */
15
+ EventListener,
16
+ /** @deprecated use from @xylabs/events instead */
17
+ EventListenerInfo,
18
+ /** @deprecated use from @xylabs/events instead */
19
+ EventName,
20
+ /** @deprecated use from @xylabs/events instead */
21
+ EventsParams,
22
+ /** @deprecated use from @xylabs/events instead */
23
+ EventUnsubscribeFunction,
24
+ /** @deprecated use from @xylabs/events instead */
25
+ MetaEventData, } from '@xylabs/events';
26
+ export {
27
+ /** @deprecated use from @xylabs/events instead */
28
+ Events, } from '@xylabs/events';
3
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY;AACV,kDAAkD;AAClD,WAAW;AACX,kDAAkD;AAClD,YAAY;AACZ,kDAAkD;AAClD,gBAAgB;AAChB,kDAAkD;AAClD,SAAS;AACT,kDAAkD;AAClD,SAAS;AACT,kDAAkD;AAClD,cAAc;AACd,kDAAkD;AAClD,aAAa;AACb,kDAAkD;AAClD,iBAAiB;AACjB,kDAAkD;AAClD,SAAS;AACT,kDAAkD;AAClD,YAAY;AACZ,kDAAkD;AAClD,wBAAwB;AACxB,kDAAkD;AAClD,aAAa,GACd,MAAM,gBAAgB,CAAA;AACvB,OAAO;AACL,kDAAkD;AAClD,MAAM,GACP,MAAM,gBAAgB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/module-events",
3
- "version": "3.15.6",
3
+ "version": "3.15.8",
4
4
  "description": "Primary SDK for using XYO Protocol 2.0",
5
5
  "homepage": "https://xyo.network",
6
6
  "bugs": {
@@ -29,19 +29,12 @@
29
29
  "module": "dist/neutral/index.mjs",
30
30
  "types": "dist/types/index.d.ts",
31
31
  "dependencies": {
32
- "@xylabs/assert": "^4.9.8",
33
- "@xylabs/base": "^4.9.8",
34
- "@xylabs/error": "^4.9.8",
35
- "@xylabs/forget": "^4.9.8",
36
- "@xylabs/promise": "^4.9.8"
32
+ "@xylabs/events": "^4.9.18"
37
33
  },
38
34
  "devDependencies": {
39
- "@xylabs/delay": "^4.9.8",
40
- "@xylabs/ts-scripts-yarn3": "^6.5.5",
41
- "@xylabs/tsconfig": "^6.5.5",
42
- "@xylabs/vitest-extended": "^4.9.8",
43
- "typescript": "^5.8.3",
44
- "vitest": "^3.1.3"
35
+ "@xylabs/ts-scripts-yarn3": "^6.5.6",
36
+ "@xylabs/tsconfig": "^6.5.6",
37
+ "typescript": "^5.8.3"
45
38
  },
46
39
  "publishConfig": {
47
40
  "access": "public"
package/src/index.ts CHANGED
@@ -1,2 +1,30 @@
1
- export * from './Events/index.ts'
2
- export * from './model/index.ts'
1
+ export type {
2
+ /** @deprecated use from @xylabs/events instead */
3
+ DebugLogger,
4
+ /** @deprecated use from @xylabs/events instead */
5
+ DebugOptions,
6
+ /** @deprecated use from @xylabs/events instead */
7
+ EventAnyListener,
8
+ /** @deprecated use from @xylabs/events instead */
9
+ EventArgs,
10
+ /** @deprecated use from @xylabs/events instead */
11
+ EventData,
12
+ /** @deprecated use from @xylabs/events instead */
13
+ EventFunctions,
14
+ /** @deprecated use from @xylabs/events instead */
15
+ EventListener,
16
+ /** @deprecated use from @xylabs/events instead */
17
+ EventListenerInfo,
18
+ /** @deprecated use from @xylabs/events instead */
19
+ EventName,
20
+ /** @deprecated use from @xylabs/events instead */
21
+ EventsParams,
22
+ /** @deprecated use from @xylabs/events instead */
23
+ EventUnsubscribeFunction,
24
+ /** @deprecated use from @xylabs/events instead */
25
+ MetaEventData,
26
+ } from '@xylabs/events'
27
+ export {
28
+ /** @deprecated use from @xylabs/events instead */
29
+ Events,
30
+ } from '@xylabs/events'
@@ -1,65 +0,0 @@
1
- import type { BaseParams } from '@xylabs/base';
2
- import { Base } from '@xylabs/base';
3
- import type { EventAnyListener, EventArgs, EventData, EventFunctions, EventListener, EventName } from '../model/index.ts';
4
- /**
5
- Emittery can collect and log debug information.
6
-
7
- To enable this feature set the `DEBUG` environment variable to `emittery` or `*`. Additionally, you can set the static `isDebugEnabled` variable to true
8
- on the Emittery class, or `myEmitter.debug.enabled` on an instance of it for debugging a single instance.
9
-
10
- See API for more information on how debugging works.
11
- */
12
- export type DebugLogger = (type: string, debugName: string, eventName?: EventName, eventData?: EventArgs) => void;
13
- export type EventListenerInfo<TEventArgs extends EventArgs = EventArgs> = {
14
- filter?: TEventArgs;
15
- listener: EventListener<TEventArgs>;
16
- };
17
- /**
18
- Configure debug options of an instance.
19
- */
20
- export type DebugOptions = {
21
- enabled?: boolean;
22
- logger?: DebugLogger;
23
- readonly name: string;
24
- };
25
- export type MetaEventData<TEventData extends EventData> = {
26
- listenerAdded: {
27
- eventName?: keyof TEventData;
28
- listener: EventListener<TEventData[keyof TEventData]> | EventAnyListener<TEventData[keyof TEventData]>;
29
- };
30
- listenerRemoved: {
31
- eventName?: keyof TEventData;
32
- listener: EventListener<TEventData[keyof TEventData]> | EventAnyListener<TEventData[keyof TEventData]>;
33
- };
34
- };
35
- export type EventsParams = BaseParams<{
36
- readonly debug?: DebugOptions;
37
- }>;
38
- export declare class Events<TEventData extends EventData = EventData> extends Base<EventsParams> implements EventFunctions<TEventData> {
39
- protected static anyMap: WeakMap<object, Set<EventAnyListener>>;
40
- protected static eventsMap: WeakMap<object, Map<PropertyKey, Set<EventListenerInfo<EventArgs>>>>;
41
- private static canEmitMetaEvents;
42
- private static isGlobalDebugEnabled;
43
- eventData: TEventData;
44
- constructor(params?: EventsParams);
45
- static get isDebugEnabled(): boolean;
46
- static set isDebugEnabled(newValue: boolean);
47
- get debug(): DebugOptions | undefined;
48
- clearListeners(eventNames: keyof TEventData | (keyof TEventData)[]): void;
49
- emit<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]): Promise<void>;
50
- emitMetaEvent<TEventName extends keyof MetaEventData<TEventData>>(eventName: TEventName, eventArgs: MetaEventData<TEventData>[TEventName]): Promise<void>;
51
- emitSerial<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]): Promise<void>;
52
- listenerCount(eventNames?: keyof TEventData | (keyof TEventData)[]): number;
53
- logIfDebugEnabled<TEventName extends EventName>(type: string, eventName?: TEventName, eventArgs?: EventArgs): void;
54
- off<TEventName extends keyof TEventData, TEventListener = EventListener<TEventData[TEventName]>>(eventNames: TEventName | TEventName[], listener: TEventListener): void;
55
- offAny(listener: EventAnyListener): void;
56
- on<TEventName extends keyof TEventData = keyof TEventData>(eventNames: TEventName | TEventName[], listener: EventListener<TEventData[TEventName]>, filter?: TEventData[TEventName]): () => void;
57
- onAny(listener: EventAnyListener): () => void;
58
- once<TEventName extends keyof TEventData>(eventName: TEventName, listener: EventListener<TEventData[TEventName]>): () => void;
59
- private emitInternal;
60
- private emitMetaEventInternal;
61
- private getListeners;
62
- private safeCallAnyListener;
63
- private safeCallListener;
64
- }
65
- //# sourceMappingURL=Events.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Events.d.ts","sourceRoot":"","sources":["../../../src/Events/Events.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export * from './Events.ts';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Events/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
@@ -1,22 +0,0 @@
1
- import type { Promisable } from '@xylabs/promise';
2
- export type EventName = PropertyKey;
3
- export type EventArgs = string | number | object;
4
- export type EventData = {
5
- [key: EventName]: EventArgs;
6
- };
7
- export type EventUnsubscribeFunction = () => void;
8
- export type EventAnyListener<TEventArgs extends EventArgs = EventArgs> = (eventName: EventName, eventData: TEventArgs) => Promisable<void>;
9
- export type EventListener<TEventArgs extends EventArgs = EventArgs> = (eventData: TEventArgs) => Promisable<void>;
10
- export interface EventFunctions<TEventData extends EventData> {
11
- eventData: TEventData;
12
- clearListeners(eventNames: keyof TEventData | (keyof TEventData)[]): void;
13
- emit<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]): Promise<void>;
14
- emitSerial<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]): Promise<void>;
15
- listenerCount(eventNames: keyof TEventData | (keyof TEventData)[]): number;
16
- off<TEventName extends keyof TEventData>(eventNames: TEventName | TEventName[], listener: EventListener<TEventData[TEventName]>): void;
17
- offAny(listener: EventAnyListener | Promise<void>): void;
18
- on<TEventName extends keyof TEventData>(eventNames: TEventName | TEventName[], listener: EventListener<TEventData[TEventName]>): EventUnsubscribeFunction;
19
- onAny(listener: EventAnyListener): EventUnsubscribeFunction;
20
- once<TEventName extends keyof TEventData>(eventName: TEventName, listener: EventListener<TEventData[TEventName]>): EventUnsubscribeFunction;
21
- }
22
- //# sourceMappingURL=Event.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Event.d.ts","sourceRoot":"","sources":["../../../src/model/Event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,MAAM,MAAM,SAAS,GAAG,WAAW,CAAA;AACnC,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;AAChD,MAAM,MAAM,SAAS,GAAG;IAAE,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,CAAA;AACvD,MAAM,MAAM,wBAAwB,GAAG,MAAM,IAAI,CAAA;AACjD,MAAM,MAAM,gBAAgB,CAAC,UAAU,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,KAAK,UAAU,CAAC,IAAI,CAAC,CAAA;AAC1I,MAAM,MAAM,aAAa,CAAC,UAAU,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,SAAS,EAAE,UAAU,KAAK,UAAU,CAAC,IAAI,CAAC,CAAA;AAEjH,MAAM,WAAW,cAAc,CAAC,UAAU,SAAS,SAAS;IAC1D,SAAS,EAAE,UAAU,CAAA;IACrB,cAAc,CAAC,UAAU,EAAE,MAAM,UAAU,GAAG,CAAC,MAAM,UAAU,CAAC,EAAE,GAAG,IAAI,CAAA;IACzE,IAAI,CAAC,UAAU,SAAS,MAAM,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClH,UAAU,CAAC,UAAU,SAAS,MAAM,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACxH,aAAa,CAAC,UAAU,EAAE,MAAM,UAAU,GAAG,CAAC,MAAM,UAAU,CAAC,EAAE,GAAG,MAAM,CAAA;IAC1E,GAAG,CAAC,UAAU,SAAS,MAAM,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,EAAE,EAAE,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAAA;IACtI,MAAM,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACxD,EAAE,CAAC,UAAU,SAAS,MAAM,UAAU,EACpC,UAAU,EAAE,UAAU,GAAG,UAAU,EAAE,EACrC,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,GAC9C,wBAAwB,CAAA;IAC3B,KAAK,CAAC,QAAQ,EAAE,gBAAgB,GAAG,wBAAwB,CAAA;IAC3D,IAAI,CAAC,UAAU,SAAS,MAAM,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,GAAG,wBAAwB,CAAA;CAC5I"}
@@ -1,2 +0,0 @@
1
- export * from './Event.ts';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/model/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA"}
@@ -1,384 +0,0 @@
1
- import { assertEx } from '@xylabs/assert'
2
- import type { BaseParams } from '@xylabs/base'
3
- import { Base } from '@xylabs/base'
4
- import { handleError } from '@xylabs/error'
5
- import { forget } from '@xylabs/forget'
6
-
7
- import type {
8
- EventAnyListener, EventArgs, EventData, EventFunctions, EventListener, EventName,
9
- } from '../model/index.ts'
10
-
11
- /**
12
- Emittery can collect and log debug information.
13
-
14
- To enable this feature set the `DEBUG` environment variable to `emittery` or `*`. Additionally, you can set the static `isDebugEnabled` variable to true
15
- on the Emittery class, or `myEmitter.debug.enabled` on an instance of it for debugging a single instance.
16
-
17
- See API for more information on how debugging works.
18
- */
19
- export type DebugLogger = (type: string, debugName: string, eventName?: EventName, eventData?: EventArgs) => void
20
-
21
- export type EventListenerInfo<TEventArgs extends EventArgs = EventArgs> = {
22
- filter?: TEventArgs
23
- listener: EventListener<TEventArgs>
24
- }
25
-
26
- const NO_META_EVENT_ERROR_MESSAGE = '`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`'
27
-
28
- /**
29
- Configure debug options of an instance.
30
- */
31
- export type DebugOptions = {
32
- enabled?: boolean
33
- logger?: DebugLogger
34
- readonly name: string
35
- }
36
-
37
- const resolvedPromise = Promise.resolve()
38
-
39
- export type MetaEventData<TEventData extends EventData> = {
40
- listenerAdded: {
41
- eventName?: keyof TEventData
42
- listener: EventListener<TEventData[keyof TEventData]> | EventAnyListener<TEventData[keyof TEventData]>
43
- }
44
- listenerRemoved: {
45
- eventName?: keyof TEventData
46
- listener: EventListener<TEventData[keyof TEventData]> | EventAnyListener<TEventData[keyof TEventData]>
47
- }
48
- }
49
-
50
- const isMetaEvent = (eventName: EventName) => eventName === 'listenerAdded' || eventName === 'listenerRemoved'
51
-
52
- export type EventsParams = BaseParams<{ readonly debug?: DebugOptions }>
53
-
54
- export class Events<TEventData extends EventData = EventData> extends Base<EventsParams> implements EventFunctions<TEventData> {
55
- protected static anyMap = new WeakMap<object, Set<EventAnyListener>>()
56
- protected static eventsMap = new WeakMap<object, Map<EventName, Set<EventListenerInfo>>>()
57
-
58
- private static canEmitMetaEvents = false
59
- private static isGlobalDebugEnabled = false
60
-
61
- // this is here to be able to query the type, not use
62
- eventData = {} as TEventData
63
-
64
- constructor(params: EventsParams = {}) {
65
- const mutatedParams = { ...params }
66
- if (mutatedParams.debug) {
67
- mutatedParams.debug.logger
68
- = mutatedParams.debug.logger
69
- ?? ((type: string, debugName: string, eventName?: EventName, eventData?: EventArgs) => {
70
- let eventDataString: string
71
- try {
72
- eventDataString = JSON.stringify(eventData)
73
- } catch {
74
- eventDataString = `Object with the following keys failed to stringify: ${Object.keys(eventData ?? {}).join(',')}`
75
- }
76
-
77
- const eventNameString = typeof eventName === 'symbol' || typeof eventName === 'number' ? eventName.toString() : eventName
78
-
79
- const currentTime = new Date()
80
- const logTime = `${currentTime.getHours()}:${currentTime.getMinutes()}:${currentTime.getSeconds()}.${currentTime.getMilliseconds()}`
81
- this.logger?.log(`[${logTime}][events:${type}][${debugName}] Event Name: ${eventNameString}\n\tdata: ${eventDataString}`)
82
- })
83
- }
84
- super(mutatedParams)
85
- Events.anyMap.set(this, new Set<EventAnyListener>())
86
- Events.eventsMap.set(this, new Map<keyof TEventData, Set<EventListenerInfo>>())
87
- }
88
-
89
- static get isDebugEnabled() {
90
- // In a browser environment, `globalThis.process` can potentially reference a DOM Element with a `#process` ID,
91
- // so instead of just type checking `globalThis.process`, we need to make sure that `globalThis.process.env` exists.
92
-
93
- if (typeof globalThis.process?.env !== 'object') {
94
- return Events.isGlobalDebugEnabled
95
- }
96
-
97
- const { env } = globalThis.process ?? { env: {} }
98
- return env.DEBUG === 'events' || env.DEBUG === '*' || Events.isGlobalDebugEnabled
99
- }
100
-
101
- static set isDebugEnabled(newValue) {
102
- Events.isGlobalDebugEnabled = newValue
103
- }
104
-
105
- get debug() {
106
- return this.params.debug
107
- }
108
-
109
- clearListeners(eventNames: keyof TEventData | (keyof TEventData)[]) {
110
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]
111
-
112
- for (const eventName of eventNamesArray) {
113
- this.logIfDebugEnabled('clear', eventName)
114
-
115
- if (typeof eventName === 'string' || typeof eventName === 'symbol' || typeof eventName === 'number') {
116
- const set = this.getListeners(eventName)
117
- if (set) {
118
- set.clear()
119
- }
120
- } else {
121
- Events.anyMap.get(this)?.clear()
122
-
123
- for (const [eventName, listeners] of assertEx(Events.eventsMap.get(this)).entries()) {
124
- listeners.clear()
125
- Events.eventsMap.get(this)?.delete(eventName)
126
- }
127
- }
128
- }
129
- }
130
-
131
- async emit<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]) {
132
- await this.emitInternal(eventName, eventArgs)
133
- }
134
-
135
- async emitMetaEvent<TEventName extends keyof MetaEventData<TEventData>>(eventName: TEventName, eventArgs: MetaEventData<TEventData>[TEventName]) {
136
- if (isMetaEvent(eventName)) {
137
- try {
138
- Events.canEmitMetaEvents = true
139
- await this.emitMetaEventInternal(eventName, eventArgs)
140
- } finally {
141
- Events.canEmitMetaEvents = false
142
- }
143
- }
144
- }
145
-
146
- async emitSerial<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]) {
147
- if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {
148
- throw new TypeError(NO_META_EVENT_ERROR_MESSAGE)
149
- }
150
-
151
- const filterMatch = (args: TEventData[TEventName], filter: TEventData[TEventName]) => {
152
- if (filter) {
153
- switch (typeof filter) {
154
- case 'object': {
155
- // eslint-disable-next-line unicorn/no-array-reduce
156
- return Object.entries(args).reduce((prev, [key, value]) => ((filter as Record<PropertyKey, unknown>)[key] === value ? true : prev), false)
157
- }
158
- default: {
159
- return args === filter
160
- }
161
- }
162
- }
163
- return true
164
- }
165
-
166
- this.logIfDebugEnabled('emitSerial', eventName, eventArgs)
167
-
168
- const listeners = this.getListeners(eventName) ?? new Set()
169
- const filteredListeners = [...listeners.values()]
170
- .filter(value => (value.filter ? filterMatch(eventArgs, value.filter as TEventData[TEventName]) : true))
171
- .map(info => info.listener)
172
- const anyListeners = assertEx(Events.anyMap.get(this))
173
- const staticListeners = [...filteredListeners]
174
- const staticAnyListeners = [...anyListeners]
175
-
176
- await resolvedPromise
177
-
178
- for (const listener of staticListeners) {
179
- await this.safeCallListener(eventName, eventArgs, listener)
180
- }
181
-
182
- for (const listener of staticAnyListeners) {
183
- await this.safeCallAnyListener(eventName, eventArgs, listener)
184
- }
185
- }
186
-
187
- // TODO: Make test for this
188
- listenerCount(eventNames?: keyof TEventData | (keyof TEventData)[]) {
189
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]
190
- let count = 0
191
-
192
- for (const eventName of eventNamesArray) {
193
- if (typeof eventName === 'string') {
194
- count += assertEx(Events.anyMap.get(this)).size + (this.getListeners(eventName)?.size ?? 0)
195
-
196
- continue
197
- }
198
-
199
- count += assertEx(Events.anyMap.get(this)).size
200
-
201
- for (const value of assertEx(Events.eventsMap.get(this)).values()) {
202
- count += value.size
203
- }
204
- }
205
-
206
- return count
207
- }
208
-
209
- logIfDebugEnabled<TEventName extends EventName>(type: string, eventName?: TEventName, eventArgs?: EventArgs) {
210
- if (Events.isDebugEnabled || this.debug?.enabled) {
211
- this.debug?.logger?.(type, this.debug.name, eventName, eventArgs)
212
- }
213
- }
214
-
215
- off<TEventName extends keyof TEventData, TEventListener = EventListener<TEventData[TEventName]>>(
216
- eventNames: TEventName | TEventName[],
217
- listener: TEventListener,
218
- ) {
219
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]
220
- for (const eventName of eventNamesArray) {
221
- const set = this.getListeners(eventName) as Set<TEventListener>
222
- if (set) {
223
- set.delete(listener)
224
- if (set.size === 0) {
225
- const events = Events.eventsMap.get(this)
226
- events?.delete(eventName)
227
- }
228
- }
229
-
230
- this.logIfDebugEnabled('unsubscribe', eventName)
231
-
232
- if (!isMetaEvent(eventName)) {
233
- forget(this.emitMetaEvent('listenerRemoved', { eventName, listener: listener as EventListener }))
234
- }
235
- }
236
- }
237
-
238
- offAny(listener: EventAnyListener) {
239
- this.logIfDebugEnabled('unsubscribeAny')
240
-
241
- const typedMap = Events.anyMap.get(this) as Set<EventAnyListener<TEventData[keyof TEventData]>>
242
- typedMap?.delete(listener)
243
- forget(this.emitMetaEvent('listenerRemoved', { listener: listener as EventAnyListener }))
244
- }
245
-
246
- on<TEventName extends keyof TEventData = keyof TEventData>(
247
- eventNames: TEventName | TEventName[],
248
- listener: EventListener<TEventData[TEventName]>,
249
- filter?: TEventData[TEventName],
250
- ) {
251
- const eventNamesArray = Array.isArray(eventNames) ? eventNames : [eventNames]
252
- for (const eventName of eventNamesArray) {
253
- let set = this.getListeners(eventName)
254
- if (!set) {
255
- set = new Set()
256
- const events = Events.eventsMap.get(this)
257
- events?.set(eventName, set)
258
- }
259
-
260
- set.add({ filter, listener: listener as EventListener })
261
-
262
- this.logIfDebugEnabled('subscribe', eventName)
263
-
264
- if (!isMetaEvent(eventName)) {
265
- forget(this.emitMetaEvent('listenerAdded', { eventName, listener: listener as EventListener }))
266
- }
267
- }
268
-
269
- return this.off.bind(this, eventNames, listener as EventListener)
270
- }
271
-
272
- onAny(listener: EventAnyListener) {
273
- this.logIfDebugEnabled('subscribeAny')
274
-
275
- Events.anyMap.get(this)?.add(listener as EventAnyListener)
276
- forget(this.emitMetaEvent('listenerAdded', { listener: listener as EventAnyListener }))
277
- return this.offAny.bind(this, listener as EventAnyListener)
278
- }
279
-
280
- once<TEventName extends keyof TEventData>(eventName: TEventName, listener: EventListener<TEventData[TEventName]>) {
281
- const subListener = async (args: TEventData[TEventName]) => {
282
- this.off(eventName, subListener)
283
- await this.safeCallListener(eventName, args, listener)
284
- }
285
- this.on(eventName, subListener)
286
- return this.off.bind(this, eventName, subListener as EventListener)
287
- }
288
-
289
- private async emitInternal<TEventName extends keyof TEventData, TEventArgs extends TEventData[TEventName]>(
290
- eventName: TEventName,
291
- eventArgs: TEventArgs,
292
- filter?: TEventArgs,
293
- ) {
294
- if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {
295
- throw new TypeError(NO_META_EVENT_ERROR_MESSAGE)
296
- }
297
-
298
- this.logIfDebugEnabled('emit', eventName, eventArgs)
299
-
300
- const listeners = this.getListeners(eventName) ?? new Set()
301
- const filteredListeners = [...listeners.values()].filter(value => (filter ? value.listener : true)).map(info => info.listener)
302
- const anyListeners = assertEx(Events.anyMap.get(this))
303
- const staticListeners = [...filteredListeners]
304
- const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners]
305
-
306
- await resolvedPromise
307
- await Promise.all([
308
- ...staticListeners.map(async (listener) => {
309
- await this.safeCallListener(eventName, eventArgs, listener)
310
- }),
311
- ...staticAnyListeners.map(async (listener) => {
312
- if (anyListeners.has(listener)) {
313
- await this.safeCallAnyListener(eventName, eventArgs, listener)
314
- }
315
- }),
316
- ])
317
- }
318
-
319
- private async emitMetaEventInternal<TEventName extends keyof MetaEventData<TEventData>>(
320
- eventName: TEventName,
321
- eventArgs: MetaEventData<TEventData>[TEventName],
322
- ) {
323
- if (isMetaEvent(eventName) && !Events.canEmitMetaEvents) {
324
- throw new TypeError('`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`')
325
- }
326
-
327
- this.logIfDebugEnabled('emit', eventName, eventArgs)
328
-
329
- const listeners = this.getListeners(eventName) ?? new Set()
330
- const filteredListeners = [...listeners.values()].map(info => info.listener)
331
- const anyListeners = assertEx(Events.anyMap.get(this))
332
- const staticListeners = [...filteredListeners]
333
- const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners]
334
-
335
- await resolvedPromise
336
- await Promise.all([
337
- ...staticListeners.map(async (listener) => {
338
- await this.safeCallListener(eventName, eventArgs, listener)
339
- }),
340
- ...staticAnyListeners.map(async (listener) => {
341
- if (anyListeners.has(listener)) {
342
- await this.safeCallAnyListener(eventName, eventArgs, listener)
343
- }
344
- }),
345
- ])
346
- }
347
-
348
- private getListeners<TEventName extends keyof TEventData>(eventName: TEventName) {
349
- const events = assertEx(Events.eventsMap.get(this))
350
- if (!events.has(eventName)) {
351
- return
352
- }
353
-
354
- return events.get(eventName)
355
- }
356
-
357
- private async safeCallAnyListener<TEventData extends EventData, TEventName extends keyof EventData>(
358
- eventName: TEventName,
359
- eventArgs: TEventData[TEventName],
360
- listener: EventAnyListener<TEventData[TEventName]>,
361
- ) {
362
- try {
363
- return await listener(eventName, eventArgs)
364
- } catch (ex) {
365
- handleError(ex, (error) => {
366
- this.logger?.error(`Listener[${String(eventName)}] Excepted: ${error.message}`)
367
- })
368
- }
369
- }
370
-
371
- private async safeCallListener<TEventData extends EventData, TEventName extends keyof EventData>(
372
- eventName: TEventName,
373
- eventArgs: TEventData[TEventName],
374
- listener: EventListener<TEventData[TEventName]>,
375
- ) {
376
- try {
377
- return await listener(eventArgs)
378
- } catch (ex) {
379
- handleError(ex, (error) => {
380
- this.logger?.error(`Listener[${String(eventName)}] Excepted: ${error.message}`)
381
- })
382
- }
383
- }
384
- }
@@ -1 +0,0 @@
1
- export * from './Events.ts'
@@ -1,24 +0,0 @@
1
- import type { Promisable } from '@xylabs/promise'
2
-
3
- export type EventName = PropertyKey
4
- export type EventArgs = string | number | object
5
- export type EventData = { [key: EventName]: EventArgs }
6
- export type EventUnsubscribeFunction = () => void
7
- export type EventAnyListener<TEventArgs extends EventArgs = EventArgs> = (eventName: EventName, eventData: TEventArgs) => Promisable<void>
8
- export type EventListener<TEventArgs extends EventArgs = EventArgs> = (eventData: TEventArgs) => Promisable<void>
9
-
10
- export interface EventFunctions<TEventData extends EventData> {
11
- eventData: TEventData
12
- clearListeners(eventNames: keyof TEventData | (keyof TEventData)[]): void
13
- emit<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]): Promise<void>
14
- emitSerial<TEventName extends keyof TEventData>(eventName: TEventName, eventArgs: TEventData[TEventName]): Promise<void>
15
- listenerCount(eventNames: keyof TEventData | (keyof TEventData)[]): number
16
- off<TEventName extends keyof TEventData>(eventNames: TEventName | TEventName[], listener: EventListener<TEventData[TEventName]>): void
17
- offAny(listener: EventAnyListener | Promise<void>): void
18
- on<TEventName extends keyof TEventData>(
19
- eventNames: TEventName | TEventName[],
20
- listener: EventListener<TEventData[TEventName]>,
21
- ): EventUnsubscribeFunction
22
- onAny(listener: EventAnyListener): EventUnsubscribeFunction
23
- once<TEventName extends keyof TEventData>(eventName: TEventName, listener: EventListener<TEventData[TEventName]>): EventUnsubscribeFunction
24
- }
@@ -1 +0,0 @@
1
- export * from './Event.ts'