banca / 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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
;; shadow-cljs builds for the banca client (ROOMS stack in CLJS — chat
;; (sueta) is the canon this scaffold mirrors; dev/docs/CLJS.md is the law).
;;
;; NONE of the ardegazu kits are in this repo, and none of them is consumed as
;; a dist: rooms-kit, id-kit, social-kit and wallet-kit all put their `src` on
;; the classpath (client/deps.edn holds the rule and the reasoning; the sha pins
;; in package.json decide which sha sits there). shadow compiles their
;; namespaces exactly like your own, so they land in the modules below by the
;; same lowest-common-ancestor rule — which is the whole point, and why the
;; :social boundary below is real rather than notional. Nothing here has to name
;; a kit.
;;
;; :app — the browser build. An APP bundles its npm deps rather than leaving
;; them external: the libp2p/helia/@orbitdb family is 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 banca.social AND the social kit's agent, loaded once a room is live
;;
;; THE THIRD BOUNDARY IS REAL AGAIN, and it is worth knowing why it stopped
;; being: while social-kit was consumed as a DIST, `ardegazu-wallet-kit`'s dist
;; imported it (it signs over social-kit's canonical JSON), lib/fold imports
;; wallet-kit, and the fold is the app — so the whole kit was a dependency of
;; :room and shadow placed it in the lowest common ancestor of :room and
;; :social, which is :room. That was a property of DIST LINKING, not of banca:
;; a dist is a bundle taken whole, so needing `canon` meant taking friends,
;; presence, invites and selfsync too. As source, the fold's dependency is
;; exactly `ardegazu.social.canon`, and everything else the agent needs follows
;; banca.social down into :social (room.js −28 KB gz at the change).
;;
;; So all three boundaries now cost a user something and scripts/build.mjs gates
;; all three. :main carries neither the social agent nor the wallet stack —
;; which is why app/rooms.cljs (the lobby) must never require lib/view or
;; lib/wallet — and the one piece of the social kit it DOES carry is
;; `ardegazu.social.join`'s hub chip, whose only dependency is
;; `ardegazu.social.text`.
;;
;; :asset-path is RELATIVE — one build must serve at https://banca.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. 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` runs `cljfmt check`, then `shadow-cljs release testlib`, then
;; `node --test test/*.test.mjs`. The :testlib build below is what the golden
;; vectors are asserted against — never `src/`, because a vector that reads the
;; source pins the source rather than what ships.
{: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.
 :dev-http {5173 {:roots ["public" "dist-dev"] :use-index-files true :push-state/index "index.html"}
            4173 {:roots ["public" "dist-dev"] :use-index-files true :push-state/index "index.html"}}
 :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 banca.main/init}
    :room {:entries [banca.room]
           :depends-on #{:main}}
    :social {:entries [banca.social]
             :depends-on #{:room}}}}

  ;; :testlib — the pure logic compiled to node-consumable ESM for the black-box
  ;; suite in test/*.test.mjs. Golden vectors run against THIS, never against
  ;; src/: a vector that reads the source pins the source, not what ships.
  ;;
  ;; :js-provider :import leaves any FOREIGN npm specifier as a real ESM import
  ;; for node to resolve at run time, instead of bundling it. It no longer has
  ;; any of our kits to leave alone: id-kit, social-kit and wallet-kit are
  ;; compiled in from source like every other namespace, so this module emits
  ;; ZERO imports today — one `Identity` class in the process by construction
  ;; rather than by hoping npm hoisted one copy. It stays because the moment a
  ;; tested namespace reaches a foreign package (`@noble/curves`, say, via
  ;; ardegazu.id.xkey) node must resolve it rather than shadow inline it.
  :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 [banca.testlib]
     :exports {APP_SALT banca.config/APP-SALT
               NS banca.config/NS

               ;; --- the wallet-kit seam (lib/wallet.cljs) ---
               DOM_PAY_ORD banca.lib.wallet/DOM-PAY-ORD
               DOM_PAY_RCP banca.lib.wallet/DOM-PAY-RCP
               AMT_MIN banca.lib.wallet/AMT-MIN
               AMT_MAX banca.lib.wallet/AMT-MAX
               CTX_MAX banca.lib.wallet/CTX-MAX
               MEMO_MAX banca.lib.wallet/MEMO-MAX
               NEUTRAL_UNIT banca.lib.wallet/NEUTRAL-UNIT
               NEUTRAL_CODE banca.lib.wallet/NEUTRAL-CODE
               DECLINE_REASONS banca.lib.wallet/DECLINE-REASONS
               canon banca.lib.wallet/canon
               currencyId banca.lib.wallet/currency-id
               bankerOf banca.lib.wallet/banker-of
               parseCurrency banca.lib.wallet/parse-currency
               isPayableCurrency banca.lib.wallet/payable-currency?
               unsignedOrder banca.lib.wallet/unsigned-order
               orderPreimage banca.lib.wallet/order-preimage
               orderShape banca.lib.wallet/order-shape
               orderId banca.lib.wallet/order-id
               verifyOrder banca.lib.wallet/verify-order
               unsignedSettlement banca.lib.wallet/unsigned-settlement
               settlementPreimage banca.lib.wallet/settlement-preimage
               receiptOf banca.lib.wallet/receipt-of
               verifySettlement banca.lib.wallet/verify-settlement
               ;; the two signing builders, so the banker's ack arms are driven
               ;; end to end in node (a signer is publicKeyB64 + signRaw)
               buildIssuance banca.lib.wallet/build-issuance
               buildSettlement banca.lib.wallet/build-settlement

               ;; the issuance receipt (wri) — the wrc seam's mirror image
               DOM_PAY_ISS banca.lib.wallet/DOM-PAY-ISS
               unsignedIssuance banca.lib.wallet/unsigned-issuance
               issuancePreimage banca.lib.wallet/issuance-preimage
               issuanceShape banca.lib.wallet/issuance-shape
               issuanceKey banca.lib.wallet/issuance-key
               issuanceOf banca.lib.wallet/issuance-of
               verifyIssuance banca.lib.wallet/verify-issuance

               ;; --- BANK/1's op union (lib/protocol.cljs) ---
               MAX_NAME banca.lib.protocol/MAX-NAME
               MAX_SYM banca.lib.protocol/MAX-SYM
               MAX_DEC banca.lib.protocol/MAX-DEC
               MAX_REF banca.lib.protocol/MAX-REF
               mkCharter banca.lib.protocol/mk-charter
               mkOpen banca.lib.protocol/mk-open
               mkAcct banca.lib.protocol/mk-acct
               mkMint banca.lib.protocol/mk-mint
               mkBurn banca.lib.protocol/mk-burn
               mkPay banca.lib.protocol/mk-pay
               mkAck banca.lib.protocol/mk-ack
               mkLock banca.lib.protocol/mk-lock
               mkClaim banca.lib.protocol/mk-claim
               mkUnlock banca.lib.protocol/mk-unlock
               validLock banca.lib.protocol/valid-lock?
               validClaim banca.lib.protocol/valid-claim?
               validUnlock banca.lib.protocol/valid-unlock?
               opVersion banca.lib.protocol/version-of-op
               mkRate banca.lib.protocol/mk-rate
               mkReq banca.lib.protocol/mk-req
               validOp banca.lib.protocol/valid-op?
               validCharter banca.lib.protocol/valid-charter?
               validOpen banca.lib.protocol/valid-open?
               validAcct banca.lib.protocol/valid-acct?
               validMint banca.lib.protocol/valid-mint?
               validBurn banca.lib.protocol/valid-burn?
               validPay banca.lib.protocol/valid-pay?
               validAck banca.lib.protocol/valid-ack?
               validRate banca.lib.protocol/valid-rate?
               validReq banca.lib.protocol/valid-req?
               opType banca.lib.protocol/op-type?
               slotType banca.lib.protocol/slot-type?
               bankerOnly banca.lib.protocol/banker-only?

               ;; --- the settlement fold (lib/fold.cljs) ---
               BankFold banca.lib.fold/BankFold

               ;; --- the bank link (lib/link.cljs) ---
               parseLink banca.lib.link/parse
               fmtLink banca.lib.link/fmt
               isBankLink banca.lib.link/bank?
               linkSecret banca.lib.link/secret-of
               linkBanker banca.lib.link/banker-of
               linkVersion banca.lib.link/version-of
               linkSupported banca.lib.link/supported?
               LINK_MAX_VERSION banca.lib.link/MAX-VERSION
               saltFor banca.config/salt-for

               ;; --- the resident bots' public banks (lib/publicbanks.cljs) ---
               PUBLIC_BANKS banca.lib.publicbanks/PUBLIC-BANKS
               validPublicBank banca.lib.publicbanks/valid-entry?
               publicBanksAvailable banca.lib.publicbanks/available

               ;; --- the view model (lib/view.cljs) ---
               ;;
               ;; Everything the INTERFACE decides, exported so the interface's
               ;; decisions are black-box tested in node rather than clicked
               ;; through a browser. `paymentState` and `stateKey` are the two
               ;; that matter most: they are where the fold's `settled` becomes
               ;; the word `provisional`, and where an interface that blurred
               ;; provisional into final would first go wrong.
               decOf banca.lib.view/dec-of
               symOf banca.lib.view/sym-of
               nameOf banca.lib.view/name-of
               fmtUnits banca.lib.view/fmt-units
               fmtMoney banca.lib.view/fmt-money
               fmtSigned banca.lib.view/fmt-signed
               parseUnits banca.lib.view/parse-units
               amountError banca.lib.view/amount-error
               paymentState banca.lib.view/payment-state
               stateKey banca.lib.view/state-key
               stateNoteKey banca.lib.view/state-note-key
               whyKey banca.lib.view/why-key
               isAcked banca.lib.view/acked?
               isIssuance banca.lib.view/issuance?
               isReceiptable banca.lib.view/receiptable?
               accountState banca.lib.view/account-state
               isMember banca.lib.view/member?
               viewBalanceOf banca.lib.view/balance-of
               labelOf banca.lib.view/label-of
               openAccounts banca.lib.view/open-accounts
               historyOf banca.lib.view/history
               ledgerOf banca.lib.view/ledger
               provisionalCount banca.lib.view/provisional-count
               provisionalNet banca.lib.view/provisional-net
               unpinnedCount banca.lib.view/unpinned-count
               unpinnedNet banca.lib.view/unpinned-net
               requestsFor banca.lib.view/requests-for
               verifyLockReceipt banca.lib.wallet/verify-lock-receipt
               ackable banca.lib.view/ackable
               lockedCount banca.lib.view/locked-count
               lockedNet banca.lib.view/locked-net
               allFinal banca.lib.view/all-final?
               knocks banca.lib.view/knocks
               ;; the ack seams store/ack! runs on — the three-way dispatch and
               ;; the artifact-ts hand-off, driven black-box in test/view.test.mjs
               ackDispatch banca.lib.view/ack-dispatch
               ackOpFor banca.lib.view/ack-op-for
               adoptLabel banca.lib.view/adopt-label
               defaultKnockName banca.lib.view/default-knock-name
               charterError banca.lib.view/charter-error
               payError banca.lib.view/pay-error
               issueError banca.lib.view/issue-error
               burnError banca.lib.view/burn-error
               rateError banca.lib.view/rate-error
               reqError banca.lib.view/req-error

               ;; presentation windows/buckets/filters — how much of an
               ;; unbounded list a screen renders at once, never how much the
               ;; fold keeps (history is never capped; paging is presentation)
               PAGE_INIT banca.lib.view/PAGE-INIT
               PAGE_STEP banca.lib.view/PAGE-STEP
               pagePlan banca.lib.view/page-plan
               dayKey banca.lib.view/day-key
               groupDays banca.lib.view/group-days
               FILTER_THRESHOLD banca.lib.view/FILTER-THRESHOLD
               accountMatches banca.lib.view/account-matches?
               filterAccounts banca.lib.view/filter-accounts
               whoDesc banca.lib.view/who-desc

               ;; --- the catalogs, so a key a screen asks for must exist ---
               catalogKeys banca.testlib/catalog-keys
               catalogValue banca.testlib/catalog-value}}}}}}

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