@vernikr/size-report 2.5.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -64
- package/package.json +2 -2
- package/src/check.js +1 -1
- package/src/data.js +0 -18
- package/src/doctor.js +4 -4
- package/src/history.js +3 -9
- package/src/init.js +2 -1
- package/src/locales.js +9 -9
- package/src/metrics.js +45 -63
- package/src/minify.js +2 -2
- package/src/modes.js +8 -8
- package/src/optional.js +2 -2
- package/src/page/app.css +6 -8
- package/src/page/app.js +116 -67
- package/src/page/build.js +161 -19
- package/src/page/panel.js +111 -20
- package/src/page/payload.js +168 -0
- package/src/page/state.js +87 -32
- package/src/page/table.js +260 -73
- package/src/parse.js +1 -1
- package/src/project.js +2 -2
- package/src/strip/guard.js +4 -3
- package/src/strip.js +4 -5
- package/src/table.css +44 -8
- package/src/tokens.js +5 -6
- package/templates/README.md +3 -3
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ shows.
|
|
|
10
10
|
|
|
11
11
|
## Status
|
|
12
12
|
|
|
13
|
-
**Release 2.
|
|
13
|
+
**Release 2.6.0 (2026-09-17).** The tool lives as a package of its own: the registry name is
|
|
14
14
|
`@vernikr/size-report` (published by tag from CI, with no secret). A project may keep no settings at
|
|
15
15
|
all: without a config file the tool derives them from the project itself and says so in one line,
|
|
16
16
|
and `--init` pins what was derived into a file. The report is **one file**, the self-contained page
|
|
@@ -19,13 +19,19 @@ is installed and on the first run. The version is in the manifest, and every rel
|
|
|
19
19
|
the journal — `worklog/` for today's entries, `worklog/archive/WORKLOG.md` for the earlier ones:
|
|
20
20
|
what changes in the numbers is measured rather than retold.
|
|
21
21
|
|
|
22
|
-
2.
|
|
23
|
-
the
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
2.6.0 changes the numbers themselves, and they are measured rather than retold: on this repository's own
|
|
23
|
+
history the page this engine writes is **85 955 B against 1 899 370 B** written by 2.5.0 — 22.1 times
|
|
24
|
+
smaller, −95.5 % — because the data travels as one packed block (49 392 B, `base64+gzip`) instead of a list
|
|
25
|
+
of rows, the program is pasted without comments and indentation (28 007 B) and the styling is 6 172 B. The
|
|
26
|
+
page also stops rebuilding itself: a click on a filter rewrites the nodes in place and recomputes the
|
|
27
|
+
totals, the columns carry computed widths under a fixed layout, and two candidates (`content-visibility`,
|
|
28
|
+
`border-collapse: separate`) were measured dead here and left out, with the records in
|
|
29
|
+
`plans/2026-09-17-page-perf/`. **The contract loses fields:** `metrics[].accuracy` and the `approx` bit map
|
|
30
|
+
are gone and the split into exact and approximate numbers with them, so a reader of `--data` that still
|
|
31
|
+
asks for them gets nothing — while the two schema numbers (`1` for the contract, `2` for the packed block)
|
|
32
|
+
stay where they were. The checks grow with the work: 70 → **81** in the fast profile and 175 → **186** in
|
|
33
|
+
the full one. The note of 2.5.0 — the language the tool speaks — stands in the journal,
|
|
34
|
+
`worklog/0203-release-2.5.0.md`.
|
|
29
35
|
|
|
30
36
|
**Parity with the implementation the move started from is proven, not asserted.** The command is
|
|
31
37
|
`bin/size.js` and the package's entry point is `src/size-table.js` (a re-export only), with the
|
|
@@ -65,14 +71,54 @@ instruction below. The step with a key left it later, along with private access.
|
|
|
65
71
|
**The data contract and the page.** The engine hands over absolute values and the shape of the table
|
|
66
72
|
(`--data`), while deltas, totals, "now" and the filters are computed by the page — which is the
|
|
67
73
|
report itself (`size-report.html`): without that split the filters and "the total over the
|
|
68
|
-
selection" are impossible in principle. The contract
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
selection" are impossible in principle. The contract tells how each number was obtained (the metric's
|
|
75
|
+
`method`) and nothing else about it: the page shows what the engine said and judges no number — it keeps
|
|
76
|
+
no rule of counting of its own, and the split of numbers into exact and approximate was taken out of the
|
|
77
|
+
package. The page's panel is a
|
|
71
78
|
tree of files by folder, with a switch per folder for the whole subtree; a reader's choice survives
|
|
72
79
|
a revisit and travels in a link — the page's address is the link. The contract carries the **project
|
|
73
80
|
catalogue** too: every path git sees, so the page's tree is the project's tree, while numbers exist
|
|
74
81
|
only for the files that became columns (release 2.2.0).
|
|
75
82
|
|
|
83
|
+
**The page's block is the contract in sparse form.** The file carries the history as changes rather than
|
|
84
|
+
as a snapshot per commit — for every file the rows it appeared in (absolute numbers), moved in (deltas
|
|
85
|
+
against its own previous record) and disappeared in — with the texts in a dictionary and the rows' links
|
|
86
|
+
cut by the part they share. The page's own chapter unrolls it back into exactly the contract
|
|
87
|
+
(`src/page/payload.js`), so the calculation and the table know nothing of the sparse form and there is no
|
|
88
|
+
second way to count a row; `--data` still answers with the dense contract, and the block's `schema: 2` is
|
|
89
|
+
what refuses a record written for the previous form. On this repository the data block is
|
|
90
|
+
1 370 724 → 88 712 B, and its parse is 11.6 → 0.6 ms plus 3.3 ms of unrolling (`contract-data` holds the
|
|
91
|
+
round trip).
|
|
92
|
+
|
|
93
|
+
**The block travels packed, and that is the page's one asynchronous step.** It lies in the file gzipped and
|
|
94
|
+
base64 encoded — the tag says so (`data-pack="base64+gzip"`) — and the page unpacks it with the platform's own
|
|
95
|
+
`DecompressionStream`: no library travels in the page, nothing is fetched, and the whole artifact of this
|
|
96
|
+
repository goes 122 668 → 78 319 B (the block 88 786 → 42 856 B — 74 B more than step 05 measured, because the
|
|
97
|
+
report is itself a column of the report and its own size moved in between). The price is deliberate and twofold: the
|
|
98
|
+
block can no longer be read by eye or by `diff`, and the first drawing waits for a promise where it used to
|
|
99
|
+
happen during the parse. Everything after the first drawing is as synchronous as it was; a host that cannot
|
|
100
|
+
unpack is told in words rather than left with an empty table. The checks read the page in jsdom, which has no
|
|
101
|
+
such API, so the harness puts the platform's own implementations of it into the window — and that seam is
|
|
102
|
+
tested from both sides: the ordinary path with them put in, and the message in words without them.
|
|
103
|
+
|
|
104
|
+
**What the page carries is squeezed, and only what the page carries.** The program and the styling are pasted
|
|
105
|
+
with their comments and indentation out — the same stripping the `min` metric counts — so the artifact holds
|
|
106
|
+
code without ballast while `src/derived.js`, `src/page/*.js`, `src/table.css` and `src/page/app.css` stay the
|
|
107
|
+
ordinary files a person reads: the squeeze lives in the paste and nowhere else. It is 58 922 → 24 885 B of
|
|
108
|
+
program and 15 505 → 5 905 B of styling (the artifact 166 305 → 122 668 B), and the assembled program is
|
|
109
|
+
guarded at build time by the stripper's own `assertCompilable` — a squeeze that ate code stops the build
|
|
110
|
+
rather than the browser.
|
|
111
|
+
|
|
112
|
+
**Minification of what the page carries is decided, not defaulted: not taken — and measured.** esbuild would
|
|
113
|
+
take the pasted program 24 885 → 18 128 B and the styling 5 906 → 5 102 B, the artifact 122 668 → 115 107 B
|
|
114
|
+
(7 561 B), for 91 ms of every build. The price is not those bytes but the contract: esbuild is an **optional**
|
|
115
|
+
dependency and its absence is a different count rather than a refusal, while the artifact is rebuilt by the
|
|
116
|
+
post-commit hook on whatever machine made the commit — a builder that minifies when it can would build **a
|
|
117
|
+
different file** there, and the report would stop being a fixed point. Buying determinism instead would mean
|
|
118
|
+
a pinned version and a page that cannot be assembled at all without esbuild (`src/optional.js`), for 6 % of
|
|
119
|
+
the file. What the decision rests on — the bytes it would save, the fixed point it would cost, and what
|
|
120
|
+
reopens it — is written down beside the plan the step belongs to.
|
|
121
|
+
|
|
76
122
|
The tool grew out of one script in the consumer project [`safe-resets`](../figma/safe-resets) — the
|
|
77
123
|
metrics `raw` and "a simplification instead of minification", a static report in git; that path
|
|
78
124
|
does not exist in this repository, and it is not named anywhere without the project.
|
|
@@ -111,8 +157,7 @@ refusal site — the maps `SITES` and `PRINTED` hold the counts — and a case i
|
|
|
111
157
|
entry, so a new refusal cannot appear without a check. Refusals a run cannot reach are named
|
|
112
158
|
explicitly: four are guarded by a check of their own (the catalogue names the file and the phrases),
|
|
113
159
|
and one cannot be caught at all — "internal error" — which is said where it stands. What the
|
|
114
|
-
catalogue does not take on is said in words: wording beyond the listed phrases, and meaning,
|
|
115
|
-
"!" sign, which is a note (an approximation, a mixed commit, the automation switched off) rather
|
|
160
|
+
catalogue does not take on is said in words: wording beyond the listed phrases, and meaning, andthe "!" sign, which is a note (another count, a mixed commit, the automation switched off) rather
|
|
116
161
|
than a refusal, with exit code zero.
|
|
117
162
|
|
|
118
163
|
**And the advice in a refusal is executable — that is checked as well.** The truth about the cause is
|
|
@@ -149,10 +194,10 @@ commits and installs hooks; the reason for each expensive file is named line by
|
|
|
149
194
|
|
|
150
195
|
| Run | Command | Checks |
|
|
151
196
|
|---|---|---|
|
|
152
|
-
| Fast — every edit | `pnpm test` | **
|
|
153
|
-
| Full — release and CI | `pnpm test:all` | **
|
|
197
|
+
| Fast — every edit | `pnpm test` | **81 of 186** |
|
|
198
|
+
| Full — release and CI | `pnpm test:all` | **186** |
|
|
154
199
|
|
|
155
|
-
No check is lost or weakened: the full run starts all
|
|
200
|
+
No check is lost or weakened: the full run starts all 186 with the same files, the fast one takes part
|
|
156
201
|
of them. The default is the full run — a file becomes fast only explicitly and with a reason — so new
|
|
157
202
|
expensive work cannot quietly move into the fast one. Two declarations guard that:
|
|
158
203
|
`test/suites.test.js` (every file classified, and a reason for each) and the documentation guard
|
|
@@ -261,9 +306,22 @@ its middle is out of reach.
|
|
|
261
306
|
|
|
262
307
|
**Folding is pure view, and it counts no numbers.** The subtree lies in the markup and a class on the
|
|
263
308
|
row hides it, so a click on the sign changes exactly the three things the reader sees — the class, the
|
|
264
|
-
sign and the note in the memory.
|
|
265
|
-
|
|
266
|
-
|
|
309
|
+
sign and the note in the memory. What guards this is that after folding the table is the same markup
|
|
310
|
+
rather than a rebuilt one (`test/page-tree.test.js`).
|
|
311
|
+
|
|
312
|
+
**A click shows and hides rather than builds.** The table is assembled once, with every column of every
|
|
313
|
+
file, and a switch afterwards changes only what is visible: a metric is one class on the table plus the
|
|
314
|
+
`colSpan` of the group headings, a file's column is a class per node of it, and a folder or a category is
|
|
315
|
+
the same for each file of its subtree. The table's own nodes stay the objects the first drawing made:
|
|
316
|
+
`test/page-view.test.js` counts what a click appends (a metric: nothing at all; a file, a folder or a
|
|
317
|
+
category: at most the cells of the totals, rows × metrics) and checks that the rows and the cells are
|
|
318
|
+
still the very same objects. What makes this possible is that the order of the columns depends on the
|
|
319
|
+
files rather than on the choice — the last commit's first, then the settings' order — so a hidden column
|
|
320
|
+
keeps its place and the visible ones do not move. The totals are the only numbers a choice changes, and
|
|
321
|
+
they are carried rather than recounted: a sum is linear, so a file switched off subtracts exactly its own
|
|
322
|
+
values, which costs its own rows instead of rows × files. That arithmetic is the step's one new piece,
|
|
323
|
+
and it is held against the engine's own `rowModel` cell by cell for a mixed choice, so that counting a
|
|
324
|
+
row stays in one place (`test/page-view.test.js`).
|
|
267
325
|
|
|
268
326
|
**The columns the last commit touched come first.** The report is rebuilt after every commit, and a
|
|
269
327
|
reader's first question is what that edit brought. The mark comes from the history rather than from the
|
|
@@ -290,17 +348,17 @@ numbers behind the layout is the contract rather than the markup: switching a fo
|
|
|
290
348
|
its columns and exactly its volume from the total (`test/contract.test.js`).
|
|
291
349
|
|
|
292
350
|
**A checkbox takes away neither the numbers' room nor the reader's place in the list.** The panel is
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
its focus
|
|
296
|
-
the panel from the start
|
|
351
|
+
built once and a switch writes only the fields it reached, so the reader's place is his still: there is
|
|
352
|
+
no rebuild that could lose the scroll of the panel or of the list, and the field under the keyboard keeps
|
|
353
|
+
its focus without being found again by hand (`test/page-tree.test.js`) — with a rebuild every switch with
|
|
354
|
+
`Tab` and `Space` would mean walking the panel from the start. The file list has no ceiling of its own in a wide window: the panel
|
|
297
355
|
scrolls, and the list does not push the table. The row of categories sticks to the top of the panel,
|
|
298
356
|
with the panel's own background (or passing rows of the list would read through it), and the panel's own
|
|
299
357
|
top padding lives on its first field, which travels away with it. File captions use the table's font size
|
|
300
358
|
(12.5px), and the legend under the tree is gone on purpose: below the list it pushed the numbers away,
|
|
301
359
|
while what it explained already stands next to the thing it explains — the sign of a number names the
|
|
302
|
-
colour of a delta,
|
|
303
|
-
|
|
360
|
+
colour of a delta, the way each number was counted stands under the metric switches, and the mark of a gap
|
|
361
|
+
lives in the cell's own text.
|
|
304
362
|
|
|
305
363
|
**The panel remembers the reader's choice.** The record lives in the browser's memory, tied to the
|
|
306
364
|
report's passport — the tool's name, the data schema, the artifact's path, the title and the column
|
|
@@ -331,15 +389,14 @@ check rather than a promise (`test/page-view.test.js`, `test/parity.test.js`).
|
|
|
331
389
|
`"engine": "strip"` is the earlier removal of comments and indentation. The default did not change,
|
|
332
390
|
because both frozen references were taken under it. Measured on the fixture: real minification is
|
|
333
391
|
smaller than stripping in **44 cells and never larger**; `src/code.js` **276 → 185 B**, `src/style.css`
|
|
334
|
-
**55 → 43 B**, and over the fixture's history **−1 372 B**. JSON is minified by parsing
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
answers come from one rule (`pointExact` in `src/metrics.js`), so they cannot diverge. With no minifier
|
|
392
|
+
**55 → 43 B**, and over the fixture's history **−1 372 B**. JSON is minified by parsing (parsing loses
|
|
393
|
+
only insignificant whitespace, and nobody would make it shorter), while the formats the minifier does not
|
|
394
|
+
take are named in the metric's caption **by extension**: `esbuild … (minify, rename); other formats
|
|
395
|
+
(.md .toml) lose comments and indentation`. The split of numbers into exact and approximate is gone from
|
|
396
|
+
the package: how a column was counted is told once, in the metric's method, and no cell carries a mark of
|
|
397
|
+
it any more. The list comes from the columns rather than from the name of the method (`otherCountFormats`
|
|
398
|
+
in `src/metrics.js`), so a report made only of formats the minifier takes says nothing about other
|
|
399
|
+
formats. With no minifier
|
|
343
400
|
(an installation without optional dependencies, a platform without it) the metric falls back to
|
|
344
401
|
stripping, the method says so in words and the run answers **code 4** rather than staying silent, while
|
|
345
402
|
the numbers are the same as the earlier way of counting — byte for byte with the reference. The derived
|
|
@@ -365,9 +422,7 @@ and it has nothing to count tokens with. Counting every family on every run woul
|
|
|
365
422
|
the reader may never ask about, so the choice of family and encoding lives where it costs time — in the
|
|
366
423
|
run's settings — while the page **names** it: the method of each metric stands under the switches as
|
|
367
424
|
text rather than only in a tooltip. Formats without text (a picture, a font, an archive) are named in
|
|
368
|
-
the metric's caption
|
|
369
|
-
marked by the same rule, and the caption takes the worst in the column — two answers have nothing to
|
|
370
|
-
diverge with. With no dictionary (an installation without optional dependencies, a platform without it)
|
|
425
|
+
the metric's caption by extension: their number goes by bytes rather than text. With no dictionary (an installation without optional dependencies, a platform without it)
|
|
371
426
|
the count is an estimate by length with the coefficient named in the method, and the run answers **code
|
|
372
427
|
4**; the other metrics stay what they were in a report without tokens, and that seam is checked in an
|
|
373
428
|
environment with no optional dependencies at all (`SIZE_REPORT_NO_OPTIONAL`). Counting tokens costs a
|
|
@@ -415,6 +470,7 @@ acceptance for each.
|
|
|
415
470
|
|
|
416
471
|
| File | Role |
|
|
417
472
|
|---|---|
|
|
473
|
+
| `plans/` | The plans of work on this repository: `plans/archive/` holds the earlier ones, `plans/2026-09-17-page-perf/` the plan of the page work — an index and one file per step of the report, each with why, what changes, acceptance and the risks (`plans/2026-09-17-page-perf/README.md`) |
|
|
418
474
|
| `plans/archive/PLAN.md` | **The main document of the move:** inventory, boundaries, invariants, architecture, the seven steps, acceptance, risks, open questions |
|
|
419
475
|
| `docs/requirements.md` | The customer's requirements: what and why |
|
|
420
476
|
| `docs/module-design.md` | The design of the extraction: how the module is put together |
|
|
@@ -427,6 +483,7 @@ acceptance for each.
|
|
|
427
483
|
| `tools/parity-freeze.js` | Takes the parity reference (`pnpm run parity`): with the frozen copy, at the project revision from the manifest — `--json`, the config, the artifact's hash, the tool's hash |
|
|
428
484
|
| `tools/make-fixture.js` | Assembles the synthetic fixture (`pnpm run fixture`): a deterministic history with traps plus the reference numbers |
|
|
429
485
|
| `tools/synthetic/` | The subjects of that assembly, one per matter: `repo.js` — how git is spoken to (pinned time, author, settings), `content.js` — what the files hold, `history.js` — which commits come of it, `note.js` — the fixture's note with the list of traps |
|
|
486
|
+
| `probes/` | The scripted measurements behind `plans/2026-09-17-page-perf/`: one file per step, run by hand against live Chrome at the debug port — the fixed layout, where `content-visibility` acts at all, and the two border models with their pixels (`probes/README.md`). Outside the sensors' paths on purpose: they measure the product rather than being part of it, and a suite cannot see layout, paint or a browser's own skipping |
|
|
430
487
|
| `tools/parity-live.js` | Compares the engine with the live project on a clone: the numbers and the self-contained report at the path the consumer's settings give (`pnpm run parity:live`) |
|
|
431
488
|
| `tools/pack-check.js` | Assembles the tarball and checks that everything works from it: all sources arrived, the numbers and the report as from the repository (`pnpm run pack:check`) |
|
|
432
489
|
| `tools/check-standards.js` | Checks that both references reproduce: a re-take goes nowhere and is compared with what is committed (our files byte for byte, the bundle by content), and that the live-history bundle carries `HEAD` (`pnpm run check:standards`) |
|
|
@@ -458,14 +515,15 @@ acceptance for each.
|
|
|
458
515
|
| `src/css.js` | Reading the styling from disk: which sets of styles exist and what role each has |
|
|
459
516
|
| `src/table.css` | The report's table: the geometry of a cell, the sticky header and commit column, the colour of deltas |
|
|
460
517
|
| `src/page/app.css` | The page's styling on top of the shared part: the panel with the file tree and its sticky row of categories (a column on the left on a wide screen, the page fitting the window), the empty states, a narrow window |
|
|
461
|
-
| `src/page/
|
|
518
|
+
| `src/page/payload.js` | The page's block in sparse form, and the one place that unrolls it back: the history as changes (a file's appearance, its moves, its disappearance) turned into the snapshots the calculation and the table already speak — a value that did not move is one object shared by the rows that hold it |
|
|
519
|
+
| `src/page/state.js` | The page's state: the report's data (the block unrolled by the payload chapter), the view of the checkboxes, the pointer "which path is which column", folded folders, the record's passport, the browser's memory and the exchange by link — a chapter of the page's program |
|
|
462
520
|
| `src/page/dom.js` | The page's nodes: the small helpers of markup (`appEl`, `appBox`) — one set for the panel and the table alike |
|
|
463
|
-
| `src/page/panel.js` | The panel of choices: the switches of metrics and files, the categories, the tree of the project's paths (files outside the report keep a checkbox off with a reason and stand after the rest; folders carry a folding sign that hides the subtree by a class rather than by a rebuild);
|
|
464
|
-
| `src/page/table.js` | The page's table: a cell, a commit's caption, the header
|
|
465
|
-
| `src/page/app.js` | Assembling and starting the page: the
|
|
466
|
-
| `src/page/build.js` | Assembling the page: data, styling and program in one file with no external references |
|
|
521
|
+
| `src/page/panel.js` | The panel of choices: the switches of metrics and files, the categories, the tree of the project's paths (files outside the report keep a checkbox off with a reason and stand after the rest; folders carry a folding sign that hides the subtree by a class rather than by a rebuild); built once, with the fields of the switches and of the folders and categories written where they stand |
|
|
522
|
+
| `src/page/table.js` | The page's table, built once: a cell, a commit's caption, the header, the empty states and the cache of the nodes of every column — markup over the shared calculation, with the totals carried rather than recounted |
|
|
523
|
+
| `src/page/app.js` | Assembling and starting the page: the first drawing, then a switch that shows, hides and rewrites the totals without making a node; an anchor change; pasted into the assembled page |
|
|
524
|
+
| `src/page/build.js` | Assembling the page: data, styling and program in one file with no external references — the pasted text is **squeezed** on the way in (comments and indentation out, the same stripping the `min` metric counts) while the sources keep them, and the result is guarded by the stripper's own `assertCompilable` |
|
|
467
525
|
| `src/git.js` | The only border where git is called: the pinned settings, blobs by the batch, the history, the comparison with the working tree |
|
|
468
|
-
| `src/strip.js` | Removing ballast: which form goes to which file (extension, strategy) and
|
|
526
|
+
| `src/strip.js` | Removing ballast: which form goes to which file (extension, strategy) and which strategies are minification itself — the entry to the parsing of forms |
|
|
469
527
|
| `src/strip/js.js` | Removing comments and indentation in JS: a pass over the cases (a comment, a regexp, a string, a character) — through strings and templates as well |
|
|
470
528
|
| `src/strip/forms.js` | The forms of text with a removal of their own: markup, styles, the lines of a file and JSON |
|
|
471
529
|
| `src/strip/guard.js` | The stripper's guard: what was stripped has to compile — as a script in the process or as a module in a worker thread |
|
|
@@ -494,7 +552,7 @@ acceptance for each.
|
|
|
494
552
|
| `test/api.test.js` | The package's public API: the list of names is frozen, and splitting the engine may not change it |
|
|
495
553
|
| `eslint.config.js` | The rules of formatting: the same as the consumer project's, plus a ban on gluing operators into one line (`pnpm run lint`, `pnpm run lint:strict`) |
|
|
496
554
|
| `tools/harness.js` | The harness of the checks: paths, clones of the fixture (including one shared per suite and one with CRLF), running the tool, reading refusals, hashes |
|
|
497
|
-
| `tools/page-harness.js` | The harness of the contract and page checks: the contract data, the assembled page, reading it in a real DOM, the panel's switches — one for
|
|
555
|
+
| `tools/page-harness.js` | The harness of the contract and page checks: the contract data, the assembled page, reading it in a real DOM, the panel's switches, the page's calculation and its decoder evaluated from their sources, the block unpacked, and the platform's unpacker put into jsdom (which has none) — one for six suites |
|
|
498
556
|
| `tools/suites.js` | The split of the suite: which files go into the fast run (with a reason for each) and why every dear one is in the full run |
|
|
499
557
|
| `tools/run-tests.js` | Running the suite (`pnpm test`, `pnpm test:all`, `pnpm run suites:measure`): each file's duration measured on its own, and the counts of checks adding up |
|
|
500
558
|
| `tools/docs-facts.js` | Reading facts out of the documentation — one layer for the four checks of the documentation guard: what a document names (paths, calls, section addresses) against what the repository holds |
|
|
@@ -508,11 +566,12 @@ acceptance for each.
|
|
|
508
566
|
| `test/cli.test.js`, `test/cli-paths.test.js` | The command line's refusals: the help, the settings, the exit codes — and where the tool writes |
|
|
509
567
|
| `test/refusals.test.js` | The refusals are executed: each one is called by a run, its exit code and its promised phrases are compared (with clones of their own for someone else's hook, a shallow history and a branch past the report), and **the advice runs** — the command answers with the promised code and no stack, while where "the refusal is gone" is declared the same call answers differently after it |
|
|
510
568
|
| `test/refusals-catalog.test.js` | The guard of the refusal catalogue: every refusal site in the sources has an entry, every entry declares its advice, and refusals handed to another check are really accepted by it (the named file and line are checked) |
|
|
511
|
-
| `test/contract-data.test.js` | The data contract: the numbers against the reference, the set of fields against the derived quantities, the
|
|
569
|
+
| `test/contract-data.test.js` | The data contract: the numbers against the reference, the set of fields against the derived quantities, the metric's method against the way the numbers were counted — and the round trip through the page's sparse block, which restores the contract whole and twice over the same bytes |
|
|
512
570
|
| `test/contract-derived.test.js` | The derived quantities against the artifact's numbers: a row's totals, a cell's delta and the delta of a total — on the code that lies in the tree |
|
|
513
|
-
| `test/page-view.test.js` | The assembled page: pasted with no copy of the calculation, self-contained, the empty states, the styling and the
|
|
514
|
-
| `test/page-tree.test.js` | The panel's file tree: folders by the project's paths, three states, the subtree, files and folders outside the report (a checkbox off, a place after the rest), folding without a rebuild and
|
|
571
|
+
| `test/page-view.test.js` | The assembled page: pasted with no copy of the calculation, self-contained, the empty states, the styling, the switches, a click that makes no table and the carried totals against the engine's own sums |
|
|
572
|
+
| `test/page-tree.test.js` | The panel's file tree: folders by the project's paths, three states, the subtree, files and folders outside the report (a checkbox off, a place after the rest), folding without a rebuild and a scroll a click does not touch |
|
|
515
573
|
| `test/page-choice.test.js` | The memory of the choice and the exchange by link: a revisit, someone else's report, a foreign and a broken record, an address change on an open page |
|
|
574
|
+
| `test/page-cols.test.js` | The fixed layout the page carries: a column's width is counted from the model rather than measured in a laid-out cell, the clip keeps a caption inside its column, the sticky header and commit column keep their edges, and the table names its own width (`width: auto` would hand the layout back to the automatic algorithm) |
|
|
516
575
|
| `test/module.test.js` | A module under a `.js` extension: measured without touching the settings; the stripper's guard is alive (proved by mutation) and does not accuse the innocent |
|
|
517
576
|
| `test/guard.test.js` | Parsing a module: it goes through a thread, both paths give one verdict, the fallback works with the thread's file away, and hundreds of parses are cheaper than a launch |
|
|
518
577
|
| `test/runner.test.js` | Reading a process's output: chunks are glued as buffers rather than appended to a string — a multi-byte character at a chunk border does not turn into two replacement characters |
|
|
@@ -563,8 +622,9 @@ The seams between modules follow the borders of data: above sit the parts that r
|
|
|
563
622
|
(`git`, `strip`, `metrics`, `history`), below the parts that work on values already collected (`data`,
|
|
564
623
|
`derived`, `page`), while the settings, the texts and the refusal stand at the edges, because everyone
|
|
565
624
|
knows them and they know no one. Both reports are counted at build time: the page gets the sources of the
|
|
566
|
-
shared calculation and of its own program pasted in (`src/derived.js`, `src/page/*.js`)
|
|
567
|
-
from disk, with no server and no network. The rest is planned step by step in
|
|
625
|
+
shared calculation and of its own program pasted in (`src/derived.js`, `src/page/*.js`) and squeezed on the way
|
|
626
|
+
in, because it opens from disk, with no server and no network. The rest is planned step by step in
|
|
627
|
+
`plans/archive/PLAN.md`.
|
|
568
628
|
|
|
569
629
|
## Wiring it into your project
|
|
570
630
|
|
|
@@ -591,7 +651,7 @@ The same release can be taken by a reference to the repository — installation
|
|
|
591
651
|
registry, but stays tied to a revision:
|
|
592
652
|
|
|
593
653
|
```bash
|
|
594
|
-
pnpm add -D github:vernikr/size-report#v2.
|
|
654
|
+
pnpm add -D github:vernikr/size-report#v2.6.0
|
|
595
655
|
```
|
|
596
656
|
|
|
597
657
|
With no network (or nothing to fetch from codeload) — the tarball: `pnpm pack` in the package clone, then
|
|
@@ -603,7 +663,7 @@ the branch moves on the installation fails with `Could not resolve <sha> to a co
|
|
|
603
663
|
observation rather than reasoning: the short pin `6530237` installed while `main` stood on it and stopped
|
|
604
664
|
working at the very next commit, while the same sha in full installed. A branch name (`#main`) and a tag
|
|
605
665
|
are both accepted, but a branch is a moving target and a tag is constant: this release stands on the tag
|
|
606
|
-
`v2.
|
|
666
|
+
`v2.6.0`, which is also the one in the example (forty characters work as well, but they have to be copied
|
|
607
667
|
out of the history by eye).
|
|
608
668
|
|
|
609
669
|
The revision in the example is a part of the claim rather than decoration: what is described below is
|
|
@@ -674,7 +734,7 @@ known to a person. What is edited most often:
|
|
|
674
734
|
| `columns` | the table's columns: `{label, paths: [...]}`; **a column is a file**: the list of paths is its renames (a revision takes whichever of them it holds), not several files at once; `label` is what a person will see |
|
|
675
735
|
| `metrics` | what a number is made of: `raw` (the size of the git object), `min` (the minified form — which one, `minify.engine` decides), `tok` (tokens), `gzip` |
|
|
676
736
|
| `tokens.family`, `tokens.encoding` | the dictionary for `tok`: the family (`openai`) and the encoding (`o200k_base` or `cl100k_base`) — the encoding changes the number, which is why it is both in the settings and in the metric's label |
|
|
677
|
-
| `minify.engine` | what counts `min`: `strip` (comments and indentation,
|
|
737
|
+
| `minify.engine` | what counts `min`: `strip` (comments and indentation — a simplification, and the method names it as one) or `esbuild` (real compression; a format the minifier does not take counts as stripping, and the method says so) |
|
|
678
738
|
| `output` | the report file (in the derived profile `docs/size-report.html`; the directory is created by the writer). The path enters the report's passport — the key of the saved choice — so a changed path means a fresh choice |
|
|
679
739
|
| `journal` | where to look for the journal sections the rows refer to |
|
|
680
740
|
| `links.commitUrl` | the commit link template, for example `https://github.com/org/repo/commit/{sha}`; derived from the `origin` address for GitHub and GitLab (for other hosts — empty rather than a guess) |
|
|
@@ -732,11 +792,11 @@ commit".
|
|
|
732
792
|
|
|
733
793
|
`size doctor` gathers all the diagnostics into one answer: the environment and its influence on the numbers
|
|
734
794
|
(the machine's settings do not influence them — the engine pins them at the call's border), the state of
|
|
735
|
-
the optional dependencies and what it means for
|
|
795
|
+
the optional dependencies and what it means for the count, the validity of the settings and the completeness
|
|
736
796
|
of the coverage. It answers with the same pieces as the other commands: the coverage block is exactly the
|
|
737
797
|
answer of `size check` rather than a second calculation. The exit code is the first by importance rather
|
|
738
798
|
than "something was found": `2` the settings are unreadable (there is nothing else to read), `3` the
|
|
739
|
-
history is cut short, `1` the coverage is incomplete, `4` a
|
|
799
|
+
history is cut short, `1` the coverage is incomplete, `4` a sensor counted another way, `0` nothing to do. A
|
|
740
800
|
sensor the settings are silent about is named unneeded rather than missing, and it is not loaded: the
|
|
741
801
|
dictionary weighs megabytes, and there is nothing to pay with for an answer the numbers never needed.
|
|
742
802
|
|
|
@@ -768,7 +828,7 @@ put together from are the templates above.
|
|
|
768
828
|
| 1 | the table diverged from the history (or an edit on disk is not committed); for `size check` — a path of the history is neither tracked nor excluded | `pnpm run sizes` and commit the table; for `check` — add the path as a column or to `skip` |
|
|
769
829
|
| 2 | something in the call or in the project — the causes are quoted as the tool prints them: **command line** (unknown flag, flag without a value, repeated flag, two modes at once, extra word, command and mode, unknown command, incompatible flag, no JSON answer, two answers at once, no commit); **settings and the project** (no settings file, settings not parsed, settings invalid, git missing, not a git repository, config already exists); **history** (no such commit, ambiguous commit, commit outside the history); **hook** (foreign hook, foreign core.hooksPath, no way to invoke the tool); **measurement** (file is not JavaScript, minifier did not parse) | the refusal text names the reason and a ready command — and it is executable: `test/refusals.test.js` guards that |
|
|
770
830
|
| 3 | a shallow history (a clone with `--depth`) | a full clone: `git fetch --unshallow` |
|
|
771
|
-
| 4 | no sensor | `minify.engine: "esbuild"` with no minifier: the numbers are stripped rather than minified. The report is built, and its text carries the reason and the fix; if the table also diverges from the history, the code stays **1** (a mismatch outranks the
|
|
831
|
+
| 4 | no sensor | `minify.engine: "esbuild"` with no minifier: the numbers are stripped rather than minified. The report is built, and its text carries the reason and the fix; if the table also diverges from the history, the code stays **1** (a mismatch outranks the sensor note) while the note about the other count is printed next to it |
|
|
772
832
|
| 5 | an internal error | this is a defect of the tool: we are the ones who need the text — see "Traps worth testing the engine on" below |
|
|
773
833
|
|
|
774
834
|
The cell of code 2 quotes the tool rather than describing it: those are the names of the refusal registry
|
|
@@ -832,12 +892,12 @@ behaviour rather than as workarounds:
|
|
|
832
892
|
metric honestly falls back to stripping: the numbers are the same as `strip`, the label says so in words,
|
|
833
893
|
and a **build** (`--write`) returns **code 4** with a ready fix. A **check** answers in two parts in that
|
|
834
894
|
case, and it is named here because it is what CI advises: if the report on disk was built with the real
|
|
835
|
-
minifier while the run goes without it, the
|
|
836
|
-
agree with the history, so the check says as much (**code 1**), showing the diverged signature
|
|
837
|
-
**naming the other count right there** in a note with a ready fix. The verdict stays with the
|
|
838
|
-
code 4 would claim the difference is explained by the sensor, and nobody checked that — the
|
|
839
|
-
may also be an edit that went past the report (the same order as `size check` and `doctor`: a
|
|
840
|
-
outranks
|
|
895
|
+
minifier while the run goes without it, the numbers were counted another way — the numbers in the table
|
|
896
|
+
no longer agree with the history, so the check says as much (**code 1**), showing the diverged signature
|
|
897
|
+
row and **naming the other count right there** in a note with a ready fix. The verdict stays with the
|
|
898
|
+
divergence: code 4 would claim the difference is explained by the sensor, and nobody checked that — the
|
|
899
|
+
divergence may also be an edit that went past the report (the same order as `size check` and `doctor`: a
|
|
900
|
+
mismatch outranks the sensor note). The fix in both cases is `pnpm run sizes`; on this environment it returns
|
|
841
901
|
**code 4**. This can be checked without reinstalling by the `SIZE_REPORT_NO_OPTIONAL=1` environment — the
|
|
842
902
|
same way `test/minify.test.js` does it.
|
|
843
903
|
- **The module parse is one worker raised once per a run** (`REFACTOR.md` R-5.4): the fallback to
|
|
@@ -933,9 +993,9 @@ rejected tools (knip, ast-grep, size-limit, gitleaks) are in `worklog/archive/WO
|
|
|
933
993
|
excluded, untracked) and a ready fix. The commit is named by a revision (`HEAD`, a branch, a tag), by a
|
|
934
994
|
full sha or by its beginning.
|
|
935
995
|
- The data without the markup — the rows, the numbers, the totals — is `--json` (the earlier form, frozen
|
|
936
|
-
byte for byte by the parity reference) and `--data` (the
|
|
937
|
-
|
|
938
|
-
command does not exist yet.
|
|
996
|
+
byte for byte by the parity reference) and `--data` (the contract: absolute values and the shape of the
|
|
997
|
+
table, with nothing derived — whatever the page can count itself is not there; the page's own block is the
|
|
998
|
+
same data in sparse form). A `size measure` command does not exist yet.
|
|
939
999
|
- `--json` is a form of answer rather than a mode of its own, and it has one rule: exactly four calls have
|
|
940
1000
|
an answer. With no command it is the earlier form of the data (frozen by the parity reference), and for
|
|
941
1001
|
`check`, `explain` and `doctor` it is their answer. For a command with no answer, and next to a mode
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vernikr/size-report",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"author": "vernikr",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"report"
|
|
66
66
|
],
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@vernikr/size-report": "2.
|
|
68
|
+
"@vernikr/size-report": "2.5.0",
|
|
69
69
|
"c8": "10",
|
|
70
70
|
"dependency-cruiser": "17",
|
|
71
71
|
"eslint": "^9.18.0",
|
package/src/check.js
CHANGED
|
@@ -68,7 +68,7 @@ function pathCoverage(cfg, commits) {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/* The full answer: settings, history, paths, sensors — and the verdict. `ok` means only "nothing went past
|
|
71
|
-
* the report": a sensor counting
|
|
71
|
+
* the report": a sensor counting another way does not change the verdict (it has an exit code of its own,
|
|
72
72
|
* as in every other mode). */
|
|
73
73
|
export function coverage(cfg, root, configFile) {
|
|
74
74
|
assertFullHistory(root);
|
package/src/data.js
CHANGED
|
@@ -75,28 +75,10 @@ export function reportData(cfg, root) {
|
|
|
75
75
|
* changed just now rather than the rest. This is a fact from the history rather than a derived quantity:
|
|
76
76
|
* it does not count anything, it says what the edit touched. */
|
|
77
77
|
last: last,
|
|
78
|
-
approx: approxMarks(rows, state, cfg),
|
|
79
78
|
skipped: dropped.map(skipLine)
|
|
80
79
|
};
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
/* Marks of approximate cells — one record per metric: a string of marks over the row cells and one over the
|
|
84
|
-
* "now" row. '1' means the number came out of stripping or an estimate, '0' that it is exact. A metric with
|
|
85
|
-
* no mark at all does not appear in the report: all numbers exact — silence.
|
|
86
|
-
*
|
|
87
|
-
* The engine sets a mark where it counts the number, by the same rule as the metric's label. Hence the page
|
|
88
|
-
* derives nothing about paths and formats: it only shows what was said and keeps no second rule of accuracy. */
|
|
89
|
-
function approxMarks(rows, state, cfg) {
|
|
90
|
-
const out = {};
|
|
91
|
-
cfg.metrics.forEach((m) => {
|
|
92
|
-
const mark = (flags) => (flags !== null && flags[m] ? '1' : '0');
|
|
93
|
-
const inRows = rows.map((r) => r.approx.map(mark).join('')).join('');
|
|
94
|
-
const now = state.map((s) => mark(s === null ? null : s.approx)).join('');
|
|
95
|
-
if (inRows.indexOf('1') >= 0 || now.indexOf('1') >= 0) out[m] = { rows: inRows, now: now };
|
|
96
|
-
});
|
|
97
|
-
return out;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
82
|
/* The part of a row shared by both answers: the page's contract (`--data`) and the older `--json` form (frozen
|
|
101
83
|
* by the parity fixture). One place, because these two answers can drift apart exactly here, and **the order
|
|
102
84
|
* of the fields is the bytes of the answer**: the object holds them in the order the frozen form prints. */
|
package/src/doctor.js
CHANGED
|
@@ -48,12 +48,12 @@ function environment(root) {
|
|
|
48
48
|
|
|
49
49
|
/* Dependencies: what counts the metrics here and now. The very loaders the sensors use are asked
|
|
50
50
|
* (`minifier`, `tokenizer`), so the answer cannot drift from the number: without the minifier `min` counts
|
|
51
|
-
* by
|
|
51
|
+
* by simplification, without the dictionary `tok` by estimate.
|
|
52
52
|
*
|
|
53
53
|
* Only what the project actually asked for is loaded: the dictionary weighs megabytes, and touching it for
|
|
54
54
|
* the sake of an "installed" line would mean paying for an answer the numbers never needed (the same rule as
|
|
55
55
|
* in the report: `test/tokens.test.js`). An unwanted sensor is named unneeded rather than unknown — it does
|
|
56
|
-
* not affect
|
|
56
|
+
* not affect the count, and that is the answer; "unknown" stays for the case where the settings are unreadable
|
|
57
57
|
* and there is nobody to ask. */
|
|
58
58
|
const UNREADABLE = 'unknown: the settings cannot be read';
|
|
59
59
|
|
|
@@ -132,8 +132,8 @@ function hookFindings(hooks) {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
/* Coverage is the same answer `size check` gives, plus the kind of trouble if there is one: an incomplete path
|
|
135
|
-
* or
|
|
136
|
-
* without it there are no numbers at all.
|
|
135
|
+
* or a sensor counting another way (the kinds weigh differently — `WEIGHT`), with incompleteness outranking,
|
|
136
|
+
* because without it there are no numbers at all.
|
|
137
137
|
* What becomes a finding and what does not: the report holds the whole coverage block (the same text as
|
|
138
138
|
* `size check`), so incompleteness is not retold a second time — it weighs. Sensors do get a finding:
|
|
139
139
|
* `size check` prints them as a `!` line, while here they are part of the answer. */
|
package/src/history.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { assertFullHistory, diskForm, diskHashes, git, headTree, readBlobs, readHistory } from './git.js';
|
|
4
|
-
import { METRICS, measureBlob
|
|
4
|
+
import { METRICS, measureBlob } from './metrics.js';
|
|
5
5
|
import { touchedSection } from './journal.js';
|
|
6
6
|
import { EXIT, refuse } from './refusal.js';
|
|
7
7
|
|
|
@@ -82,15 +82,10 @@ function applyPicks(pass, c, picks) {
|
|
|
82
82
|
}
|
|
83
83
|
const blob = pass.blobs.get(pick.spec);
|
|
84
84
|
const cells = {};
|
|
85
|
-
/* Approximation is a property of the path rather than of the blob: whether the format goes to
|
|
86
|
-
* the minifier depends on its extension. It is computed here along with the measurement, and
|
|
87
|
-
* so it does not enter the content cache. */
|
|
88
|
-
const approx = {};
|
|
89
85
|
pass.metrics.forEach((m) => {
|
|
90
86
|
cells[m] = pass.measure(m, blob, pick.path, c.sha);
|
|
91
|
-
approx[m] = !pointExact(m, pick.path, pass.cfg);
|
|
92
87
|
});
|
|
93
|
-
pass.state[i] = { path: pick.path, sha: blob.sha, cells: cells
|
|
88
|
+
pass.state[i] = { path: pick.path, sha: blob.sha, cells: cells };
|
|
94
89
|
});
|
|
95
90
|
}
|
|
96
91
|
|
|
@@ -127,8 +122,7 @@ function stepCommit(pass, c, ci) {
|
|
|
127
122
|
when: c.when,
|
|
128
123
|
subject: c.subject,
|
|
129
124
|
section: section,
|
|
130
|
-
cells: pass.state.map((s) => (s === null ? null : s.cells))
|
|
131
|
-
approx: pass.state.map((s) => (s === null ? null : s.approx))
|
|
125
|
+
cells: pass.state.map((s) => (s === null ? null : s.cells))
|
|
132
126
|
});
|
|
133
127
|
}
|
|
134
128
|
|
package/src/init.js
CHANGED
|
@@ -14,7 +14,8 @@ import { packageManager } from './project.js';
|
|
|
14
14
|
* pass the very check the first run will apply**, or the advice leads a person into a new dead end.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
/* What to say after writing: what was written, what
|
|
17
|
+
/* What to say after writing: what was written, what counts the same numbers when the optional
|
|
18
|
+
* dependency is missing, and what to do
|
|
18
19
|
* next. The lines are assembled into a list rather than printed as they come, so that "what was said"
|
|
19
20
|
* can be read as a whole. */
|
|
20
21
|
function draftLines(root, target, cfg) {
|
package/src/locales.js
CHANGED
|
@@ -37,12 +37,6 @@ export const LOCALES = {
|
|
|
37
37
|
categoryByExtension: 'по расширению',
|
|
38
38
|
all: 'все',
|
|
39
39
|
sub: '{tool} {version} · {artifact}',
|
|
40
|
-
/* Words of precision: a metric label speaks about the worst in its column, a cell
|
|
41
|
-
* about its own number. One word serves both the label and the cell hint, so the two
|
|
42
|
-
* cannot drift or sound differently. */
|
|
43
|
-
exact: 'точное число',
|
|
44
|
-
approximate: 'приближение',
|
|
45
|
-
approximateCell: 'приближённое число: ',
|
|
46
40
|
panelMethod: 'способ:',
|
|
47
41
|
emptyMetrics: 'Ни одна метрика не выбрана — таблицу не из чего собрать. '
|
|
48
42
|
+ 'Включите хотя бы одну в панели выше: без метрик нет ни одной колонки с числом.',
|
|
@@ -54,6 +48,11 @@ export const LOCALES = {
|
|
|
54
48
|
+ 'что выбрано в этом браузере.',
|
|
55
49
|
linkExtra: 'Часть ссылки пропущена: в этом отчёте нет {n} названных имён. '
|
|
56
50
|
+ 'Остальное применено.',
|
|
51
|
+
/* Данные отчёта лежат в файле сжатыми, и распаковывает их браузер. Текст называет причину
|
|
52
|
+
* (браузера нет в списке тех, что умеют `DecompressionStream`) и что с этим делать — пустая
|
|
53
|
+
* таблица не сказала бы читателю ничего. */
|
|
54
|
+
unpack: 'Данные отчёта сжаты, а браузер не умеет их распаковать: в нём нет DecompressionStream. '
|
|
55
|
+
+ 'Обновите браузер — таблицу показывать не из чего.',
|
|
57
56
|
note: 'Абсолютные размеры стоят один раз — в строке «{now}». Строк: {rows}: коммиты без '
|
|
58
57
|
+ 'изменения объёма и коммиты, тронувшие только выключенные файлы, строк не получают. '
|
|
59
58
|
+ 'Собрано из истории git: {command}.'
|
|
@@ -99,9 +98,6 @@ export const LOCALES = {
|
|
|
99
98
|
categoryByExtension: 'by extension',
|
|
100
99
|
all: 'all',
|
|
101
100
|
sub: '{tool} {version} · {artifact}',
|
|
102
|
-
exact: 'an exact number',
|
|
103
|
-
approximate: 'an approximation',
|
|
104
|
-
approximateCell: 'an approximate number: ',
|
|
105
101
|
panelMethod: 'method:',
|
|
106
102
|
emptyMetrics: 'No metric is selected — there is nothing to build the table from. '
|
|
107
103
|
+ 'Turn on at least one above: without metrics there is no column holding a number.',
|
|
@@ -113,6 +109,10 @@ export const LOCALES = {
|
|
|
113
109
|
+ 'has.',
|
|
114
110
|
linkExtra: 'Part of the link is skipped: this report has none of the {n} names '
|
|
115
111
|
+ 'it mentions. The rest is applied.',
|
|
112
|
+
/* The report's data lies in the file compressed and the browser unpacks it; this text is what a
|
|
113
|
+
* browser without `DecompressionStream` gets instead of an empty table. */
|
|
114
|
+
unpack: 'The report\u2019s data is compressed and this browser cannot unpack it: there is no '
|
|
115
|
+
+ 'DecompressionStream. Update the browser — there is nothing to build the table from.',
|
|
116
116
|
note: 'Absolute sizes appear once — in the “{now}” row. Rows: {rows}: commits that change '
|
|
117
117
|
+ 'no number, and commits touching only the disabled files, get no row. '
|
|
118
118
|
+ 'Collected from git history: {command}.'
|