@vernikr/size-report 2.7.0 → 2.8.1
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 +96 -55
- package/package.json +2 -2
- package/src/css.js +2 -2
- package/src/locales.js +0 -6
- package/src/page/app.css +15 -33
- package/src/page/app.js +29 -57
- package/src/page/build.js +14 -17
- package/src/page/payload.js +4 -5
- package/src/page/table.js +251 -293
- package/src/table.css +113 -67
- package/src/page/work.js +0 -55
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ shows.
|
|
|
10
10
|
|
|
11
11
|
## Status
|
|
12
12
|
|
|
13
|
-
**Release 2.
|
|
13
|
+
**Release 2.8.1 (2026-09-18).** 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,6 +19,42 @@ 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.8.1 is the drawing of the page put right after its table became a window, and its figures are measured rather than
|
|
23
|
+
retold. **The panel and the table were sharing one class:** the table's rows were styled by a bare `.row` while the
|
|
24
|
+
panel's own rows are `.panel .row`, so the table's rule took the metrics row and the three method lines out of the flow
|
|
25
|
+
and painted them over one another — every rule of the shared part now hangs off `#grid`, and a check reads the selector
|
|
26
|
+
list of that sheet rather than a sample of the page. **The numbers were placed from the grid's left edge while the commit
|
|
27
|
+
column is pinned over it**, which hid the first column — the overall total — completely; they begin at the column's right
|
|
28
|
+
edge now, a 220px figure written in the script and in the styling and held together like the three beside it. **The order
|
|
29
|
+
of the columns comes from the numbers rather than from the commit's list of paths**: a commit can touch a file without
|
|
30
|
+
moving it — this package's own attachment to itself, 2.7.0 → 2.8.0, is one character for another — and a column of empty
|
|
31
|
+
cells standing in front of the table is what a reader calls a broken order, so a file's newest move decides its place;
|
|
32
|
+
the engine's mark `last` stays in `--data` while the page's block no longer carries it. **One border and one height:**
|
|
33
|
+
every line of the table is 1px of one colour (the header's two lines were 2px and another shade) and the header is two rows
|
|
34
|
+
of the table's own height, while a file's name is centred over its group. The artifact grows 351 B for it — 85 495 B
|
|
35
|
+
against 85 144 B of one history. The checks go 88 → **89** in the fast profile and 193 → **194** in the full one; the
|
|
36
|
+
figures and the reasoning stand in `worklog/0209-page-drawing-order.md`.
|
|
37
|
+
|
|
38
|
+
2.8.0 is about what the report costs whoever opens it, and its figures are measured rather than retold.
|
|
39
|
+
**The table is a window of itself:** every row and every column in sight is built, plus four beyond each edge so that
|
|
40
|
+
the edge of the window is never seen empty, while the rest of the table exists as the extent of the scrolled box and
|
|
41
|
+
nothing else. This repository's own report was a `<table>` of 238 500 cells — 253 770 nodes in the document, 377 396 in
|
|
42
|
+
the browser, 1.46 GB of a fresh Chrome's memory with the page open and nothing else — and the window of it is
|
|
43
|
+
**2 460 nodes, 7 320 and 0.15 GB**: a hundredth of the nodes and a tenth of the memory. Scrolling the whole table cost
|
|
44
|
+
**1.1 s of task time over 251 steps**, against **36 s over 60 steps** for the same page as a full table (a median of
|
|
45
|
+
571 ms a frame, which is the freeze a reader felt). **Every column is 70px wide and fixed** — the numbers are short and
|
|
46
|
+
of one kind, and a width that came out of the text is a measurement of every cell of the column — while a file's name
|
|
47
|
+
that does not fit its group is cut with an ellipsis rather than wrapped (the whole name stands in the tooltip). **The
|
|
48
|
+
stripe over a drawing is gone with the freeze it was drawn for**: a switch costs a few milliseconds, so there is nothing
|
|
49
|
+
for an indicator to indicate, and `src/page/work.js` left the tree with it. A virtualizer library was measured and not
|
|
50
|
+
taken — `@tanstack/virtual-core` is ~6.7 kB gzip and headless, `virtua`'s grid is experimental and `Clusterize.js`
|
|
51
|
+
knows rows and not columns — because each would be vendored into the artifact, which the report then measures as its own
|
|
52
|
+
bytes. **The checks of the old table are deactivated while it is rebuilt:** `test/page-view.test.js`, `page-cols`,
|
|
53
|
+
`page-tree` and `page-choice` skip every check with its reason at the top of the file, and this document names them
|
|
54
|
+
where they are the promise-holders of what they described; `test/page-grid.test.js` is what guards the window meanwhile.
|
|
55
|
+
The figures and the reasoning stand in `worklog/0208-table-window.md`. The checks grow with the work: 81 → **88** in the
|
|
56
|
+
fast profile and 186 → **193** in the full one.
|
|
57
|
+
|
|
22
58
|
2.7.0 is about the page and what a reader does with it, and its figures are measured rather than retold.
|
|
23
59
|
**The report's address stays clean:** a switch writes the record into the browser's memory and nothing into the
|
|
24
60
|
address bar — the page no longer puts a `#size-report=…` tail on the report it was opened with — while a link
|
|
@@ -217,11 +253,10 @@ commits and installs hooks; the reason for each expensive file is named line by
|
|
|
217
253
|
|
|
218
254
|
| Run | Command | Checks |
|
|
219
255
|
|---|---|---|
|
|
220
|
-
| Fast — every edit | `pnpm test` | **
|
|
221
|
-
| Full — release and CI | `pnpm test:all` | **
|
|
256
|
+
| Fast — every edit | `pnpm test` | **89 of 194** |
|
|
257
|
+
| Full — release and CI | `pnpm test:all` | **194** |
|
|
222
258
|
|
|
223
|
-
No check is lost or weakened: the full run starts
|
|
224
|
-
of them. The default is the full run — a file becomes fast only explicitly and with a reason — so new
|
|
259
|
+
No check is lost or weakened: the full run starts every file, the fast one takes part of them. The default is the full run — a file becomes fast only explicitly and with a reason — so new
|
|
225
260
|
expensive work cannot quietly move into the fast one. Two declarations guard that:
|
|
226
261
|
`test/suites.test.js` (every file classified, and a reason for each) and the documentation guard
|
|
227
262
|
`test/docs-numbers.test.js` (the numbers in the table above).
|
|
@@ -336,45 +371,51 @@ row hides it, so a click on the sign changes exactly the three things the reader
|
|
|
336
371
|
sign and the note in the memory. What guards this is that after folding the table is the same markup
|
|
337
372
|
rather than a rebuilt one (`test/page-tree.test.js`).
|
|
338
373
|
|
|
339
|
-
**
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
374
|
+
**The table is a window of itself, and the window is what a scroll moves.** A row stands at its own `top` inside the
|
|
375
|
+
scrolled content and a column at its own `left`, so scrolling costs the browser nothing but painting — no layout of the
|
|
376
|
+
table to redo and no script to run — while the page works only when the window has really moved, and then only on what
|
|
377
|
+
left it and what entered it. The header sticks to the top of the shell and the commit column to its left, so the commit a
|
|
378
|
+
number belongs to and the file it stands under are always in sight. The price of a table is what this step removed:
|
|
379
|
+
238 500 cells were 253 770 nodes in the document and 377 396 in the browser, **1.46 GB** of a fresh Chrome's memory at
|
|
380
|
+
rest, and any change of a column's visibility meant the browser laying the whole of it out again — 234.5 ms of layout for
|
|
381
|
+
a *single* cell of this repository's report, 539 ms for 6 000 (`probes/step-12-columns.mjs`). A window of the same
|
|
382
|
+
table is **2 460 nodes and 0.15 GB**, a hundredth of the nodes and a tenth of the memory, and the whole-table scroll
|
|
383
|
+
pass that took 36 s of task time over 60 steps takes **1.1 s over 251** (`worklog/0208-table-window.md`). **The columns
|
|
384
|
+
are one width and fixed, 70px each**: the numbers are short and of one kind, and a width that came out of the text is a
|
|
385
|
+
measurement of every cell of the column — the very cost this step removed. A file's name stands centred over its group
|
|
386
|
+
and is cut with an ellipsis rather than wrapped — the whole name stays in the tooltip. The header is two lines of one
|
|
387
|
+
row each, the numbers begin at the
|
|
388
|
+
right edge of the pinned commit column rather than under it, and every line of the table — under a row, under a header
|
|
389
|
+
cell, along a group's left edge — is one pixel of one colour: a heavier line would promise a hierarchy to work out
|
|
390
|
+
rather than read. The geometry is four figures — a column, a row, the header, the pinned column — written in the styling
|
|
391
|
+
and in the script that counts the window's ordinals in them, and `test/page-grid.test.js` reads both and holds them
|
|
392
|
+
together.
|
|
393
|
+
|
|
394
|
+
**A click builds the window again, and that is cheap now.** A file switched off is simply not among the columns that
|
|
395
|
+
are built, and a metric switched off not among the metrics: there is nothing to hide and nothing to carry, and the
|
|
396
|
+
window is built from the choice as it is — a few hundred cells, 1–5 ms on this repository's report against the ~1 s the
|
|
397
|
+
same click cost as a table. The totals are the sum over the files that are on, counted by the shared `rowModel` for the
|
|
398
|
+
rows the window holds (`src/derived.js`), rather than kept in a running cache that a second road would have to agree
|
|
399
|
+
with. **There is no stripe over the page any longer, and that is a measurement rather than an omission:** it stood over
|
|
400
|
+
the browser's relayout of the whole table, and work that is over before a frame could paint it has no moment to be
|
|
401
|
+
shown in (`src/page/work.js` left the tree with the freeze it was drawn for). **Nothing of it is a library**, and that
|
|
402
|
+
was measured too: a virtualizer of both axes is not a solved problem for a page like this one —
|
|
403
|
+
`@tanstack/virtual-core` is ~6.7 kB gzip and headless (the rows and the columns are two virtualizers, and every node
|
|
404
|
+
is still yours to write), `virtua` calls its grid `experimental_VGrid` and has no sticky pieces, `Clusterize.js`
|
|
405
|
+
virtualizes rows out of a string of all of them and knows nothing of columns — and each would have to be vendored into
|
|
406
|
+
the artifact, whose bytes this very tool measures. What is left to write after any of them is what the chapter is: the
|
|
407
|
+
window, the cells, the header and the pinned column.
|
|
408
|
+
|
|
409
|
+
**The columns whose numbers last moved come first.** The report is rebuilt after every commit, and a
|
|
410
|
+
reader's first question is what that edit brought. The mark is taken from the numbers rather than from
|
|
411
|
+
the commit's list of paths, and that is the whole of the difference: a commit can touch a column without
|
|
412
|
+
moving it — a version bumped inside a line of the same length, this package's own attachment to itself is
|
|
413
|
+
one — and a column of empty cells standing in front of the table is what a reader calls a broken order.
|
|
414
|
+
The rest follows in the settings' order (the sort is stable), so the order of the columns is what the
|
|
415
|
+
reader is used to, and his choice of files does not rearrange it (`src/page/table.js`; the rule is counted
|
|
416
|
+
from the contract's own rows in `test/page-grid.test.js`). The engine still answers with `last` — the
|
|
417
|
+
columns the newest commit touched — in `--data`; the page no longer reads it, and the block it carries no
|
|
418
|
+
longer holds it.
|
|
378
419
|
|
|
379
420
|
**On a wide window the panel stands to the left of the table and takes no room from the numbers** (from
|
|
380
421
|
900px, `src/page/app.css`). That is not decoration: a desktop has much side room and little vertical
|
|
@@ -557,15 +598,14 @@ acceptance for each.
|
|
|
557
598
|
| `src/size-table.js` | The package's entry point: a re-export of the public API (55 names) and no calculation of its own |
|
|
558
599
|
| `src/derived.js` | The report's shared calculation: totals, deltas, a cell, a commit's caption — one for the engine and the page's program |
|
|
559
600
|
| `src/css.js` | Reading the styling from disk: which sets of styles exist and what role each has |
|
|
560
|
-
| `src/table.css` | The report's table: the geometry of
|
|
601
|
+
| `src/table.css` | The report's table: the geometry of the window — one width per column, one height per row, the two lines of the header, the pinned commit column — the sticky header and commit column, one 1px line of one colour for every border, a file's caption centred over its group and cut with an ellipsis, the colour of deltas |
|
|
561
602
|
| `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 |
|
|
562
603
|
| `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 |
|
|
563
604
|
| `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", the unfolded folders, the record's passport, the browser's memory and the link that is read out of the address — a chapter of the page's program |
|
|
564
605
|
| `src/page/dom.js` | The page's nodes: the small helpers of markup (`appEl`, `appBox`) — one set for the panel and the table alike |
|
|
565
606
|
| `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, and a hidden name after every visible one; the tree opens folded and folders carry a 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 |
|
|
566
|
-
| `src/page/table.js` | The page's table
|
|
567
|
-
| `src/page/
|
|
568
|
-
| `src/page/app.js` | Assembling and starting the page: the first drawing, then a switch that counts the numbers on the click, hands the columns to the queue and writes the fields it reached without making a node; an anchor change; pasted into the assembled page |
|
|
607
|
+
| `src/page/table.js` | The page's table as a window: the rows and the columns the reader can see (plus four beyond each edge), a cell, a commit's caption, the header, the empty states and the order of the columns — markup over the shared calculation, with the totals counted per row from the choice, the geometry in pixels that the styling mirrors, and the reason a library was not taken |
|
|
608
|
+
| `src/page/app.js` | Assembling and starting the page: the first drawing, then a switch that builds the window again and writes the fields it reached without making a node of the panel; an anchor change; pasted into the assembled page |
|
|
569
609
|
| `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` |
|
|
570
610
|
| `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 |
|
|
571
611
|
| `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 |
|
|
@@ -597,7 +637,7 @@ acceptance for each.
|
|
|
597
637
|
| `test/api.test.js` | The package's public API: the list of names is frozen, and splitting the engine may not change it |
|
|
598
638
|
| `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`) |
|
|
599
639
|
| `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 |
|
|
600
|
-
| `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
|
|
640
|
+
| `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 seven suites |
|
|
601
641
|
| `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 |
|
|
602
642
|
| `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 |
|
|
603
643
|
| `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 |
|
|
@@ -613,10 +653,11 @@ acceptance for each.
|
|
|
613
653
|
| `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) |
|
|
614
654
|
| `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 |
|
|
615
655
|
| `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 |
|
|
616
|
-
| `test/page-
|
|
617
|
-
| `test/page-
|
|
618
|
-
| `test/page-
|
|
619
|
-
| `test/page-
|
|
656
|
+
| `test/page-grid.test.js` | The grid of the page as a window: what the reader sees is built and no more, the geometry of the styling against the script's, the rows and the columns that a scroll builds and drops, a number under its own caption, a file and a metric switched off, every row of the window against the engine's own calculation, and the drawing's own rules — the order of the columns by the numbers, one border, the header's rows of one height, and the panel out of the shared styling's reach |
|
|
657
|
+
| `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 — **deactivated** while the table is rebuilt, every check skipped with its reason in the file |
|
|
658
|
+
| `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), the hidden names at the end of a level, the tree that opens folded and the unfolding the memory keeps, folding without a rebuild and a scroll a click does not touch — **deactivated** with the table, the checks skipped with their reason |
|
|
659
|
+
| `test/page-choice.test.js` | The reader's choice and the work a click starts: the memory and a revisit, someone else's report, a foreign and a broken record, an address that stays clean, a link read at opening and on an open page, and the drawing of a long switch in a task of its own behind the stripe — **deactivated**: the choice and the link are the same, while the counts and the stripe are not |
|
|
660
|
+
| `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 — **deactivated** with the table: the columns are one fixed width now |
|
|
620
661
|
| `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 |
|
|
621
662
|
| `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 |
|
|
622
663
|
| `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 |
|
|
@@ -696,7 +737,7 @@ The same release can be taken by a reference to the repository — installation
|
|
|
696
737
|
registry, but stays tied to a revision:
|
|
697
738
|
|
|
698
739
|
```bash
|
|
699
|
-
pnpm add -D github:vernikr/size-report#v2.
|
|
740
|
+
pnpm add -D github:vernikr/size-report#v2.8.1
|
|
700
741
|
```
|
|
701
742
|
|
|
702
743
|
With no network (or nothing to fetch from codeload) — the tarball: `pnpm pack` in the package clone, then
|
|
@@ -708,7 +749,7 @@ the branch moves on the installation fails with `Could not resolve <sha> to a co
|
|
|
708
749
|
observation rather than reasoning: the short pin `6530237` installed while `main` stood on it and stopped
|
|
709
750
|
working at the very next commit, while the same sha in full installed. A branch name (`#main`) and a tag
|
|
710
751
|
are both accepted, but a branch is a moving target and a tag is constant: this release stands on the tag
|
|
711
|
-
`v2.
|
|
752
|
+
`v2.8.1`, which is also the one in the example (forty characters work as well, but they have to be copied
|
|
712
753
|
out of the history by eye).
|
|
713
754
|
|
|
714
755
|
The revision in the example is a part of the claim rather than decoration: what is described below is
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vernikr/size-report",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.1",
|
|
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.8.0",
|
|
69
69
|
"c8": "10",
|
|
70
70
|
"dependency-cruiser": "17",
|
|
71
71
|
"eslint": "^9.18.0",
|
package/src/css.js
CHANGED
|
@@ -7,8 +7,8 @@ import fs from 'node:fs';
|
|
|
7
7
|
*
|
|
8
8
|
* There are two sets, each with a role of its own:
|
|
9
9
|
*
|
|
10
|
-
* 1. `table.css` — the **table**:
|
|
11
|
-
* the colours of the deltas.
|
|
10
|
+
* 1. `table.css` — the **table**: the geometry of the window (a column, a row, the header), the sticky header
|
|
11
|
+
* and commit column, a commit's caption, the colours of the deltas.
|
|
12
12
|
* 2. `page/app.css` — the page's look **on top of the table**: the canvas, the panel of choices, the empty
|
|
13
13
|
* states and the adaptation to a narrow window.
|
|
14
14
|
*
|
package/src/locales.js
CHANGED
|
@@ -53,9 +53,6 @@ export const LOCALES = {
|
|
|
53
53
|
* таблица не сказала бы читателю ничего. */
|
|
54
54
|
unpack: 'Данные отчёта сжаты, а браузер не умеет их распаковать: в нём нет DecompressionStream. '
|
|
55
55
|
+ 'Обновите браузер — таблицу показывать не из чего.',
|
|
56
|
-
/* Полоска вверху страницы: имя для тех, кто читает страницу не глазами, — она показывает,
|
|
57
|
-
* что идёт отрисовка колонок, а не что отчёт завис. */
|
|
58
|
-
working: 'отрисовка колонок',
|
|
59
56
|
note: 'Абсолютные размеры стоят один раз — в строке «{now}». Строк: {rows}: коммиты без '
|
|
60
57
|
+ 'изменения объёма и коммиты, тронувшие только выключенные файлы, строк не получают. '
|
|
61
58
|
+ 'Собрано из истории git: {command}.'
|
|
@@ -116,9 +113,6 @@ export const LOCALES = {
|
|
|
116
113
|
* browser without `DecompressionStream` gets instead of an empty table. */
|
|
117
114
|
unpack: 'The report\u2019s data is compressed and this browser cannot unpack it: there is no '
|
|
118
115
|
+ 'DecompressionStream. Update the browser — there is nothing to build the table from.',
|
|
119
|
-
/* The bar at the top of the page: a name for whoever reads the page without eyes — it shows
|
|
120
|
-
* that the columns are being drawn rather than that the report has hung. */
|
|
121
|
-
working: 'drawing the columns',
|
|
122
116
|
note: 'Absolute sizes appear once — in the “{now}” row. Rows: {rows}: commits that change '
|
|
123
117
|
+ 'no number, and commits touching only the disabled files, get no row. '
|
|
124
118
|
+ 'Collected from git history: {command}.'
|
package/src/page/app.css
CHANGED
|
@@ -14,7 +14,10 @@
|
|
|
14
14
|
--pad: clamp(16px, 3vw, 34px);
|
|
15
15
|
--radius: 10px;
|
|
16
16
|
--muted: rgba(127, 127, 127, .85);
|
|
17
|
-
|
|
17
|
+
/* The same grey as the table's own lines (`--grid-line` of `src/table.css`): the frame around the numbers and the rows
|
|
18
|
+
* inside it are one drawing, and a second grey for the chrome is what makes a page look assembled from two. The two
|
|
19
|
+
* declarations are held together by the check that reads the borders of both sheets. */
|
|
20
|
+
--line: rgba(127, 127, 127, .25);
|
|
18
21
|
--tint: rgba(127, 127, 127, .07);
|
|
19
22
|
}
|
|
20
23
|
|
|
@@ -116,7 +119,8 @@ h1 { margin: 0 0 3px; font-size: 21px; font-weight: 650; letter-spacing: -.012em
|
|
|
116
119
|
|
|
117
120
|
/* The table has a frame and a scroll of its own: the header and the commit column stick to it (the rules of stickiness
|
|
118
121
|
* live in the shared part) rather than to the page, so scrolling sideways shows whose row it is while scrolling down shows
|
|
119
|
-
* which column it is.
|
|
122
|
+
* which column it is. What stands inside that frame is a window of the grid rather than the whole of it
|
|
123
|
+
* (`src/page/table.js`). */
|
|
120
124
|
.shell {
|
|
121
125
|
overflow: auto;
|
|
122
126
|
max-height: calc(100vh - 300px);
|
|
@@ -127,34 +131,11 @@ h1 { margin: 0 0 3px; font-size: 21px; font-weight: 650; letter-spacing: -.012em
|
|
|
127
131
|
/* Numbers are denser than the page's text: there are more of them, they are shorter, and they are read by their digits. */
|
|
128
132
|
#grid { font-size: 12.5px; }
|
|
129
133
|
|
|
130
|
-
/*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* stripe — a travelling highlight, which is what this state is in the language of progress — and it moves by a transform,
|
|
136
|
-
* so the stripe itself costs the compositor rather than the page. Its colour is the system accent, the one colour the page
|
|
137
|
-
* uses for anything but the numbers, and it carries a role and a name, because a reader without eyes has to be told that
|
|
138
|
-
* work is going on rather than that the report is broken. */
|
|
139
|
-
.bar { position: fixed; top: 0; left: 0; right: 0; z-index: 5; height: 3px; overflow: hidden; }
|
|
140
|
-
.bar[hidden] { display: none; }
|
|
141
|
-
.bar > i {
|
|
142
|
-
display: block;
|
|
143
|
-
width: 30%;
|
|
144
|
-
height: 100%;
|
|
145
|
-
background: AccentColor;
|
|
146
|
-
animation: bar-run 1.1s linear infinite;
|
|
147
|
-
}
|
|
148
|
-
@keyframes bar-run {
|
|
149
|
-
from { transform: translateX(-100%); }
|
|
150
|
-
to { transform: translateX(333%); }
|
|
151
|
-
}
|
|
152
|
-
/* Whoever asked the system for less motion gets a still stripe: the state is what matters, not its travelling. */
|
|
153
|
-
@media (prefers-reduced-motion: reduce) {
|
|
154
|
-
.bar > i { animation: none; width: 100%; }
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/* The message about a link that came in stands above the table, so that it cannot be missed, while it does not push the
|
|
134
|
+
/* There is no stripe of progress over the page any longer, and that is a measurement rather than an omission: it stood
|
|
135
|
+
* over the browser's relayout of the whole table, and the table is built as a window now — a switch costs a few
|
|
136
|
+
* milliseconds (`src/page/table.js`), so an indicator would be a promise the page does not keep.
|
|
137
|
+
*
|
|
138
|
+
* The message about a link that came in stands above the table, so that it cannot be missed, while it does not push the
|
|
158
139
|
* table away: one line in the place of the page. Its colour is the system one (the accent), for the page keeps no colours
|
|
159
140
|
* of its own. */
|
|
160
141
|
.notice {
|
|
@@ -253,7 +234,8 @@ h1 { margin: 0 0 3px; font-size: 21px; font-weight: 650; letter-spacing: -.012em
|
|
|
253
234
|
h1 { font-size: 18px; }
|
|
254
235
|
#grid { font-size: 12px; }
|
|
255
236
|
.shell { max-height: calc(100vh - 260px); }
|
|
256
|
-
/* The commit column
|
|
257
|
-
* (`
|
|
258
|
-
*
|
|
237
|
+
/* The commit column keeps its width on a narrow screen, and that is deliberate rather than forgotten: the numbers
|
|
238
|
+
* are placed beside it by the script (`APP_COMMIT`), so a narrower column here would leave a band of empty grid
|
|
239
|
+
* between the two — one number would have to be read from the styling by the script, which is a second copy of a
|
|
240
|
+
* geometry the check holds together (`test/page-grid.test.js`). */
|
|
259
241
|
}
|
package/src/page/app.js
CHANGED
|
@@ -1,42 +1,23 @@
|
|
|
1
1
|
import { appUnpack } from './payload.js';
|
|
2
2
|
import { appApply, appBoot, appData, appFoldRead, appLinkUse, appNotice, appRead, appUi, appView, appWrite } from './state.js';
|
|
3
|
-
import {
|
|
4
|
-
import { appDraw } from './work.js';
|
|
3
|
+
import { appState, appTable, appWindow } from './table.js';
|
|
5
4
|
import { appPanel, appPanelAll, appPanelState } from './panel.js';
|
|
6
5
|
|
|
7
|
-
/* Assembling the report: the table is
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
/* Assembling the report: the table is a window of the grid (`appWindow` of the table chapter) and nothing is built
|
|
7
|
+
* that the reader cannot see. Two paths and no third, as before: `appPaint` draws the whole view (the first drawing, a
|
|
8
|
+
* record from the browser's memory, a link in the address), while a click on a box does the same work for the choice
|
|
9
|
+
* it made — and the difference between them is only how much of the view moved.
|
|
11
10
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* browser's own relayout of the table, and it is paid once here rather than once per slice). Neither path makes a
|
|
18
|
-
* node.
|
|
11
|
+
* What a click costs now: the window of rows and columns is built again — a few hundred cells, measured at 1–5 ms on
|
|
12
|
+
* this repository's report — instead of a class on every node of a column of a table the browser lays out whole. The
|
|
13
|
+
* stripe that used to stand over a long drawing (`src/page/work.js`) is gone with the reason for it: a switch no
|
|
14
|
+
* longer has anything to wait for, and an indicator over work that is over before it could be painted would be a
|
|
15
|
+
* promise the page does not keep.
|
|
19
16
|
*/
|
|
20
17
|
|
|
21
|
-
// The table's
|
|
18
|
+
// The table's window: made once, at the first drawing.
|
|
22
19
|
let appCache = null;
|
|
23
20
|
|
|
24
|
-
/* One file's column drawn from the view — the state is read when the slice runs rather than kept from the click that
|
|
25
|
-
* queued it, so a click that arrives while the queue is running is drawn by the next slice rather than after it. */
|
|
26
|
-
function appDrawColumn(i) {
|
|
27
|
-
appColumn(appCache, i, appView.files[i] === true);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/* The columns of a switch that have to be drawn, as the units the work chapter weighs (`{i, units}` — the file and the
|
|
31
|
-
* nodes of its column). Only the columns whose nodes are out of step with the view are asked for (`appColumnStale`): a
|
|
32
|
-
* report opened with everything switched on has nothing to draw, and a column that is already right would cost its
|
|
33
|
-
* nodes again. The count is the table's (`appColumnSize`), because the table is the only place that knows how many
|
|
34
|
-
* nodes a column has. */
|
|
35
|
-
function appColumns(indexes) {
|
|
36
|
-
const todo = indexes.filter((i) => appColumnStale(appCache, i));
|
|
37
|
-
appDraw(appDrawColumn, todo.map((i) => ({ i: i, units: appColumnSize(appCache, i) })));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
21
|
/* The note under the table: what a row is and how the report was made. It does not depend on the choice, so it is
|
|
41
22
|
* written once — with the table rather than with every drawing of it. */
|
|
42
23
|
function appNote() {
|
|
@@ -45,68 +26,59 @@ function appNote() {
|
|
|
45
26
|
.replace('{command}', appData.report.fixCommand);
|
|
46
27
|
}
|
|
47
28
|
|
|
48
|
-
/* What the empty states are told: how many metrics and how many files are left. The
|
|
49
|
-
* case
|
|
29
|
+
/* What the empty states are told: how many metrics and how many files are left. The window stands there in either
|
|
30
|
+
* case — the words are about what is shown. */
|
|
50
31
|
export function appCounts() {
|
|
51
32
|
appState(appData.metrics.filter((m) => appView.metrics[m.key] === true).length,
|
|
52
33
|
appView.files.filter((on) => on === true).length);
|
|
53
34
|
}
|
|
54
35
|
|
|
55
|
-
/* The whole view drawn:
|
|
56
|
-
*
|
|
36
|
+
/* The whole view drawn: the window of the grid, the metrics, the empty states and the panel's fields. This is what a
|
|
37
|
+
* link, a record from the memory and the first drawing need. */
|
|
57
38
|
export function appPaint() {
|
|
58
|
-
|
|
59
|
-
appTotalsReset(appCache);
|
|
60
|
-
appMetrics(appCache);
|
|
39
|
+
appWindow(appCache, true);
|
|
61
40
|
appCounts();
|
|
62
41
|
appPanelAll();
|
|
63
42
|
appWrite();
|
|
64
43
|
}
|
|
65
44
|
|
|
66
|
-
/* One file switched by the reader: the view,
|
|
67
|
-
*
|
|
68
|
-
* reader has read it. */
|
|
45
|
+
/* One file switched by the reader: the view, the window (its column is simply not among the columns that are built),
|
|
46
|
+
* the fields it shows in. The message about a link fades here: by this action the reader has read it. */
|
|
69
47
|
export function appSwitch(i, on) {
|
|
70
48
|
if (appView.files[i] === on) return;
|
|
71
49
|
appView.files[i] = on;
|
|
72
|
-
|
|
73
|
-
appTotals(appCache);
|
|
50
|
+
appWindow(appCache, true);
|
|
74
51
|
appCounts();
|
|
75
52
|
appPanelState([i]);
|
|
76
53
|
appWrite();
|
|
77
54
|
appNotice('');
|
|
78
|
-
appColumns([i]);
|
|
79
55
|
}
|
|
80
56
|
|
|
81
|
-
/* A group switched at once — a folder or a category: the same work per file, then the
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* counts them as one piece of work. */
|
|
57
|
+
/* A group switched at once — a folder or a category: the same work per file, then the fields of the files the choice
|
|
58
|
+
* really reached (switching a folder on when a part of it was already on touches only the rest, and a field that did
|
|
59
|
+
* not move is not written). The columns of the whole group leave or enter the window together. */
|
|
85
60
|
export function appSwitchGroup(indexes, on) {
|
|
86
61
|
const touched = indexes.filter((i) => appView.files[i] !== on);
|
|
87
|
-
touched.forEach((i) => {
|
|
88
|
-
|
|
89
|
-
appContribute(appCache, i, on);
|
|
90
|
-
});
|
|
91
|
-
appTotals(appCache);
|
|
62
|
+
touched.forEach((i) => { appView.files[i] = on; });
|
|
63
|
+
appWindow(appCache, true);
|
|
92
64
|
appCounts();
|
|
93
65
|
appPanelState(touched);
|
|
94
66
|
appWrite();
|
|
95
67
|
appNotice('');
|
|
96
|
-
appColumns(touched);
|
|
97
68
|
}
|
|
98
69
|
|
|
99
|
-
/* One metric switched:
|
|
100
|
-
*
|
|
70
|
+
/* One metric switched: the columns of that metric are not among the columns that are built any longer, so this is the
|
|
71
|
+
* same drawing as a file's switch. The metric's own field is the box the reader just clicked. */
|
|
101
72
|
export function appSwitchMetric() {
|
|
102
|
-
|
|
73
|
+
appWindow(appCache, true);
|
|
103
74
|
appCounts();
|
|
104
75
|
appWrite();
|
|
105
76
|
appNotice('');
|
|
106
77
|
}
|
|
107
78
|
|
|
108
79
|
/* The first drawing: the choice is already in the view (the link and the memory are applied above), the panel is
|
|
109
|
-
* built to match it, the
|
|
80
|
+
* built to match it, the window of the grid is built — the columns the choice leaves and the rows the shell shows —
|
|
81
|
+
* and the panel's fields are written from the view. */
|
|
110
82
|
function appFirst() {
|
|
111
83
|
appPanel();
|
|
112
84
|
appCache = appTable(document.getElementById('grid'));
|