"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var ricos_event_exports = {};
__export(ricos_event_exports, {
  EventInitializationError: () => EventInitializationError,
  EventSubscriber: () => EventSubscriber,
  RicosEvent: () => RicosEvent
});
module.exports = __toCommonJS(ricos_event_exports);
var import_topics = require("./topics.js");
class EventInitializationError extends Error {
}
class DisposedEventAccessError extends Error {
}
const _RicosEvent = class _RicosEvent {
  constructor(topicDescriptor, logger) {
    this.subscribers = [];
    this.isActive = true;
    this.logger = logger;
    const topic = import_topics.RicosTopic.fromString(topicDescriptor);
    if (topic.isWildcard()) {
      throw new EventInitializationError(
        `cannot create event with wildcard topic ${topicDescriptor}`
      );
    }
    this.topic = topic;
  }
  subscribe(handler, subscriberId) {
    const subscriber = new EventSubscriber(handler, subscriberId);
    if (this.isDuplicateSubscriber(subscriber)) {
    }
    this.subscribers.push(subscriber);
    this.logger.log(`[${this.topic}]: ${subscriberId} subscribed`);
    return {
      topic: this.topic.toString(),
      cancel: () => {
        this.logger.log(`[${this.topic}]: ${subscriberId} unsubscribed`);
        this.subscribers = this.subscribers.filter((s) => s !== subscriber);
      }
    };
  }
  isDuplicateSubscriber(subscriber) {
    return this.subscribers.some((s) => s.id === subscriber.id);
  }
  publishSync(data) {
    if (!this.isActive) {
      throw new DisposedEventAccessError(`[${this.topic}] cannot publish disposed event`);
    }
    const t1 = performance.now();
    const processings = this.subscribers.map((subscriber) => {
      const t3 = performance.now();
      subscriber.invoke(this.topic.toString(), data);
      const t4 = performance.now();
      return {
        subscriberId: subscriber.id,
        duration: t4 - t3
      };
    });
    const t2 = performance.now();
    const metadata = {
      topic: this.topic.toString(),
      eventId: ++_RicosEvent.eventId,
      data,
      duration: t2 - t1,
      timestamp: /* @__PURE__ */ new Date(),
      isAsync: false,
      processings
    };
    this.logger.log(metadata);
    return this.subscribers.length > 0;
  }
  publish(data) {
    if (!this.isActive) {
      throw new DisposedEventAccessError(`[${this.topic}] cannot publish disposed event`);
    }
    const t1 = performance.now();
    this.subscribers.forEach(
      (subscriber) => setTimeout(() => subscriber.invoke(this.topic.toString(), data), 0)
    );
    const t2 = performance.now();
    const metadata = {
      topic: this.topic.toString(),
      eventId: ++_RicosEvent.eventId,
      data,
      duration: t2 - t1,
      timestamp: /* @__PURE__ */ new Date(),
      isAsync: true
    };
    this.logger.log(metadata);
    return this.subscribers.length > 0;
  }
  publishOnce(data) {
    const published = this.publish(data);
    if (published) {
      this.dispose();
    }
    return published;
  }
  getTopic() {
    return this.topic;
  }
  dispose() {
    this.subscribers = [];
    this.isActive = false;
    this.logger.log(`[${this.topic}]: event disposed`);
  }
};
_RicosEvent.eventId = 0;
let RicosEvent = _RicosEvent;
class EventSubscriber {
  constructor(callback, id) {
    this.id = id;
    this.callback = callback;
  }
  invoke(topic, data) {
    this.callback(topic, data);
  }
}
//# sourceMappingURL=ricos-event.js.map
