;; ported-from: src/lib/descriptor.ts @ v1.0.0
;;
;; Best-effort fetch of the relay host's /.well-known/ap2p descriptor so the
;; operator can rotate the relay's PeerId or TURN endpoint without a client
;; release. Baked-in defaults win when the fetch fails (static IPFS hosting must
;; keep working offline).
;;
;; Shapes (types/index.d.ts carries them for TS consumers):
;; RelayConfig {relayMultiaddr, turnCredsUrl, discoveryTopic, mailbox?}
;; MailboxConfig {baseUrl, credsUrl, maxMessageKb}
;; `mailbox` absent ⇒ the offline store-and-forward feature is off (§9).
(ns ardegazu.rooms.lib.descriptor
(:require [ardegazu.rooms.js :as j]
[shadow.cljs.modern :refer (js-await)]))
(def ^:private DNS4-HOST #"^/dns4/([^/]+)/")
(defn- nn
"JS `a ?? b`: only null/undefined fall through (0 and \"\" do not)."
[a b]
(if (or (nil? a) (identical? a js/undefined)) b a))
(defn resolve-relay-config
([defaults] (resolve-relay-config defaults 2000))
([defaults timeout-ms]
(let [m (.match (unchecked-get defaults "relayMultiaddr") DNS4-HOST)
host (when (some? m) (aget m 1))]
(if-not (j/truthy? host)
;; dev/self-host multiaddr (ip4 etc.) — no descriptor
(js/Promise.resolve defaults)
(-> (js/Promise.resolve nil)
(.then
(fn [_]
(js-await [res (js/fetch (str "https://" host "/.well-known/ap2p")
(j/ordered "signal" (js/AbortSignal.timeout timeout-ms)))]
(if-not (j/truthy? (unchecked-get res "ok"))
defaults
(js-await [d (.json ^js res)]
(let [mbx (unchecked-get d "mailbox")
endpoint (when (some? mbx) (unchecked-get mbx "endpoint"))
mint (when (some? mbx) (unchecked-get mbx "mint_endpoint"))
mailbox (if (and (j/truthy? endpoint) (j/truthy? mint))
(j/ordered "baseUrl" endpoint
"credsUrl" mint
"maxMessageKb" (nn (unchecked-get mbx "max_message_kb") 64))
(unchecked-get defaults "mailbox"))
relay (unchecked-get d "relay")
mas (when (some? relay) (unchecked-get relay "multiaddrs"))
endpoints (unchecked-get d "endpoints")
out (j/ordered
"relayMultiaddr" (nn (when (some? mas) (aget mas 0))
(unchecked-get defaults "relayMultiaddr"))
"turnCredsUrl" (nn (when (some? endpoints)
(unchecked-get endpoints "turn_credentials"))
(unchecked-get defaults "turnCredsUrl"))
"discoveryTopic" (nn (when (some? relay)
(unchecked-get relay "pubsub_discovery_topic"))
(unchecked-get defaults "discoveryTopic")))]
(when (j/truthy? mailbox) (unchecked-set out "mailbox" mailbox))
out))))))
(.catch (fn [_] defaults)))))))