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 | {;; Exact pins — the Closure compiler version rides on these two (the same
;; known-good pair as the kits and game1); half of the deterministic-build story.
;;
;; Relative paths only — never :local/root, never an absolute path: the idpat
;; publish gate scans every decompressed git object for local path fragments.
;;
;; ardegazu-rooms-kit carries the shared rooms core (js + lib/{access,crypto,
;; descriptor,encryption,log,net,orbit-identity,protocol,turn}) that this app
;; used to vendor under src/sueta/. It is reached through its npm install, so
;; the sha pin in package.json stays the ONE cross-repo dependency mechanism
;; (dev/docs/CLJS.md) — one bump path, one lockfile, ardz kit-release unchanged.
;; What stays app-local is what the kit has no counterpart for: lib/mailbox,
;; lib/media, lib/selftest and stores.cljs (the browser's IDB store opener —
;; lib/log's open-helia deliberately names no store package).
;;
;; OUR OWN KITS ARE CLASSPATH SOURCE, NOT npm DISTS. rooms-kit, id-kit and
;; social-kit are ClojureScript libraries this repo owns; they are consumed as
;; ClojureScript — their `src` on this classpath, compiled once into this
;; build, requiring their defining namespaces (`ardegazu.rooms.*`,
;; `ardegazu.id.*`, `ardegazu.social.*`). Never `ardegazu.id.index` or
;; `ardegazu.social.index`: those are re-export shims that exist to shape each
;; kit's ESM surface and have no business on a source consumer's requires.
;; FOREIGN packages (@libp2p/*, @noble/*, helia, @orbitdb/core, events, …)
;; stay string requires — that is ordinary interop, not the hybrid.
;; The npm install still governs: the sha pin in package.json is what fixes
;; WHICH source lands here, so it remains the ONE cross-repo dependency
;; mechanism (dev/docs/CLJS.md) — one bump path, one lockfile, ardz
;; kit-release unchanged.
;;
;; This used to say id-kit had to stay a dist or two Identity classes would
;; break `instanceof`. That had the causation backwards: rooms-kit compiles
;; id-kit from SOURCE now and owns the class, so it is the leftover dist
;; import that would manufacture a second copy. Source everywhere = exactly
;; one compiled `Identity` per build, and the `Identity` reached through
;; `ardegazu.rooms.*` is the same object as the one reached through
;; `ardegazu.id.identity`.
:paths ["src"
"node_modules/ardegazu-rooms-kit/src"
"node_modules/ardegazu-id-kit/src"
"node_modules/ardegazu-social-kit/src"]
;;
;; replicant is the view layer (dev/docs/CLJS.md, "the renderer is replicant").
;; It SHIPS — app/lobby.cljs is in the :main module, so this is first-paint
;; code, not a dev tool, and it is exact-pinned for the same reason the two
;; above are: the dist must rebuild byte-identically or the IPFS/IPNS release
;; flow loses its determinism. The API in use is four functions and two
;; keywords; app/view.cljs's header records why that matters.
;;
;; promesa is the ONE async idiom, and it is gated: `sueta.room` and below may
;; require it, `sueta.main` may not (test/module-split.test.mjs asserts both
;; directions over the require graph). It ships in the :room module only, which
;; is the chunk that already carries libp2p, Helia and OrbitDB. Exact pin, same
;; reason as the three above: two cold builds must be byte-identical or the
;; IPFS/IPNS release flow loses its determinism. Its only dependency is
;; org.clojure/clojure, so it drags nothing onto this classpath.
;;
;; What it buys: `js-await` is pure `.then` sugar (it expands to
;; `(-> thenable (.then (fn [name] body)))`), so sixteen sequential awaits could
;; only ever be sixteen nested closures — room.cljs's boot was one expression 29
;; paren levels deep. `p/let` is the same chain with one binding vector.
;;
;; Know before you touch it: promesa's ClojureScript runtime is NOT js/Promise.
;; It ships its own `promesa.impl.promise/PromiseImpl` (a goog.provide'd .js in
;; the jar) and `p/let` returns one of those. It is thenable, it has .then /
;; .catch / .finally, and native code assimilates it — but it is not
;; `instanceof Promise`, and an unhandled rejection on one does NOT fire
;; window.onunhandledrejection. sueta.main's "Could not decrypt" guard is
;; therefore unaffected (OrbitDB's own promises are native), and every promesa
;; chain in room.cljs ends in a catch of its own.
:deps {org.clojure/clojurescript {:mvn/version "1.12.134"}
thheller/shadow-cljs {:mvn/version "3.3.6"}
no.cjohansen/replicant {:mvn/version "2026.07.1"}
funcool/promesa {:mvn/version "12.0.1"}}
:aliases
{:dev {:extra-deps {cider/cider-nrepl {:mvn/version "0.59.0"}}}
;; cljfmt is a TOOL, not a dependency. :replace-deps keeps it off the build
;; classpath (neither shadow-cljs nor clojurescript is loaded to run it) and
;; :replace-paths keeps the sources off it too — cljfmt only ever reads the
;; files named on the command line. Exact pin, same rule as the two above.
;; The config is committed beside this file; both paths are relative, because
;; the idpat publish gate aborts on a local filesystem path in any object.
;; Wired into `npm test` as the FIRST link of the test script itself, not as
;; a `pretest` hook: an npm lifecycle hook is skipped outright under
;; `ignore-scripts=true`, which is a gate that passes by not running.
:cljfmt {:replace-deps {dev.weavejester/cljfmt {:mvn/version "0.13.1"}}
:replace-paths []
:main-opts ["-m" "cljfmt.main" "--config" ".cljfmt.edn"]}
;; clj-kondo is a TOOL too, same shape and same reasons as :cljfmt above:
;; :replace-deps keeps it off the build classpath and :replace-paths keeps the
;; sources off its own, since it reads only the paths named on the command
;; line. Running it as a pinned JVM dep rather than the native binary is
;; deliberate — the gate must not depend on what happens to be installed, and
;; three versions (2025.06.05, 2026.01.19 and this pin) were measured to give
;; identical findings on this tree, as did the native binary.
;; Config and the defclass hook are committed at .clj-kondo/ beside this file;
;; every path here is relative, because the idpat publish gate aborts on a
;; local filesystem path in any object.
;; Wired into `npm test` as the second link of the test script itself, right
;; after cljfmt and before anything compiles — never as a `pretest` hook, which
;; `ignore-scripts=true` skips outright (a gate that passes by not running).
;; --fail-level warning is the default and is what makes this a gate; the
;; config promotes the one :info linter this tree can trip so it cannot print
;; a finding and still exit 0.
:clj-kondo {:replace-deps {clj-kondo/clj-kondo {:mvn/version "2026.08.04"}}
:replace-paths []
;; --cache false, and this one is a GATE FIX, not a preference.
;; clj-kondo writes an analysis cache under .clj-kondo/.cache/,
;; which is gitignored — so it exists on a developer's machine and
;; never on a fresh clone, and the gate says different things in
;; the two places. Concretely, in Phase 6b: the cache held an
;; analysis of `ardegazu.rooms.js` taken before rooms-kit grew
;; `later`/`each-in-order!`, so using either raised "Unresolved
;; var" HERE and nothing at all on a clean checkout. A lint whose
;; findings depend on an untracked file is not a gate; the cache
;; buys nothing on a five-file lint, so it is off.
:main-opts ["-m" "clj-kondo.main" "--lint" "src"
"--cache" "false" "--fail-level" "warning"]}}}
|