rooms-kit / src / ardegazu / rooms / lib / descriptor.cljs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
;; 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)))))))

static mirror of HEAD · about · clone: git clone https://git.ardegazu.ro/rooms-kit.git