var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
var __typeError = (msg) => {
  throw TypeError(msg);
};
var __using = (stack, value, async) => {
  if (value != null) {
    if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
    var dispose, inner;
    if (async) dispose = value[__knownSymbol("asyncDispose")];
    if (dispose === void 0) {
      dispose = value[__knownSymbol("dispose")];
      if (async) inner = dispose;
    }
    if (typeof dispose !== "function") __typeError("Object not disposable");
    if (inner) dispose = function() {
      try {
        inner.call(this);
      } catch (e) {
        return Promise.reject(e);
      }
    };
    stack.push([async, dispose, value]);
  } else if (async) {
    stack.push([async]);
  }
  return value;
};
var __callDispose = (stack, error, hasError) => {
  var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
    return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
  };
  var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
  var next = (it) => {
    while (it = stack.pop()) {
      try {
        var result = it[1] && it[1].call(it[2]);
        if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
      } catch (e) {
        fail(e);
      }
    }
    if (hasError) throw error;
  };
  return next();
};
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Diagnostic, Observable } from "#general";
import { INTERACTION_PROTOCOL_ID } from "#types";
import { SessionClosedError } from "./errors.js";
import { MRP } from "./MRP.js";
class ExchangeProvider {
  constructor(exchangeManager) {
    this.exchangeManager = exchangeManager;
  }
  hasProtocolHandler(protocolId) {
    return this.exchangeManager.hasProtocolHandler(protocolId);
  }
  getProtocolHandler(protocolId) {
    return this.exchangeManager.getProtocolHandler(protocolId);
  }
  addProtocolHandler(handler) {
    this.exchangeManager.addProtocolHandler(handler);
  }
  get channelType() {
    return this.session.channel.type;
  }
}
class DedicatedChannelExchangeProvider extends ExchangeProvider {
  #session;
  supportsReconnect = false;
  constructor(exchangeManager, session) {
    super(exchangeManager);
    this.#session = session;
  }
  async initiateExchange() {
    return this.exchangeManager.initiateExchangeForSession(this.#session, INTERACTION_PROTOCOL_ID);
  }
  async reconnectChannel() {
    return false;
  }
  get session() {
    return this.#session;
  }
  maximumPeerResponseTime(expectedProcessingTime = MRP.DEFAULT_EXPECTED_PROCESSING_TIME, includeMaximumSendingTime) {
    return this.exchangeManager.calculateMaximumPeerResponseTimeMsFor(
      this.#session,
      expectedProcessingTime,
      includeMaximumSendingTime
    );
  }
}
class ReconnectableExchangeProvider extends ExchangeProvider {
  constructor(exchangeManager, sessions, address, reconnectChannelFunc) {
    super(exchangeManager);
    this.sessions = sessions;
    this.#address = address;
    this.#reconnectChannelFunc = reconnectChannelFunc;
    sessions.sessions.added.on((session) => {
      if (session.peerAddress === this.#address) {
        this.#channelUpdated.emit();
      }
    });
  }
  supportsReconnect = true;
  #address;
  #reconnectChannelFunc;
  #channelUpdated = Observable();
  get channelUpdated() {
    return this.#channelUpdated;
  }
  async initiateExchange(protocol = INTERACTION_PROTOCOL_ID) {
    if (!this.sessions.maybeSessionFor(this.#address)) {
      var _stack = [];
      try {
        const _connecting = __using(_stack, this.sessions.construction.join(
          "connecting to",
          Diagnostic.strong(this.#address.toString())
        ));
        await this.reconnectChannel();
      } catch (_) {
        var _error = _, _hasError = true;
      } finally {
        __callDispose(_stack, _error, _hasError);
      }
    }
    if (!this.sessions.maybeSessionFor(this.#address)) {
      throw new SessionClosedError("Channel not connected");
    }
    return this.exchangeManager.initiateExchange(this.#address, protocol);
  }
  async reconnectChannel(options = {}) {
    if (this.#reconnectChannelFunc === void 0) {
      return false;
    }
    await this.#reconnectChannelFunc(options);
    return true;
  }
  get session() {
    return this.sessions.sessionFor(this.#address);
  }
  maximumPeerResponseTime(expectedProcessingTime = MRP.DEFAULT_EXPECTED_PROCESSING_TIME, includeMaximumSendingTime) {
    return this.exchangeManager.calculateMaximumPeerResponseTimeMsFor(
      this.sessions.sessionFor(this.#address),
      expectedProcessingTime,
      includeMaximumSendingTime
    );
  }
}
export {
  DedicatedChannelExchangeProvider,
  ExchangeProvider,
  ReconnectableExchangeProvider
};
//# sourceMappingURL=ExchangeProvider.js.map
