wallet-kit / test / module-budget.test.mjs
 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
/**
 * The module budget — the tripwire on the one edit that quietly makes this kit
 * an order of magnitude more expensive for every app that embeds it.
 *
 * social-kit's shipped dist contains NO ClojureScript collection of any kind,
 * and measured what the first one costs: with nothing reaching a persistent
 * map, vector, set or seq, :advanced dead-code-eliminates the whole cljs.core
 * collection/seq/keyword/protocol runtime, and putting ONE of them back costs
 * ~19 KB gzipped — hoisted into :shared, because more than one module reaches
 * it. One cliff, not a gradient: ~240 bytes for everything after the first.
 *
 * This kit follows the same rule for the same reason, which is why shapes.cljs
 * and ledger.cljs are written in JS objects, JS Maps and `dotimes` rather than
 * in Clojure data above a declared boundary.
 *
 * The caps 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, measure WHICH module grew before raising it.
 */
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: a few hundred bytes today, ~20 KB the
  // moment any Clojure collection is reachable from more than one module
  "shared.js": 4 * 1024,
  // the codec a page can load on its own, to render one incoming request
  "paylink.js": 4 * 1024,
  "index.js": 12 * 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", () => {
  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",
  );
});

test("the paylink module does not drag the ledger in", () => {
  const src = readFileSync(new URL("../dist/paylink.js", import.meta.url), "utf8");
  assert.ok(!/localStorage/.test(src), "a page that only reads a link must not touch storage");
});

static mirror of HEAD · about · clone: git clone https://git.ardegazu.ro/wallet-kit.git