"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: all[name]
    });
}
_export(exports, {
    CallbackManager: function() {
        return CallbackManager;
    },
    LlamaIndexCustomEvent: function() {
        return LlamaIndexCustomEvent;
    }
});
const _env = require("@llamaindex/env");
const _EventCaller = require("../internal/context/EventCaller.js");
class LlamaIndexCustomEvent extends _env.CustomEvent {
    reason;
    constructor(event, options){
        super(event, options);
        this.reason = options?.reason ?? null;
    }
    static fromEvent(type, detail) {
        return new LlamaIndexCustomEvent(type, {
            detail: detail,
            reason: (0, _EventCaller.getEventCaller)()
        });
    }
}
//#endregion
const noop = ()=>void 0;
class CallbackManager {
    /**
   * @deprecated will be removed in the next major version
   */ get onLLMStream() {
        return async (response)=>{
            await Promise.all(this.#handlers.get("stream").map((handler)=>handler(LlamaIndexCustomEvent.fromEvent("stream", response))));
        };
    }
    /**
   * @deprecated will be removed in the next major version
   */ get onRetrieve() {
        return async (response)=>{
            await Promise.all(this.#handlers.get("retrieve").map((handler)=>handler(LlamaIndexCustomEvent.fromEvent("retrieve", response))));
        };
    }
    /**
   * @deprecated will be removed in the next major version
   */ set onLLMStream(_) {
        throw new Error("onLLMStream is deprecated. Use on('stream') instead");
    }
    /**
   * @deprecated will be removed in the next major version
   */ set onRetrieve(_) {
        throw new Error("onRetrieve is deprecated. Use `on('retrieve')` instead");
    }
    #handlers = new Map();
    constructor(handlers){
        const onLLMStream = handlers?.onLLMStream ?? noop;
        this.on("stream", (event)=>onLLMStream(event.detail));
        const onRetrieve = handlers?.onRetrieve ?? noop;
        this.on("retrieve", (event)=>onRetrieve(event.detail));
    }
    on(event, handler) {
        if (!this.#handlers.has(event)) {
            this.#handlers.set(event, []);
        }
        this.#handlers.get(event).push(handler);
        return this;
    }
    off(event, handler) {
        if (!this.#handlers.has(event)) {
            return;
        }
        const handlers = this.#handlers.get(event);
        const index = handlers.indexOf(handler);
        if (index > -1) {
            handlers.splice(index, 1);
        }
        return this;
    }
    dispatchEvent(event, detail) {
        const handlers = this.#handlers.get(event);
        if (!handlers) {
            return;
        }
        queueMicrotask(()=>{
            handlers.forEach((handler)=>handler(LlamaIndexCustomEvent.fromEvent(event, {
                    ...detail
                })));
        });
    }
}
