chat / client / src / sueta / social.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
62
63
64
65
66
67
68
;; The social-kit lazy boundary, mirroring room.ts's
;; `void import("ardegazu-social-kit")`.
;;
;; This is the ONLY namespace that requires the kit's engine; shadow-cljs.edn
;; puts it in its own :social module and scripts/build.mjs gates that the kit's
;; self-sync wire literal appears ONLY in that chunk. Loaded through shadow.lazy
;; from sueta.room, after the room is already live — it must never delay or
;; break the room.
;;
;; The kit is CLASSPATH SOURCE now (deps.edn), so the boundary is drawn by the
;; require graph rather than by an npm dist file: shadow puts every
;; `ardegazu.social.*` namespace in the deepest module that needs it, and
;; nothing above this one names the engine. The one exception is deliberate —
;; `ardegazu.social.join` (the paste/home chips) is required from app/lobby and
;; therefore lands in :main, exactly where the `ardegazu-social-kit/join` chip
;; used to be fetched from. It reaches only `ardegazu.social.text`.
;;
;; `attach-social` is `ardegazu.social.app-boot`'s — never
;; `ardegazu.social.index`, which is the kit's ESM re-export shim and would drag
;; the WHOLE public surface (net, selftest, gamelb) in behind it.
(ns sueta.social
  (:require [ardegazu.social.app-boot :refer (attach-social)]
            [sueta.app.chat :as chat]
            [sueta.app.rooms :as rooms]
            [sueta.app.ui :as ui]
            [sueta.config :as config]
            [sueta.i18n :as i18n :refer (tn)]
            [ardegazu.rooms.js :as j]
            [shadow.cljs.modern :refer (js-await)]))

(defn attach! [opts]
  (let [net-obj (unchecked-get opts "net")
        id-boot (unchecked-get opts "idBoot")
        bridge (unchecked-get opts "bridge")
        store (unchecked-get opts "store")
        ui-obj (unchecked-get opts "ui")
        secret (unchecked-get opts "secret")
        last-rec (.lastRecord ^js bridge)]
    (js-await [agent (attach-social
                      (j/ordered
                       "ns" config/NS
                       "app" "chat.ardegazu.ro"
                       "identity" (unchecked-get id-boot "identity")
                       "seed" (unchecked-get id-boot "seed")
                       "myName" (fn [] (chat/my-name store))
                       "pubsub" (unchecked-get (unchecked-get (unchecked-get net-obj "libp2p") "services") "pubsub")
                       "soc" (when (j/truthy? last-rec) (unchecked-get last-rec "soc"))
                       "roomLink" (fn [] (str (.-origin js/location) (.-pathname js/location) "#" secret))
                       "t" i18n/t-kit
                       ;; room-list sync, second transport: the sealed
                       ;; self-channel fsync (mailbox-backed) reaches devices that
                       ;; never share a live room. Same fold + toast as the
                       ;; directed in-room roomsync in room.cljs.
                       "appState"
                       (j/ordered
                        "get" (fn [] (rooms/build-room-sync))
                        "apply" (fn [s]
                                  (try
                                    (let [n (rooms/merge-rooms s secret)]
                                      (when (pos? n) (ui/toast ui-obj (tn "toast.rooms-synced" n))))
                                    (catch :default _ nil))
                                  js/undefined))))]
      (do
        ;; any local list change (visit/rename/forget/merge) → debounced,
        ;; hash-gated self-sync deposit for this identity's other devices
        (when (j/truthy? agent)
          (rooms/set-on-rooms-changed (fn [] (.syncNow ^js agent) js/undefined)))
        js/undefined))))

static mirror of HEAD · about · clone: git clone https://git.ardegazu.ro/chat.git