dev / templates / app-cljs-rooms / 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
;; shadow-cljs builds for the __NAME__ client (ROOMS stack in CLJS — chat
;; (sueta) is the canon this scaffold mirrors; dev/docs/CLJS.md is the law).
;;
;; The shared rooms core — ardegazu.rooms.js and ardegazu.rooms.lib.* — is NOT
;; in this repo: it is ardegazu-rooms-kit's own sources, compiled off the
;; classpath (client/deps.edn adds node_modules/ardegazu-rooms-kit/src, and the
;; sha pin in package.json decides which sha sits there). shadow compiles them
;; exactly like your own namespaces, so they land in the modules below by the
;; same lowest-common-ancestor rule; nothing here has to name the kit.
;;
;; :app — the browser build. Unlike the kits (external ESM imports), an APP
;; bundles its npm deps: the libp2p/helia/@orbitdb family and the two ardegazu
;; kit dists are plain ESM in node_modules, which shadow's default :browser
;; bundling consumes.
;;
;; :optimizations :simple, NOT :advanced — the safe default for a fresh app, and
;; where board still is. Almost every line below the app boundary is interop
;; with untyped ESM (@orbitdb/core ships no type declarations, and helia/libp2p
;; types never reach the CLJS side); :simple removes the externs risk class
;; entirely. (game1's live stack is :advanced because its surface is small and
;; typed; this one is neither.)
;;
;; chat has since moved this same stack to :advanced and measured main.js
;; 236 KB gz -> 91 KB gz, on the observation that Closure never renames a
;; string-keyed property access, so the whole untyped-ESM surface is
;; renaming-IMMUNE. If you follow it, read chat's shadow-cljs.edn header and its
;; externs.js FIRST: what breaks under :advanced is not the libraries but our
;; own prototype installs (`(unchecked-set proto "handleFrames" …)` called by
;; dot-access), and the failure is a runtime TypeError at room boot, not a build
;; error.
;; 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, and
;; scripts/build.mjs gates all three:
;;   :main   the lobby + i18n + config + room crypto — first paint
;;   :room   the whole p2p stack (libp2p v2, Helia, @orbitdb/core, the mailbox,
;;           the room UI), loaded via shadow.lazy only when entering a room
;;   :social attachSocial from `ardegazu-social-kit`, the ONLY module
;;           referencing the full kit
;;
;; :asset-path is RELATIVE — one build must serve at https://__HOST__/ 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. The
;; `@libp2p/config` entry aliases away a package this app must never pull in —
;; see src/js/libp2p-config-shim.mjs. scripts/build.mjs greps the emitted
;; bundle for both, because a wrong resolution here fails at RUNTIME inside
;; OrbitDB, not at build time.
;;
;; Expect :infer-warning lines from the app and kit 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 list you would have
;; to pin in an externs.js before switching to :advanced. Do not "fix" them by
;; moving the hints onto the calls: that suppresses inference silently.
;;
;; :parallel-build false — many namespaces plus a :simple build is exactly the
;; combination CLJS.md says the gensym normalizer cannot repair. Serial
;; compilation is the only fix; only cold builds pay the time.
;;
;; `npm test` out of the scaffold runs the two gates a day-zero app can run
;; honestly: `cljfmt check` and test/source-hygiene.test.mjs. It does NOT run a
;; :testlib build, because there are no black-box tests yet. When you add them,
;; add a :testlib build here (:target :esm, :optimizations :simple, :js-options
;; {:js-provider :import}) exporting the pure logic, and add it back to the
;; `test` script — chat's shadow-cljs.edn shows the shape, client/test/README.md
;; the steps.
{: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 __NAME__.main/init}
    :room {:entries [__NAME__.room]
           :depends-on #{:main}}
    :social {:entries [__NAME__.social]
             :depends-on #{:room}}}}}}

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