fidelity-kit 0.2.0 → 1.0.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 +11 -12
- package/dist/core/compare.d.ts +13 -4
- package/dist/core/compare.d.ts.map +1 -1
- package/dist/core/compare.js +12 -7
- package/dist/core/compare.js.map +1 -1
- package/dist/core/hash.d.ts +1 -1
- package/dist/core/hash.js +3 -3
- package/dist/core/hash.js.map +1 -1
- package/dist/core/hash.test.js +16 -0
- package/dist/core/hash.test.js.map +1 -1
- package/dist/core/paths.d.ts +5 -2
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/paths.js +6 -3
- package/dist/core/paths.js.map +1 -1
- package/dist/core/process.d.ts +2 -0
- package/dist/core/process.d.ts.map +1 -1
- package/dist/core/process.js +69 -35
- package/dist/core/process.js.map +1 -1
- package/dist/core/process.test.js +145 -5
- package/dist/core/process.test.js.map +1 -1
- package/dist/core/scan.d.ts +3 -1
- package/dist/core/scan.d.ts.map +1 -1
- package/dist/core/scan.js +45 -23
- package/dist/core/scan.js.map +1 -1
- package/dist/core/schema.d.ts +0 -1
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +0 -1
- package/dist/core/schema.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -3
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +31 -0
- package/dist/server.test.js.map +1 -1
- package/dist/watch.test.js +34 -1
- package/dist/watch.test.js.map +1 -1
- package/package.json +1 -1
- package/viewer/assets/{ViewControls-Ck9smy3A.js → ViewControls-DEU3XE_l.js} +2 -2
- package/viewer/assets/{_-Bn1LyOgm.js → _-C4WPVjTH.js} +1 -1
- package/viewer/assets/{index-BZCd8VsK.js → index-DgTxNUtG.js} +2 -2
- package/viewer/assets/index-aFK_LL0Z.css +2 -0
- package/viewer/assets/{routes-sEPFkb5w.js → routes-Mb9xRfeQ.js} +1 -1
- package/viewer/index.html +2 -2
- package/viewer/assets/index-VKD_ZeZu.css +0 -2
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ results/
|
|
|
40
40
|
my-renderer.avif
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
Folders can have as many group levels as you need. A scene is any folder containing an image at `<output>/<renderer
|
|
43
|
+
Folders can have as many group levels as you need. A scene is any folder containing an image at `<output>/<renderer>.<extension>` for names declared in `fidelity.json`. Supported input extensions are `.avif`, `.webp`, `.png`, and `.jpg`; when several files match a renderer, that order determines which one is used. Formats can be mixed across renderers and outputs. 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
44
|
|
|
45
45
|
Start with this configuration:
|
|
46
46
|
|
|
@@ -51,12 +51,11 @@ Start with this configuration:
|
|
|
51
51
|
{ "id": "reference", "label": "Reference", "reference": true },
|
|
52
52
|
{ "id": "my-renderer", "label": "My Renderer" }
|
|
53
53
|
],
|
|
54
|
-
"outputs": [{ "id": "beauty" }, { "id": "ao", "label": "Ambient occlusion" }]
|
|
55
|
-
"delta": true
|
|
54
|
+
"outputs": [{ "id": "beauty" }, { "id": "ao", "label": "Ambient occlusion" }]
|
|
56
55
|
}
|
|
57
56
|
```
|
|
58
57
|
|
|
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.
|
|
58
|
+
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. Every comparison generates metrics and a delta image. Legacy `delta` settings are ignored.
|
|
60
59
|
|
|
61
60
|
For searchable scene labels, add a `scene.json` next to a scene's images:
|
|
62
61
|
|
|
@@ -75,14 +74,14 @@ pnpm exec fidelity-kit dev results
|
|
|
75
74
|
|
|
76
75
|
The CLI supports this workflow:
|
|
77
76
|
|
|
78
|
-
| Command | Use
|
|
79
|
-
| ---------------------------------------- |
|
|
80
|
-
| `fidelity-kit process results` | Generate comparison metrics,
|
|
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.
|
|
77
|
+
| Command | Use |
|
|
78
|
+
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
79
|
+
| `fidelity-kit process results` | Generate comparison metrics, delta images, and the viewer index. Reruns update only stale comparisons; add `--force` to recompute all. |
|
|
80
|
+
| `fidelity-kit dev results` | Process stale comparisons, then open a local viewer with caching disabled. |
|
|
81
|
+
| `fidelity-kit serve results` | Process stale comparisons, then serve the viewer with browser and CDN caching. |
|
|
82
|
+
| `fidelity-kit build results --out site/` | Process stale comparisons and export a site for static hosting. |
|
|
84
83
|
|
|
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`.
|
|
84
|
+
`process` computes PSNR, RMSE, MAE, and maximum error for each available comparison. Heatmaps are encoded as lossy WebP at quality 85 and effort 4 (`<renderer>.vs-<reference>.delta.webp`) to reduce file size; source images keep their original formats, and metrics are computed from the source pixels before heatmap compression. Existing cached heatmaps are retained; run `fidelity-kit process results --force` to regenerate them with this setting. 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
85
|
|
|
87
86
|
`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
87
|
|
|
@@ -140,4 +139,4 @@ Created by [Ben Houston](https://github.com/bhouston) and sponsored by [Land of
|
|
|
140
139
|
|
|
141
140
|
`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
141
|
|
|
143
|
-
Input freshness uses modification
|
|
142
|
+
Input freshness uses the existing modification-time and byte-size signatures, with the selected filename identifying each input. Metrics keep their signatures in the metrics JSON; heatmaps keep theirs separately in `<renderer>.vs-<reference>.delta.webp.json`. These heatmap cache sidecars are not served or exported. Each artifact is checked independently: replacing a missing or stale heatmap preserves current metrics, and refreshing metrics does not re-encode a current heatmap. Older-dated replacements are detected; changes preserving both values require `--force`. Metrics without saved input signatures are regenerated once. Upgrading from AVIF heatmaps generates WebP heatmaps once while retaining current metrics; old AVIF heatmaps may remain on disk. Existing indexes still work with `--no-process`. 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/core/compare.d.ts
CHANGED
|
@@ -15,6 +15,11 @@ export declare const RESULT_AVIF: {
|
|
|
15
15
|
readonly quality: 90;
|
|
16
16
|
readonly chromaSubsampling: '4:4:4';
|
|
17
17
|
};
|
|
18
|
+
/** Heatmaps trade minor visual differences for smaller files at modest encoding cost. */
|
|
19
|
+
export declare const DELTA_WEBP: {
|
|
20
|
+
readonly quality: 85;
|
|
21
|
+
readonly effort: 4;
|
|
22
|
+
};
|
|
18
23
|
/** Decodes an image (path or encoded buffer) to 8-bit RGB, dropping alpha. */
|
|
19
24
|
export declare function readRgb(input: string | Buffer): Promise<RawImage>;
|
|
20
25
|
/** Computes metrics and an RGB heat-map delta image (black = identical) from two equal-size RGB images. */
|
|
@@ -22,10 +27,14 @@ export declare function compareRgb(reference: RawImage, test: RawImage): {
|
|
|
22
27
|
metrics: ImageMetrics;
|
|
23
28
|
delta: RawImage;
|
|
24
29
|
};
|
|
25
|
-
/**
|
|
26
|
-
export declare function
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
/** Computes metrics without encoding an already-cached heatmap. */
|
|
31
|
+
export declare function measureImages(reference: string | Buffer, test: string | Buffer): Promise<{
|
|
32
|
+
metrics: ImageMetrics;
|
|
33
|
+
width: number;
|
|
34
|
+
height: number;
|
|
35
|
+
}>;
|
|
36
|
+
/** Compares two encoded images; returns metrics and a quality-85 WebP heatmap. */
|
|
37
|
+
export declare function compareImages(reference: string | Buffer, test: string | Buffer): Promise<{
|
|
29
38
|
metrics: ImageMetrics;
|
|
30
39
|
width: number;
|
|
31
40
|
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,yFAAyF;AACzF,eAAO,MAAM,UAAU;aAAK,OAAO,EAAE,EAAE;aAAE,MAAM,EAAE,CAAC;CAAW,CAAC;AAE9D,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,mEAAmE;AACnE,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;;;;GAGpF;AAED,kFAAkF;AAClF,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,GAAG,MAAM,EAC1B,IAAI,EAAE,MAAM,GAAG,MAAM,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAOvF"}
|
package/dist/core/compare.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import sharp from 'sharp';
|
|
2
2
|
/** Encoding for committed result images: near-lossless (worst render ~40 dB PSNR vs PNG), full-res chroma so noise and false colour survive. */
|
|
3
3
|
export const RESULT_AVIF = { quality: 90, chromaSubsampling: '4:4:4' };
|
|
4
|
+
/** Heatmaps trade minor visual differences for smaller files at modest encoding cost. */
|
|
5
|
+
export const DELTA_WEBP = { quality: 85, effort: 4 };
|
|
4
6
|
/** Decodes an image (path or encoded buffer) to 8-bit RGB, dropping alpha. */
|
|
5
7
|
export async function readRgb(input) {
|
|
6
8
|
const { data, info } = await sharp(input)
|
|
@@ -69,15 +71,18 @@ export function compareRgb(reference, test) {
|
|
|
69
71
|
delta: { data: delta, width: reference.width, height: reference.height },
|
|
70
72
|
};
|
|
71
73
|
}
|
|
72
|
-
/**
|
|
73
|
-
export async function
|
|
74
|
+
/** Computes metrics without encoding an already-cached heatmap. */
|
|
75
|
+
export async function measureImages(reference, test) {
|
|
76
|
+
const [ref, tst] = await Promise.all([readRgb(reference), readRgb(test)]);
|
|
77
|
+
return { metrics: compareRgb(ref, tst).metrics, width: ref.width, height: ref.height };
|
|
78
|
+
}
|
|
79
|
+
/** Compares two encoded images; returns metrics and a quality-85 WebP heatmap. */
|
|
80
|
+
export async function compareImages(reference, test) {
|
|
74
81
|
const [ref, tst] = await Promise.all([readRgb(reference), readRgb(test)]);
|
|
75
82
|
const { metrics, delta } = compareRgb(ref, tst);
|
|
76
|
-
const deltaImage =
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
.avif(RESULT_AVIF)
|
|
80
|
-
.toBuffer();
|
|
83
|
+
const deltaImage = await sharp(delta.data, { raw: { width: delta.width, height: delta.height, channels: 3 } })
|
|
84
|
+
.webp(DELTA_WEBP)
|
|
85
|
+
.toBuffer();
|
|
81
86
|
return { metrics, width: ref.width, height: ref.height, deltaImage };
|
|
82
87
|
}
|
|
83
88
|
//# 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":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAgB1B,gJAAgJ;AAChJ,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,OAAO,EAAW,CAAC;AAEhF,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAsB;IAClD,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC;SACtC,WAAW,EAAE;SACb,aAAa,CAAC,MAAM,CAAC;SACrB,GAAG,EAAE;SACL,QAAQ,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAC1D,CAAC;AAED,qFAAqF;AACrF,MAAM,OAAO,GAAG;IACd,CAAC,qBAAqB,EAAE,oBAAoB,EAAE,CAAC,mBAAmB,CAAC;IACnE,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,iBAAiB,CAAC;IAC3D,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,EAAE,CAAC,gBAAgB,CAAC;IAC1D,CAAC,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;IAC1D,CAAC,eAAe,EAAE,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,CAAC;IACzD,CAAC,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;IAC1D,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,CAAC;CACnD,CAAC;AAEX,SAAS,OAAO,CAAC,CAAS;IACxB,MAAM,GAAG,GAA6B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;YAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC;QAC7E,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iHAAiH;AACjH,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtG,2GAA2G;AAC3G,MAAM,UAAU,UAAU,CAAC,SAAmB,EAAE,IAAc;IAC5D,IAAI,SAAS,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CACb,kCAAkC,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,MAAM,YAAY,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAC7G,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;YAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;YACf,MAAM,IAAI,CAAC,CAAC;YACZ,IAAI,CAAC,GAAG,QAAQ;gBAAE,QAAQ,GAAG,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,QAAQ,GAAG,GAAG;YAAE,GAAG,GAAG,QAAQ,CAAC;QACnC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAE,CAAC;QACvC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACb,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QACjB,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC;IACtB,OAAO;QACL,OAAO,EAAE;YACP,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;YAC3D,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG;YAC1B,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,GAAG;YACrB,QAAQ,EAAE,GAAG,GAAG,GAAG;SACpB;QACD,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE;KACzE,CAAC;AACJ,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/core/compare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAgB1B,gJAAgJ;AAChJ,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,OAAO,EAAW,CAAC;AAEhF,yFAAyF;AACzF,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAW,CAAC;AAE9D,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAsB;IAClD,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC;SACtC,WAAW,EAAE;SACb,aAAa,CAAC,MAAM,CAAC;SACrB,GAAG,EAAE;SACL,QAAQ,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAC1D,CAAC;AAED,qFAAqF;AACrF,MAAM,OAAO,GAAG;IACd,CAAC,qBAAqB,EAAE,oBAAoB,EAAE,CAAC,mBAAmB,CAAC;IACnE,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,iBAAiB,CAAC;IAC3D,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,EAAE,CAAC,gBAAgB,CAAC;IAC1D,CAAC,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;IAC1D,CAAC,eAAe,EAAE,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,CAAC;IACzD,CAAC,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;IAC1D,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,CAAC;CACnD,CAAC;AAEX,SAAS,OAAO,CAAC,CAAS;IACxB,MAAM,GAAG,GAA6B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;YAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC;QAC7E,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iHAAiH;AACjH,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtG,2GAA2G;AAC3G,MAAM,UAAU,UAAU,CAAC,SAAmB,EAAE,IAAc;IAC5D,IAAI,SAAS,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CACb,kCAAkC,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,MAAM,YAAY,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAC7G,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;YAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;YACf,MAAM,IAAI,CAAC,CAAC;YACZ,IAAI,CAAC,GAAG,QAAQ;gBAAE,QAAQ,GAAG,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,QAAQ,GAAG,GAAG;YAAE,GAAG,GAAG,QAAQ,CAAC;QACnC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAE,CAAC;QACvC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACb,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QACjB,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC;IACtB,OAAO;QACL,OAAO,EAAE;YACP,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;YAC3D,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG;YAC1B,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,GAAG;YACrB,QAAQ,EAAE,GAAG,GAAG,GAAG;SACpB;QACD,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE;KACzE,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAA0B,EAAE,IAAqB;IACnF,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1E,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;AACzF,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,SAA0B,EAC1B,IAAqB;IAErB,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1E,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;SAC3G,IAAI,CAAC,UAAU,CAAC;SAChB,QAAQ,EAAE,CAAC;IACd,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;AACvE,CAAC"}
|
package/dist/core/hash.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export interface HashSuiteResult {
|
|
|
25
25
|
total: number;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
* Writes `<root>/image-hashes.json` for every served
|
|
28
|
+
* Writes `<root>/image-hashes.json` for every served image. Incremental: an entry whose size and mtimeMs are unchanged
|
|
29
29
|
* is reused without reading the file. Output is sorted and timestamp-free, so unchanged files give identical bytes.
|
|
30
30
|
*/
|
|
31
31
|
export declare function hashSuite(root: string, opts?: HashSuiteOptions): Promise<HashSuiteResult>;
|
package/dist/core/hash.js
CHANGED
|
@@ -5,7 +5,7 @@ import { join, resolve } from 'node:path';
|
|
|
5
5
|
import { crc32 } from 'node:zlib';
|
|
6
6
|
import pLimit from 'p-limit';
|
|
7
7
|
import { z } from 'zod';
|
|
8
|
-
import { isDataFile } from './paths.js';
|
|
8
|
+
import { isDataFile, isImageFile } from './paths.js';
|
|
9
9
|
export const HASHES_FILE = 'image-hashes.json';
|
|
10
10
|
const fileSchema = z.object({
|
|
11
11
|
version: z.literal(1),
|
|
@@ -34,7 +34,7 @@ export async function readHashFile(root) {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
|
-
* Writes `<root>/image-hashes.json` for every served
|
|
37
|
+
* Writes `<root>/image-hashes.json` for every served image. Incremental: an entry whose size and mtimeMs are unchanged
|
|
38
38
|
* is reused without reading the file. Output is sorted and timestamp-free, so unchanged files give identical bytes.
|
|
39
39
|
*/
|
|
40
40
|
export async function hashSuite(root, opts = {}) {
|
|
@@ -55,7 +55,7 @@ export async function hashSuite(root, opts = {}) {
|
|
|
55
55
|
continue;
|
|
56
56
|
if (entry.isDirectory())
|
|
57
57
|
pending.push(rel);
|
|
58
|
-
else if (entry.isFile() && rel
|
|
58
|
+
else if (entry.isFile() && isImageFile(rel) && isDataFile(rel))
|
|
59
59
|
rels.push(rel);
|
|
60
60
|
}
|
|
61
61
|
scanned++;
|
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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"}
|
package/dist/core/hash.test.js
CHANGED
|
@@ -75,4 +75,20 @@ test('hash concurrency never exceeds the limit', async () => {
|
|
|
75
75
|
await hashSuite(root, { concurrency: 1, hash });
|
|
76
76
|
expect(peak).toBe(1);
|
|
77
77
|
});
|
|
78
|
+
test('hashes all supported source formats and WebP heatmaps without cache sidecars', async () => {
|
|
79
|
+
const root = await suite();
|
|
80
|
+
for (const name of ['z.webp', 'z.png', 'z.jpg', 'z.vs-ref.delta.webp', 'z.vs-ref.delta.webp.json', 'z.webp.tmp'])
|
|
81
|
+
await writeFile(join(root, 'a/beauty', name), name);
|
|
82
|
+
expect(await hashSuite(root)).toMatchObject({ hashed: 7, total: 7 });
|
|
83
|
+
expect(Object.keys((await read(root)).files)).toEqual([
|
|
84
|
+
'a/beauty/x.avif',
|
|
85
|
+
'a/beauty/y.avif',
|
|
86
|
+
'a/beauty/z.jpg',
|
|
87
|
+
'a/beauty/z.png',
|
|
88
|
+
'a/beauty/z.vs-ref.delta.webp',
|
|
89
|
+
'a/beauty/z.webp',
|
|
90
|
+
'b/beauty/x.avif',
|
|
91
|
+
]);
|
|
92
|
+
expect(await hashSuite(root)).toMatchObject({ hashed: 0, reused: 7 });
|
|
93
|
+
});
|
|
78
94
|
//# sourceMappingURL=hash.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.test.js","sourceRoot":"","sources":["../../src/core/hash.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hash.test.js","sourceRoot":"","sources":["../../src/core/hash.test.ts"],"names":[],"mappings":"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"}
|
package/dist/core/paths.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export declare const IMAGE_EXT = ".avif";
|
|
2
|
-
|
|
2
|
+
/** Preferred source formats, in selection order. */
|
|
3
|
+
export declare const IMAGE_EXTENSIONS: readonly ['.avif', '.webp', '.png', '.jpg'];
|
|
4
|
+
export declare const imageFile: (renderer: string, extension?: string) => string;
|
|
5
|
+
export declare const isImageFile: (file: string) => boolean;
|
|
3
6
|
export declare const metricsFile: (renderer: string, reference: string) => string;
|
|
4
|
-
export declare const deltaFile: (renderer: string, reference: string) => string;
|
|
7
|
+
export declare const deltaFile: (renderer: string, reference: string, extension?: '.webp' | '.avif') => string;
|
|
5
8
|
/** The only suite files the viewer may read; also what `build` exports and `hash` covers. */
|
|
6
9
|
export declare function isDataFile(rel: string): boolean;
|
|
7
10
|
//# sourceMappingURL=paths.d.ts.map
|
package/dist/core/paths.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,SAAS,aAAc,MAAM,
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,oDAAoD;AACpD,eAAO,MAAM,gBAAgB,YAAI,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAC5E,eAAO,MAAM,SAAS,aAAc,MAAM,cAAa,MAAM,WAA0C,CAAC;AACxG,eAAO,MAAM,WAAW,SAAU,MAAM,YAAmE,CAAC;AAC5G,eAAO,MAAM,WAAW,aAAc,MAAM,aAAa,MAAM,WAA+C,CAAC;AAC/G,eAAO,MAAM,SAAS,aAAc,MAAM,aAAa,MAAM,cAAa,OAAO,GAAG,OAAO,WAC1C,CAAC;AAElD,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG/C"}
|
package/dist/core/paths.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
// Client-safe file naming (no node imports): shared by the CLI and the viewer.
|
|
2
2
|
export const IMAGE_EXT = '.avif';
|
|
3
|
-
|
|
3
|
+
/** Preferred source formats, in selection order. */
|
|
4
|
+
export const IMAGE_EXTENSIONS = ['.avif', '.webp', '.png', '.jpg'];
|
|
5
|
+
export const imageFile = (renderer, extension = IMAGE_EXT) => `${renderer}${extension}`;
|
|
6
|
+
export const isImageFile = (file) => IMAGE_EXTENSIONS.some((extension) => file.endsWith(extension));
|
|
4
7
|
export const metricsFile = (renderer, reference) => `${renderer}.vs-${reference}.metrics.json`;
|
|
5
|
-
export const deltaFile = (renderer, reference) => `${renderer}.vs-${reference}.delta${
|
|
8
|
+
export const deltaFile = (renderer, reference, extension = '.webp') => `${renderer}.vs-${reference}.delta${extension}`;
|
|
6
9
|
/** The only suite files the viewer may read; also what `build` exports and `hash` covers. */
|
|
7
10
|
export function isDataFile(rel) {
|
|
8
11
|
if (rel.split('/').some((s) => s.startsWith('.') || s === '..'))
|
|
9
12
|
return false;
|
|
10
|
-
return rel === 'index.json' || rel === 'README.md' || rel.endsWith('/README.md') || rel
|
|
13
|
+
return rel === 'index.json' || rel === 'README.md' || rel.endsWith('/README.md') || isImageFile(rel);
|
|
11
14
|
}
|
|
12
15
|
//# sourceMappingURL=paths.js.map
|
package/dist/core/paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC;AACjC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,GAAG,QAAQ,GAAG,SAAS,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC;AACjC,oDAAoD;AACpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAC5E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAE,SAAS,GAAW,SAAS,EAAE,EAAE,CAAC,GAAG,QAAQ,GAAG,SAAS,EAAE,CAAC;AACxG,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AAC5G,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAE,SAAiB,EAAE,EAAE,CAAC,GAAG,QAAQ,OAAO,SAAS,eAAe,CAAC;AAC/G,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAE,SAAiB,EAAE,SAAS,GAAsB,OAAO,EAAE,EAAE,CACvG,GAAG,QAAQ,OAAO,SAAS,SAAS,SAAS,EAAE,CAAC;AAElD,6FAA6F;AAC7F,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9E,OAAO,GAAG,KAAK,YAAY,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;AACvG,CAAC"}
|
package/dist/core/process.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export interface MetricsRecord extends ImageMetrics {
|
|
|
6
6
|
width: number;
|
|
7
7
|
height: number;
|
|
8
8
|
generatedAt: string;
|
|
9
|
+
/** Present in the viewer index; legacy entries refer to AVIF heatmaps. */
|
|
10
|
+
deltaFile?: string;
|
|
9
11
|
}
|
|
10
12
|
export type SuiteIndex = Suite & {
|
|
11
13
|
metrics: Record<string, MetricsRecord>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/core/process.ts"],"names":[],"mappings":"AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/core/process.ts"],"names":[],"mappings":"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"}
|
package/dist/core/process.js
CHANGED
|
@@ -3,9 +3,9 @@ import { randomUUID } from 'node:crypto';
|
|
|
3
3
|
import { availableParallelism } from 'node:os';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import pLimit from 'p-limit';
|
|
6
|
-
import { compareImages } from './compare.js';
|
|
6
|
+
import { compareImages, measureImages } from './compare.js';
|
|
7
7
|
import { readConfig, scanScene, scanSuite } from './scan.js';
|
|
8
|
-
import { deltaFile, imageFile, metricsFile } from './paths.js';
|
|
8
|
+
import { deltaFile, imageFile, IMAGE_EXTENSIONS, isImageFile, metricsFile } from './paths.js';
|
|
9
9
|
const emptyResult = () => ({ computed: 0, skipped: 0, failed: [] });
|
|
10
10
|
const signatureKey = (inputs) => JSON.stringify(inputs);
|
|
11
11
|
async function signature(path) {
|
|
@@ -19,6 +19,20 @@ async function signature(path) {
|
|
|
19
19
|
throw error;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
/** Version 1 AVIF metrics predate explicit source filenames and independent delta records. */
|
|
23
|
+
function matchesSource(saved, inputs) {
|
|
24
|
+
if (!saved || typeof saved !== 'object')
|
|
25
|
+
return false;
|
|
26
|
+
const source = saved;
|
|
27
|
+
return (source.version === 1 &&
|
|
28
|
+
['reference', 'renderer'].every((side) => {
|
|
29
|
+
const previous = source[side];
|
|
30
|
+
const current = inputs[side];
|
|
31
|
+
return (previous?.size === current.size &&
|
|
32
|
+
previous.mtimeMs === current.mtimeMs &&
|
|
33
|
+
(previous.path === current.path || (previous.path === undefined && current.path.endsWith('.avif'))));
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
22
36
|
function validMetrics(value) {
|
|
23
37
|
if (!value || typeof value !== 'object')
|
|
24
38
|
return false;
|
|
@@ -94,12 +108,13 @@ export class SuiteProcessor {
|
|
|
94
108
|
return parts.join('/');
|
|
95
109
|
if (file === 'README.md')
|
|
96
110
|
return parts.join('/');
|
|
97
|
-
if (file.includes('.vs-') && file.endsWith(
|
|
111
|
+
if (file.includes('.vs-') && IMAGE_EXTENSIONS.some((ext) => file.endsWith(`.delta${ext}`)))
|
|
98
112
|
return null;
|
|
99
113
|
const output = parts.pop();
|
|
100
114
|
if (!parts.length || !this.config.outputs.some((o) => o.id === output))
|
|
101
115
|
return null;
|
|
102
|
-
if (!
|
|
116
|
+
if (!isImageFile(file) ||
|
|
117
|
+
!this.config.renderers.some((r) => IMAGE_EXTENSIONS.some((ext) => imageFile(r.id, ext) === file)))
|
|
103
118
|
return null;
|
|
104
119
|
return parts.join('/');
|
|
105
120
|
}
|
|
@@ -173,7 +188,7 @@ export class SuiteProcessor {
|
|
|
173
188
|
if (node) {
|
|
174
189
|
for (const [output, renderers] of Object.entries(node.images)) {
|
|
175
190
|
const images = new Map(await Promise.all(renderers.map(async (r) => {
|
|
176
|
-
const path = `${rel}/${output}/${imageFile(r)}`;
|
|
191
|
+
const path = `${rel}/${output}/${node.imageFiles?.[output]?.[r] ?? imageFile(r)}`;
|
|
177
192
|
return [r, { path, signature: await signature(join(this.root, path)) }];
|
|
178
193
|
})));
|
|
179
194
|
for (const ref of this.config.renderers.filter((r) => r.reference && images.has(r.id))) {
|
|
@@ -183,7 +198,7 @@ export class SuiteProcessor {
|
|
|
183
198
|
if (!a.signature || !b.signature)
|
|
184
199
|
continue;
|
|
185
200
|
const key = `${rel}/${output}/${metricsFile(renderer, ref.id)}`;
|
|
186
|
-
const inputs = { reference: a.signature, renderer: b.signature };
|
|
201
|
+
const inputs = { reference: { ...a.signature, path: a.path }, renderer: { ...b.signature, path: b.path } };
|
|
187
202
|
const pair = old?.pairs.get(key) ?? {
|
|
188
203
|
key,
|
|
189
204
|
scene: rel,
|
|
@@ -196,21 +211,28 @@ export class SuiteProcessor {
|
|
|
196
211
|
};
|
|
197
212
|
if (signatureKey(pair.inputs) !== signatureKey(inputs)) {
|
|
198
213
|
pair.inputs = inputs;
|
|
214
|
+
pair.reference = a.path;
|
|
215
|
+
pair.renderer = b.path;
|
|
199
216
|
pair.attempted = undefined;
|
|
200
217
|
delete this.metrics[key];
|
|
201
218
|
}
|
|
202
219
|
pairs.set(key, pair);
|
|
203
|
-
if (process && pair.attempted !== signatureKey(inputs)) {
|
|
204
|
-
if (!this.dirty.has(pair) && !pair.running) {
|
|
205
|
-
this.progressTotal++;
|
|
206
|
-
this.reportComparing();
|
|
207
|
-
}
|
|
208
|
-
this.dirty.add(pair);
|
|
209
|
-
}
|
|
210
220
|
}
|
|
211
221
|
}
|
|
212
222
|
}
|
|
213
223
|
this.scenes.set(rel, { node, pairs });
|
|
224
|
+
// A completing task can pump the queue during any await above. Publish the entire scene
|
|
225
|
+
// before making its pairs runnable, otherwise new pairs can be discarded as obsolete.
|
|
226
|
+
if (process)
|
|
227
|
+
for (const pair of pairs.values()) {
|
|
228
|
+
if (pair.attempted === signatureKey(pair.inputs))
|
|
229
|
+
continue;
|
|
230
|
+
if (!this.dirty.has(pair) && !pair.running) {
|
|
231
|
+
this.progressTotal++;
|
|
232
|
+
this.reportComparing();
|
|
233
|
+
}
|
|
234
|
+
this.dirty.add(pair);
|
|
235
|
+
}
|
|
214
236
|
}
|
|
215
237
|
else {
|
|
216
238
|
this.scenes.delete(rel);
|
|
@@ -255,15 +277,19 @@ export class SuiteProcessor {
|
|
|
255
277
|
signature(join(this.root, pair.reference)),
|
|
256
278
|
signature(join(this.root, pair.renderer)),
|
|
257
279
|
]);
|
|
258
|
-
return reference && renderer
|
|
280
|
+
return reference && renderer
|
|
281
|
+
? { reference: { ...reference, path: pair.reference }, renderer: { ...renderer, path: pair.renderer } }
|
|
282
|
+
: null;
|
|
259
283
|
}
|
|
260
284
|
async processPair(pair) {
|
|
261
285
|
const epoch = this.epochs.get(pair.scene) ?? 0;
|
|
262
286
|
const inputs = pair.inputs;
|
|
263
287
|
const key = signatureKey(inputs);
|
|
264
288
|
const metricsPath = join(this.root, pair.key);
|
|
265
|
-
//
|
|
266
|
-
const source = { version: 1,
|
|
289
|
+
// Independent commit markers let either artifact be refreshed without rewriting the other.
|
|
290
|
+
const source = { version: 1, ...inputs };
|
|
291
|
+
const deltaPath = join(this.root, pair.delta);
|
|
292
|
+
const deltaCachePath = `${deltaPath}.json`;
|
|
267
293
|
const stillCurrent = async () => {
|
|
268
294
|
const actual = await this.readInputs(pair);
|
|
269
295
|
return this.current(pair, epoch) && signatureKey(actual) === key;
|
|
@@ -283,19 +309,25 @@ export class SuiteProcessor {
|
|
|
283
309
|
return;
|
|
284
310
|
}
|
|
285
311
|
let record;
|
|
312
|
+
let deltaCurrent = false;
|
|
286
313
|
if (!pair.force) {
|
|
287
314
|
try {
|
|
288
315
|
const { source: saved, ...cached } = JSON.parse(await readFile(metricsPath, 'utf8'));
|
|
289
|
-
if (
|
|
290
|
-
validMetrics(cached) &&
|
|
291
|
-
(!this.config.delta || (await signature(join(this.root, pair.delta)))))
|
|
316
|
+
if (matchesSource(saved, inputs) && validMetrics(cached))
|
|
292
317
|
record = cached;
|
|
293
318
|
}
|
|
294
319
|
catch {
|
|
295
|
-
/* Missing or invalid metrics are recomputed. */
|
|
320
|
+
/* Missing or invalid metrics are recomputed independently of the delta. */
|
|
321
|
+
}
|
|
322
|
+
try {
|
|
323
|
+
const saved = JSON.parse(await readFile(deltaCachePath, 'utf8'));
|
|
324
|
+
deltaCurrent = matchesSource(saved, inputs) && !!(await signature(deltaPath));
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
/* The delta has its own input signature and commit marker. */
|
|
296
328
|
}
|
|
297
329
|
}
|
|
298
|
-
if (record) {
|
|
330
|
+
if (record && deltaCurrent) {
|
|
299
331
|
if (!(await stillCurrent())) {
|
|
300
332
|
retry();
|
|
301
333
|
return;
|
|
@@ -303,23 +335,25 @@ export class SuiteProcessor {
|
|
|
303
335
|
this.result.skipped++;
|
|
304
336
|
}
|
|
305
337
|
else {
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
});
|
|
309
|
-
record = {
|
|
310
|
-
...compared.metrics,
|
|
311
|
-
width: compared.width,
|
|
312
|
-
height: compared.height,
|
|
313
|
-
generatedAt: new Date().toISOString(),
|
|
314
|
-
};
|
|
338
|
+
const compare = deltaCurrent ? measureImages : compareImages;
|
|
339
|
+
const compared = await compare(join(this.root, pair.reference), join(this.root, pair.renderer));
|
|
315
340
|
if (!(await stillCurrent())) {
|
|
316
341
|
retry();
|
|
317
342
|
return;
|
|
318
343
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
await atomicWrite(
|
|
322
|
-
|
|
344
|
+
if (compared.deltaImage) {
|
|
345
|
+
await atomicWrite(deltaPath, compared.deltaImage);
|
|
346
|
+
await atomicWrite(deltaCachePath, JSON.stringify(source, null, 2) + '\n');
|
|
347
|
+
}
|
|
348
|
+
if (!record) {
|
|
349
|
+
record = {
|
|
350
|
+
...compared.metrics,
|
|
351
|
+
width: compared.width,
|
|
352
|
+
height: compared.height,
|
|
353
|
+
generatedAt: new Date().toISOString(),
|
|
354
|
+
};
|
|
355
|
+
await atomicWrite(metricsPath, JSON.stringify({ ...record, source }, null, 2) + '\n');
|
|
356
|
+
}
|
|
323
357
|
if (!(await stillCurrent())) {
|
|
324
358
|
retry();
|
|
325
359
|
return;
|
|
@@ -329,7 +363,7 @@ export class SuiteProcessor {
|
|
|
329
363
|
}
|
|
330
364
|
pair.attempted = key;
|
|
331
365
|
pair.force = false;
|
|
332
|
-
this.metrics[pair.key] = record;
|
|
366
|
+
this.metrics[pair.key] = { ...record, deltaFile: pair.delta.split('/').pop() };
|
|
333
367
|
this.indexDirty = true;
|
|
334
368
|
}
|
|
335
369
|
catch (error) {
|