@mantiq/events 0.5.20 → 0.5.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/Dispatcher.ts +25 -8
package/package.json
CHANGED
package/src/Dispatcher.ts
CHANGED
|
@@ -38,8 +38,11 @@ export class Dispatcher implements EventDispatcher {
|
|
|
38
38
|
*/
|
|
39
39
|
once(eventClass: Constructor<Event>, handler: EventHandler): void {
|
|
40
40
|
const wrapper: EventHandler = async (event) => {
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
try {
|
|
42
|
+
await handler(event)
|
|
43
|
+
} finally {
|
|
44
|
+
this.off(eventClass, wrapper)
|
|
45
|
+
}
|
|
43
46
|
}
|
|
44
47
|
this.on(eventClass, wrapper)
|
|
45
48
|
}
|
|
@@ -104,18 +107,32 @@ export class Dispatcher implements EventDispatcher {
|
|
|
104
107
|
|
|
105
108
|
async emit(event: Event): Promise<void> {
|
|
106
109
|
const eventClass = event.constructor as Constructor<Event>
|
|
107
|
-
|
|
110
|
+
// Snapshot the array to avoid issues if listeners modify it during iteration
|
|
111
|
+
const registered = [...(this.listeners.get(eventClass) ?? [])]
|
|
112
|
+
const errors: ListenerError[] = []
|
|
108
113
|
|
|
109
|
-
// Fire class-based and closure listeners
|
|
114
|
+
// Fire class-based and closure listeners — isolated, one failure doesn't stop others
|
|
110
115
|
for (const listener of registered) {
|
|
111
|
-
|
|
116
|
+
try {
|
|
117
|
+
await this.callListener(listener, event)
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (error instanceof ListenerError) errors.push(error)
|
|
120
|
+
else errors.push(new ListenerError(event.constructor.name, 'unknown', error instanceof Error ? error : new Error(String(error))))
|
|
121
|
+
}
|
|
112
122
|
}
|
|
113
123
|
|
|
114
|
-
// Fire wildcard listeners
|
|
115
|
-
for (const handler of this.wildcardListeners) {
|
|
116
|
-
|
|
124
|
+
// Fire wildcard listeners — also isolated
|
|
125
|
+
for (const handler of [...this.wildcardListeners]) {
|
|
126
|
+
try {
|
|
127
|
+
await handler(event)
|
|
128
|
+
} catch (error) {
|
|
129
|
+
errors.push(new ListenerError(event.constructor.name, handler.name || '(wildcard)', error instanceof Error ? error : new Error(String(error))))
|
|
130
|
+
}
|
|
117
131
|
}
|
|
118
132
|
|
|
133
|
+
// Re-throw first error after all listeners have run (preserves the contract)
|
|
134
|
+
if (errors.length > 0) throw errors[0]
|
|
135
|
+
|
|
119
136
|
// Broadcast if the event implements ShouldBroadcast
|
|
120
137
|
if (this.broadcaster && isBroadcastable(event)) {
|
|
121
138
|
await this.broadcaster.broadcast(event as Event & ShouldBroadcast)
|