@microsoft/teams.common
Version:
<p> <a href="https://www.npmjs.com/package/@microsoft/teams.common" target="_blank"> <img src="https://img.shields.io/npm/v/@microsoft/teams.common/latest" /> </a> <a href="https://www.npmjs.com/package/@microsoft/teams.common?activeTa
86 lines (84 loc) • 2.44 kB
JavaScript
;
class EventEmitter {
/**
* @param logger Used to report handler failures from {@link emitAsync}.
* Defaults to `console` when omitted, so failures are never silent.
*/
constructor(logger) {
this.logger = logger;
}
logger;
index = -1;
subscriptions = /* @__PURE__ */ new Map();
on(event, handler) {
const id = ++this.index;
const subs = this.subscriptions.get(event) || [];
subs.push({ id, handler });
this.subscriptions.set(event, subs);
return id;
}
once(event, handler) {
const id = this.on(event, (value) => {
this.off(id);
return handler(value);
});
return id;
}
off(id) {
for (const [_, subs] of this.subscriptions.entries()) {
const i = subs.findIndex((s) => s.id === id);
if (i === -1) continue;
subs.splice(i, 1);
return;
}
}
emit(event, value) {
const subs = this.subscriptions.get(event) || [];
for (const sub of subs) {
sub.handler(value);
}
}
/**
* Emit an event and wait for every subscribed handler to settle.
*
* Handlers are started in subscription order and then awaited together, so
* async handlers run concurrently. Use this instead of `emit` when the
* emitter must not continue until async listeners have finished — for
* example when those listeners touch resources that are torn down once the
* emitting operation returns.
*
* A handler that throws or rejects is logged and does not stop the other
* handlers; this never rejects.
*/
async emitAsync(event, value) {
const subs = [...this.subscriptions.get(event) || []];
const pending = [];
for (const sub of subs) {
try {
const result = sub.handler(value);
if (result) {
pending.push(result);
}
} catch (err) {
this.reportHandlerError(event, err);
}
}
const results = await Promise.allSettled(pending);
for (const result of results) {
if (result.status === "rejected") {
this.reportHandlerError(event, result.reason);
}
}
}
reportHandlerError(event, err) {
const message = `event handler failed for "${String(event)}"`;
if (this.logger) {
this.logger.error(message, err);
return;
}
console.error(message, err);
}
}
exports.EventEmitter = EventEmitter;
//# sourceMappingURL=event-emitter.js.map
//# sourceMappingURL=event-emitter.js.map