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.
- package/README.md +27 -2
- package/dist/commands/build.d.ts +2 -0
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +2 -1
- 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 -57
- 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 +70 -6
- package/dist/core/scan.js.map +1 -1
- package/dist/core/suite.test.js +24 -1
- 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 +32 -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 +20 -2
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +42 -1
- 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 +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.test.d.ts","sourceRoot":"","sources":["../../src/core/process.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { mkdtemp, mkdir, readFile, rm, stat, utimes, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import sharp from 'sharp';
|
|
5
|
+
import { afterEach, expect, test, vi } from 'vitest';
|
|
6
|
+
import * as comparison from './compare.js';
|
|
7
|
+
import * as scanning from './scan.js';
|
|
8
|
+
import { processSuite, SuiteProcessor } from './process.js';
|
|
9
|
+
const roots = [];
|
|
10
|
+
afterEach(async () => {
|
|
11
|
+
vi.restoreAllMocks();
|
|
12
|
+
await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
|
|
13
|
+
});
|
|
14
|
+
const image = (v) => sharp({ create: { width: 8, height: 8, channels: 3, background: { r: v, g: v, b: v } } })
|
|
15
|
+
.avif({ lossless: true })
|
|
16
|
+
.toBuffer();
|
|
17
|
+
const index = async (root) => JSON.parse(await readFile(join(root, 'index.json'), 'utf8'));
|
|
18
|
+
async function addScene(root, scene, value = 100) {
|
|
19
|
+
const dir = join(root, scene, 'beauty');
|
|
20
|
+
await mkdir(dir, { recursive: true });
|
|
21
|
+
for (const renderer of ['ref', 'a', 'b'])
|
|
22
|
+
await writeFile(join(dir, `${renderer}.avif`), await image(value));
|
|
23
|
+
return dir;
|
|
24
|
+
}
|
|
25
|
+
async function fixture() {
|
|
26
|
+
const root = await mkdtemp(join(tmpdir(), 'fk-process-'));
|
|
27
|
+
roots.push(root);
|
|
28
|
+
await writeFile(join(root, 'fidelity.json'), JSON.stringify({ title: 'T', renderers: [{ id: 'ref', reference: true }, { id: 'a' }, { id: 'b' }] }));
|
|
29
|
+
return { root, dir: await addScene(root, 'one') };
|
|
30
|
+
}
|
|
31
|
+
const aKey = 'one/beauty/a.vs-ref.metrics.json';
|
|
32
|
+
test('persisted signatures detect older timestamps and size-only changes, and reuse future timestamps', async () => {
|
|
33
|
+
const { root, dir } = await fixture();
|
|
34
|
+
const file = join(dir, 'a.avif');
|
|
35
|
+
const future = new Date('2040-01-01');
|
|
36
|
+
await utimes(file, future, future);
|
|
37
|
+
expect(await processSuite(root)).toMatchObject({ computed: 2 });
|
|
38
|
+
expect(await processSuite(root)).toMatchObject({ computed: 0, skipped: 2 });
|
|
39
|
+
await writeFile(file, await image(160));
|
|
40
|
+
const old = new Date('2000-01-01');
|
|
41
|
+
await utimes(file, old, old);
|
|
42
|
+
expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
|
|
43
|
+
expect((await index(root)).metrics[aKey].maxError).toBeGreaterThan(0);
|
|
44
|
+
await writeFile(file, Buffer.concat([await readFile(file), Buffer.from('padding')]));
|
|
45
|
+
await utimes(file, old, old);
|
|
46
|
+
expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
|
|
47
|
+
});
|
|
48
|
+
test('missing outputs, malformed metrics, and old cache formats are recomputed', async () => {
|
|
49
|
+
const { root, dir } = await fixture();
|
|
50
|
+
await processSuite(root);
|
|
51
|
+
await rm(join(dir, 'a.vs-ref.delta.avif'));
|
|
52
|
+
expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
|
|
53
|
+
const metrics = join(root, aKey);
|
|
54
|
+
const saved = JSON.parse(await readFile(metrics, 'utf8'));
|
|
55
|
+
await writeFile(metrics, JSON.stringify({ ...saved, width: -1 }));
|
|
56
|
+
expect(await processSuite(root)).toMatchObject({ computed: 1 });
|
|
57
|
+
const { source: _source, ...legacy } = saved;
|
|
58
|
+
await writeFile(metrics, JSON.stringify(legacy));
|
|
59
|
+
expect(await processSuite(root)).toMatchObject({ computed: 1 });
|
|
60
|
+
});
|
|
61
|
+
test('coalesces shared input changes and updates metadata without comparing images', async () => {
|
|
62
|
+
const { root, dir } = await fixture();
|
|
63
|
+
const processor = await SuiteProcessor.create(root);
|
|
64
|
+
await processor.initialize();
|
|
65
|
+
const compare = vi.spyOn(comparison, 'compareImages');
|
|
66
|
+
await writeFile(join(dir, 'ref.avif'), await image(140));
|
|
67
|
+
await writeFile(join(dir, 'a.avif'), await image(120));
|
|
68
|
+
processor.notify(['one/beauty/ref.avif', 'one/beauty/a.avif', 'one/beauty/ref.avif']);
|
|
69
|
+
expect(await processor.flush()).toMatchObject({ computed: 2, failed: [] });
|
|
70
|
+
expect(compare).toHaveBeenCalledTimes(2);
|
|
71
|
+
compare.mockClear();
|
|
72
|
+
await writeFile(join(root, 'one/scene.json'), JSON.stringify({ title: 'Renamed' }));
|
|
73
|
+
processor.notify(['one/scene.json']);
|
|
74
|
+
expect(await processor.flush()).toMatchObject({ computed: 0, skipped: 0 });
|
|
75
|
+
expect(compare).not.toHaveBeenCalled();
|
|
76
|
+
expect((await index(root)).root.scenes[0].title).toBe('Renamed');
|
|
77
|
+
});
|
|
78
|
+
test('adds and removes scenes and images while retaining explicit empty scenes', async () => {
|
|
79
|
+
const { root, dir } = await fixture();
|
|
80
|
+
const processor = await SuiteProcessor.create(root);
|
|
81
|
+
await processor.initialize();
|
|
82
|
+
await addScene(root, 'group/two');
|
|
83
|
+
processor.notify(['group/two/beauty/a.avif']);
|
|
84
|
+
expect(await processor.flush()).toMatchObject({ computed: 2 });
|
|
85
|
+
await rm(join(dir, 'ref.avif'));
|
|
86
|
+
processor.notify(['one/beauty/ref.avif']);
|
|
87
|
+
await processor.flush();
|
|
88
|
+
expect(Object.keys((await index(root)).metrics)).not.toContain(aKey);
|
|
89
|
+
await writeFile(join(dir, 'ref.avif'), await image(130));
|
|
90
|
+
processor.notify(['one/beauty/ref.avif']);
|
|
91
|
+
expect(await processor.flush()).toMatchObject({ computed: 2 });
|
|
92
|
+
await writeFile(join(root, 'one/scene.json'), '{}');
|
|
93
|
+
await rm(dir, { recursive: true });
|
|
94
|
+
processor.notify(['one/beauty/ref.avif', 'one/beauty/a.avif', 'one/beauty/b.avif', 'one/scene.json']);
|
|
95
|
+
await processor.flush();
|
|
96
|
+
expect((await index(root)).root.scenes[0].images).toEqual({});
|
|
97
|
+
await rm(join(root, 'group'), { recursive: true });
|
|
98
|
+
processor.removeDirectory('group');
|
|
99
|
+
await processor.flush();
|
|
100
|
+
expect((await index(root)).root.groups).toEqual([]);
|
|
101
|
+
expect((await index(root)).metrics).toEqual({});
|
|
102
|
+
await rm(join(root, 'one/scene.json'));
|
|
103
|
+
processor.notify(['one/scene.json']);
|
|
104
|
+
await processor.flush();
|
|
105
|
+
expect((await index(root)).root.scenes).toEqual([]);
|
|
106
|
+
});
|
|
107
|
+
test('discards in-flight results and waits for a settled batch before recomputing', async () => {
|
|
108
|
+
const { root, dir } = await fixture();
|
|
109
|
+
const processor = await SuiteProcessor.create(root, { concurrency: 1 });
|
|
110
|
+
await processor.initialize();
|
|
111
|
+
const started = Promise.withResolvers();
|
|
112
|
+
const release = Promise.withResolvers();
|
|
113
|
+
const original = comparison.compareImages;
|
|
114
|
+
const compare = vi.spyOn(comparison, 'compareImages').mockImplementationOnce(async (...args) => {
|
|
115
|
+
const result = await original(...args);
|
|
116
|
+
started.resolve();
|
|
117
|
+
await release.promise;
|
|
118
|
+
return result;
|
|
119
|
+
});
|
|
120
|
+
await writeFile(join(dir, 'a.avif'), await image(120));
|
|
121
|
+
processor.notify(['one/beauty/a.avif']);
|
|
122
|
+
const running = processor.flush();
|
|
123
|
+
await started.promise;
|
|
124
|
+
await writeFile(join(dir, 'a.avif'), await image(180));
|
|
125
|
+
processor.notify(['one/beauty/a.avif'], true);
|
|
126
|
+
release.resolve();
|
|
127
|
+
expect(await running).toMatchObject({ computed: 0 });
|
|
128
|
+
expect((await index(root)).metrics[aKey]).toBeUndefined();
|
|
129
|
+
expect(compare).toHaveBeenCalledTimes(1);
|
|
130
|
+
processor.settle();
|
|
131
|
+
expect(await processor.flush()).toMatchObject({ computed: 1 });
|
|
132
|
+
expect(compare).toHaveBeenCalledTimes(2);
|
|
133
|
+
expect((await index(root)).metrics[aKey].maxError).toBeGreaterThan(0.25);
|
|
134
|
+
});
|
|
135
|
+
test('deleting and recreating a scene cannot publish its previous running comparison', async () => {
|
|
136
|
+
const { root, dir } = await fixture();
|
|
137
|
+
const processor = await SuiteProcessor.create(root, { concurrency: 1 });
|
|
138
|
+
await processor.initialize();
|
|
139
|
+
const started = Promise.withResolvers();
|
|
140
|
+
const release = Promise.withResolvers();
|
|
141
|
+
const original = comparison.compareImages;
|
|
142
|
+
vi.spyOn(comparison, 'compareImages').mockImplementationOnce(async (...args) => {
|
|
143
|
+
const result = await original(...args);
|
|
144
|
+
started.resolve();
|
|
145
|
+
await release.promise;
|
|
146
|
+
return result;
|
|
147
|
+
});
|
|
148
|
+
await writeFile(join(dir, 'a.avif'), await image(130));
|
|
149
|
+
processor.notify(['one/beauty/a.avif']);
|
|
150
|
+
const running = processor.flush();
|
|
151
|
+
await started.promise;
|
|
152
|
+
await rm(join(root, 'one'), { recursive: true });
|
|
153
|
+
processor.removeDirectory('one');
|
|
154
|
+
release.resolve();
|
|
155
|
+
expect(await running).toMatchObject({ computed: 0, failed: [] });
|
|
156
|
+
expect((await index(root)).metrics).toEqual({});
|
|
157
|
+
await addScene(root, 'one', 170);
|
|
158
|
+
processor.notify(['one/beauty/a.avif']);
|
|
159
|
+
expect(await processor.flush()).toMatchObject({ computed: 2 });
|
|
160
|
+
expect((await index(root)).metrics[aKey].maxError).toBe(0);
|
|
161
|
+
});
|
|
162
|
+
test('streams discovery into a globally bounded queue', async () => {
|
|
163
|
+
const { root } = await fixture();
|
|
164
|
+
await addScene(root, 'two');
|
|
165
|
+
const started = Promise.withResolvers();
|
|
166
|
+
const discovered = Promise.withResolvers();
|
|
167
|
+
const originalCompare = comparison.compareImages;
|
|
168
|
+
let active = 0;
|
|
169
|
+
let maximum = 0;
|
|
170
|
+
vi.spyOn(comparison, 'compareImages').mockImplementation(async (...args) => {
|
|
171
|
+
active++;
|
|
172
|
+
maximum = Math.max(maximum, active);
|
|
173
|
+
if (active === 2)
|
|
174
|
+
started.resolve();
|
|
175
|
+
await discovered.promise;
|
|
176
|
+
try {
|
|
177
|
+
return await originalCompare(...args);
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
active--;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
const originalScan = scanning.scanSuite;
|
|
184
|
+
vi.spyOn(scanning, 'scanSuite').mockImplementation((path, options) => originalScan(path, {
|
|
185
|
+
...options,
|
|
186
|
+
onScene: async (scene) => {
|
|
187
|
+
if (scene.path === 'two') {
|
|
188
|
+
await started.promise;
|
|
189
|
+
discovered.resolve();
|
|
190
|
+
}
|
|
191
|
+
await options?.onScene?.(scene);
|
|
192
|
+
},
|
|
193
|
+
}));
|
|
194
|
+
expect(await processSuite(root, { concurrency: 2 })).toMatchObject({ computed: 4, failed: [] });
|
|
195
|
+
expect(maximum).toBe(2);
|
|
196
|
+
});
|
|
197
|
+
test('ignores all generated outputs and keeps renderer/pass configuration fixed', async () => {
|
|
198
|
+
const { root } = await fixture();
|
|
199
|
+
const processor = await SuiteProcessor.create(root);
|
|
200
|
+
await processor.initialize();
|
|
201
|
+
const before = (await stat(join(root, 'index.json'))).mtimeMs;
|
|
202
|
+
processor.notify([
|
|
203
|
+
'index.json',
|
|
204
|
+
aKey,
|
|
205
|
+
'one/beauty/a.vs-ref.delta.avif',
|
|
206
|
+
'one/beauty/a.avif.uuid.tmp',
|
|
207
|
+
'fidelity.json',
|
|
208
|
+
'one/new-pass/a.avif',
|
|
209
|
+
'one/beauty/new-renderer.avif',
|
|
210
|
+
]);
|
|
211
|
+
expect(await processor.flush()).toEqual({ computed: 0, skipped: 0, failed: [] });
|
|
212
|
+
expect((await stat(join(root, 'index.json'))).mtimeMs).toBe(before);
|
|
213
|
+
});
|
|
214
|
+
test('failed pairs do not spin and retry after a new input revision', async () => {
|
|
215
|
+
const { root, dir } = await fixture();
|
|
216
|
+
const processor = await SuiteProcessor.create(root);
|
|
217
|
+
await processor.initialize();
|
|
218
|
+
await writeFile(join(dir, 'a.avif'), 'partial');
|
|
219
|
+
processor.notify(['one/beauty/a.avif']);
|
|
220
|
+
expect((await processor.flush()).failed).toHaveLength(1);
|
|
221
|
+
processor.notify(['one/beauty/a.avif']);
|
|
222
|
+
expect(await processor.flush()).toEqual({ computed: 0, skipped: 0, failed: [] });
|
|
223
|
+
await writeFile(join(dir, 'a.avif'), await image(150));
|
|
224
|
+
processor.notify(['one/beauty/a.avif']);
|
|
225
|
+
expect(await processor.flush()).toMatchObject({ computed: 1, failed: [] });
|
|
226
|
+
});
|
|
227
|
+
test('multiple references invalidate both incoming and outgoing comparisons', async () => {
|
|
228
|
+
const { root, dir } = await fixture();
|
|
229
|
+
const config = JSON.parse(await readFile(join(root, 'fidelity.json'), 'utf8'));
|
|
230
|
+
config.renderers[2].reference = true;
|
|
231
|
+
await writeFile(join(root, 'fidelity.json'), JSON.stringify(config));
|
|
232
|
+
const processor = await SuiteProcessor.create(root);
|
|
233
|
+
expect(await processor.initialize()).toMatchObject({ computed: 4 });
|
|
234
|
+
await writeFile(join(dir, 'b.avif'), await image(140));
|
|
235
|
+
processor.notify(['one/beauty/b.avif']);
|
|
236
|
+
expect(await processor.flush()).toMatchObject({ computed: 3 });
|
|
237
|
+
});
|
|
238
|
+
test('metrics-only processing avoids delta encoding and reuses its results', async () => {
|
|
239
|
+
const { root } = await fixture();
|
|
240
|
+
const config = JSON.parse(await readFile(join(root, 'fidelity.json'), 'utf8'));
|
|
241
|
+
await writeFile(join(root, 'fidelity.json'), JSON.stringify({ ...config, delta: false }));
|
|
242
|
+
const compare = vi.spyOn(comparison, 'compareImages');
|
|
243
|
+
expect(await processSuite(root)).toMatchObject({ computed: 2 });
|
|
244
|
+
for (const result of compare.mock.results)
|
|
245
|
+
expect((await result.value).deltaImage.length).toBe(0);
|
|
246
|
+
expect((await index(root)).metrics[aKey].maxError).toBe(0);
|
|
247
|
+
await expect(stat(join(root, 'one/beauty/a.vs-ref.delta.avif'))).rejects.toMatchObject({ code: 'ENOENT' });
|
|
248
|
+
expect(await processSuite(root)).toMatchObject({ computed: 0, skipped: 2 });
|
|
249
|
+
});
|
|
250
|
+
test('one-shot changes remove stale index records after files disappeared before startup', async () => {
|
|
251
|
+
const { root, dir } = await fixture();
|
|
252
|
+
await processSuite(root);
|
|
253
|
+
await rm(dir, { recursive: true });
|
|
254
|
+
const { processChanges } = await import('./process.js');
|
|
255
|
+
expect(await processChanges(root, ['one/beauty/ref.avif'])).toMatchObject({ computed: 0, failed: [] });
|
|
256
|
+
expect((await index(root)).metrics).toEqual({});
|
|
257
|
+
expect((await index(root)).root.scenes).toEqual([]);
|
|
258
|
+
});
|
|
259
|
+
test('output-directory removal invalidates its scene even without individual unlink events', async () => {
|
|
260
|
+
const { root, dir } = await fixture();
|
|
261
|
+
const processor = await SuiteProcessor.create(root);
|
|
262
|
+
await processor.initialize();
|
|
263
|
+
await rm(dir, { recursive: true });
|
|
264
|
+
processor.removeDirectory('one/beauty');
|
|
265
|
+
await processor.flush();
|
|
266
|
+
expect((await index(root)).metrics).toEqual({});
|
|
267
|
+
expect((await index(root)).root.scenes).toEqual([]);
|
|
268
|
+
});
|
|
269
|
+
//# sourceMappingURL=process.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.test.js","sourceRoot":"","sources":["../../src/core/process.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/core/progress.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/core/progress.ts"],"names":[],"mappings":""}
|
package/dist/core/scan.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type FidelityConfig } from './schema.js';
|
|
2
|
+
import type { ProgressCallback } from './progress.js';
|
|
2
3
|
export interface SceneNode {
|
|
3
4
|
/** Slash-joined path from the root, e.g. `surfaces/standard_surface/brass`. */
|
|
4
5
|
path: string;
|
|
@@ -21,6 +22,12 @@ export interface Suite {
|
|
|
21
22
|
}
|
|
22
23
|
export declare function readConfig(root: string): Promise<FidelityConfig>;
|
|
23
24
|
/** A directory is a scene when any `<output>/<renderer>.avif` exists in it; every other directory is a group. */
|
|
24
|
-
export declare function scanSuite(root: string
|
|
25
|
+
export declare function scanSuite(root: string, options?: {
|
|
26
|
+
config?: FidelityConfig;
|
|
27
|
+
onScene?: (scene: SceneNode) => Promise<void>;
|
|
28
|
+
onProgress?: ProgressCallback;
|
|
29
|
+
}): Promise<Suite>;
|
|
30
|
+
/** Scan one known scene without walking the rest of the suite. */
|
|
31
|
+
export declare function scanScene(root: string, rel: string, config: FidelityConfig): Promise<SceneNode | null>;
|
|
25
32
|
export declare function allScenes(g: GroupNode): Generator<SceneNode>;
|
|
26
33
|
//# sourceMappingURL=scan.d.ts.map
|
package/dist/core/scan.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/core/scan.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/core/scan.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,WAAW,SAAS;IACxB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAClC;AACD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AACD,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,SAAS,CAAC;CACjB;AAaD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAEtE;AAED,iHAAiH;AACjH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC1B,GACL,OAAO,CAAC,KAAK,CAAC,CAyDhB;AAED,kEAAkE;AAClE,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAO5G;AA8BD,wBAAiB,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAG7D"}
|
package/dist/core/scan.js
CHANGED
|
@@ -8,10 +8,28 @@ export async function readConfig(root) {
|
|
|
8
8
|
return configSchema.parse(JSON.parse(await readFile(join(root, 'fidelity.json'), 'utf8')));
|
|
9
9
|
}
|
|
10
10
|
/** A directory is a scene when any `<output>/<renderer>.avif` exists in it; every other directory is a group. */
|
|
11
|
-
export async function scanSuite(root) {
|
|
12
|
-
const config = await readConfig(root);
|
|
11
|
+
export async function scanSuite(root, options = {}) {
|
|
12
|
+
const config = options.config ?? (await readConfig(root));
|
|
13
13
|
const rendererIds = config.renderers.map((r) => r.id);
|
|
14
|
+
let completed = 0;
|
|
15
|
+
let total = 1;
|
|
16
|
+
const report = () => options.onProgress?.({ phase: 'Scanning', completed, total, unit: 'directories' });
|
|
17
|
+
report();
|
|
14
18
|
async function visit(rel) {
|
|
19
|
+
try {
|
|
20
|
+
return await visitDirectory(rel);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (rel && isMissing(error))
|
|
24
|
+
return null;
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
completed++;
|
|
29
|
+
report();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function visitDirectory(rel) {
|
|
15
33
|
const dir = join(root, rel);
|
|
16
34
|
const images = {};
|
|
17
35
|
for (const o of config.outputs) {
|
|
@@ -26,13 +44,18 @@ export async function scanSuite(root) {
|
|
|
26
44
|
// scene.json also marks scenes whose renders are all missing or failed.
|
|
27
45
|
if (rel && (Object.keys(images).length || (await exists(join(dir, 'scene.json'))))) {
|
|
28
46
|
const meta = sceneMetaSchema.parse((await exists(join(dir, 'scene.json'))) ? JSON.parse(await readFile(join(dir, 'scene.json'), 'utf8')) : {});
|
|
29
|
-
|
|
47
|
+
const scene = { path: rel, title: meta.title ?? rel.split('/').pop(), tags: meta.tags, hasReadme, images };
|
|
48
|
+
await options.onScene?.(scene);
|
|
49
|
+
return scene;
|
|
30
50
|
}
|
|
31
51
|
const group = { path: rel, hasReadme, groups: [], scenes: [] };
|
|
32
52
|
const outputIds = new Set(config.outputs.map((o) => o.id));
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
53
|
+
const children = (await readdir(dir, { withFileTypes: true }))
|
|
54
|
+
.filter((e) => e.isDirectory() && !e.name.startsWith('.') && !outputIds.has(e.name))
|
|
55
|
+
.toSorted((a, b) => a.name.localeCompare(b.name));
|
|
56
|
+
total += children.length;
|
|
57
|
+
report();
|
|
58
|
+
for (const e of children) {
|
|
36
59
|
const child = await visit(rel ? `${rel}/${e.name}` : e.name);
|
|
37
60
|
if (!child)
|
|
38
61
|
continue;
|
|
@@ -48,6 +71,47 @@ export async function scanSuite(root) {
|
|
|
48
71
|
const top = (await visit('')) ?? { path: '', hasReadme: false, groups: [], scenes: [] };
|
|
49
72
|
return { config, hasReadme: await exists(join(root, 'README.md')), root: top };
|
|
50
73
|
}
|
|
74
|
+
/** Scan one known scene without walking the rest of the suite. */
|
|
75
|
+
export async function scanScene(root, rel, config) {
|
|
76
|
+
try {
|
|
77
|
+
return await scanSceneDirectory(root, rel, config);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (isMissing(error))
|
|
81
|
+
return null;
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function isMissing(error) {
|
|
86
|
+
const code = error.code;
|
|
87
|
+
return code === 'ENOENT' || code === 'ENOTDIR';
|
|
88
|
+
}
|
|
89
|
+
async function scanSceneDirectory(root, rel, config) {
|
|
90
|
+
const dir = join(root, rel);
|
|
91
|
+
if (!rel || !(await isDir(dir)))
|
|
92
|
+
return null;
|
|
93
|
+
const images = {};
|
|
94
|
+
for (const output of config.outputs) {
|
|
95
|
+
const found = [];
|
|
96
|
+
for (const renderer of config.renderers) {
|
|
97
|
+
if (await exists(join(dir, output.id, imageFile(renderer.id))))
|
|
98
|
+
found.push(renderer.id);
|
|
99
|
+
}
|
|
100
|
+
if (found.length)
|
|
101
|
+
images[output.id] = found;
|
|
102
|
+
}
|
|
103
|
+
const metaFile = join(dir, 'scene.json');
|
|
104
|
+
if (!Object.keys(images).length && !(await exists(metaFile)))
|
|
105
|
+
return null;
|
|
106
|
+
const meta = sceneMetaSchema.parse((await exists(metaFile)) ? JSON.parse(await readFile(metaFile, 'utf8')) : {});
|
|
107
|
+
return {
|
|
108
|
+
path: rel,
|
|
109
|
+
title: meta.title ?? rel.split('/').pop(),
|
|
110
|
+
tags: meta.tags,
|
|
111
|
+
hasReadme: await exists(join(dir, 'README.md')),
|
|
112
|
+
images,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
51
115
|
export function* allScenes(g) {
|
|
52
116
|
yield* g.scenes;
|
|
53
117
|
for (const c of g.groups)
|
package/dist/core/scan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/core/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAuB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/core/scan.ts"],"names":[],"mappings":"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"}
|
package/dist/core/suite.test.js
CHANGED
|
@@ -22,7 +22,13 @@ test('scan, process, staleness, etag', async () => {
|
|
|
22
22
|
tags: ['x'],
|
|
23
23
|
images: { beauty: ['ref', 'a', 'b'] },
|
|
24
24
|
});
|
|
25
|
-
|
|
25
|
+
const progress = [];
|
|
26
|
+
expect(await processSuite(root, { onProgress: (update) => progress.push(update) })).toMatchObject({
|
|
27
|
+
computed: 2,
|
|
28
|
+
skipped: 0,
|
|
29
|
+
failed: [],
|
|
30
|
+
});
|
|
31
|
+
expect(progress.filter((update) => update.completed === update.total).map((update) => update.phase)).toEqual(expect.arrayContaining(['Scanning', 'Comparing', 'Writing index']));
|
|
26
32
|
const a = JSON.parse(await readFile(join(dir, 'a.vs-ref.metrics.json'), 'utf8'));
|
|
27
33
|
const b = JSON.parse(await readFile(join(dir, 'b.vs-ref.metrics.json'), 'utf8'));
|
|
28
34
|
expect(a.psnr).toBeNull();
|
|
@@ -74,4 +80,21 @@ test('config rejects empty outputs and duplicate ids', async () => {
|
|
|
74
80
|
await expect(readConfig(root)).rejects.toThrow();
|
|
75
81
|
}
|
|
76
82
|
});
|
|
83
|
+
const strip = (raw) => JSON.parse(raw.replace(/"generatedAt": "[^"]*"/g, '"generatedAt": ""'));
|
|
84
|
+
test('concurrent and sequential processing give identical results', async () => {
|
|
85
|
+
const root = await mkdtemp(join(tmpdir(), 'fk-conc-'));
|
|
86
|
+
await writeFile(join(root, 'fidelity.json'), JSON.stringify({ title: 'T', renderers: [{ id: 'ref', reference: true }, { id: 'a' }, { id: 'b' }] }));
|
|
87
|
+
for (let i = 0; i < 6; i++) {
|
|
88
|
+
const dir = join(root, `s${i}`, 'beauty');
|
|
89
|
+
await mkdir(dir, { recursive: true });
|
|
90
|
+
await writeFile(join(root, `s${i}`, 'scene.json'), '{}');
|
|
91
|
+
await writeFile(join(dir, 'ref.avif'), await png(100));
|
|
92
|
+
await writeFile(join(dir, 'a.avif'), await png(100 + i));
|
|
93
|
+
await writeFile(join(dir, 'b.avif'), await png(120 + i));
|
|
94
|
+
}
|
|
95
|
+
expect(await processSuite(root, { concurrency: 1 })).toMatchObject({ computed: 12, failed: [] });
|
|
96
|
+
const seq = strip(await readFile(join(root, 'index.json'), 'utf8'));
|
|
97
|
+
expect(await processSuite(root, { force: true, concurrency: 4 })).toMatchObject({ computed: 12, failed: [] });
|
|
98
|
+
expect(strip(await readFile(join(root, 'index.json'), 'utf8'))).toEqual(seq);
|
|
99
|
+
});
|
|
77
100
|
//# sourceMappingURL=suite.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suite.test.js","sourceRoot":"","sources":["../../src/core/suite.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"suite.test.js","sourceRoot":"","sources":["../../src/core/suite.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ProgressCallback } from './core/progress.js';
|
|
2
|
+
export interface ProgressStream {
|
|
3
|
+
isTTY?: boolean;
|
|
4
|
+
columns?: number;
|
|
5
|
+
write(text: string): unknown;
|
|
6
|
+
}
|
|
7
|
+
/** A single terminal line, throttled across phase changes and file completions. */
|
|
8
|
+
export declare function createProgress(label: string, quiet?: boolean, stream?: ProgressStream, now?: () => number): {
|
|
9
|
+
update: ProgressCallback;
|
|
10
|
+
finish: () => void;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAkB,MAAM,oBAAoB,CAAC;AAE3E,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAC9B;AAED,mFAAmF;AACnF,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,KAAK,UAAQ,EACb,MAAM,GAAE,cAA+B,EACvC,GAAG,GAAE,MAAM,MAAiB,GAC3B;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAkClD"}
|
package/dist/progress.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** A single terminal line, throttled across phase changes and file completions. */
|
|
2
|
+
export function createProgress(label, quiet = false, stream = process.stdout, now = Date.now) {
|
|
3
|
+
let phase = '';
|
|
4
|
+
let phaseStart = 0;
|
|
5
|
+
let lastWrite = -Infinity;
|
|
6
|
+
let showing = false;
|
|
7
|
+
const update = (status) => {
|
|
8
|
+
if (quiet || !stream.isTTY)
|
|
9
|
+
return;
|
|
10
|
+
const time = now();
|
|
11
|
+
if (status.phase !== phase) {
|
|
12
|
+
phase = status.phase;
|
|
13
|
+
phaseStart = time;
|
|
14
|
+
}
|
|
15
|
+
if (time - lastWrite < 1000)
|
|
16
|
+
return;
|
|
17
|
+
const remaining = Math.max(0, status.total - status.completed);
|
|
18
|
+
const elapsed = time - phaseStart;
|
|
19
|
+
const eta = status.completed > 0 && elapsed >= 1000 && remaining > 0
|
|
20
|
+
? `, ETA ~${formatDuration((elapsed / status.completed) * remaining)}`
|
|
21
|
+
: '';
|
|
22
|
+
const line = `${label}: ${phase} ${status.completed}/${status.total} ${status.unit} (${remaining} remaining${eta})`;
|
|
23
|
+
stream.write(`\r\x1b[2K${line.slice(0, Math.max(0, (stream.columns ?? Infinity) - 1))}`);
|
|
24
|
+
lastWrite = time;
|
|
25
|
+
showing = true;
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
update,
|
|
29
|
+
finish: () => {
|
|
30
|
+
if (showing)
|
|
31
|
+
stream.write('\r\x1b[2K');
|
|
32
|
+
showing = false;
|
|
33
|
+
phase = '';
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function formatDuration(ms) {
|
|
38
|
+
const seconds = Math.ceil(ms / 1000);
|
|
39
|
+
if (seconds < 60)
|
|
40
|
+
return `${seconds}s`;
|
|
41
|
+
const minutes = Math.ceil(seconds / 60);
|
|
42
|
+
if (minutes < 60)
|
|
43
|
+
return `${minutes}m`;
|
|
44
|
+
return `${Math.ceil(minutes / 60)}h`;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"AAQA,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAC5B,KAAa,EACb,KAAK,GAAG,KAAK,EACb,MAAM,GAAmB,OAAO,CAAC,MAAM,EACvC,GAAG,GAAiB,IAAI,CAAC,GAAG;IAE5B,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,SAAS,GAAG,CAAC,QAAQ,CAAC;IAC1B,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,MAAM,MAAM,GAAG,CAAC,MAAsB,EAAE,EAAE;QACxC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK;YAAE,OAAO;QACnC,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC;QACnB,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YAC3B,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YACrB,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,IAAI,GAAG,SAAS,GAAG,IAAI;YAAE,OAAO;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,IAAI,GAAG,UAAU,CAAC;QAClC,MAAM,GAAG,GACP,MAAM,CAAC,SAAS,GAAG,CAAC,IAAI,OAAO,IAAI,IAAI,IAAI,SAAS,GAAG,CAAC;YACtD,CAAC,CAAC,UAAU,cAAc,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,EAAE;YACtE,CAAC,CAAC,EAAE,CAAC;QACT,MAAM,IAAI,GAAG,GAAG,KAAK,KAAK,KAAK,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,aAAa,GAAG,GAAG,CAAC;QACpH,MAAM,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzF,SAAS,GAAG,IAAI,CAAC;QACjB,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC,CAAC;IAEF,OAAO;QACL,MAAM;QACN,MAAM,EAAE,GAAG,EAAE;YACX,IAAI,OAAO;gBAAE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACvC,OAAO,GAAG,KAAK,CAAC;YAChB,KAAK,GAAG,EAAE,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,EAAU;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACrC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,GAAG,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACxC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,GAAG,CAAC;IACvC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.test.d.ts","sourceRoot":"","sources":["../src/progress.test.ts"],"names":[],"mappings":""}
|