/**
* The module budget — and specifically, the tripwire on the one edit that can
* silently make this kit an order of magnitude more expensive for nine apps.
*
* social-kit's shipped dist contains NO ClojureScript collection of any kind.
* That is not a style note, it is a load-bearing property of the build: with
* nothing reaching a persistent map, vector, set or seq, :advanced
* dead-code-eliminates the whole cljs.core collection/seq/keyword/protocol
* runtime, and what is left is small enough that `./join` — the
* dependency-free chip every app pulls at first paint — is 1.5 KB gzipped over
* a 1.2 KB shared base.
*
* The first line of code that uses a Clojure collection puts all of it back,
* and shadow hoists it into :shared because more than one module reaches it,
* so `./join` pays for it too. Measured on this tree during the idiomatic
* rewrite of the common core, all figures gzip -9:
*
* baseline shared 1.25 KB index 17.0 KB
* + one 7-key {:keyword …} literal in envelope shared 20.3 KB index 17.2 KB
* + map/filter/reduce over a JS array shared 20.9 KB index 18.4 KB
* + a persistent vector literal on top of that shared 20.9 KB index 18.4 KB
* + a keyword map literal on top of that shared 20.9 KB index 18.6 KB
*
* One cliff, not a gradient: +19 KB gzipped for the first one, ~240 bytes for
* everything after. This is why the idiomatic rewrite of friends/presence/
* envelope/pair/selfsync uses named boundary macros, small pure functions and
* JavaScript containers rather than "Clojure data above a declared wire
* boundary" — the suite-wide plan's default costs nothing in chat, where
* cljs.core is already 43% of the bundle, and costs 19 KB at first paint in
* every one of the nine apps here.
*
* The caps below are deliberately loose enough not to fail on ordinary
* drift and far tighter than the cliff, so the only thing that trips them is
* the thing they are for. If one fails, do not raise it without measuring
* WHICH module grew and why — a genuine feature will show up in :index.
*/
import test from "node:test";
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { gzipSync } from "node:zlib";
const gz = (name) =>
gzipSync(readFileSync(new URL(`../dist/${name}`, import.meta.url)), { level: 9 }).length;
const BUDGET_GZ = {
// the collection-runtime tripwire: ~1.25 KB today, ~20.3 KB the moment any
// Clojure collection is reachable from more than one module
"shared.js": 4 * 1024,
// first paint in nine apps — join depends only on :shared
"join.js": 4 * 1024,
"index.js": 24 * 1024,
"net.js": 8 * 1024,
"selftest.js": 8 * 1024,
};
for (const [name, cap] of Object.entries(BUDGET_GZ)) {
test(`dist/${name} stays inside its gzip budget`, () => {
const size = gz(name);
assert.ok(size <= cap, `dist/${name} is ${size} B gzipped, budget ${cap} B`);
});
}
test("the shared base really is collection-runtime free", () => {
// The direct assertion behind the budget: :shared carries the ESM preamble
// and almost nothing else. cljs.core's collection runtime is ~19 KB gzipped
// and cannot hide inside this.
assert.ok(gz("shared.js") < 2 * 1024,
`shared.js is ${gz("shared.js")} B gzipped — something pulled cljs.core's ` +
"collection runtime into the shared base; see this file's header");
});