import "./chunk-GJND2PHR.js";
import {
  NetworkAdapter,
  require_browser
} from "./chunk-Y6QP355O.js";
import "./chunk-52WFVLSC.js";
import {
  import_index
} from "./chunk-BZGBHEIV.js";
import "./chunk-SVC3MPPD.js";
import {
  __toESM
} from "./chunk-5WWUZCGV.js";

// node_modules/.deno/@automerge+automerge-repo-network-messagechannel@1.2.1/node_modules/@automerge/automerge-repo-network-messagechannel/dist/StrongMessagePortRef.js
var StrongMessagePortRef = class extends import_index.default {
  port;
  constructor(port) {
    port.addEventListener("message", (event) => {
      this.emit("message", event);
    });
    super();
    this.port = port;
  }
  postMessage(message, transfer) {
    this.port.postMessage(message, transfer);
  }
  start() {
    this.port.start();
  }
  isAlive() {
    return true;
  }
};

// node_modules/.deno/@automerge+automerge-repo-network-messagechannel@1.2.1/node_modules/@automerge/automerge-repo-network-messagechannel/dist/WeakMessagePortRef.js
var WeakMessagePortRef = class extends import_index.default {
  weakRef;
  isDisconnected = false;
  constructor(port) {
    super();
    this.weakRef = new WeakRef(port);
    port.addEventListener("message", (event) => {
      this.emit("message", event);
    });
  }
  postMessage(message, transfer) {
    const port = this.weakRef.deref();
    if (!port) {
      this.disconnnect();
      return;
    }
    try {
      port.postMessage(message, transfer);
    } catch (err) {
      this.disconnnect();
    }
  }
  start() {
    const port = this.weakRef.deref();
    if (!port) {
      this.disconnnect();
      return;
    }
    try {
      port.start();
    } catch (err) {
      this.disconnnect();
    }
  }
  disconnnect() {
    if (!this.isDisconnected) {
      this.emit("close");
      this.isDisconnected = true;
    }
  }
  isAlive() {
    if (this.isDisconnected) {
      return false;
    }
    if (!this.weakRef.deref()) {
      this.disconnnect();
      return false;
    }
    return true;
  }
};

// node_modules/.deno/@automerge+automerge-repo-network-messagechannel@1.2.1/node_modules/@automerge/automerge-repo-network-messagechannel/dist/index.js
var import_debug = __toESM(require_browser());
var log = (0, import_debug.default)("automerge-repo:messagechannel");
var MessageChannelNetworkAdapter = class extends NetworkAdapter {
  channels = {};
  /** @hidden */
  messagePortRef;
  #startupComplete = false;
  constructor(messagePort, config = {}) {
    super();
    const useWeakRef = config.useWeakRef ?? false;
    this.messagePortRef = useWeakRef ? new WeakMessagePortRef(messagePort) : new StrongMessagePortRef(messagePort);
  }
  connect(peerId, peerMetadata) {
    log("messageport connecting");
    this.peerId = peerId;
    this.peerMetadata = peerMetadata;
    this.messagePortRef.start();
    this.messagePortRef.addListener("message", (e) => {
      log("message port received %o", e.data);
      const message = e.data;
      if ("targetId" in message && message.targetId !== this.peerId) {
        throw new Error("MessagePortNetwork should never receive messages for a different peer.");
      }
      const { senderId, type } = message;
      switch (type) {
        case "arrive":
          {
            const { peerMetadata: peerMetadata2 } = message;
            this.messagePortRef.postMessage({
              type: "welcome",
              senderId: this.peerId,
              peerMetadata: this.peerMetadata,
              targetId: senderId
            });
            this.announceConnection(senderId, peerMetadata2);
          }
          break;
        case "welcome":
          {
            const { peerMetadata: peerMetadata2 } = message;
            this.announceConnection(senderId, peerMetadata2);
          }
          break;
        default:
          if (!("data" in message)) {
            this.emit("message", message);
          } else {
            this.emit("message", {
              ...message,
              data: message.data ? new Uint8Array(message.data) : void 0
            });
          }
          break;
      }
    });
    this.messagePortRef.addListener("close", () => {
      this.emit("close");
    });
    this.messagePortRef.postMessage({
      senderId: this.peerId,
      type: "arrive",
      peerMetadata
    });
    setTimeout(() => {
      if (!this.#startupComplete) {
        this.#startupComplete = true;
        this.emit("ready", { network: this });
      }
    }, 100);
  }
  send(message) {
    if ("data" in message) {
      const data = message.data.buffer.slice(message.data.byteOffset, message.data.byteOffset + message.data.byteLength);
      this.messagePortRef.postMessage({
        ...message,
        data
      }, [data]);
    } else {
      this.messagePortRef.postMessage(message);
    }
  }
  announceConnection(peerId, peerMetadata) {
    if (!this.#startupComplete) {
      this.#startupComplete = true;
      this.emit("ready", { network: this });
    }
    this.emit("peer-candidate", { peerId, peerMetadata });
  }
  disconnect() {
    throw new Error("Unimplemented: leave on MessagePortNetworkAdapter");
  }
};
export {
  MessageChannelNetworkAdapter
};
//# sourceMappingURL=@automerge_automerge-repo-network-messagechannel.js.map
