class i extends Error {
  constructor(s) {
    super(s), this.name = "StreamError";
  }
}
class t extends i {
  constructor(s) {
    const e = s ? `Stream '${s}' is complete, cannot listen for more messages` : "Stream is complete, cannot listen for more messages";
    super(e);
  }
}
class n extends i {
  constructor(s) {
    const e = s ? `Stream '${s}' already has a listener, streams can only have one listener` : "Stream already has a listener, streams can only have one listener";
    super(e);
  }
}
class r {
  messages = [];
  onMessagesAvailable = void 0;
  onStreamEnd = [];
  notifyMessagesAvailable = void 0;
  done = !1;
  id;
  constructor(s = {}) {
    this.id = s.id, this.messages = (s.messages || []).map((e) => ({ type: "message", data: e }));
  }
  static fromArray(s) {
    const e = new r({ messages: s });
    return e.close(), e;
  }
  async listenForAvailableMessages() {
    if (this.done)
      throw new t(this.id);
    if (this.onMessagesAvailable)
      throw new n(this.id);
    return this.onMessagesAvailable = new Promise((s) => {
      this.notifyMessagesAvailable = s;
    }), this.onMessagesAvailable;
  }
  async *[Symbol.asyncIterator]() {
    for (this.messages.length === 0 && !this.done && await this.listenForAvailableMessages(); this.messages.length > 0 || !this.done; ) {
      const s = this.messages.shift();
      if (s === void 0) {
        await this.listenForAvailableMessages();
        continue;
      }
      if (s.type === "error")
        throw s.data;
      if (s.type === "close")
        break;
      yield s.data;
    }
  }
  async next() {
    const s = this.messages.shift();
    if (s) {
      if (s.type === "error")
        throw s.data;
      if (s.type === "close")
        throw new t(this.id);
      return s.data;
    }
    if (this.done)
      throw new t(this.id);
    return await this.listenForAvailableMessages(), this.next();
  }
  async all() {
    const s = [];
    for await (const e of this)
      s.push(e);
    return s;
  }
  async last() {
    return (await this.all()).at(-1);
  }
  send(s) {
    this.messages.push({ type: "message", data: s }), this.onMessagesAvailable = void 0, this.notifyMessagesAvailable && this.notifyMessagesAvailable();
  }
  trySend(s) {
    return this.done ? !1 : (this.send(s), !0);
  }
  close() {
    this.done = !0, this.messages.push({ type: "close" }), this.onMessagesAvailable = void 0, this.notifyMessagesAvailable && this.notifyMessagesAvailable();
    for (const s of this.onStreamEnd)
      s();
  }
  tryClose() {
    return this.done ? !1 : (this.close(), !0);
  }
  error(s) {
    this.messages.unshift({ type: "error", data: s }), this.notifyMessagesAvailable && this.notifyMessagesAvailable(), this.done = !0, this.messages.push({ type: "close" });
    for (const e of this.onStreamEnd)
      e();
  }
  onEnd(s) {
    this.onStreamEnd.push(s);
  }
}
export {
  r as AsyncStream,
  t as StreamAlreadyClosedError,
  n as StreamAlreadyHasListenerError,
  i as StreamError
};
//# sourceMappingURL=index.js.map
