fidelity-kit 0.1.0 → 0.2.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 +133 -5
- package/dist/commands/build.d.ts +2 -0
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +6 -2
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/dev.d.ts +7 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +9 -2
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/hash.d.ts +2 -0
- package/dist/commands/hash.d.ts.map +1 -1
- package/dist/commands/hash.js +7 -3
- package/dist/commands/hash.js.map +1 -1
- package/dist/commands/process.d.ts +6 -0
- package/dist/commands/process.d.ts.map +1 -1
- package/dist/commands/process.js +35 -7
- package/dist/commands/process.js.map +1 -1
- package/dist/commands/serve.d.ts +3 -1
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +2 -1
- package/dist/commands/serve.js.map +1 -1
- package/dist/core/compare.d.ts +4 -2
- package/dist/core/compare.d.ts.map +1 -1
- package/dist/core/compare.js +7 -5
- package/dist/core/compare.js.map +1 -1
- package/dist/core/hash.d.ts +2 -0
- package/dist/core/hash.d.ts.map +1 -1
- package/dist/core/hash.js +37 -10
- package/dist/core/hash.js.map +1 -1
- package/dist/core/hash.test.js +8 -1
- package/dist/core/hash.test.js.map +1 -1
- package/dist/core/process.d.ts +52 -3
- package/dist/core/process.d.ts.map +1 -1
- package/dist/core/process.js +450 -51
- package/dist/core/process.js.map +1 -1
- package/dist/core/process.test.d.ts +2 -0
- package/dist/core/process.test.d.ts.map +1 -0
- package/dist/core/process.test.js +269 -0
- package/dist/core/process.test.js.map +1 -0
- package/dist/core/progress.d.ts +8 -0
- package/dist/core/progress.d.ts.map +1 -0
- package/dist/core/progress.js +2 -0
- package/dist/core/progress.js.map +1 -0
- package/dist/core/scan.d.ts +8 -1
- package/dist/core/scan.d.ts.map +1 -1
- package/dist/core/scan.js +72 -7
- package/dist/core/scan.js.map +1 -1
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +8 -2
- package/dist/core/schema.js.map +1 -1
- package/dist/core/suite.test.js +61 -2
- package/dist/core/suite.test.js.map +1 -1
- package/dist/progress.d.ts +12 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +46 -0
- package/dist/progress.js.map +1 -0
- package/dist/progress.test.d.ts +2 -0
- package/dist/progress.test.d.ts.map +1 -0
- package/dist/progress.test.js +36 -0
- package/dist/progress.test.js.map +1 -0
- package/dist/run.d.ts +4 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +34 -6
- package/dist/run.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +25 -2
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +55 -2
- package/dist/server.test.js.map +1 -1
- package/dist/watch.d.ts +9 -0
- package/dist/watch.d.ts.map +1 -0
- package/dist/watch.js +96 -0
- package/dist/watch.js.map +1 -0
- package/dist/watch.test.d.ts +2 -0
- package/dist/watch.test.d.ts.map +1 -0
- package/dist/watch.test.js +138 -0
- package/dist/watch.test.js.map +1 -0
- package/package.json +11 -1
- package/viewer/assets/{ViewControls-hn4PfGV3.js → ViewControls-Ck9smy3A.js} +2 -2
- package/viewer/assets/_-Bn1LyOgm.js +1 -0
- package/viewer/assets/{index-D9G4C6Ns.js → index-BZCd8VsK.js} +2 -2
- package/viewer/assets/index-VKD_ZeZu.css +2 -0
- package/viewer/assets/{routes-DmeR6gGl.js → routes-sEPFkb5w.js} +1 -1
- package/viewer/index.html +2 -2
- package/dist/.tsbuildinfo +0 -1
- package/viewer/assets/_-BAkV94Fq.js +0 -1
- package/viewer/assets/index-D8YJNCs_.css +0 -2
package/README.md
CHANGED
|
@@ -1,15 +1,143 @@
|
|
|
1
1
|
# fidelity-kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[![NPM Package][npm]][npm-url]
|
|
4
|
+
[![NPM Downloads][npm-downloads]][npmtrends-url]
|
|
5
|
+
[![Tests][tests-badge]][tests-url]
|
|
6
|
+
[![Coverage][coverage-badge]][coverage-url]
|
|
7
|
+
[![Discord][discord-badge]][discord-url]
|
|
8
|
+
|
|
9
|
+
**Compare renderer output without building a comparison site.** fidelity-kit turns a folder of AVIF renders into image quality metrics, visual difference images, and a browsable website. Use it for rendering fidelity suites, visual regression reviews, and side-by-side comparisons of a renderer against one or more references.
|
|
10
|
+
|
|
11
|
+
Your renderer writes images; fidelity-kit handles the comparisons and viewer. Run the viewer locally while developing, serve the results from a container, or export a static site.
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
If you already have a results folder in the format below:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npx fidelity-kit dev results
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Open the URL printed by the command (usually <http://localhost:3000>). `dev` processes new or changed images before starting and serves files without browser caching, so a reload shows your latest render. See the [working example](https://github.com/bhouston/fidelity-kit/tree/main/examples/demo) for a complete suite.
|
|
22
|
+
|
|
23
|
+
## Adopt it in your suite
|
|
24
|
+
|
|
25
|
+
Create a `results` directory with a `fidelity.json` file. Put each scene in its own folder, with one AVIF image per renderer under each output name:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
results/
|
|
29
|
+
fidelity.json
|
|
30
|
+
README.md optional introduction shown in the viewer
|
|
31
|
+
materials/
|
|
32
|
+
brushed-metal/
|
|
33
|
+
README.md optional scene description
|
|
34
|
+
scene.json optional title and tags
|
|
35
|
+
beauty/
|
|
36
|
+
reference.avif
|
|
37
|
+
my-renderer.avif
|
|
38
|
+
ao/
|
|
39
|
+
reference.avif
|
|
40
|
+
my-renderer.avif
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Folders can have as many group levels as you need. A scene is any folder containing an image at `<output>/<renderer>.avif` for names declared in `fidelity.json`. Missing renderer images are allowed; the viewer marks them as missing. Other files, such as scene sources and textures, can live alongside the images.
|
|
44
|
+
|
|
45
|
+
Start with this configuration:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"title": "My Renderer Comparisons",
|
|
50
|
+
"renderers": [
|
|
51
|
+
{ "id": "reference", "label": "Reference", "reference": true },
|
|
52
|
+
{ "id": "my-renderer", "label": "My Renderer" }
|
|
53
|
+
],
|
|
54
|
+
"outputs": [{ "id": "beauty" }, { "id": "ao", "label": "Ambient occlusion" }],
|
|
55
|
+
"delta": true
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Mark at least one renderer as a reference. You can declare multiple references; the viewer lets readers choose which one to compare against. Renderer and output IDs must use lowercase letters, numbers, `.`, `_`, or `-`, and start with a letter or number. `outputs` defaults to `beauty` if omitted. Set `delta` to `false` if you only want metrics and the original images.
|
|
60
|
+
|
|
61
|
+
For searchable scene labels, add a `scene.json` next to a scene's images:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{ "title": "Brushed metal", "tags": ["metal", "roughness"] }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Use it during development
|
|
68
|
+
|
|
69
|
+
Install the CLI in your suite repository, or use `npx fidelity-kit` for occasional runs:
|
|
4
70
|
|
|
5
71
|
```sh
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
npx fidelity-kit build <results-dir> --out site/ # static export
|
|
72
|
+
pnpm add -D fidelity-kit
|
|
73
|
+
pnpm exec fidelity-kit dev results
|
|
9
74
|
```
|
|
10
75
|
|
|
11
|
-
|
|
76
|
+
The CLI supports this workflow:
|
|
77
|
+
|
|
78
|
+
| Command | Use |
|
|
79
|
+
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
80
|
+
| `fidelity-kit process results` | Generate comparison metrics, optional delta images, and the viewer index. Reruns update only stale comparisons; add `--force` to recompute all. |
|
|
81
|
+
| `fidelity-kit dev results` | Process stale comparisons, then open a local viewer with caching disabled. |
|
|
82
|
+
| `fidelity-kit serve results` | Process stale comparisons, then serve the viewer with browser and CDN caching. |
|
|
83
|
+
| `fidelity-kit build results --out site/` | Process stale comparisons and export a site for static hosting. |
|
|
84
|
+
|
|
85
|
+
`process` computes PSNR, RMSE, MAE, and maximum error for each available comparison. Reference and renderer images in a pair must have the same dimensions. Both `dev` and `serve` start at `localhost:3000` and try higher ports if one is occupied; use `--port` to require a specific port and `--host` to change the bind address. The actual viewer URL is printed at startup. To serve results already processed during a build, pass `--no-process`.
|
|
86
|
+
|
|
87
|
+
`process`, `dev`, and `hash` show scanning and processing progress on one updating terminal line, including the remaining count and an approximate ETA. Use `--quiet` to suppress progress and summary output; errors are still reported.
|
|
88
|
+
|
|
89
|
+
For example, add scripts to your suite's `package.json`:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"scripts": {
|
|
94
|
+
"fidelity:dev": "fidelity-kit dev results",
|
|
95
|
+
"fidelity:build": "fidelity-kit build results --out site/"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
You can deploy `site/` to any static host. The site includes the viewer and its data, so it does not need a Node server.
|
|
101
|
+
|
|
102
|
+
## Serve it from Docker
|
|
103
|
+
|
|
104
|
+
Process and hash the results while building the image, then start the server without repeating that work:
|
|
105
|
+
|
|
106
|
+
```dockerfile
|
|
107
|
+
FROM node:24-slim
|
|
108
|
+
|
|
109
|
+
RUN npm install -g fidelity-kit
|
|
110
|
+
COPY results /data
|
|
111
|
+
RUN fidelity-kit process /data && fidelity-kit hash /data
|
|
112
|
+
|
|
113
|
+
EXPOSE 8080
|
|
114
|
+
CMD ["fidelity-kit", "serve", "/data", "--host", "0.0.0.0", "--port", "8080", "--no-process"]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
docker build -t my-fidelity-site .
|
|
119
|
+
docker run --rm -p 8080:8080 my-fidelity-site
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Open <http://localhost:8080>. `hash` prepares versioned image URLs so repeat visits can reuse cached images from the first request. If your results change at runtime, run `serve` without `--no-process` to refresh comparisons at startup; `hash` is optional in that case.
|
|
12
123
|
|
|
13
124
|
## Author and sponsor
|
|
14
125
|
|
|
15
126
|
Created by [Ben Houston](https://github.com/bhouston) and sponsored by [Land of Assets](https://landofassets.com).
|
|
127
|
+
|
|
128
|
+
[npm]: https://img.shields.io/npm/v/fidelity-kit
|
|
129
|
+
[npm-url]: https://www.npmjs.com/package/fidelity-kit
|
|
130
|
+
[npm-downloads]: https://img.shields.io/npm/dw/fidelity-kit
|
|
131
|
+
[npmtrends-url]: https://www.npmtrends.com/fidelity-kit
|
|
132
|
+
[tests-badge]: https://github.com/bhouston/fidelity-kit/actions/workflows/ci.yml/badge.svg
|
|
133
|
+
[tests-url]: https://github.com/bhouston/fidelity-kit/actions/workflows/ci.yml
|
|
134
|
+
[coverage-badge]: https://codecov.io/gh/bhouston/fidelity-kit/branch/main/graph/badge.svg
|
|
135
|
+
[coverage-url]: https://codecov.io/gh/bhouston/fidelity-kit
|
|
136
|
+
[discord-badge]: https://img.shields.io/badge/Discord-Join-5865F2?logo=discord&logoColor=white
|
|
137
|
+
[discord-url]: https://discord.gg/5J5Ur3F6Z2
|
|
138
|
+
|
|
139
|
+
### Incremental processing
|
|
140
|
+
|
|
141
|
+
`process --watch` and `dev` retain per-scene dependencies, batch source changes, and share the configured `--concurrency` limit. Scenes and renderer/reference images can be added or removed while watching. Restart after changing renderer IDs, output/pass IDs, or other settings in `fidelity.json`.
|
|
142
|
+
|
|
143
|
+
Input freshness uses modification time and byte size recorded in metrics files. Older-dated replacements are detected; changes preserving both values require `--force`. Metrics without saved input signatures are regenerated once. Generated metrics, delta images, index files, and temporary writes are ignored by the watcher. Removed comparisons are dropped from the index; generated files may remain on disk.
|
package/dist/commands/build.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO;;;;;;;;EA+BlB,CAAC"}
|
package/dist/commands/build.js
CHANGED
|
@@ -14,13 +14,17 @@ export const command = defineCommand({
|
|
|
14
14
|
describe: 'Suite results directory (contains fidelity.json)',
|
|
15
15
|
})
|
|
16
16
|
.option('out', { type: 'string', demandOption: true, describe: 'Output directory' })
|
|
17
|
+
.option('concurrency', { type: 'number', describe: 'Image pairs compared in parallel (default: CPU count)' })
|
|
17
18
|
.option('process', { type: 'boolean', default: true, describe: 'Refresh stale metrics/deltas first' }),
|
|
18
19
|
handler: async (argv) => {
|
|
19
20
|
assertViewerBuilt();
|
|
20
21
|
const root = resolve(argv.root);
|
|
21
22
|
const out = resolve(argv.out);
|
|
22
|
-
if (argv.process)
|
|
23
|
-
await processSuite(root);
|
|
23
|
+
if (argv.process) {
|
|
24
|
+
const result = await processSuite(root, { concurrency: argv.concurrency });
|
|
25
|
+
if (result.failed.length)
|
|
26
|
+
throw new Error(`Failed to compare ${result.failed.length} image pair(s): ${result.failed.map((f) => `${f.file}: ${f.error}`).join('; ')}`);
|
|
27
|
+
}
|
|
24
28
|
await cp(viewerDir, out, { recursive: true });
|
|
25
29
|
await cp(root, `${out}/data`, {
|
|
26
30
|
recursive: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAExE,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC;IACnC,OAAO,EAAE,cAAc;IACvB,QAAQ,EAAE,kEAAkE;IAC5E,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,UAAU,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,kDAAkD;KAC7D,CAAC;SACD,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;SACnF,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,oCAAoC,EAAE,CAAC;IAC1G,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,iBAAiB,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,OAAO;
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAExE,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC;IACnC,OAAO,EAAE,cAAc;IACvB,QAAQ,EAAE,kEAAkE;IAC5E,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,UAAU,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,kDAAkD;KAC7D,CAAC;SACD,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;SACnF,MAAM,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,uDAAuD,EAAE,CAAC;SAC5G,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,oCAAoC,EAAE,CAAC;IAC1G,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,iBAAiB,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YAC3E,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM;gBACtB,MAAM,IAAI,KAAK,CACb,qBAAqB,MAAM,CAAC,MAAM,CAAC,MAAM,mBAAmB,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC3H,CAAC;QACN,CAAC;QACD,MAAM,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,EAAE;YAC5B,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;SAChG,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;IAC7C,CAAC;CACF,CAAC,CAAC"}
|
package/dist/commands/dev.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
export declare const command: import("yargs-file-commands").DefineCommandResult<{}, {
|
|
2
2
|
root: string;
|
|
3
3
|
} & {
|
|
4
|
-
port: number;
|
|
4
|
+
port: number | undefined;
|
|
5
5
|
} & {
|
|
6
6
|
host: string;
|
|
7
|
+
} & {
|
|
8
|
+
concurrency: number | undefined;
|
|
9
|
+
} & {
|
|
10
|
+
quiet: boolean;
|
|
7
11
|
} & {
|
|
8
12
|
process: boolean;
|
|
13
|
+
} & {
|
|
14
|
+
watch: boolean;
|
|
9
15
|
}>;
|
|
10
16
|
//# sourceMappingURL=dev.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,OAAO;;;;;;;;;;;;;;EAqBlB,CAAC"}
|
package/dist/commands/dev.js
CHANGED
|
@@ -9,9 +9,16 @@ export const command = defineCommand({
|
|
|
9
9
|
demandOption: true,
|
|
10
10
|
describe: 'Suite results directory (contains fidelity.json)',
|
|
11
11
|
})
|
|
12
|
-
.option('port', { type: 'number',
|
|
12
|
+
.option('port', { type: 'number', describe: 'Port to listen on (default: first open port from 3000)' })
|
|
13
13
|
.option('host', { type: 'string', default: 'localhost', describe: 'Interface to bind (0.0.0.0 for all)' })
|
|
14
|
-
.option('
|
|
14
|
+
.option('concurrency', { type: 'number', describe: 'Image pairs compared in parallel (default: CPU count)' })
|
|
15
|
+
.option('quiet', { type: 'boolean', default: false, describe: 'Suppress progress and summary output' })
|
|
16
|
+
.option('process', { type: 'boolean', default: true, describe: 'Refresh stale metrics/deltas before serving' })
|
|
17
|
+
.option('watch', {
|
|
18
|
+
type: 'boolean',
|
|
19
|
+
default: true,
|
|
20
|
+
describe: 'Keep metrics, deltas, and index updated as results change',
|
|
21
|
+
}),
|
|
15
22
|
handler: (argv) => run(argv, true),
|
|
16
23
|
});
|
|
17
24
|
//# sourceMappingURL=dev.js.map
|
package/dist/commands/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhC,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC;IACnC,OAAO,EAAE,YAAY;IACrB,QAAQ,EAAE,kGAAkG;IAC5G,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,UAAU,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,kDAAkD;KAC7D,CAAC;SACD,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhC,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC;IACnC,OAAO,EAAE,YAAY;IACrB,QAAQ,EAAE,kGAAkG;IAC5G,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,UAAU,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,kDAAkD;KAC7D,CAAC;SACD,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,wDAAwD,EAAE,CAAC;SACtG,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,qCAAqC,EAAE,CAAC;SACzG,MAAM,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,uDAAuD,EAAE,CAAC;SAC5G,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,sCAAsC,EAAE,CAAC;SACtG,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,6CAA6C,EAAE,CAAC;SAC9G,MAAM,CAAC,OAAO,EAAE;QACf,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,2DAA2D;KACtE,CAAC;IACN,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC;CACnC,CAAC,CAAC"}
|
package/dist/commands/hash.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/commands/hash.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/commands/hash.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO;;;;;;EAuBlB,CAAC"}
|
package/dist/commands/hash.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { availableParallelism } from 'node:os';
|
|
2
2
|
import { defineCommand } from 'yargs-file-commands';
|
|
3
3
|
import { hashSuite } from '../core/index.js';
|
|
4
|
+
import { createProgress } from '../progress.js';
|
|
4
5
|
export const command = defineCommand({
|
|
5
6
|
command: 'hash <root>',
|
|
6
7
|
describe: 'Write image-hashes.json so `serve` can use immutable, content-hashed image URLs from the first request',
|
|
@@ -14,10 +15,13 @@ export const command = defineCommand({
|
|
|
14
15
|
type: 'number',
|
|
15
16
|
default: availableParallelism(),
|
|
16
17
|
describe: 'Files hashed in parallel (default: os.availableParallelism())',
|
|
17
|
-
})
|
|
18
|
+
})
|
|
19
|
+
.option('quiet', { type: 'boolean', default: false, describe: 'Suppress progress and summary output' }),
|
|
18
20
|
handler: async (argv) => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
+
const progress = createProgress('hash', argv.quiet);
|
|
22
|
+
const r = await hashSuite(argv.root, { concurrency: argv.concurrency, onProgress: progress.update }).finally(progress.finish);
|
|
23
|
+
if (!argv.quiet)
|
|
24
|
+
console.log(`${r.hashed} hashed, ${r.reused} reused, ${r.total} total`);
|
|
21
25
|
},
|
|
22
26
|
});
|
|
23
27
|
//# sourceMappingURL=hash.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/commands/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/commands/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC;IACnC,OAAO,EAAE,aAAa;IACtB,QAAQ,EAAE,wGAAwG;IAClH,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,UAAU,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,kDAAkD;KAC7D,CAAC;SACD,MAAM,CAAC,aAAa,EAAE;QACrB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,oBAAoB,EAAE;QAC/B,QAAQ,EAAE,+DAA+D;KAC1E,CAAC;SACD,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,sCAAsC,EAAE,CAAC;IAC3G,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAC1G,QAAQ,CAAC,MAAM,CAChB,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,YAAY,CAAC,CAAC,MAAM,YAAY,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC;IAC3F,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
export declare const command: import("yargs-file-commands").DefineCommandResult<{}, {
|
|
2
2
|
root: string;
|
|
3
|
+
} & {
|
|
4
|
+
concurrency: number | undefined;
|
|
5
|
+
} & {
|
|
6
|
+
quiet: boolean;
|
|
3
7
|
} & {
|
|
4
8
|
force: boolean;
|
|
9
|
+
} & {
|
|
10
|
+
watch: boolean;
|
|
5
11
|
}>;
|
|
6
12
|
//# sourceMappingURL=process.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/commands/process.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/commands/process.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,OAAO;;;;;;;;;;EAkClB,CAAC"}
|
package/dist/commands/process.js
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { processSuite } from '../core/index.js';
|
|
2
2
|
import { defineCommand } from 'yargs-file-commands';
|
|
3
|
+
import { watchResults } from '../watch.js';
|
|
4
|
+
import { createProgress } from '../progress.js';
|
|
5
|
+
function report(r, quiet) {
|
|
6
|
+
if (!quiet)
|
|
7
|
+
console.log(`${r.computed} computed, ${r.skipped} up to date, ${r.failed.length} failed`);
|
|
8
|
+
for (const f of r.failed)
|
|
9
|
+
console.error(`FAILED ${f.file}: ${f.error}`);
|
|
10
|
+
if (r.failed.length)
|
|
11
|
+
process.exitCode = 1;
|
|
12
|
+
}
|
|
3
13
|
export const command = defineCommand({
|
|
4
14
|
command: 'process <root>',
|
|
5
15
|
describe: 'Compute metrics + delta images for stale pairs and write index.json',
|
|
@@ -9,14 +19,32 @@ export const command = defineCommand({
|
|
|
9
19
|
demandOption: true,
|
|
10
20
|
describe: 'Suite results directory (contains fidelity.json)',
|
|
11
21
|
})
|
|
12
|
-
.option('
|
|
22
|
+
.option('concurrency', { type: 'number', describe: 'Image pairs compared in parallel (default: CPU count)' })
|
|
23
|
+
.option('quiet', { type: 'boolean', default: false, describe: 'Suppress progress and summary output' })
|
|
24
|
+
.option('force', { type: 'boolean', default: false, describe: 'Recompute even when up to date' })
|
|
25
|
+
.option('watch', {
|
|
26
|
+
type: 'boolean',
|
|
27
|
+
default: false,
|
|
28
|
+
describe: 'Keep metrics, deltas, and index updated as results change',
|
|
29
|
+
}),
|
|
13
30
|
handler: async (argv) => {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
31
|
+
const progress = createProgress('process', argv.quiet);
|
|
32
|
+
const options = {
|
|
33
|
+
force: argv.force,
|
|
34
|
+
concurrency: argv.concurrency,
|
|
35
|
+
onProgress: progress.update,
|
|
36
|
+
};
|
|
37
|
+
const onResult = (result) => {
|
|
38
|
+
progress.finish();
|
|
39
|
+
report(result, argv.quiet);
|
|
40
|
+
};
|
|
41
|
+
if (argv.watch) {
|
|
42
|
+
await watchResults(argv.root, onResult, options);
|
|
43
|
+
if (!argv.quiet)
|
|
44
|
+
console.log(`Watching ${argv.root}`);
|
|
45
|
+
}
|
|
46
|
+
else
|
|
47
|
+
onResult(await processSuite(argv.root, options).finally(progress.finish));
|
|
20
48
|
},
|
|
21
49
|
});
|
|
22
50
|
//# sourceMappingURL=process.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/commands/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/commands/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAsB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,SAAS,MAAM,CAAC,CAAgB,EAAE,KAAc;IAC9C,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,cAAc,CAAC,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC;IACtG,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;QAAE,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IACxE,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC;IACnC,OAAO,EAAE,gBAAgB;IACzB,QAAQ,EAAE,qEAAqE;IAC/E,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,UAAU,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,kDAAkD;KAC7D,CAAC;SACD,MAAM,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,uDAAuD,EAAE,CAAC;SAC5G,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,sCAAsC,EAAE,CAAC;SACtG,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,gCAAgC,EAAE,CAAC;SAChG,MAAM,CAAC,OAAO,EAAE;QACf,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,2DAA2D;KACtE,CAAC;IACN,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG;YACd,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,QAAQ,CAAC,MAAM;SAC5B,CAAC;QACF,MAAM,QAAQ,GAAG,CAAC,MAAqB,EAAE,EAAE;YACzC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAC;QACF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;;YAAM,QAAQ,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACnF,CAAC;CACF,CAAC,CAAC"}
|
package/dist/commands/serve.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export declare const command: import("yargs-file-commands").DefineCommandResult<{}, {
|
|
2
2
|
root: string;
|
|
3
3
|
} & {
|
|
4
|
-
port: number;
|
|
4
|
+
port: number | undefined;
|
|
5
5
|
} & {
|
|
6
6
|
host: string;
|
|
7
7
|
} & {
|
|
8
8
|
"max-age": number;
|
|
9
9
|
} & {
|
|
10
10
|
"stale-while-revalidate": number;
|
|
11
|
+
} & {
|
|
12
|
+
concurrency: number | undefined;
|
|
11
13
|
} & {
|
|
12
14
|
process: boolean;
|
|
13
15
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,OAAO;;;;;;;;;;;;;;EAyBlB,CAAC"}
|
package/dist/commands/serve.js
CHANGED
|
@@ -10,7 +10,7 @@ export const command = defineCommand({
|
|
|
10
10
|
demandOption: true,
|
|
11
11
|
describe: 'Suite results directory (contains fidelity.json)',
|
|
12
12
|
})
|
|
13
|
-
.option('port', { type: 'number',
|
|
13
|
+
.option('port', { type: 'number', describe: 'Port to listen on (default: first open port from 3000)' })
|
|
14
14
|
.option('host', { type: 'string', default: 'localhost', describe: 'Interface to bind (0.0.0.0 for all)' })
|
|
15
15
|
.option('max-age', {
|
|
16
16
|
type: 'number',
|
|
@@ -22,6 +22,7 @@ export const command = defineCommand({
|
|
|
22
22
|
default: defaultCachePolicy.staleWhileRevalidate,
|
|
23
23
|
describe: 'Seconds a stale image may be served while it refreshes in the background',
|
|
24
24
|
})
|
|
25
|
+
.option('concurrency', { type: 'number', describe: 'Image pairs compared in parallel (default: CPU count)' })
|
|
25
26
|
.option('process', { type: 'boolean', default: true, describe: 'Refresh stale metrics/deltas before serving' }),
|
|
26
27
|
handler: (argv) => run(argv, false),
|
|
27
28
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC;IACnC,OAAO,EAAE,cAAc;IACvB,QAAQ,EAAE,gFAAgF;IAC1F,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,UAAU,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,kDAAkD;KAC7D,CAAC;SACD,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC;IACnC,OAAO,EAAE,cAAc;IACvB,QAAQ,EAAE,gFAAgF;IAC1F,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,UAAU,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,kDAAkD;KAC7D,CAAC;SACD,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,wDAAwD,EAAE,CAAC;SACtG,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,qCAAqC,EAAE,CAAC;SACzG,MAAM,CAAC,SAAS,EAAE;QACjB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,kBAAkB,CAAC,MAAM;QAClC,QAAQ,EAAE,oEAAoE;KAC/E,CAAC;SACD,MAAM,CAAC,wBAAwB,EAAE;QAChC,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,kBAAkB,CAAC,oBAAoB;QAChD,QAAQ,EAAE,0EAA0E;KACrF,CAAC;SACD,MAAM,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,uDAAuD,EAAE,CAAC;SAC5G,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,6CAA6C,EAAE,CAAC;IACnH,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC;CACpC,CAAC,CAAC"}
|
package/dist/core/compare.d.ts
CHANGED
|
@@ -22,8 +22,10 @@ export declare function compareRgb(reference: RawImage, test: RawImage): {
|
|
|
22
22
|
metrics: ImageMetrics;
|
|
23
23
|
delta: RawImage;
|
|
24
24
|
};
|
|
25
|
-
/** Compares two encoded images (paths or buffers); returns metrics and the delta encoded like the renders. */
|
|
26
|
-
export declare function compareImages(reference: string | Buffer, test: string | Buffer
|
|
25
|
+
/** Compares two encoded images (paths or buffers); returns metrics and the delta encoded like the renders (an empty buffer when disabled). */
|
|
26
|
+
export declare function compareImages(reference: string | Buffer, test: string | Buffer, options?: {
|
|
27
|
+
delta?: boolean;
|
|
28
|
+
}): Promise<{
|
|
27
29
|
metrics: ImageMetrics;
|
|
28
30
|
width: number;
|
|
29
31
|
height: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/core/compare.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kIAAkI;AAClI,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,gJAAgJ;AAChJ,eAAO,MAAM,WAAW;aAAK,OAAO,EAAE,EAAE;aAAE,iBAAiB,EAAE,OAAO;CAAW,CAAC;AAEhF,8EAA8E;AAC9E,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAOvE;AA0BD,2GAA2G;AAC3G,wBAAgB,UAAU,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,GAAG;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAmC1G;AAED,
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/core/compare.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kIAAkI;AAClI,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,gJAAgJ;AAChJ,eAAO,MAAM,WAAW;aAAK,OAAO,EAAE,EAAE;aAAE,iBAAiB,EAAE,OAAO;CAAW,CAAC;AAEhF,8EAA8E;AAC9E,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAOvE;AA0BD,2GAA2G;AAC3G,wBAAgB,UAAU,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,GAAG;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAmC1G;AAED,8IAA8I;AAC9I,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAUvF"}
|
package/dist/core/compare.js
CHANGED
|
@@ -69,13 +69,15 @@ export function compareRgb(reference, test) {
|
|
|
69
69
|
delta: { data: delta, width: reference.width, height: reference.height },
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
|
-
/** Compares two encoded images (paths or buffers); returns metrics and the delta encoded like the renders. */
|
|
73
|
-
export async function compareImages(reference, test) {
|
|
72
|
+
/** Compares two encoded images (paths or buffers); returns metrics and the delta encoded like the renders (an empty buffer when disabled). */
|
|
73
|
+
export async function compareImages(reference, test, options = {}) {
|
|
74
74
|
const [ref, tst] = await Promise.all([readRgb(reference), readRgb(test)]);
|
|
75
75
|
const { metrics, delta } = compareRgb(ref, tst);
|
|
76
|
-
const deltaImage =
|
|
77
|
-
.
|
|
78
|
-
.
|
|
76
|
+
const deltaImage = options.delta === false
|
|
77
|
+
? Buffer.alloc(0)
|
|
78
|
+
: await sharp(delta.data, { raw: { width: delta.width, height: delta.height, channels: 3 } })
|
|
79
|
+
.avif(RESULT_AVIF)
|
|
80
|
+
.toBuffer();
|
|
79
81
|
return { metrics, width: ref.width, height: ref.height, deltaImage };
|
|
80
82
|
}
|
|
81
83
|
//# sourceMappingURL=compare.js.map
|
package/dist/core/compare.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/core/compare.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/core/compare.ts"],"names":[],"mappings":"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"}
|
package/dist/core/hash.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProgressCallback } from './progress.js';
|
|
1
2
|
export declare const HASHES_FILE = "image-hashes.json";
|
|
2
3
|
export interface HashEntry {
|
|
3
4
|
hash: string;
|
|
@@ -16,6 +17,7 @@ export interface HashSuiteOptions {
|
|
|
16
17
|
concurrency?: number;
|
|
17
18
|
/** Injectable for tests. */
|
|
18
19
|
hash?: (path: string) => Promise<string>;
|
|
20
|
+
onProgress?: ProgressCallback;
|
|
19
21
|
}
|
|
20
22
|
export interface HashSuiteResult {
|
|
21
23
|
hashed: number;
|
package/dist/core/hash.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/core/hash.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/core/hash.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,eAAO,MAAM,WAAW,sBAAsB,CAAC;AAE/C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAOD;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5D;AAED,gHAAgH;AAChH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAMnF;AAED,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AACD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAoDnG"}
|
package/dist/core/hash.js
CHANGED
|
@@ -42,24 +42,51 @@ export async function hashSuite(root, opts = {}) {
|
|
|
42
42
|
const { concurrency = availableParallelism(), hash = hashFile } = opts;
|
|
43
43
|
const limit = pLimit(Math.max(1, Math.floor(concurrency)));
|
|
44
44
|
const previous = await readHashFile(root);
|
|
45
|
-
const rels =
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
const rels = [];
|
|
46
|
+
const pending = [''];
|
|
47
|
+
let scanned = 0;
|
|
48
|
+
const scanProgress = () => opts.onProgress?.({ phase: 'Scanning', completed: scanned, total: scanned + pending.length, unit: 'directories' });
|
|
49
|
+
scanProgress();
|
|
50
|
+
while (pending.length) {
|
|
51
|
+
const dir = pending.pop();
|
|
52
|
+
for (const entry of await readdir(join(root, dir), { withFileTypes: true })) {
|
|
53
|
+
const rel = dir ? `${dir}/${entry.name}` : entry.name;
|
|
54
|
+
if (entry.name.startsWith('.'))
|
|
55
|
+
continue;
|
|
56
|
+
if (entry.isDirectory())
|
|
57
|
+
pending.push(rel);
|
|
58
|
+
else if (entry.isFile() && rel.endsWith('.avif') && isDataFile(rel))
|
|
59
|
+
rels.push(rel);
|
|
60
|
+
}
|
|
61
|
+
scanned++;
|
|
62
|
+
scanProgress();
|
|
63
|
+
}
|
|
64
|
+
rels.sort();
|
|
49
65
|
let reused = 0;
|
|
66
|
+
let completed = 0;
|
|
67
|
+
const hashProgress = () => opts.onProgress?.({ phase: 'Hashing', completed, total: rels.length, unit: 'images' });
|
|
68
|
+
hashProgress();
|
|
50
69
|
const entries = await Promise.all(rels.map((rel) => limit(async () => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
try {
|
|
71
|
+
const s = await stat(join(root, rel));
|
|
72
|
+
const old = previous[rel];
|
|
73
|
+
if (old && old.size === s.size && old.mtimeMs === s.mtimeMs) {
|
|
74
|
+
reused++;
|
|
75
|
+
return [rel, old];
|
|
76
|
+
}
|
|
77
|
+
return [rel, { hash: await hash(join(root, rel)), size: s.size, mtimeMs: s.mtimeMs }];
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
completed++;
|
|
81
|
+
hashProgress();
|
|
56
82
|
}
|
|
57
|
-
return [rel, { hash: await hash(join(root, rel)), size: s.size, mtimeMs: s.mtimeMs }];
|
|
58
83
|
})));
|
|
59
84
|
const out = join(root, HASHES_FILE);
|
|
85
|
+
opts.onProgress?.({ phase: 'Writing hashes', completed: 0, total: 1, unit: 'files' });
|
|
60
86
|
const tmp = `${out}.${process.pid}.tmp`;
|
|
61
87
|
await writeFile(tmp, `${JSON.stringify({ version: 1, files: Object.fromEntries(entries) }, null, 2)}\n`);
|
|
62
88
|
await rename(tmp, out);
|
|
89
|
+
opts.onProgress?.({ phase: 'Writing hashes', completed: 1, total: 1, unit: 'files' });
|
|
63
90
|
return { hashed: entries.length - reused, reused, total: entries.length };
|
|
64
91
|
}
|
|
65
92
|
//# sourceMappingURL=hash.js.map
|
package/dist/core/hash.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/core/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAClC,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/core/hash.ts"],"names":[],"mappings":"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"}
|