fidelity-kit 0.1.1 → 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.
Files changed (76) hide show
  1. package/README.md +27 -2
  2. package/dist/commands/build.d.ts +2 -0
  3. package/dist/commands/build.d.ts.map +1 -1
  4. package/dist/commands/build.js +2 -1
  5. package/dist/commands/build.js.map +1 -1
  6. package/dist/commands/dev.d.ts +7 -1
  7. package/dist/commands/dev.d.ts.map +1 -1
  8. package/dist/commands/dev.js +9 -2
  9. package/dist/commands/dev.js.map +1 -1
  10. package/dist/commands/hash.d.ts +2 -0
  11. package/dist/commands/hash.d.ts.map +1 -1
  12. package/dist/commands/hash.js +7 -3
  13. package/dist/commands/hash.js.map +1 -1
  14. package/dist/commands/process.d.ts +6 -0
  15. package/dist/commands/process.d.ts.map +1 -1
  16. package/dist/commands/process.js +35 -7
  17. package/dist/commands/process.js.map +1 -1
  18. package/dist/commands/serve.d.ts +3 -1
  19. package/dist/commands/serve.d.ts.map +1 -1
  20. package/dist/commands/serve.js +2 -1
  21. package/dist/commands/serve.js.map +1 -1
  22. package/dist/core/compare.d.ts +4 -2
  23. package/dist/core/compare.d.ts.map +1 -1
  24. package/dist/core/compare.js +7 -5
  25. package/dist/core/compare.js.map +1 -1
  26. package/dist/core/hash.d.ts +2 -0
  27. package/dist/core/hash.d.ts.map +1 -1
  28. package/dist/core/hash.js +37 -10
  29. package/dist/core/hash.js.map +1 -1
  30. package/dist/core/hash.test.js +8 -1
  31. package/dist/core/hash.test.js.map +1 -1
  32. package/dist/core/process.d.ts +52 -3
  33. package/dist/core/process.d.ts.map +1 -1
  34. package/dist/core/process.js +450 -57
  35. package/dist/core/process.js.map +1 -1
  36. package/dist/core/process.test.d.ts +2 -0
  37. package/dist/core/process.test.d.ts.map +1 -0
  38. package/dist/core/process.test.js +269 -0
  39. package/dist/core/process.test.js.map +1 -0
  40. package/dist/core/progress.d.ts +8 -0
  41. package/dist/core/progress.d.ts.map +1 -0
  42. package/dist/core/progress.js +2 -0
  43. package/dist/core/progress.js.map +1 -0
  44. package/dist/core/scan.d.ts +8 -1
  45. package/dist/core/scan.d.ts.map +1 -1
  46. package/dist/core/scan.js +70 -6
  47. package/dist/core/scan.js.map +1 -1
  48. package/dist/core/suite.test.js +24 -1
  49. package/dist/core/suite.test.js.map +1 -1
  50. package/dist/progress.d.ts +12 -0
  51. package/dist/progress.d.ts.map +1 -0
  52. package/dist/progress.js +46 -0
  53. package/dist/progress.js.map +1 -0
  54. package/dist/progress.test.d.ts +2 -0
  55. package/dist/progress.test.d.ts.map +1 -0
  56. package/dist/progress.test.js +36 -0
  57. package/dist/progress.test.js.map +1 -0
  58. package/dist/run.d.ts +4 -1
  59. package/dist/run.d.ts.map +1 -1
  60. package/dist/run.js +32 -6
  61. package/dist/run.js.map +1 -1
  62. package/dist/server.d.ts +1 -1
  63. package/dist/server.d.ts.map +1 -1
  64. package/dist/server.js +20 -2
  65. package/dist/server.js.map +1 -1
  66. package/dist/server.test.js +42 -1
  67. package/dist/server.test.js.map +1 -1
  68. package/dist/watch.d.ts +9 -0
  69. package/dist/watch.d.ts.map +1 -0
  70. package/dist/watch.js +96 -0
  71. package/dist/watch.js.map +1 -0
  72. package/dist/watch.test.d.ts +2 -0
  73. package/dist/watch.test.d.ts.map +1 -0
  74. package/dist/watch.test.js +138 -0
  75. package/dist/watch.test.js.map +1 -0
  76. package/package.json +2 -1
@@ -1,5 +1,7 @@
1
1
  import { type ImageMetrics } from './compare.js';
2
2
  import { type Suite } from './scan.js';
3
+ import type { FidelityConfig } from './schema.js';
4
+ import type { ProgressCallback } from './progress.js';
3
5
  export interface MetricsRecord extends ImageMetrics {
4
6
  width: number;
5
7
  height: number;
@@ -16,9 +18,56 @@ export interface ProcessResult {
16
18
  error: string;
17
19
  }[];
18
20
  }
19
- /** Writes metrics + delta for every (scene, output, reference, renderer) pair whose outputs are older than either input, then `index.json`. */
20
- export declare function processSuite(root: string, opts?: {
21
+ export interface ProcessOptions {
21
22
  force?: boolean;
23
+ concurrency?: number;
22
24
  onCompute?: (file: string) => void;
23
- }): Promise<ProcessResult>;
25
+ onProgress?: ProgressCallback;
26
+ }
27
+ /** A fixed configuration, small per-scene dependency maps, and one bounded comparison queue. */
28
+ export declare class SuiteProcessor {
29
+ readonly root: string;
30
+ private opts;
31
+ readonly config: FidelityConfig;
32
+ private suite;
33
+ private scenes;
34
+ private metrics;
35
+ private pending;
36
+ private unsettled;
37
+ private epochs;
38
+ private dirty;
39
+ private active;
40
+ private limit;
41
+ private concurrency;
42
+ private result;
43
+ private flushing?;
44
+ private force;
45
+ private indexDirty;
46
+ private progressCompleted;
47
+ private progressTotal;
48
+ private reportComparing;
49
+ private constructor();
50
+ static create(root: string, opts?: ProcessOptions): Promise<SuiteProcessor>;
51
+ /** Only source inputs qualify. Generated deltas, metrics, index and temporary files never do. */
52
+ sceneForInput(path: string): string | null;
53
+ /** Invalidate synchronously, including work already running; reconciliation happens at the batch boundary. */
54
+ notify(paths: Iterable<string>, defer?: boolean): void;
55
+ /** Release one coalesced watcher batch without delaying invalidation of running work. */
56
+ settle(): void;
57
+ get needsFlush(): boolean;
58
+ removeDirectory(path: string, defer?: boolean): void;
59
+ /** Comparisons start as scenes are discovered; no second walk or metrics reread is needed. */
60
+ initialize(process?: boolean): Promise<ProcessResult>;
61
+ flush(): Promise<ProcessResult>;
62
+ private reconcile;
63
+ private current;
64
+ private pump;
65
+ private readInputs;
66
+ private processPair;
67
+ private drain;
68
+ }
69
+ /** Process discovered scenes through the same scheduler used by watch mode. */
70
+ export declare function processSuite(root: string, opts?: ProcessOptions): Promise<ProcessResult>;
71
+ /** One-shot compatibility helper. Watch mode retains its SuiteProcessor instead. */
72
+ export declare function processChanges(root: string, paths: Iterable<string>, onProgress?: ProgressCallback): Promise<ProcessResult>;
24
73
  //# sourceMappingURL=process.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/core/process.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAwB,KAAK,KAAK,EAAE,MAAM,WAAW,CAAC;AAG7D,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAQD,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CAAE,CAAC;AAE5E,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3C;AAED,+IAA+I;AAC/I,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,GACjE,OAAO,CAAC,aAAa,CAAC,CAyCxB"}
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/core/process.ts"],"names":[],"mappings":"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"}
@@ -1,71 +1,464 @@
1
- import { mkdir, readFile, stat, writeFile } from 'node:fs/promises';
2
- import { dirname, join } from 'node:path';
1
+ import { mkdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { availableParallelism } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import pLimit from 'p-limit';
3
6
  import { compareImages } from './compare.js';
4
- import { allScenes, scanSuite } from './scan.js';
7
+ import { readConfig, scanScene, scanSuite } from './scan.js';
5
8
  import { deltaFile, imageFile, metricsFile } from './paths.js';
6
- const mtime = (p) => stat(p).then((s) => s.mtimeMs, () => 0);
7
- /** Writes metrics + delta for every (scene, output, reference, renderer) pair whose outputs are older than either input, then `index.json`. */
8
- export async function processSuite(root, opts = {}) {
9
- const suite = await scanSuite(root);
10
- const refs = suite.config.renderers.filter((r) => r.reference).map((r) => r.id);
11
- const result = { computed: 0, skipped: 0, failed: [] };
12
- const validMetrics = new Set();
13
- for (const scene of allScenes(suite.root)) {
14
- for (const [output, renderers] of Object.entries(scene.images)) {
15
- const dir = join(root, scene.path, output);
16
- for (const ref of refs.filter((r) => renderers.includes(r))) {
17
- for (const r of renderers.filter((x) => x !== ref)) {
18
- const [refPath, testPath] = [join(dir, imageFile(ref)), join(dir, imageFile(r))];
19
- const metricsPath = join(dir, metricsFile(r, ref));
20
- const metricsRel = `${scene.path}/${output}/${metricsFile(r, ref)}`;
21
- const deltaPath = join(dir, deltaFile(r, ref));
22
- const inputs = Math.max(await mtime(refPath), await mtime(testPath));
23
- const outputs = [metricsPath, ...(suite.config.delta ? [deltaPath] : [])];
24
- const oldest = Math.min(...(await Promise.all(outputs.map(mtime))));
25
- if (!opts.force && oldest > inputs) {
26
- result.skipped += 1;
27
- validMetrics.add(metricsRel);
28
- continue;
9
+ const emptyResult = () => ({ computed: 0, skipped: 0, failed: [] });
10
+ const signatureKey = (inputs) => JSON.stringify(inputs);
11
+ async function signature(path) {
12
+ try {
13
+ const s = await stat(path);
14
+ return s.isFile() ? { mtimeMs: s.mtimeMs, size: s.size } : null;
15
+ }
16
+ catch (error) {
17
+ if (error.code === 'ENOENT' || error.code === 'ENOTDIR')
18
+ return null;
19
+ throw error;
20
+ }
21
+ }
22
+ function validMetrics(value) {
23
+ if (!value || typeof value !== 'object')
24
+ return false;
25
+ const r = value;
26
+ return ((r.psnr === null || Number.isFinite(r.psnr)) &&
27
+ [r.rmse, r.mae, r.maxError].every((n) => Number.isFinite(n) && n >= 0 && n <= 1) &&
28
+ Number.isInteger(r.width) &&
29
+ r.width > 0 &&
30
+ Number.isInteger(r.height) &&
31
+ r.height > 0 &&
32
+ typeof r.generatedAt === 'string');
33
+ }
34
+ async function atomicWrite(file, data) {
35
+ const tmp = `${file}.${randomUUID()}.tmp`;
36
+ try {
37
+ await writeFile(tmp, data);
38
+ await rename(tmp, file);
39
+ }
40
+ finally {
41
+ await rm(tmp, { force: true });
42
+ }
43
+ }
44
+ /** A fixed configuration, small per-scene dependency maps, and one bounded comparison queue. */
45
+ export class SuiteProcessor {
46
+ root;
47
+ opts;
48
+ config;
49
+ suite;
50
+ scenes = new Map();
51
+ metrics = {};
52
+ pending = new Set();
53
+ unsettled = new Set();
54
+ epochs = new Map();
55
+ dirty = new Set();
56
+ active = new Set();
57
+ limit;
58
+ concurrency;
59
+ result = emptyResult();
60
+ flushing;
61
+ force;
62
+ indexDirty = false;
63
+ progressCompleted = 0;
64
+ progressTotal = 0;
65
+ reportComparing() {
66
+ this.opts.onProgress?.({
67
+ phase: 'Comparing',
68
+ completed: this.progressCompleted,
69
+ total: this.progressTotal,
70
+ unit: 'pairs',
71
+ });
72
+ }
73
+ constructor(root, config, opts) {
74
+ this.root = root;
75
+ this.opts = opts;
76
+ this.config = config;
77
+ this.suite = { config, hasReadme: false, root: { path: '', hasReadme: false, groups: [], scenes: [] } };
78
+ this.concurrency = opts.concurrency ?? availableParallelism();
79
+ if (!Number.isInteger(this.concurrency) || this.concurrency < 1)
80
+ throw new Error('Concurrency must be a positive integer');
81
+ this.limit = pLimit(this.concurrency);
82
+ this.force = opts.force ?? false;
83
+ }
84
+ static async create(root, opts = {}) {
85
+ return new SuiteProcessor(root, await readConfig(root), opts);
86
+ }
87
+ /** Only source inputs qualify. Generated deltas, metrics, index and temporary files never do. */
88
+ sceneForInput(path) {
89
+ const parts = path.split('/');
90
+ if (parts.some((p) => !p || p.startsWith('.')))
91
+ return null;
92
+ const file = parts.pop();
93
+ if (file === 'scene.json' && parts.length)
94
+ return parts.join('/');
95
+ if (file === 'README.md')
96
+ return parts.join('/');
97
+ if (file.includes('.vs-') && file.endsWith('.delta.avif'))
98
+ return null;
99
+ const output = parts.pop();
100
+ if (!parts.length || !this.config.outputs.some((o) => o.id === output))
101
+ return null;
102
+ if (!this.config.renderers.some((r) => imageFile(r.id) === file))
103
+ return null;
104
+ return parts.join('/');
105
+ }
106
+ /** Invalidate synchronously, including work already running; reconciliation happens at the batch boundary. */
107
+ notify(paths, defer = false) {
108
+ for (const path of paths) {
109
+ const scene = this.sceneForInput(path);
110
+ if (scene === null)
111
+ continue;
112
+ (defer ? this.unsettled : this.pending).add(scene);
113
+ this.epochs.set(scene, (this.epochs.get(scene) ?? 0) + 1);
114
+ }
115
+ }
116
+ /** Release one coalesced watcher batch without delaying invalidation of running work. */
117
+ settle() {
118
+ for (const scene of this.unsettled)
119
+ this.pending.add(scene);
120
+ this.unsettled.clear();
121
+ }
122
+ get needsFlush() {
123
+ return !!(this.pending.size || this.active.size || this.indexDirty);
124
+ }
125
+ removeDirectory(path, defer = false) {
126
+ for (const scene of this.scenes.keys()) {
127
+ if (scene === path || scene.startsWith(`${path}/`) || path.startsWith(`${scene}/`)) {
128
+ (defer ? this.unsettled : this.pending).add(scene);
129
+ this.epochs.set(scene, (this.epochs.get(scene) ?? 0) + 1);
130
+ }
131
+ }
132
+ }
133
+ /** Comparisons start as scenes are discovered; no second walk or metrics reread is needed. */
134
+ async initialize(process = true) {
135
+ if (!process) {
136
+ const index = JSON.parse(await readFile(join(this.root, 'index.json'), 'utf8'));
137
+ this.metrics = index.metrics;
138
+ }
139
+ try {
140
+ this.suite = await scanSuite(this.root, {
141
+ config: this.config,
142
+ onProgress: this.opts.onProgress,
143
+ onScene: async (scene) => {
144
+ await this.reconcile(scene.path, scene, process);
145
+ },
146
+ });
147
+ }
148
+ catch (error) {
149
+ this.dirty.clear();
150
+ await Promise.all(this.active);
151
+ throw error;
152
+ }
153
+ if (!process) {
154
+ const valid = new Set([...this.scenes.values()].flatMap((scene) => [...scene.pairs.keys()]));
155
+ for (const key of Object.keys(this.metrics))
156
+ if (!valid.has(key))
157
+ delete this.metrics[key];
158
+ }
159
+ this.indexDirty = process;
160
+ // Events collected during discovery are reconciled even when the initial processing was disabled.
161
+ return this.flush();
162
+ }
163
+ flush() {
164
+ if (!this.flushing)
165
+ this.flushing = this.drain().finally(() => {
166
+ this.flushing = undefined;
167
+ });
168
+ return this.flushing;
169
+ }
170
+ async reconcile(rel, node, process = true) {
171
+ const old = this.scenes.get(rel);
172
+ const pairs = new Map();
173
+ if (node) {
174
+ for (const [output, renderers] of Object.entries(node.images)) {
175
+ const images = new Map(await Promise.all(renderers.map(async (r) => {
176
+ const path = `${rel}/${output}/${imageFile(r)}`;
177
+ return [r, { path, signature: await signature(join(this.root, path)) }];
178
+ })));
179
+ for (const ref of this.config.renderers.filter((r) => r.reference && images.has(r.id))) {
180
+ for (const renderer of renderers.filter((r) => r !== ref.id)) {
181
+ const a = images.get(ref.id);
182
+ const b = images.get(renderer);
183
+ if (!a.signature || !b.signature)
184
+ continue;
185
+ const key = `${rel}/${output}/${metricsFile(renderer, ref.id)}`;
186
+ const inputs = { reference: a.signature, renderer: b.signature };
187
+ const pair = old?.pairs.get(key) ?? {
188
+ key,
189
+ scene: rel,
190
+ reference: a.path,
191
+ renderer: b.path,
192
+ delta: `${rel}/${output}/${deltaFile(renderer, ref.id)}`,
193
+ inputs,
194
+ running: false,
195
+ force: this.force,
196
+ };
197
+ if (signatureKey(pair.inputs) !== signatureKey(inputs)) {
198
+ pair.inputs = inputs;
199
+ pair.attempted = undefined;
200
+ delete this.metrics[key];
201
+ }
202
+ 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
+ }
29
210
  }
211
+ }
212
+ }
213
+ this.scenes.set(rel, { node, pairs });
214
+ }
215
+ else {
216
+ this.scenes.delete(rel);
217
+ this.epochs.delete(rel);
218
+ }
219
+ for (const [key, pair] of old?.pairs ?? []) {
220
+ if (!pairs.has(key)) {
221
+ this.dirty.delete(pair);
222
+ delete this.metrics[key];
223
+ }
224
+ }
225
+ replaceScene(this.suite.root, rel, node);
226
+ this.indexDirty = true;
227
+ if (process)
228
+ this.pump();
229
+ }
230
+ current(pair, epoch) {
231
+ return this.scenes.get(pair.scene)?.pairs.get(pair.key) === pair && (this.epochs.get(pair.scene) ?? 0) === epoch;
232
+ }
233
+ pump() {
234
+ for (const pair of this.dirty) {
235
+ if (this.active.size >= this.concurrency)
236
+ break;
237
+ if (pair.running || this.unsettled.has(pair.scene))
238
+ continue;
239
+ this.dirty.delete(pair);
240
+ if (pair.attempted === signatureKey(pair.inputs))
241
+ continue;
242
+ pair.running = true;
243
+ const task = this.limit(() => this.processPair(pair)).finally(() => {
244
+ this.progressCompleted++;
245
+ this.reportComparing();
246
+ pair.running = false;
247
+ this.active.delete(task);
248
+ this.pump();
249
+ });
250
+ this.active.add(task);
251
+ }
252
+ }
253
+ async readInputs(pair) {
254
+ const [reference, renderer] = await Promise.all([
255
+ signature(join(this.root, pair.reference)),
256
+ signature(join(this.root, pair.renderer)),
257
+ ]);
258
+ return reference && renderer ? { reference, renderer } : null;
259
+ }
260
+ async processPair(pair) {
261
+ const epoch = this.epochs.get(pair.scene) ?? 0;
262
+ const inputs = pair.inputs;
263
+ const key = signatureKey(inputs);
264
+ const metricsPath = join(this.root, pair.key);
265
+ // Bump the recipe version when comparison or encoding semantics change.
266
+ const source = { version: 1, delta: this.config.delta, ...inputs };
267
+ const stillCurrent = async () => {
268
+ const actual = await this.readInputs(pair);
269
+ return this.current(pair, epoch) && signatureKey(actual) === key;
270
+ };
271
+ const retry = () => {
272
+ if (this.scenes.get(pair.scene)?.pairs.get(pair.key) === pair) {
273
+ pair.attempted = undefined;
274
+ if (!this.unsettled.has(pair.scene))
275
+ this.pending.add(pair.scene);
276
+ this.indexDirty = true;
277
+ delete this.metrics[pair.key];
278
+ }
279
+ };
280
+ try {
281
+ if (!(await stillCurrent())) {
282
+ retry();
283
+ return;
284
+ }
285
+ let record;
286
+ if (!pair.force) {
287
+ try {
288
+ const { source: saved, ...cached } = JSON.parse(await readFile(metricsPath, 'utf8'));
289
+ if (JSON.stringify(saved) === JSON.stringify(source) &&
290
+ validMetrics(cached) &&
291
+ (!this.config.delta || (await signature(join(this.root, pair.delta)))))
292
+ record = cached;
293
+ }
294
+ catch {
295
+ /* Missing or invalid metrics are recomputed. */
296
+ }
297
+ }
298
+ if (record) {
299
+ if (!(await stillCurrent())) {
300
+ retry();
301
+ return;
302
+ }
303
+ this.result.skipped++;
304
+ }
305
+ else {
306
+ const compared = await compareImages(join(this.root, pair.reference), join(this.root, pair.renderer), {
307
+ delta: this.config.delta,
308
+ });
309
+ record = {
310
+ ...compared.metrics,
311
+ width: compared.width,
312
+ height: compared.height,
313
+ generatedAt: new Date().toISOString(),
314
+ };
315
+ if (!(await stillCurrent())) {
316
+ retry();
317
+ return;
318
+ }
319
+ // Metrics are the commit marker: publish them only after all required artifacts exist.
320
+ if (this.config.delta)
321
+ await atomicWrite(join(this.root, pair.delta), compared.deltaImage);
322
+ await atomicWrite(metricsPath, JSON.stringify({ ...record, source }, null, 2) + '\n');
323
+ if (!(await stillCurrent())) {
324
+ retry();
325
+ return;
326
+ }
327
+ this.result.computed++;
328
+ this.opts.onCompute?.(metricsPath);
329
+ }
330
+ pair.attempted = key;
331
+ pair.force = false;
332
+ this.metrics[pair.key] = record;
333
+ this.indexDirty = true;
334
+ }
335
+ catch (error) {
336
+ if (!this.current(pair, epoch) || signatureKey(await this.readInputs(pair).catch(() => null)) !== key) {
337
+ retry();
338
+ return;
339
+ }
340
+ pair.attempted = key; // Wait for changed inputs; do not spin on corrupt images.
341
+ delete this.metrics[pair.key];
342
+ this.indexDirty = true;
343
+ this.result.failed.push({
344
+ file: join(this.root, pair.renderer),
345
+ error: error instanceof Error ? error.message : String(error),
346
+ });
347
+ }
348
+ }
349
+ async drain() {
350
+ do {
351
+ while (this.pending.size || this.dirty.size || this.active.size) {
352
+ const pending = [...this.pending];
353
+ this.pending.clear();
354
+ let scanned = 0;
355
+ const reportScanning = () => this.opts.onProgress?.({
356
+ phase: 'Scanning changes',
357
+ completed: scanned,
358
+ total: pending.length,
359
+ unit: 'scenes',
360
+ });
361
+ if (pending.length)
362
+ reportScanning();
363
+ for (const rel of pending) {
30
364
  try {
31
- const { metrics, width, height, deltaImage } = await compareImages(refPath, testPath);
32
- const rec = { ...metrics, width, height, generatedAt: new Date().toISOString() };
33
- await writeFile(metricsPath, JSON.stringify(rec, null, 2) + '\n');
34
- if (suite.config.delta)
35
- await writeFile(deltaPath, deltaImage);
36
- result.computed += 1;
37
- validMetrics.add(metricsRel);
38
- opts.onCompute?.(metricsPath);
365
+ if (!rel) {
366
+ this.suite.hasReadme = !!(await signature(join(this.root, 'README.md')));
367
+ this.suite.root.hasReadme = this.suite.hasReadme;
368
+ this.indexDirty = true;
369
+ }
370
+ else {
371
+ await this.reconcile(rel, await scanScene(this.root, rel, this.config));
372
+ // Newly inserted groups and README-only changes need current presence flags too.
373
+ let group = this.suite.root;
374
+ for (const part of rel.split('/')) {
375
+ const path = group.path ? `${group.path}/${part}` : part;
376
+ const child = group.groups.find((g) => g.path === path);
377
+ if (!child)
378
+ break;
379
+ child.hasReadme = !!(await signature(join(this.root, path, 'README.md')));
380
+ group = child;
381
+ }
382
+ }
39
383
  }
40
- catch (e) {
41
- result.failed.push({ file: testPath, error: e instanceof Error ? e.message : String(e) });
384
+ catch (error) {
385
+ this.result.failed.push({
386
+ file: join(this.root, rel),
387
+ error: error instanceof Error ? error.message : String(error),
388
+ });
42
389
  }
390
+ scanned++;
391
+ reportScanning();
43
392
  }
393
+ this.pump();
394
+ if (this.active.size)
395
+ await Promise.race(this.active);
396
+ else if (!this.pending.size)
397
+ break; // Remaining dirty nodes belong to an unsettled watcher batch.
44
398
  }
45
- }
399
+ if (this.indexDirty) {
400
+ this.opts.onProgress?.({ phase: 'Writing index', completed: 0, total: 1, unit: 'files' });
401
+ const index = {
402
+ ...this.suite,
403
+ metrics: Object.fromEntries(Object.entries(this.metrics).toSorted(([a], [b]) => a.localeCompare(b))),
404
+ };
405
+ await mkdir(this.root, { recursive: true });
406
+ await atomicWrite(join(this.root, 'index.json'), JSON.stringify(index, null, 2) + '\n');
407
+ this.indexDirty = false;
408
+ this.opts.onProgress?.({ phase: 'Writing index', completed: 1, total: 1, unit: 'files' });
409
+ }
410
+ } while (this.pending.size);
411
+ this.force = false;
412
+ this.progressCompleted = 0;
413
+ this.progressTotal = 0;
414
+ const result = this.result;
415
+ this.result = emptyResult();
416
+ result.failed.sort((a, b) => a.file.localeCompare(b.file));
417
+ return result;
46
418
  }
47
- await writeIndex(root, await scanSuite(root), validMetrics);
48
- return result;
49
419
  }
50
- /** `index.json`: the scan plus metrics for successful or up-to-date pairs, so the viewer never walks the disk per request. */
51
- async function writeIndex(root, suite, validMetrics) {
52
- const metrics = {};
53
- for (const scene of allScenes(suite.root)) {
54
- for (const [output, renderers] of Object.entries(scene.images)) {
55
- for (const r of renderers) {
56
- for (const ref of suite.config.renderers.filter((x) => x.reference)) {
57
- const rel = `${scene.path}/${output}/${metricsFile(r, ref.id)}`;
58
- if (!validMetrics.has(rel))
59
- continue;
60
- const raw = await readFile(join(root, rel), 'utf8').catch(() => null);
61
- if (raw)
62
- metrics[rel] = JSON.parse(raw);
63
- }
64
- }
420
+ /** Process discovered scenes through the same scheduler used by watch mode. */
421
+ export async function processSuite(root, opts = {}) {
422
+ return (await SuiteProcessor.create(root, opts)).initialize();
423
+ }
424
+ /** One-shot compatibility helper. Watch mode retains its SuiteProcessor instead. */
425
+ export async function processChanges(root, paths, onProgress) {
426
+ const processor = await SuiteProcessor.create(root, { onProgress });
427
+ try {
428
+ await processor.initialize(false);
429
+ }
430
+ catch {
431
+ return processSuite(root, { onProgress });
432
+ }
433
+ processor.notify(paths);
434
+ return processor.flush();
435
+ }
436
+ function replaceScene(root, path, scene) {
437
+ const parts = path.split('/');
438
+ const parents = [root];
439
+ let group = root;
440
+ for (const part of parts.slice(0, -1)) {
441
+ const groupPath = group.path ? `${group.path}/${part}` : part;
442
+ let child = group.groups.find((g) => g.path === groupPath);
443
+ if (!child && scene) {
444
+ child = { path: groupPath, hasReadme: false, groups: [], scenes: [] };
445
+ group.groups.push(child);
446
+ group.groups.sort((a, b) => a.path.localeCompare(b.path));
65
447
  }
448
+ if (!child)
449
+ return;
450
+ group = child;
451
+ parents.push(group);
452
+ }
453
+ group.scenes = group.scenes.filter((s) => s.path !== path);
454
+ if (scene)
455
+ group.scenes.push(scene);
456
+ group.scenes.sort((a, b) => a.path.localeCompare(b.path));
457
+ for (let i = parents.length - 1; i > 0; i--) {
458
+ const current = parents[i];
459
+ if (current.groups.length || current.scenes.length)
460
+ break;
461
+ parents[i - 1].groups = parents[i - 1].groups.filter((g) => g !== current);
66
462
  }
67
- const file = join(root, 'index.json');
68
- await mkdir(dirname(file), { recursive: true });
69
- await writeFile(file, JSON.stringify({ ...suite, metrics }, null, 2) + '\n');
70
463
  }
71
464
  //# sourceMappingURL=process.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/core/process.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/core/process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=process.test.d.ts.map