2026-06-21 14:09:35 +09:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
class TarinaiEventBus {
|
2026-06-29 16:21:58 +09:00
|
|
|
constructor() {
|
2026-06-21 14:09:35 +09:00
|
|
|
this.handlers = new Map();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
on(type, handler) {
|
|
|
|
|
if (!type || typeof handler !== "function") return () => {};
|
|
|
|
|
let list = this.handlers.get(type);
|
|
|
|
|
if (!list) {
|
|
|
|
|
list = new Set();
|
|
|
|
|
this.handlers.set(type, list);
|
|
|
|
|
}
|
|
|
|
|
list.add(handler);
|
|
|
|
|
return () => this.off(type, handler);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
off(type, handler) {
|
|
|
|
|
const list = this.handlers.get(type);
|
|
|
|
|
if (!list) return;
|
|
|
|
|
list.delete(handler);
|
|
|
|
|
if (!list.size) this.handlers.delete(type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
emit(type, detail = {}) {
|
|
|
|
|
if (!type) return null;
|
|
|
|
|
const event = { type, detail: detail || {}, at: performance?.now?.() ?? Date.now() };
|
|
|
|
|
const direct = this.handlers.get(type);
|
|
|
|
|
if (direct) for (const handler of [...direct]) this.safeCall(handler, event);
|
|
|
|
|
const wildcard = this.handlers.get("*");
|
|
|
|
|
if (wildcard) for (const handler of [...wildcard]) this.safeCall(handler, event);
|
|
|
|
|
return event;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
safeCall(handler, event) {
|
|
|
|
|
try { handler(event); }
|
|
|
|
|
catch (err) { console.error("event handler failed", event.type, err); }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window.TarinaiEvents = window.TarinaiEvents || new TarinaiEventBus();
|