board / client / shadow-cljs.edn
  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
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
;; shadow-cljs builds for the board client — the second CLJS app on the ROOMS
;; stack (libp2p v2 + Helia + OrbitDB).
;;
;; The shared rooms core — ardegazu.rooms.js and ardegazu.rooms.lib.{access,
;; crypto,descriptor,encryption,log,net,orbit-identity,turn} — is NOT in this
;; repo any more: it is ardegazu-rooms-kit's own sources, reached over the
;; classpath (client/deps.edn adds node_modules/ardegazu-rooms-kit/src). What
;; is still under src/board/lib is board's own: protocol (the bespoke op
;; union), mailbox (QUEUE-CAP 2000 — see that file's comment), and epoch,
;; policy, wrapbox, selftest, which the kit has no counterpart for.
;;
;; :app — the browser build. Like game1 and chat (and unlike the kits) an APP
;; bundles its npm deps: the libp2p/helia/@orbitdb family is plain ESM in
;; node_modules, which shadow's default :browser bundling consumes. OUR OWN
;; kits are not in that list any more — rooms-kit, id-kit and social-kit are
;; classpath SOURCE (deps.edn), compiled into this build like the app's own
;; namespaces, so no kit dist file reaches the bundler at all. Under :simple
;; that source is paid in full — no DCE, no renaming — so social.js grew 8.9 KB
;; RAW while shrinking 4.0 KB gzipped (long readable symbols compress well, and
;; the duplicate id-kit copy the dist imports used to add is gone). main.js and
;; board.js both shrank on both measures.
;;
;; :optimizations :simple, NOT :advanced — the call rooms-kit made for this
;; same code. (chat has since gone the other way, on a measurement that
;; inverted the premise; see its shadow-cljs.edn. Board has not been re-argued
;; and has no externs.js, so :simple it stays until someone does that work.)
;; Almost every line below board.app is
;; interop with untyped ESM (@orbitdb/core ships no type declarations at all,
;; and helia/libp2p types never reach the CLJS side), so :advanced would rest
;; entirely on externs inference over `unchecked-get`-reached objects — the one
;; shape dev/docs/CLJS.md documents as impossible to infer and impossible to
;; audit from the warning list. :simple removes that whole risk class.
;; NOTE :optimizations must live INSIDE :compiler-options — a top-level one is
;; silently ignored and the target default is used instead.
;;
;; Three modules keep the TS build's two dynamic boundaries REAL:
;;   :main   the lobby + i18n + config + the lean social chips
;;           (`ardegazu.social.join`, which reaches only `ardegazu.social.text`)
;;           — first paint
;;   :board  the whole p2p stack (libp2p v2, Helia, @orbitdb/core, the mailbox,
;;           the access layer, the canvas), loaded via shadow.lazy only when
;;           entering a board — this mirrors main.ts's `await import("./board")`
;;   :social GameLb-less `ardegazu.social.app-boot/attach-social`, the ONLY
;;           module referencing the kit's engine — mirrors board.ts's
;;           `void import("ardegazu-social-kit")`. With the kit on the
;;           classpath the boundary is the require graph: shadow puts each
;;           `ardegazu.social.*` namespace in the deepest module that needs it.
;; scripts/build.mjs gates all three boundaries.
;;
;; :asset-path is RELATIVE — one build must serve at https://board.ardegazu.ro/
;; and /ipfs/<cid>/ alike.
;;
;; :js-options :resolve maps the bare `events` specifier onto the npm package's
;; browser entry. @orbitdb/core (+ lru, abstract-level) import `node:events`,
;; and the browser needs the real EventEmitter, not an empty shim — this is the
;; shadow equivalent of the TS build's `resolve.alias { events: "events/events.js" }`.
;; scripts/build.mjs greps the emitted bundle for the implementation, because a
;; wrong resolution here fails at RUNTIME inside OrbitDB, not at build time.
;;
;; Expect a run of :infer-warning lines from the hand-written app namespaces:
;; every one is a `(.method ^js (unchecked-get self "_field") …)` call, where the
;; hint is lost because it sits on a macro form (dev/docs/CLJS.md). They are
;; inert under :simple — nothing is renamed — and they are exactly the shape
;; that :advanced could NOT be trusted to infer, which is the second half of the
;; argument for :simple here. Do not "fix" them by moving the hints onto the
;; calls: that suppresses inference silently.
;;
;; The count went 24 -> 30 when the kits moved onto the classpath, and the six
;; new lines are a MEASUREMENT ARTEFACT, not new risk: `putProfile`,
;; `adoptBridgeSeed`, `keepLocalSeed`, `deposit` and `replay` used to appear
;; inside the bundled kit DIST files, which fed shadow's inferred externs and so
;; silenced the warning at the call sites here. No dist, no free externs entry,
;; same unchanged call sites. Under :advanced these would be exactly what an
;; externs.js has to pin — chat, which is :advanced, already pins them and
;; stayed at 0 warnings through the same change.
;;
;; :parallel-build false — many namespaces plus a :simple build is exactly the
;; combination CLJS.md says the gensym normalizer cannot repair (parallel
;; namespace compilation varies gensym numbering, which changes what Closure's
;; variable coalescing decides, which is a STRUCTURAL difference). Serial
;; compilation is the only fix; only cold builds pay the time.
;;
;; :testlib — the app + lib namespaces compiled to node-consumable ESM for the
;; black-box tests in test/*.test.mjs (golden vectors from the TS canon).
{:deps {:aliases [:dev]}
 ;; BOTH dev ports serve public/ + dist-dev/ — the WATCH's own output tree,
 ;; never dist/. dist/ belongs to `ardz build` alone: it holds a RELEASE build
 ;; (goog.DEBUG=false → the PRODUCTION relay, and a service worker), and the
 ;; old `4173 {:roots ["dist"]}` arm served exactly that to a dev tab whenever
 ;; the watcher had not overwritten it yet (or the browser had cached it) —
 ;; two tabs of one dev session then sat on DIFFERENT relays and never met.
 ;; scripts/dev.mjs redirects the watch to dist-dev/assets via --config-merge;
 ;; smoke a release build with a standalone static server over dist/, never
 ;; through these ports.
 ;; :use-index-files true — without it shadow's undertow file handler gets NO
 ;; welcome files (it only sets them from this key), so a directory request
 ;; ("/", "/id/") falls through to the push-state handler, which 404s any
 ;; request whose Accept header lacks text/html (curl, fetch). With it, "/"
 ;; serves index.html from the first root that has one.
 :dev-http {5173 {:roots ["public" "dist-dev"] :push-state/index "index.html" :use-index-files true}
            4173 {:roots ["public" "dist-dev"] :push-state/index "index.html" :use-index-files true}}
 :builds
 {:app
  {:target :browser
   :output-dir "dist/assets"
   :asset-path "./assets"
   :compiler-options {:optimizations :simple
                      :source-map false
                      :parallel-build false}
   :js-options {:resolve {"events" {:target :npm :require "events/events.js"}
                          ;; an npm package this app must never pull in — see the
                          ;; shim's own comment
                          "@libp2p/config" {:target :file
                                            :file "src/js/libp2p-config-shim.mjs"}}}
   :module-loader true
   :modules
   {:main {:init-fn board.main/init}
    :board {:entries [board.board]
            :depends-on #{:main}}
    :social {:entries [board.social]
             :depends-on #{:board}}}}
  :testlib
  {:target :esm
   :output-dir "test-dist"
   :compiler-options {:optimizations :simple
                      :source-map false
                      :parallel-build false}
   :js-options {:js-provider :import}
   :modules
   {:testlib
    {:entries [board.testlib]
     :exports {APP_SALT board.config/APP-SALT
               NS board.config/NS
               nsKey board.config/ns-key
               nsDb board.config/ns-db
               ;; every goog-define-backed config value, so test/app.test.mjs can
               ;; assert none of them is the ""-sentinel — the exact bug that cost
               ;; chat's port its first browser boot (board.config's comment)
               RELAY_MULTIADDR board.config/RELAY-MULTIADDR
               TURN_CREDS_URL board.config/TURN-CREDS-URL
               DISCOVERY_TOPIC board.config/DISCOVERY-TOPIC
               MAILBOX_URL board.config/MAILBOX-URL
               MAILBOX_CREDS_URL board.config/MAILBOX-CREDS-URL
               ID_BRIDGE_URL board.config/ID-BRIDGE-URL
               APP_VERSION board.config/APP-VERSION

               RoomCrypto ardegazu.rooms.lib.crypto/RoomCrypto
               Sealer ardegazu.rooms.lib.crypto/Sealer
               AtRestCipher ardegazu.rooms.lib.crypto/AtRestCipher
               toB64 ardegazu.rooms.lib.crypto/to-b64
               fromB64 ardegazu.rooms.lib.crypto/from-b64
               toB64url ardegazu.rooms.lib.crypto/to-b64url
               fromB64url ardegazu.rooms.lib.crypto/from-b64url
               randomBytes ardegazu.rooms.lib.crypto/random-bytes
               newPeerId ardegazu.rooms.lib.crypto/new-peer-id
               newRoomSecret ardegazu.rooms.lib.crypto/new-room-secret

               makeLogEncryption ardegazu.rooms.lib.encryption/make-log-encryption
               signerMatchesIdentity ardegazu.rooms.lib.access/signer-matches-identity
               HardenedIPFSAccessController ardegazu.rooms.lib.access/HardenedIPFSAccessController
               SuetaIdentityProvider ardegazu.rooms.lib.orbit-identity/SuetaIdentityProvider
               registerSuetaProvider ardegazu.rooms.lib.orbit-identity/register-sueta-provider
               resolveRelayConfig ardegazu.rooms.lib.descriptor/resolve-relay-config
               IceConfig ardegazu.rooms.lib.turn/IceConfig
               ;; the browser store-NAMES entry point, exported under the name
               ;; v1.0.0 published — exactly as rooms-kit exports its Node
               ;; open-fs-helia as `openHelia` (lib/log's own open-helia takes
               ;; already-open stores and is shared with the kit byte-for-byte)
               openHelia board.stores/open-idb-helia
               RoomLog ardegazu.rooms.lib.log/RoomLog
               Net ardegazu.rooms.lib.net/Net
               newSessionKey ardegazu.rooms.lib.net/new-session-key
               MailboxAuth board.lib.mailbox/MailboxAuth
               MailboxClient board.lib.mailbox/MailboxClient
               MailboxSync board.lib.mailbox/MailboxSync
               runSelfTest board.lib.selftest/run-self-test

               EpochKeyring board.lib.epoch/EpochKeyring
               encodeGrant board.lib.epoch/encode-grant
               decodeGrant board.lib.epoch/decode-grant
               AccessFold board.lib.policy/AccessFold
               isControlOp board.lib.policy/control-op?
               deriveXKeyPair board.lib.wrapbox/derive-x-key-pair
               signXCert board.lib.wrapbox/sign-x-cert
               verifyXCert board.lib.wrapbox/verify-x-cert
               wrapTo board.lib.wrapbox/wrap-to
               unwrap board.lib.wrapbox/unwrap-wrap

               newElementId board.app.ops/new-element-id
               clampTs board.app.ops/clamp-ts
               encodePts board.app.ops/encode-pts
               decodePts board.app.ops/decode-pts
               validId board.app.ops/valid-id?
               sanitizeElement board.app.ops/sanitize-element
               sanitizePatch board.app.ops/sanitize-patch
               elementBBox board.app.ops/element-bbox
               bboxUnion board.app.ops/bbox-union
               bboxIntersects board.app.ops/bbox-intersects?
               distToSegment board.app.ops/dist-to-segment
               MAX_PTS board.app.ops/MAX-PTS

               BoardStore board.app.state/BoardStore
               VAULT_CLOCK_OFFSET board.app.state/VAULT-CLOCK-OFFSET

               trustObserve board.app.trust/observe
               trustSetVerified board.app.trust/set-verified
               trustIsVerified board.app.trust/verified?

               loadRooms board.app.boards/load-rooms
               touchRoom board.app.boards/touch-room
               renameRoom board.app.boards/rename-room
               forgetRoom board.app.boards/forget-room
               buildRoomSync board.app.boards/build-room-sync
               mergeRooms board.app.boards/merge-rooms
               setOnRoomsChanged board.app.boards/set-on-rooms-changed

               ToolController board.app.tools/ToolController
               Camera board.app.canvas/Camera
               themeFor board.app.canvas/theme-for
               resolveColor board.app.canvas/resolve-color
               layoutText board.app.canvas/layout-text

               catalogKeys board.testlib/catalog-keys
               catalogMsg board.testlib/catalog-msg
               catalogRaw board.testlib/catalog-raw
               t board.testlib/t
               tn board.testlib/tn}}}}}}

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