"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.__tsfTypeAliases = exports.eventDispatcher = exports.event = exports.EventBus = exports.EventToken = void 0;
exports.getListenerMethodMetadata = getListenerMethodMetadata;
const tslib_1 = require("tslib");
const _a = tslib_1.__importStar(require("@zyno-io/ts-reflection/type-metadata-runtime"));
const __tsf_metadata_type = _a.createCompactMetadataRegistryV1("[1,[{\"kind\":6},{\"kind\":2},{\"kind\":2,\"typeName\":\"() =\\u003e void\"},{\"kind\":22,\"type\":{\"kind\":3}}]]", []);
let _EventTokenMetadata_1;
class EventToken {
    name;
    constructor(name) {
        this.name = name;
    }
    static __tsfType = _EventTokenMetadata_1 = _a.decodeCompactMetadataV1("[1,{\"kind\":16,\"name\":\"EventToken\",\"typeName\":\"EventToken\",\"classType\":{\"$tsf\":0},\"properties\":[],\"methods\":[],\"hasConstructor\":true,\"constructorParameters\":[{\"name\":\"name\",\"type\":{\"$tsfType\":0},\"optional\":false,\"default\":false}]}]", [() => EventToken], __tsf_metadata_type);
}
exports.EventToken = EventToken;
_EventTokenMetadata_1.classType = EventToken;
EventToken.__tsfType = _EventTokenMetadata_1;
const listenerMetadata = new WeakMap();
let _EventBusMetadata_1;
class EventBus {
    handlers = new Map();
    listen(token, handler, order = 0) {
        const handlers = this.handlers.get(token) ?? [];
        const registered = { handler, order };
        handlers.push(registered);
        handlers.sort((a, b) => b.order - a.order);
        this.handlers.set(token, handlers);
        return () => {
            const current = this.handlers.get(token) ?? [];
            this.handlers.set(token, current.filter(item => item !== registered));
        };
    }
    async dispatch(token, event) {
        const handlers = [...(this.handlers.get(token) ?? [])];
        for (const { handler } of handlers) {
            await handler(event);
        }
    }
    static __tsfType = _EventBusMetadata_1 = _a.decodeCompactMetadataV1("[1,{\"kind\":16,\"name\":\"EventBus\",\"typeName\":\"EventBus\",\"classType\":{\"$tsf\":0},\"properties\":[],\"methods\":[{\"name\":\"listen\",\"parameters\":[{\"name\":\"token\",\"type\":{\"kind\":16,\"typeName\":\"EventToken\",\"classType\":{\"$tsf\":1},\"typeArguments\":[{\"kind\":16,\"typeName\":\"TEvent\",\"classType\":{\"$tsf\":2}}]},\"optional\":false,\"default\":false},{\"name\":\"handler\",\"type\":{\"kind\":2,\"typeName\":\"EventHandler\",\"typeArguments\":[{\"kind\":16,\"typeName\":\"TEvent\",\"classType\":{\"$tsf\":2}}]},\"optional\":false,\"default\":false},{\"name\":\"order\",\"type\":{\"$tsfType\":1},\"optional\":true,\"default\":true}],\"returnType\":{\"$tsfType\":2}},{\"name\":\"dispatch\",\"parameters\":[{\"name\":\"token\",\"type\":{\"kind\":16,\"typeName\":\"EventToken\",\"classType\":{\"$tsf\":1},\"typeArguments\":[{\"kind\":16,\"typeName\":\"TEvent\",\"classType\":{\"$tsf\":2}}]},\"optional\":false,\"default\":false},{\"name\":\"event\",\"type\":{\"kind\":16,\"typeName\":\"TEvent\",\"classType\":{\"$tsf\":2}},\"optional\":false,\"default\":false}],\"returnType\":{\"$tsfType\":3}}],\"hasConstructor\":false,\"constructorParameters\":[]}]", [() => EventBus, () => (typeof EventToken !== "undefined" ? EventToken : (typeof exports !== "undefined" ? exports.EventToken : undefined)), () => (typeof TEvent !== "undefined" ? TEvent : (typeof exports !== "undefined" ? exports.TEvent : undefined))], __tsf_metadata_type);
}
exports.EventBus = EventBus;
_EventBusMetadata_1.classType = EventBus;
EventBus.__tsfType = _EventBusMetadata_1;
function listen(token, order = 0) {
    return (target, propertyKey) => {
        const handlers = listenerMetadata.get(target) ?? [];
        handlers.push({ token, methodName: propertyKey, order });
        listenerMetadata.set(target, handlers);
    };
}
exports.event = { listen };
exports.eventDispatcher = { listen };
function getListenerMethodMetadata(instanceOrPrototype) {
    const result = [];
    const seen = new Set();
    let prototype = typeof instanceOrPrototype === 'function' ? instanceOrPrototype.prototype : instanceOrPrototype;
    while (prototype && prototype !== Object.prototype) {
        for (const item of listenerMetadata.get(prototype) ?? []) {
            if (seen.has(item.methodName))
                continue;
            seen.add(item.methodName);
            result.push(item);
        }
        prototype = Object.getPrototypeOf(prototype);
    }
    return result;
}
exports.__tsfTypeAliases = _a.decodeCompactMetadataV1("[1,{\"ListenerMethodMetadata\":{\"kind\":18,\"typeName\":\"ListenerMethodMetadata\",\"types\":[{\"kind\":20,\"name\":\"token\",\"type\":{\"kind\":16,\"typeName\":\"EventToken\",\"classType\":{\"$tsf\":0},\"typeArguments\":[{\"kind\":2,\"typeName\":\"TEvent\"}]},\"optional\":false},{\"kind\":20,\"name\":\"methodName\",\"type\":{\"kind\":12,\"types\":[{\"kind\":6},{\"kind\":2,\"typeName\":\"symbol\"}],\"typeName\":\"ListenerMethodKey\"},\"optional\":false},{\"kind\":20,\"name\":\"order\",\"type\":{\"kind\":7},\"optional\":false}],\"typeParameters\":[\"TEvent\"]}}]", [() => (typeof EventToken !== "undefined" ? EventToken : (typeof exports !== "undefined" ? exports.EventToken : undefined))], __tsf_metadata_type);
//# sourceMappingURL=event-bus.js.map