@fusion.dev/helix-diagnostics 0.140.0 → 0.142.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 +59 -1
- package/dist/index.d.ts +1 -1
- package/dist/report.d.ts +55 -8
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -126,6 +126,54 @@ The address is always on a local host.
|
|
|
126
126
|
`[::1]`, `*.localhost`, and `*.test`. It listens on `127.0.0.1`, so nothing
|
|
127
127
|
else on your network reaches it, and production pages never send to it.
|
|
128
128
|
|
|
129
|
+
## Scan your code
|
|
130
|
+
|
|
131
|
+
`helix scan` reads every stylesheet, template, and module in your repository,
|
|
132
|
+
judges them against the lint data of the Helix packages you installed, and
|
|
133
|
+
writes one run in the shape a page writes, with `source: "code"`:
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
npx helix scan
|
|
137
|
+
npx helix scan --build dist --out reports/helix-diagnostics.json
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- **Each finding has its file and line**, and the kind and fingerprint a page
|
|
141
|
+
gives the same fault, so a dashboard joins the two.
|
|
142
|
+
- **It reads every file, and so every route.** A page sees the routes someone
|
|
143
|
+
opened, so a scan is the better count of what your project uses. An element
|
|
144
|
+
written once counts once, however many times it renders, and
|
|
145
|
+
`usage.counted` is `scanned`.
|
|
146
|
+
- **What only a page can settle is `unsettled`.** A hook set on a Helix tag
|
|
147
|
+
that does not have it works where an element with the hook is inside that
|
|
148
|
+
tag, and only the running page shows whether one is. The scan lists these
|
|
149
|
+
apart, each with the fingerprint the page's finding would have, and they
|
|
150
|
+
never fail the scan.
|
|
151
|
+
- **It reads** CSS, Sass, and Less files; HTML, Vue, Svelte, and Astro
|
|
152
|
+
templates; MDX outside its code samples; and JavaScript and TypeScript, for
|
|
153
|
+
JSX, Lit's `html` and `css` templates, and Angular's inline templates. A
|
|
154
|
+
file that does not parse, and a stylesheet in Sass's indented syntax or
|
|
155
|
+
Stylus, is listed in `coverage.unreadable`.
|
|
156
|
+
- **It leaves out** what `.gitignore` leaves out, the folders a build or a
|
|
157
|
+
package manager writes, and tests: a name with `.test.` or `.spec.`, and
|
|
158
|
+
anything under `__tests__`.
|
|
159
|
+
- **An attribute is checked where the code writes it as one.** In
|
|
160
|
+
`tone="primary"`, the name and the value are checked. Lit's `tone=${...}`
|
|
161
|
+
writes the attribute, so its name is checked. An expression in JSX, Svelte,
|
|
162
|
+
or Angular, and Vue's `:tone`, set a property where the element has one, so
|
|
163
|
+
none of them is checked.
|
|
164
|
+
- **With `--build`, it weighs your bundle**: what each Helix family and
|
|
165
|
+
package adds to it, from its source maps, as `performance.weight`. Turn
|
|
166
|
+
source maps on in your bundler, and pass the folder it writes the browser's
|
|
167
|
+
files to, such as `dist` or `.next/static`.
|
|
168
|
+
- **With `--out`, it writes its run to the CI file**, and keeps the runs
|
|
169
|
+
`helix diagnostics` wrote there. The relay keeps the scan's run the same
|
|
170
|
+
way, so the two share one file, in either order.
|
|
171
|
+
|
|
172
|
+
It reads `helix-diagnostics.json` from the project, then from the directory it
|
|
173
|
+
runs in, or the file `--config <path>` names, and refuses a setting that names
|
|
174
|
+
nothing, as the page does. It exits 1 on a finding at `error`, and 3 where the
|
|
175
|
+
project installs no Helix lint data. `--json` prints the run.
|
|
176
|
+
|
|
129
177
|
## Run it once, directly
|
|
130
178
|
|
|
131
179
|
`diagnose()` is one run, which `initDiagnostics()` makes for you. Call it
|
|
@@ -169,9 +217,12 @@ A report is one run, in one shape for every sink, versioned by `schema`:
|
|
|
169
217
|
severity, the tag and its family, a `category` (`styling`, `markup`,
|
|
170
218
|
`integrity`, or `guideline`), an `owner` (`consumer`, or `helix` for a fault
|
|
171
219
|
in the library), a `fingerprint` that stays the same from one run to the next
|
|
172
|
-
for the same fault, and the rule's own text as evidence.
|
|
220
|
+
for the same fault, and the rule's own text as evidence. A scan's findings
|
|
221
|
+
also have the file's `line`.
|
|
173
222
|
- **`performance`**: what the components cost, by tag, where you asked for it.
|
|
174
223
|
See [Performance](#performance).
|
|
224
|
+
- **`unsettled`**: from a scan, the faults only a page can settle. See
|
|
225
|
+
[Scan your code](#scan-your-code).
|
|
175
226
|
- **`runtime`**: what the library reported going wrong as it ran on the page,
|
|
176
227
|
from its first load. One entry per distinct event, with its `kind`, its
|
|
177
228
|
`tag`, the sentence that says what to do, how many times it was reported,
|
|
@@ -284,6 +335,9 @@ that has not asked pays one property read per element. Layout shift and long
|
|
|
284
335
|
tasks are measured in Chromium only. Elsewhere `measured` says so, and their
|
|
285
336
|
numbers are left out.
|
|
286
337
|
|
|
338
|
+
What each family adds to your bundle is measured from the code, by
|
|
339
|
+
`helix scan --build`, as `weight`. See [Scan your code](#scan-your-code).
|
|
340
|
+
|
|
287
341
|
## Configure it
|
|
288
342
|
|
|
289
343
|
Every setting can be given in three places, and a later place wins, field by
|
|
@@ -357,6 +411,10 @@ A fault found on many pages is one line, with the pages it was on. `error`
|
|
|
357
411
|
findings fail the job by default; pass `failOn: 'warn'` to fail on warnings
|
|
358
412
|
too, or `'never'` to report without failing.
|
|
359
413
|
|
|
414
|
+
`ciSink` writes the whole file, so to add a run from your code, run
|
|
415
|
+
`helix scan --out` with the same file after it. The scan keeps the runs it
|
|
416
|
+
finds there.
|
|
417
|
+
|
|
360
418
|
## Versions
|
|
361
419
|
|
|
362
420
|
`@fusion.dev/helix-core` lists its version on the page as it loads, and every
|
package/dist/index.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ export { fingerprintOf, normalize } from './identity.js';
|
|
|
35
35
|
export { type Diagnostics, INSTANCE, type InitOptions, initDiagnostics } from './init.js';
|
|
36
36
|
export type { LintData, LintTag, ManifestSource, Published, Tier } from './manifest.js';
|
|
37
37
|
export { index, lintOf, nearest } from './manifest.js';
|
|
38
|
-
export type { Category, Configuration, Coverage, Environment, Finding, FindingCategory, Kind, Layer, Origin, Owner, Report, Severity, Unreadable, Usage, } from './report.js';
|
|
38
|
+
export type { Category, Configuration, Coverage, Environment, Finding, FindingCategory, Kind, Layer, Origin, Owner, Report, Severity, Unreadable, Usage, Weight, } from './report.js';
|
|
39
39
|
export { CATEGORIES, KINDS } from './report.js';
|
|
40
40
|
export { type Override, type Rules, SHIPPED_RULES } from './rules.js';
|
|
41
41
|
export { TIMING, type Timing } from './schedule.js';
|
package/dist/report.d.ts
CHANGED
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
/** Where a rule was read from, so a reader can go and look at it. */
|
|
14
14
|
export interface Origin {
|
|
15
15
|
/**
|
|
16
|
-
* The rule's own text, which is the receipt.
|
|
16
|
+
* The rule's own text, which is the receipt. For a scan's finding about
|
|
17
|
+
* an attribute, the opening tag's text.
|
|
17
18
|
*
|
|
18
|
-
* **
|
|
19
|
+
* **A page has no line number and cannot have one.** CSSOM exposes
|
|
19
20
|
* `cssText` and an index within the sheet; the byte offset in the authored
|
|
20
21
|
* file is not in the object model at any level. A line was asked for, and
|
|
21
22
|
* this is the honest substitute: the text of the rule is what a
|
|
@@ -23,9 +24,18 @@ export interface Origin {
|
|
|
23
24
|
* line number would not.
|
|
24
25
|
*/
|
|
25
26
|
cssText: string;
|
|
26
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Position within the sheet's own rule list, for a sheet with repeats. For
|
|
29
|
+
* a scan's finding about an attribute, the element's position in the file.
|
|
30
|
+
*/
|
|
27
31
|
index: number;
|
|
28
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* The line the rule's first declaration, or the element's opening tag, is
|
|
34
|
+
* on, counting from 1. A scan reads the file, so its findings have one. A
|
|
35
|
+
* page's never do.
|
|
36
|
+
*/
|
|
37
|
+
line?: number;
|
|
38
|
+
/** The sheet's `href`, or a description of why it has none. For a scan, the file's path. */
|
|
29
39
|
sheet: string;
|
|
30
40
|
}
|
|
31
41
|
/**
|
|
@@ -109,6 +119,23 @@ export type Identified = Omit<Finding, 'decidedBy' | 'severity'>;
|
|
|
109
119
|
export declare const CATEGORIES: readonly ['assist', 'configuration', 'coverage', 'findings', 'performance', 'runtime', 'usage'];
|
|
110
120
|
/** A kind of telemetry. */
|
|
111
121
|
export type Category = (typeof CATEGORIES)[number];
|
|
122
|
+
/**
|
|
123
|
+
* What each Helix family adds to a build, measured by `helix scan --build`
|
|
124
|
+
* from the build's source maps, in bytes before compression.
|
|
125
|
+
*/
|
|
126
|
+
export interface Weight {
|
|
127
|
+
/** The bytes from each family's folder, across the tiers. */
|
|
128
|
+
families: Record<string, number>;
|
|
129
|
+
/** The bundle files read with a source map, and without one, which cannot be split. */
|
|
130
|
+
files: {
|
|
131
|
+
mapped: number;
|
|
132
|
+
unmapped: number;
|
|
133
|
+
};
|
|
134
|
+
/** The bytes from each Helix package. */
|
|
135
|
+
packages: Record<string, number>;
|
|
136
|
+
/** Every byte in the bundle files read, Helix or not. */
|
|
137
|
+
total: number;
|
|
138
|
+
}
|
|
112
139
|
/**
|
|
113
140
|
* What the components cost on a page, by tag, where a project asked for it.
|
|
114
141
|
*/
|
|
@@ -140,6 +167,12 @@ export interface PerformanceReport {
|
|
|
140
167
|
/** The layout shift its elements moved, summed as the browser scores it. */
|
|
141
168
|
shift: number;
|
|
142
169
|
}>;
|
|
170
|
+
/**
|
|
171
|
+
* What each family adds to the build, from a scan given the build. A scan
|
|
172
|
+
* measures nothing in a browser, so its `measured` is false and its `tags`
|
|
173
|
+
* are empty.
|
|
174
|
+
*/
|
|
175
|
+
weight?: Weight;
|
|
143
176
|
}
|
|
144
177
|
/**
|
|
145
178
|
* A runtime event as a run holds it: what `@fusion.dev/helix-core` reported
|
|
@@ -168,9 +201,14 @@ export interface RuntimeEntry {
|
|
|
168
201
|
}
|
|
169
202
|
/** Where a run was declared to happen. Undeclared is never sent. */
|
|
170
203
|
export type Environment = 'ci' | 'development' | 'production';
|
|
171
|
-
/**
|
|
204
|
+
/**
|
|
205
|
+
* A sheet the collector could not read, and the reason. For a scan, a file
|
|
206
|
+
* that did not parse is `threw`, and a stylesheet in a language the scan does
|
|
207
|
+
* not read, such as Sass's indented syntax or Stylus, is `unsupported`.
|
|
208
|
+
*/
|
|
172
209
|
export interface Unreadable {
|
|
173
|
-
reason: 'cross-origin' | 'detached' | 'threw';
|
|
210
|
+
reason: 'cross-origin' | 'detached' | 'threw' | 'unsupported';
|
|
211
|
+
/** The sheet's `href`, or for a scan, the file's path. */
|
|
174
212
|
sheet: string;
|
|
175
213
|
}
|
|
176
214
|
/**
|
|
@@ -183,6 +221,8 @@ export interface Unreadable {
|
|
|
183
221
|
* hole this reports rather than steps over.
|
|
184
222
|
*/
|
|
185
223
|
export interface Coverage {
|
|
224
|
+
/** Files read, for a scan: stylesheets, templates, and modules. */
|
|
225
|
+
files?: number;
|
|
186
226
|
/** Sheets whose rules were read end to end. */
|
|
187
227
|
read: number;
|
|
188
228
|
/** Shadow roots entered, including nested ones. */
|
|
@@ -214,9 +254,10 @@ export interface Usage {
|
|
|
214
254
|
* How the elements were counted. `watched`: every element that rendered
|
|
215
255
|
* since `watch()` began, including the ones that have gone, such as a
|
|
216
256
|
* closed dialog. `walked`: the elements in the page at the moment of the
|
|
217
|
-
* run, which misses those.
|
|
257
|
+
* run, which misses those. `scanned`: each element written in the code, by
|
|
258
|
+
* `helix scan`, counted once however many times it renders.
|
|
218
259
|
*/
|
|
219
|
-
counted: 'walked' | 'watched';
|
|
260
|
+
counted: 'scanned' | 'walked' | 'watched';
|
|
220
261
|
/** Each hook the page's stylesheets set, by tag, counted per declaration. */
|
|
221
262
|
hooks: Record<string, Record<string, number>>;
|
|
222
263
|
/**
|
|
@@ -321,6 +362,12 @@ export interface Report {
|
|
|
321
362
|
* first load: one entry per distinct event, counted.
|
|
322
363
|
*/
|
|
323
364
|
runtime: RuntimeEntry[];
|
|
365
|
+
/**
|
|
366
|
+
* The faults a scan found and only a page can settle, such as a hook set
|
|
367
|
+
* on an element for one inside it, each with the fingerprint the page's
|
|
368
|
+
* finding would have. A scan's alone.
|
|
369
|
+
*/
|
|
370
|
+
unsettled?: Identified[];
|
|
324
371
|
/**
|
|
325
372
|
* The project's own name and labels, as its configuration gives them. The
|
|
326
373
|
* key is never written into a report.
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.142.0';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-diagnostics",
|
|
3
3
|
"description": "Finds the Helix mistakes that are valid CSS: dead parts, misnamed hooks, two copies of the library.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.142.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@fusion.dev/helix-testing": "0.
|
|
36
|
+
"@fusion.dev/helix-testing": "0.142.0",
|
|
37
37
|
"@types/bun": "^1.3.0"
|
|
38
38
|
},
|
|
39
39
|
"homepage": "https://fusion.dev",
|