@vernikr/size-report 2.8.3 → 2.8.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vernikr/size-report",
3
- "version": "2.8.3",
3
+ "version": "2.8.5",
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.8.2",
68
+ "@vernikr/size-report": "2.8.4",
69
69
  "c8": "10",
70
70
  "dependency-cruiser": "17",
71
71
  "eslint": "^9.18.0",
package/src/config.js CHANGED
@@ -76,7 +76,7 @@ export function gitRoot() {
76
76
  * request for that very file, so its absence stays a refusal (otherwise a typo in the path would
77
77
  * silently yield someone else's settings). `path` is given in words rather than as a path: there is no
78
78
  * file, and "edit <path>" would lead the reader to something the project does not have. */
79
- export function derivedConfig(root) {
79
+ function derivedConfig(root) {
80
80
  const cfg = derivedProfile(root);
81
81
  cfg.path = 'derived from the project';
82
82
  cfg.derived = true;
package/src/hook.js CHANGED
@@ -2,10 +2,9 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import { EXIT, Refusal, cliCommand, refuseCause } from './refusal.js';
5
- import { installSpec } from './tool.js';
5
+ import { TOOL_PKG, installSpec } from './tool.js';
6
6
  import { git, gitTry } from './git.js';
7
7
  import { loadConfig } from './config.js';
8
- import { TOOL_PKG } from './tool.js';
9
8
  import { rebuild } from './artifact.js';
10
9
 
11
10
  /* The `post-commit` and `post-merge` hooks: after every commit and merge the report rebuilds itself and, when it is tracked
@@ -120,6 +119,16 @@ function script(entry) {
120
119
  + 'exec node ' + entry.quoted + ' hook-run\n';
121
120
  }
122
121
 
122
+ /* Writing the hook files, executable: the named command and the silent install write the same bytes, since a difference
123
+ * between them would surface only after somebody's commit. */
124
+ function installFiles(hooks, entry, files) {
125
+ fs.mkdirSync(hooks.dir, { recursive: true });
126
+ files.forEach((file) => {
127
+ fs.writeFileSync(file, script(entry));
128
+ fs.chmodSync(file, 0o755);
129
+ });
130
+ }
131
+
123
132
  /* The hook's state for `size doctor`: whether it is installed and how its last run ended. It counts nothing and commits
124
133
  * to nothing. */
125
134
  export function hookStatus(root) {
@@ -180,11 +189,7 @@ export function installHook(root, cfg) {
180
189
  ' to remove it: ' + cliCommand('uninstall-hook')
181
190
  ] };
182
191
  }
183
- fs.mkdirSync(hooks.dir, { recursive: true });
184
- files.forEach((file) => {
185
- fs.writeFileSync(file, script(entry));
186
- fs.chmodSync(file, 0o755);
187
- });
192
+ installFiles(hooks, entry, files);
188
193
 
189
194
  const lines = [
190
195
  '✓ hook: ' + rels.join(', '),
@@ -219,11 +224,7 @@ export function autoInstall(root, cfg) {
219
224
  const files = HOOKS.map((name) => path.join(hooks.dir, name));
220
225
  if (files.some((f) => fs.existsSync(f) && !isOurs(f))) return null;
221
226
  if (files.every(isOurs)) return null;
222
- fs.mkdirSync(hooks.dir, { recursive: true });
223
- files.forEach((file) => {
224
- fs.writeFileSync(file, script(entry));
225
- fs.chmodSync(file, 0o755);
226
- });
227
+ installFiles(hooks, entry, files);
227
228
  return files.map((f) => path.relative(root, f));
228
229
  } catch (_e) {
229
230
  /* Not a git repository, no rights on `.git`, a foreign format — all of it means one thing: there will be no automation
package/src/locales.js CHANGED
@@ -48,9 +48,6 @@ export const LOCALES = {
48
48
  + 'что выбрано в этом браузере.',
49
49
  linkExtra: 'Часть ссылки пропущена: в этом отчёте нет {n} названных имён. '
50
50
  + 'Остальное применено.',
51
- /* Данные отчёта лежат в файле сжатыми, и распаковывает их браузер. Текст называет причину
52
- * (браузера нет в списке тех, что умеют `DecompressionStream`) и что с этим делать — пустая
53
- * таблица не сказала бы читателю ничего. */
54
51
  unpack: 'Данные отчёта сжаты, а браузер не умеет их распаковать: в нём нет DecompressionStream. '
55
52
  + 'Обновите браузер — таблицу показывать не из чего.',
56
53
  note: 'Абсолютные размеры стоят один раз — в строке «{now}». Строк: {rows}: коммиты без '
package/src/metrics.js CHANGED
@@ -58,9 +58,6 @@ const STYLES = {
58
58
  }
59
59
  };
60
60
 
61
- /* Метрика объявляет, нужен ли ей текст блоба: `needsText: false` вместе с
62
- * `fromSize: true` означает «хватит размера объекта», и тогда содержимое не
63
- * читается вовсе (`git cat-file --batch` не вызывается). */
64
61
  export const METRICS = {
65
62
  raw: {
66
63
  label: 'raw',
@@ -208,7 +205,7 @@ function esbuildLoader(file, cfg) {
208
205
  /* The engine actually in force: the requested one may be unavailable, in which case the metric
209
206
  * counts another way — and that is announced (`sensorGaps`), or a different count would travel
210
207
  * into CI as the requested one. */
211
- export function minEngine(cfg) {
208
+ function minEngine(cfg) {
212
209
  if (cfg.minify.engine !== 'esbuild') return 'strip';
213
210
  return minifier().tool === null ? 'strip' : 'esbuild';
214
211
  }
package/src/page/table.js CHANGED
@@ -8,8 +8,8 @@ import { appData, appUi, appView } from './state.js';
8
8
  *
9
9
  * **Why not a `<table>`.** Measured on this repository's own report (238 500 cells = 370 758 nodes, a table 71 712 ×
10
10
  * 5 982 px): about 1.4 GB of a browser's memory, of which roughly half the nodes and half the painted area, and a
11
- * browser's relayout of it costs close to a second on any switch (`probes/step-12-columns.mjs`). `content-visibility:
12
- * auto`, the cheap way out, is ignored on a table row by Chrome 153 (`probes/step-10-tables.mjs`), so the answer is
11
+ * browser's relayout of it costs close to a second on any switch (`probes/archive/step-12-columns.mjs`). `content-visibility:
12
+ * auto`, the cheap way out, is ignored on a table row by Chrome 153 (`probes/archive/step-10-tables.mjs`), so the answer is
13
13
  * to build less rather than to promise the browser will skip it. A grid of `position: absolute` rows has no layout to
14
14
  * be redone: a row is placed by its `top`, a column by the `left` of the group of cells that starts it, and the
15
15
  * browser never measures a cell to decide a width — every column is `--col` wide (70px), which is what the numbers
@@ -36,7 +36,7 @@ import { appData, appUi, appView } from './state.js';
36
36
  * numbers, so a step sideways makes the columns that entered and drops the ones that left (`appStrip`) — a cell per
37
37
  * row, the header's two lines included. A row that left the window vertically is dropped and made again when the
38
38
  * reader comes back to it, which is what makes a jump down the table cost the same as a step. Building the rows again
39
- * on every sideways scroll — the first version of this step — is what `probes/step-12-window.mjs` measures against the
39
+ * on every sideways scroll — the first version of this step — is what `probes/archive/step-12-window.mjs` measures against the
40
40
  * splice (`worklog/0211-sideways-step.md`).
41
41
  *
42
42
  * The choice is applied by building the window again: the columns of a switched-off file are simply not among the
package/src/project.js CHANGED
@@ -204,7 +204,7 @@ function columnsOf(files, journal) {
204
204
  }
205
205
 
206
206
  export function projectConfig(root) {
207
- const output = outputOf(root);
207
+ const output = outputOf();
208
208
  const journal = journalOf(root);
209
209
  const files = allPaths(root);
210
210
  /* Only what git tracks becomes a column: a file absent at HEAD has nothing to measure (it would be
package/src/refusal.js CHANGED
@@ -28,8 +28,8 @@ export function refuse(code, message) {
28
28
  }
29
29
 
30
30
  /* The causes of a code-2 refusal in one list, and this is the only place where they are
31
- * spelled out: the help prints them from it, the code table in `README.md` is checked
32
- * against it (`test/docs-commands.test.js`), and `refuseCause` lets no refusal through
31
+ * spelled out: the help prints them from it, the code table in `docs/archive/README_old.md` is
32
+ * checked against it (`test/docs-commands.test.js`), and `refuseCause` lets no refusal through
33
33
  * without a named cause. So "the documentation says less than happens" cannot pass here
34
34
  * silently. The groups say where a cause comes from: the command line, settings and the
35
35
  * project, history, the hook, measurement. */
@@ -133,5 +133,5 @@ export const USAGE = [
133
133
  'internal error. doctor has an order of its own: 2, 3, 1, 4 — by the weight of a finding',
134
134
  'rather than by what came first.',
135
135
  '',
136
- 'Causes of a code-2 refusal (the code table in README.md names them too):'
136
+ 'Causes of a code-2 refusal:'
137
137
  ].concat(CAUSE_LINES, ['']).join('\n');
package/src/strip/js.js CHANGED
@@ -59,16 +59,21 @@ function regexAllowed(last, word) {
59
59
  return '([{,;:=!&|?+-*%~^<>'.indexOf(last) !== -1;
60
60
  }
61
61
 
62
- function takeRegex(s) {
63
- if (s.src[s.i] !== '/' || !regexAllowed(s.last, s.word)) return false;
64
- const end = endOfRegex(s.src, s.i);
62
+ /* A token taken whole: it goes into the output and the pass state is advanced over it — the token itself, not the word
63
+ * before it, decides where a regex may stand next, and the word being read ends with it. */
64
+ function take(s, end, last) {
65
65
  s.out += s.src.slice(s.i, end);
66
66
  s.i = end;
67
- s.last = '/';
67
+ s.last = last;
68
68
  s.word = '';
69
69
  return true;
70
70
  }
71
71
 
72
+ function takeRegex(s) {
73
+ if (s.src[s.i] !== '/' || !regexAllowed(s.last, s.word)) return false;
74
+ return take(s, endOfRegex(s.src, s.i), '/');
75
+ }
76
+
72
77
  function endOfRegex(src, start) {
73
78
  let i = start + 1;
74
79
  let inClass = false;
@@ -88,12 +93,7 @@ function endOfRegex(src, start) {
88
93
  function takeString(s) {
89
94
  const quote = s.src[s.i];
90
95
  if (quote !== '"' && quote !== "'" && quote !== '`') return false;
91
- const end = endOfString(s.src, s.i, quote);
92
- s.out += s.src.slice(s.i, end);
93
- s.i = end;
94
- s.last = quote;
95
- s.word = '';
96
- return true;
96
+ return take(s, endOfString(s.src, s.i, quote), quote);
97
97
  }
98
98
 
99
99
  function endOfString(src, start, quote) {
package/src/tokens.js CHANGED
@@ -28,7 +28,7 @@ export const CHARS_PER_TOKEN = 3;
28
28
  * and the tokenizer would split them into anything at all, giving a random number. The list
29
29
  * exists so that the metric says this in words instead of passing such a count off as counted.
30
30
  * SVG is deliberately not here: it is text, and its tokens are meaningful. */
31
- export const BINARY_EXTS = [
31
+ const BINARY_EXTS = [
32
32
  '.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico', '.avif',
33
33
  '.woff', '.woff2', '.ttf', '.otf', '.eot',
34
34
  '.pdf', '.zip', '.gz', '.tar', '.mp4', '.mp3', '.mov'
@@ -83,5 +83,5 @@ well. About a single commit `pnpm exec size explain <sha>` answers.
83
83
 
84
84
  A block for the project's own agent files (`AGENTS.md` and the like) is deliberately absent here: the
85
85
  requirements do not ask for such a file, and inventing the format of someone else's repository is not
86
- something the tool should do. What an agent needs to know it will take from `size --help` and `size --data` —
87
- the commands and the data are described in the package's `README.md`, section "For an AI agent".
86
+ something the tool should do. What an agent needs to know it will take from `size --help` and
87
+ `size --data` — the commands and the data are described there rather than in a file of the tool's own.