;; ported-from: src/core/bootstrap.ts @ v1.3.0
;;
;; Relay endpoint discovery: fetch the p2p app's /.well-known/ap2p descriptor
;; so a relay identity rotation never needs a client release. Falls back to the
;; compiled-in relay info when the fetch fails or times out.
(ns ardegazu.peer.core.bootstrap
(:require [shadow.cljs.modern :refer (js-await)]))
(defn fetch-relay-info
"RelayInfo = #js {:peerId :multiaddrs}. `timeout-ms` defaults to 3000; the
TS original took it as an optional third parameter, so callers that pass
js/undefined get the same default (dev/docs/CLJS.md: optional JS params are
a fixed arity plus a js/undefined sentinel, not a CLJS multi-arity)."
([descriptor-url fallback] (fetch-relay-info descriptor-url fallback js/undefined))
([descriptor-url fallback timeout-ms]
(let [t (if (identical? timeout-ms js/undefined) 3000 timeout-ms)]
(-> (js/Promise.resolve nil)
(.then
(fn [_]
(js-await [res (js/fetch descriptor-url
(js-obj "signal" (js/AbortSignal.timeout t)))]
(do
(when-not (.-ok ^js res)
(throw (js/Error. (str "descriptor " (.-status ^js res)))))
(js-await [d (.json ^js res)]
(let [relay (unchecked-get d "relay")
peer-id (when (some? relay) (unchecked-get relay "peer_id"))
maddrs (when (some? relay)
(let [m (unchecked-get relay "multiaddrs")]
(when (some? m)
(.filter ^js m (fn [x] (and (string? x) (pos? (.-length x))))))))]
(when-not (and ^boolean (js* "!!(~{})" peer-id)
(some? maddrs)
(pos? (.-length ^js maddrs)))
(throw (js/Error. "descriptor missing relay block")))
(js-obj "peerId" peer-id "multiaddrs" maddrs)))))))
(.catch
(fn [err]
(js/console.warn "ap2p descriptor unavailable, using compiled-in relay info" err)
fallback))))))