199ce36b创建于 2023年6月29日历史提交
import { getExtRuntime } from "./utils"

export type PubSubMessage = {
  from?: number
  to?: number
  payload: any
}

// Only usable from BGSW
export const getHubMap = (): Map<number, chrome.runtime.Port> =>
  globalThis.__plasmoInternalHubMap

// Only usable by BGSW
export const startHub = () => {
  const runtime = getExtRuntime()
  if (!runtime.onConnectExternal) {
    throw new Error(
      "onConnect External not available. You need externally_connectable entry possibly"
    )
  }

  globalThis.__plasmoInternalHubMap = new Map()
  const hub = getHubMap()

  runtime.onConnectExternal.addListener((port) => {
    const tabId = port.sender.tab.id
    if (!hub.has(tabId)) {
      hub.set(tabId, port)
      port.onMessage.addListener((message) => {
        broadcast({ from: tabId, payload: message })
      })
      port.onDisconnect.addListener(() => {
        //TODO - Should we log?
        hub.delete(tabId)
      })
    }
  })
}

// Only usable by BGSW
export const broadcast = (pubSubMessage: PubSubMessage) => {
  const hub = getHubMap()
  hub.forEach((port, tabId) => {
    const skipBroadcast = tabId === pubSubMessage.from
    if (skipBroadcast) {
      return
    }
    port.postMessage({ ...pubSubMessage, to: tabId })
  })
}

export const connectToHub = (extensionId: string) => {
  const runtime = getExtRuntime()
  if (!runtime.connect) {
    throw new Error(
      "runtime.connect not available. You need to use startHub in BGSW"
    )
  }
  const port = runtime.connect(extensionId)
  return port
}