{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import {\n  createRelayManager,\n  createTopicStrategy,\n  makeSocket,\n  pauseRelayReconnection,\n  resumeRelayReconnection,\n  selfId,\n  toJson,\n  type BaseRoomConfig,\n  type JoinRoom,\n  type RelayConfig,\n  type SocketClient,\n  type StrategyMessage\n} from '@trystero-p2p/core'\n\nconst relayManager = createRelayManager<SocketClient>(client => client.socket)\nconst msgHandlers =\n  relayManager.scoped<Set<(topic: string, data: StrategyMessage) => void>>()\n\nexport type WsRelayConfig = Omit<RelayConfig, 'urls' | 'redundancy'> & {\n  urls: string[]\n}\n\nexport type WsRelayRoomConfig = BaseRoomConfig & {\n  relayConfig: WsRelayConfig\n}\n\nexport type WsRelayClientMessage =\n  | {type: 'subscribe'; topic: string}\n  | {type: 'unsubscribe'; topic: string}\n  | {type: 'publish'; topic: string; payload: StrategyMessage}\n\nexport type WsRelayServerMessage = {\n  topic: string\n  payload: StrategyMessage\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n  typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst isStrategyMessage = (value: unknown): value is StrategyMessage =>\n  typeof value === 'string' || isRecord(value)\n\nconst parseServerMessage = (data: string): WsRelayServerMessage | null => {\n  try {\n    const msg = JSON.parse(data) as Partial<WsRelayServerMessage>\n\n    return typeof msg.topic === 'string' && isStrategyMessage(msg.payload)\n      ? {topic: msg.topic, payload: msg.payload}\n      : null\n  } catch {\n    return null\n  }\n}\n\nconst publish = (\n  topic: string,\n  payload: StrategyMessage\n): WsRelayClientMessage =>\n  ({\n    type: 'publish',\n    topic,\n    payload\n  }) as const\n\nconst subscribe = (topic: string): WsRelayClientMessage => ({\n  type: 'subscribe',\n  topic\n})\n\nconst unsubscribe = (topic: string): WsRelayClientMessage => ({\n  type: 'unsubscribe',\n  topic\n})\n\nexport const joinRoom: JoinRoom<WsRelayRoomConfig> = createTopicStrategy({\n  init: config =>\n    config.relayConfig.urls.map(url => {\n      const client = relayManager.register(url, () =>\n        makeSocket(url, data => {\n          const msg = parseServerMessage(data)\n\n          if (!msg) {\n            return\n          }\n\n          msgHandlers\n            .forRelay(client)\n            [msg.topic]?.forEach(handler => handler(msg.topic, msg.payload))\n        })\n      )\n\n      return client.ready\n    }),\n\n  subscribeTopic: (client, topic, onMessage) => {\n    const handlers = msgHandlers.forRelay(client)\n    const topicHandler = (topic: string, data: StrategyMessage): void =>\n      void onMessage(topic, data)\n\n    const wasEmpty = !handlers[topic]\n    const topicHandlers = (handlers[topic] ??= new Set())\n\n    topicHandlers.add(topicHandler)\n\n    if (wasEmpty) {\n      client.send(toJson(subscribe(topic)))\n    }\n\n    return () => {\n      const topicHandlers = handlers[topic]\n\n      if (!topicHandlers) {\n        return\n      }\n\n      topicHandlers.delete(topicHandler)\n\n      if (topicHandlers.size === 0) {\n        delete handlers[topic]\n        client.send(toJson(unsubscribe(topic)))\n      }\n    }\n  },\n\n  publishTopic: (client, topic, msg) => client.send(toJson(publish(topic, msg)))\n})\n\nexport const getRelaySockets = relayManager.getSockets\n\nexport {pauseRelayReconnection, resumeRelayReconnection, selfId}\n\nexport type * from '@trystero-p2p/core'\n"],"mappings":";;AAeA,MAAM,eAAe,oBAAiC,WAAU,OAAO,MAAM;AAC7E,MAAM,cACJ,aAAa,OAA4D;AAoB3E,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,MAAM,qBAAqB,UACzB,OAAO,UAAU,YAAY,SAAS,KAAK;AAE7C,MAAM,sBAAsB,SAA8C;CACxE,IAAI;EACF,MAAM,MAAM,KAAK,MAAM,IAAI;EAE3B,OAAO,OAAO,IAAI,UAAU,YAAY,kBAAkB,IAAI,OAAO,IACjE;GAAC,OAAO,IAAI;GAAO,SAAS,IAAI;EAAO,IACvC;CACN,QAAQ;EACN,OAAO;CACT;AACF;AAEA,MAAM,WACJ,OACA,aAEC;CACC,MAAM;CACN;CACA;AACF;AAEF,MAAM,aAAa,WAAyC;CAC1D,MAAM;CACN;AACF;AAEA,MAAM,eAAe,WAAyC;CAC5D,MAAM;CACN;AACF;AAEA,MAAa,WAAwC,oBAAoB;CACvE,OAAM,WACJ,OAAO,YAAY,KAAK,KAAI,QAAO;EACjC,MAAM,SAAS,aAAa,SAAS,WACnC,WAAW,MAAK,SAAQ;GACtB,MAAM,MAAM,mBAAmB,IAAI;GAEnC,IAAI,CAAC,KACH;GAGF,YACG,SAAS,MAAM,CAAC,CAChB,IAAI,MAAM,EAAE,SAAQ,YAAW,QAAQ,IAAI,OAAO,IAAI,OAAO,CAAC;EACnE,CAAC,CACH;EAEA,OAAO,OAAO;CAChB,CAAC;CAEH,iBAAiB,QAAQ,OAAO,cAAc;EAC5C,MAAM,WAAW,YAAY,SAAS,MAAM;EAC5C,MAAM,gBAAgB,OAAe,SACnC,KAAK,UAAU,OAAO,IAAI;EAE5B,MAAM,WAAW,CAAC,SAAS;EAG3B,CAFuB,SAAS,2BAAW,IAAI,IAAI,EAAA,CAErC,IAAI,YAAY;EAE9B,IAAI,UACF,OAAO,KAAK,OAAO,UAAU,KAAK,CAAC,CAAC;EAGtC,aAAa;GACX,MAAM,gBAAgB,SAAS;GAE/B,IAAI,CAAC,eACH;GAGF,cAAc,OAAO,YAAY;GAEjC,IAAI,cAAc,SAAS,GAAG;IAC5B,OAAO,SAAS;IAChB,OAAO,KAAK,OAAO,YAAY,KAAK,CAAC,CAAC;GACxC;EACF;CACF;CAEA,eAAe,QAAQ,OAAO,QAAQ,OAAO,KAAK,OAAO,QAAQ,OAAO,GAAG,CAAC,CAAC;AAC/E,CAAC;AAED,MAAa,kBAAkB,aAAa"}