fidelity-kit 2.0.0 → 2.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 CHANGED
@@ -21,6 +21,12 @@ npx fidelity-kit dev results
21
21
 
22
22
  Open the URL printed by the command (usually <http://localhost:3000>). `dev` processes new or changed images before starting and serves files without browser caching, so a reload shows your latest render. See the [working example](https://github.com/bhouston/fidelity-kit/tree/main/examples/demo) for a complete suite.
23
23
 
24
+ ## See it in action
25
+
26
+ [Material Fidelity](https://material-fidelity.ben3d.ca) uses fidelity-kit to compare renderer output side by side, with visual deltas and PSNR metrics. Open the live site to explore the results.
27
+
28
+ [![Material Fidelity comparison site showing renderer images, visual deltas, and PSNR metrics](https://raw.githubusercontent.com/bhouston/fidelity-kit/main/packages/website/static/img/material-fidelity-preview.webp)](https://material-fidelity.ben3d.ca)
29
+
24
30
  ## Adopt it in your suite
25
31
 
26
32
  Create a `results` directory with a `fidelity.json` file. Put each scene in its own folder, with one AVIF image per renderer under each output name:
@@ -7,6 +7,7 @@ export declare const configSchema: z.ZodObject<{
7
7
  id: z.ZodString;
8
8
  label: z.ZodOptional<z.ZodString>;
9
9
  reference: z.ZodOptional<z.ZodBoolean>;
10
+ enabled: z.ZodOptional<z.ZodBoolean>;
10
11
  category: z.ZodOptional<z.ZodString>;
11
12
  }, z.core.$strip>>;
12
13
  outputs: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,2FAA2F;AAC3F,eAAO,MAAM,YAAY;;;;;;;;;;;;;iBA4BvB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAE1D,qCAAqC;AACrC,eAAO,MAAM,eAAe;;;iBAAoF,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,2FAA2F;AAC3F,eAAO,MAAM,YAAY;;;;;;;;;;;;;;iBA8BvB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAE1D,qCAAqC;AACrC,eAAO,MAAM,eAAe;;;iBAAoF,CAAC"}
@@ -16,6 +16,8 @@ export const configSchema = z.object({
16
16
  id,
17
17
  label: z.string().optional(),
18
18
  reference: z.boolean().optional(),
19
+ /** `false` hides the renderer by default; viewers can still toggle it on. */
20
+ enabled: z.boolean().optional(),
19
21
  category: z.string().optional(),
20
22
  }))
21
23
  .refine((r) => r.some((x) => x.reference), 'at least one renderer needs "reference": true')
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;AACtD,MAAM,SAAS,GAAG,CAA2B,KAAU,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC;AAExH,2FAA2F;AAC3F,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACzE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QACrB,UAAU,CAAC,IAAI,CAAC,EAClB,8EAA8E,CAC/E;SACA,QAAQ,EAAE;IACb,SAAS,EAAE,CAAC;SACT,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,EAAE;QACF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC5B,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QACjC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAChC,CAAC,CACH;SACA,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,+CAA+C,CAAC;SAC1F,MAAM,CAAC,SAAS,EAAE,6BAA6B,CAAC;IACnD,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;SACrD,GAAG,CAAC,CAAC,EAAE,iCAAiC,CAAC;SACzC,MAAM,CAAC,SAAS,EAAE,2BAA2B,CAAC;SAC9C,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;CAC/B,CAAC,CAAC;AAGH,qCAAqC;AACrC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;AACtD,MAAM,SAAS,GAAG,CAA2B,KAAU,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC;AAExH,2FAA2F;AAC3F,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACzE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QACrB,UAAU,CAAC,IAAI,CAAC,EAClB,8EAA8E,CAC/E;SACA,QAAQ,EAAE;IACb,SAAS,EAAE,CAAC;SACT,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,EAAE;QACF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC5B,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QACjC,6EAA6E;QAC7E,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC/B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAChC,CAAC,CACH;SACA,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,+CAA+C,CAAC;SAC1F,MAAM,CAAC,SAAS,EAAE,6BAA6B,CAAC;IACnD,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;SACrD,GAAG,CAAC,CAAC,EAAE,iCAAiC,CAAC;SACzC,MAAM,CAAC,SAAS,EAAE,2BAA2B,CAAC;SAC9C,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;CAC/B,CAAC,CAAC;AAGH,qCAAqC;AACrC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ export declare const liveReloadPath = "/data/events";
2
+ /** One trailing debounce shared by all clients; revisions catch updates missed during reconnects. */
3
+ export declare function createLiveReload(debounceMs?: number): {
4
+ revision: () => string;
5
+ notify(): void;
6
+ response(req: Request): Response;
7
+ close(): void;
8
+ };
9
+ export type LiveReload = ReturnType<typeof createLiveReload>;
10
+ /** Observe published results (including external processing) and viewer README content. */
11
+ export declare function watchLiveReload(root: string, liveReload: LiveReload): Promise<import("chokidar").FSWatcher>;
12
+ //# sourceMappingURL=live-reload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-reload.d.ts","sourceRoot":"","sources":["../src/live-reload.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAE7C,qGAAqG;AACrG,wBAAgB,gBAAgB,CAAC,UAAU,SAAO;;;kBAoBhC,OAAO,GAAG,QAAQ;;EA4CnC;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE7D,2FAA2F;AAC3F,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,yCAyBzE"}
@@ -0,0 +1,108 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { relative, resolve, sep } from 'node:path';
3
+ import { watch } from 'chokidar';
4
+ export const liveReloadPath = '/data/events';
5
+ /** One trailing debounce shared by all clients; revisions catch updates missed during reconnects. */
6
+ export function createLiveReload(debounceMs = 5000) {
7
+ const boot = randomUUID();
8
+ let version = 0;
9
+ let timer;
10
+ let closed = false;
11
+ const clients = new Set();
12
+ const revision = () => `${boot}:${version}`;
13
+ const frame = (event) => `event: ${event}\ndata: ${revision()}\n\n`;
14
+ return {
15
+ revision,
16
+ notify() {
17
+ if (closed)
18
+ return;
19
+ if (timer)
20
+ clearTimeout(timer);
21
+ timer = setTimeout(() => {
22
+ timer = undefined;
23
+ version++;
24
+ for (const client of clients)
25
+ client.send(frame('change'));
26
+ }, debounceMs);
27
+ timer.unref();
28
+ },
29
+ response(req) {
30
+ const headers = {
31
+ 'Content-Type': 'text/event-stream',
32
+ 'Cache-Control': 'no-store',
33
+ 'X-Accel-Buffering': 'no',
34
+ };
35
+ if (closed)
36
+ return new Response(null, { status: 503, headers });
37
+ if (req.method === 'HEAD')
38
+ return new Response(null, { headers });
39
+ let dispose;
40
+ const body = new ReadableStream({
41
+ start(controller) {
42
+ const encoder = new TextEncoder();
43
+ const client = {
44
+ send(message) {
45
+ // A stalled reader reconnects instead of accumulating an unbounded queue.
46
+ if ((controller.desiredSize ?? 0) <= 0)
47
+ return client.close();
48
+ controller.enqueue(encoder.encode(message));
49
+ },
50
+ close() {
51
+ dispose?.();
52
+ controller.close();
53
+ },
54
+ };
55
+ const heartbeat = setInterval(() => client.send(': keepalive\n\n'), 15000);
56
+ heartbeat.unref();
57
+ dispose = () => {
58
+ clearInterval(heartbeat);
59
+ clients.delete(client);
60
+ };
61
+ clients.add(client);
62
+ client.send(frame('ready'));
63
+ },
64
+ cancel() {
65
+ dispose?.();
66
+ },
67
+ });
68
+ return new Response(body, { headers });
69
+ },
70
+ close() {
71
+ closed = true;
72
+ if (timer)
73
+ clearTimeout(timer);
74
+ for (const client of clients)
75
+ client.close();
76
+ },
77
+ };
78
+ }
79
+ /** Observe published results (including external processing) and viewer README content. */
80
+ export async function watchLiveReload(root, liveReload) {
81
+ const base = resolve(root);
82
+ const relevant = (path) => {
83
+ const rel = relative(base, path).split(sep).join('/');
84
+ return rel === 'index.json' || rel === 'README.md' || rel.endsWith('/README.md');
85
+ };
86
+ const watcher = watch(base, {
87
+ ignoreInitial: true,
88
+ awaitWriteFinish: { stabilityThreshold: 500, pollInterval: 100 },
89
+ ignored: (path, stats) => !!stats?.isFile() && !relevant(path),
90
+ });
91
+ watcher.on('all', (event, path) => {
92
+ if (event === 'unlinkDir' || relevant(path))
93
+ liveReload.notify();
94
+ });
95
+ watcher.on('error', (error) => console.error('Live reload watch error:', error));
96
+ try {
97
+ await new Promise((resolveReady, reject) => {
98
+ watcher.once('ready', resolveReady);
99
+ watcher.once('error', reject);
100
+ });
101
+ }
102
+ catch (error) {
103
+ await watcher.close();
104
+ throw error;
105
+ }
106
+ return watcher;
107
+ }
108
+ //# sourceMappingURL=live-reload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-reload.js","sourceRoot":"","sources":["../src/live-reload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC;AAE7C,qGAAqG;AACrG,MAAM,UAAU,gBAAgB,CAAC,UAAU,GAAG,IAAI;IAChD,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAgD,CAAC;IACrD,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkD,CAAC;IAC1E,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,UAAU,KAAK,WAAW,QAAQ,EAAE,MAAM,CAAC;IAC5E,OAAO;QACL,QAAQ;QACR,MAAM;YACJ,IAAI,MAAM;gBAAE,OAAO;YACnB,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YAC/B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBACtB,KAAK,GAAG,SAAS,CAAC;gBAClB,OAAO,EAAE,CAAC;gBACV,KAAK,MAAM,MAAM,IAAI,OAAO;oBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC7D,CAAC,EAAE,UAAU,CAAC,CAAC;YACf,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;QACD,QAAQ,CAAC,GAAY;YACnB,MAAM,OAAO,GAAG;gBACd,cAAc,EAAE,mBAAmB;gBACnC,eAAe,EAAE,UAAU;gBAC3B,mBAAmB,EAAE,IAAI;aAC1B,CAAC;YACF,IAAI,MAAM;gBAAE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;YAChE,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM;gBAAE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAClE,IAAI,OAAiC,CAAC;YACtC,MAAM,IAAI,GAAG,IAAI,cAAc,CAAa;gBAC1C,KAAK,CAAC,UAAU;oBACd,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;oBAClC,MAAM,MAAM,GAAG;wBACb,IAAI,CAAC,OAAe;4BAClB,0EAA0E;4BAC1E,IAAI,CAAC,UAAU,CAAC,WAAW,IAAI,CAAC,CAAC,IAAI,CAAC;gCAAE,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC;4BAC9D,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;wBAC9C,CAAC;wBACD,KAAK;4BACH,OAAO,EAAE,EAAE,CAAC;4BACZ,UAAU,CAAC,KAAK,EAAE,CAAC;wBACrB,CAAC;qBACF,CAAC;oBACF,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,CAAC;oBAC3E,SAAS,CAAC,KAAK,EAAE,CAAC;oBAClB,OAAO,GAAG,GAAG,EAAE;wBACb,aAAa,CAAC,SAAS,CAAC,CAAC;wBACzB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBACzB,CAAC,CAAC;oBACF,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBACpB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC9B,CAAC;gBACD,MAAM;oBACJ,OAAO,EAAE,EAAE,CAAC;gBACd,CAAC;aACF,CAAC,CAAC;YACH,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACzC,CAAC;QACD,KAAK;YACH,MAAM,GAAG,IAAI,CAAC;YACd,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YAC/B,KAAK,MAAM,MAAM,IAAI,OAAO;gBAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAC/C,CAAC;KACF,CAAC;AACJ,CAAC;AAID,2FAA2F;AAC3F,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,UAAsB;IACxE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,EAAE;QAChC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtD,OAAO,GAAG,KAAK,YAAY,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACnF,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE;QAC1B,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,EAAE,kBAAkB,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE;QAChE,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;KAC/D,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAChC,IAAI,KAAK,KAAK,WAAW,IAAI,QAAQ,CAAC,IAAI,CAAC;YAAE,UAAU,CAAC,MAAM,EAAE,CAAC;IACnE,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC,CAAC;IACjF,IAAI,CAAC;QACH,MAAM,IAAI,OAAO,CAAO,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE;YAC/C,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=live-reload.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-reload.test.d.ts","sourceRoot":"","sources":["../src/live-reload.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,112 @@
1
+ import { mkdtemp, rm, writeFile } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { afterEach, expect, test, vi } from 'vitest';
5
+ import { createLiveReload, watchLiveReload } from './live-reload.js';
6
+ import { createHandler, serve } from './server.js';
7
+ afterEach(() => vi.useRealTimers());
8
+ const decode = (value) => new TextDecoder().decode(value);
9
+ test('broadcasts one update to all clients five seconds after the last publication', async () => {
10
+ vi.useFakeTimers();
11
+ const live = createLiveReload();
12
+ const a = live.response(new Request('http://x/data/events')).body.getReader();
13
+ const b = live.response(new Request('http://x/data/events')).body.getReader();
14
+ try {
15
+ const revision = live.revision();
16
+ expect(decode((await a.read()).value)).toContain(`event: ready\ndata: ${revision}`);
17
+ await b.read();
18
+ live.notify();
19
+ await vi.advanceTimersByTimeAsync(4000);
20
+ live.notify();
21
+ await vi.advanceTimersByTimeAsync(4999);
22
+ expect(live.revision()).toBe(revision);
23
+ await vi.advanceTimersByTimeAsync(1);
24
+ expect(live.revision()).not.toBe(revision);
25
+ expect(decode((await a.read()).value)).toContain(`event: change\ndata: ${live.revision()}`);
26
+ expect(decode((await b.read()).value)).toContain('event: change');
27
+ await a.cancel();
28
+ live.notify();
29
+ await vi.advanceTimersByTimeAsync(5000);
30
+ expect(decode((await b.read()).value)).toContain('event: change');
31
+ }
32
+ finally {
33
+ live.close();
34
+ }
35
+ expect((await b.read()).done).toBe(true);
36
+ });
37
+ test('handshake carries current revision after reconnect and shutdown cancels pending notifications', async () => {
38
+ vi.useFakeTimers();
39
+ const live = createLiveReload();
40
+ live.notify();
41
+ await vi.advanceTimersByTimeAsync(5000);
42
+ const response = live.response(new Request('http://x/data/events'));
43
+ expect(response.headers.get('Content-Type')).toBe('text/event-stream');
44
+ expect(response.headers.get('Cache-Control')).toBe('no-store');
45
+ const reader = response.body.getReader();
46
+ expect(decode((await reader.read()).value)).toContain(live.revision());
47
+ const revision = live.revision();
48
+ live.notify();
49
+ live.close();
50
+ await vi.advanceTimersByTimeAsync(5000);
51
+ expect(live.revision()).toBe(revision);
52
+ expect((await reader.read()).done).toBe(true);
53
+ });
54
+ test('dev advertises the channel, serve does not, and HTTP disconnects clean up streams', async () => {
55
+ const root = await mkdtemp(join(tmpdir(), 'fk-live-http-'));
56
+ await writeFile(join(root, 'index.json'), '{}');
57
+ const live = createLiveReload(20);
58
+ const handler = createHandler(root, { dev: true, liveReload: live });
59
+ const server = await serve(handler, 0, '127.0.0.1');
60
+ try {
61
+ const address = server.address();
62
+ if (!address || typeof address === 'string')
63
+ throw new Error('Expected TCP address');
64
+ const url = `http://127.0.0.1:${address.port}`;
65
+ const index = await fetch(`${url}/data/index.json`);
66
+ expect(index.headers.get('X-Fidelity-Events')).toBe('data/events');
67
+ expect(index.headers.get('X-Fidelity-Revision')).toBe(live.revision());
68
+ await index.text();
69
+ const head = await fetch(`${url}/data/events`, { method: 'HEAD' });
70
+ expect(head.headers.get('Content-Type')).toBe('text/event-stream');
71
+ expect(await head.text()).toBe('');
72
+ const abort = new AbortController();
73
+ const response = await fetch(`${url}/data/events`, { signal: abort.signal });
74
+ const reader = response.body.getReader();
75
+ expect(decode((await reader.read()).value)).toContain('event: ready');
76
+ live.notify();
77
+ expect(decode((await reader.read()).value)).toContain('event: change');
78
+ abort.abort();
79
+ await reader.cancel().catch(() => { });
80
+ const ordinary = createHandler(root, { liveReload: live });
81
+ const normalIndex = await ordinary(new Request('http://x/data/index.json'));
82
+ expect(normalIndex.headers.get('X-Fidelity-Events')).toBeNull();
83
+ await normalIndex.text();
84
+ expect((await ordinary(new Request('http://x/data/events'))).status).toBe(404);
85
+ }
86
+ finally {
87
+ live.close();
88
+ server.closeAllConnections();
89
+ await new Promise((resolve) => server.close(() => resolve()));
90
+ await rm(root, { recursive: true, force: true });
91
+ }
92
+ });
93
+ test('watches external index and README publications but ignores temporary and input files', async () => {
94
+ const root = await mkdtemp(join(tmpdir(), 'fk-live-watch-'));
95
+ const live = createLiveReload();
96
+ const notify = vi.spyOn(live, 'notify');
97
+ const watcher = await watchLiveReload(root, live);
98
+ try {
99
+ await writeFile(join(root, 'index.json.tmp'), '{}');
100
+ await writeFile(join(root, 'renderer.png'), 'image');
101
+ await writeFile(join(root, 'index.json'), '{}');
102
+ await vi.waitFor(() => expect(notify).toHaveBeenCalledTimes(1), { timeout: 4000 });
103
+ await writeFile(join(root, 'README.md'), '# Updated');
104
+ await vi.waitFor(() => expect(notify).toHaveBeenCalledTimes(2), { timeout: 4000 });
105
+ }
106
+ finally {
107
+ await watcher.close();
108
+ live.close();
109
+ await rm(root, { recursive: true, force: true });
110
+ }
111
+ });
112
+ //# sourceMappingURL=live-reload.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-reload.test.js","sourceRoot":"","sources":["../src/live-reload.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEnD,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,CAAC;AACpC,MAAM,MAAM,GAAG,CAAC,KAAkB,EAAE,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEvE,IAAI,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;IAC9F,EAAE,CAAC,aAAa,EAAE,CAAC;IACnB,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAK,CAAC,SAAS,EAAE,CAAC;IAC/E,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAK,CAAC,SAAS,EAAE,CAAC;IAC/E,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;QACpF,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,wBAAwB,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC5F,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAClE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;QACjB,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACpE,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IACD,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+FAA+F,EAAE,KAAK,IAAI,EAAE;IAC/G,EAAE,CAAC,aAAa,EAAE,CAAC;IACnB,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,IAAI,CAAC,MAAM,EAAE,CAAC;IACd,MAAM,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC;IACpE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACvE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAK,CAAC,SAAS,EAAE,CAAC;IAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;IACd,IAAI,CAAC,KAAK,EAAE,CAAC;IACb,MAAM,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mFAAmF,EAAE,KAAK,IAAI,EAAE;IACnG,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IAC5D,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,IAAI,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;IACpD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACrF,MAAM,GAAG,GAAG,oBAAoB,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,kBAAkB,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvE,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACnE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACnE,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,cAAc,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7E,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAK,CAAC,SAAS,EAAE,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACtE,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QACvE,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,IAAI,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC;QAC5E,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAChE,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjF,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAC7B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACpE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sFAAsF,EAAE,KAAK,IAAI,EAAE;IACtG,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,IAAI,CAAC,CAAC;QACpD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACnF,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,WAAW,CAAC,CAAC;QACtD,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACrF,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC,CAAC,CAAC"}
package/dist/run.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,uEAAuE;AACvE,wBAAsB,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,iBA8CpD"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,uEAAuE;AACvE,wBAAsB,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,iBA0DpD"}
package/dist/run.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createLiveReload, watchLiveReload } from './live-reload.js';
1
2
  import { existsSync } from 'node:fs';
2
3
  import { resolve } from 'node:path';
3
4
  import { processSuite } from './core/index.js';
@@ -34,10 +35,23 @@ export async function run(argv, dev) {
34
35
  console.error(`FAILED ${f.file}: ${f.error}`);
35
36
  }, { concurrency: argv.concurrency, process: argv.process, onProgress: progress.update });
36
37
  }
37
- const server = await serve(createHandler(root, { cache, dev }), argv.port, argv.host).catch(async (error) => {
38
+ const liveReload = dev ? createLiveReload() : undefined;
39
+ let liveWatcher;
40
+ const server = await (async () => {
41
+ if (liveReload)
42
+ liveWatcher = await watchLiveReload(root, liveReload);
43
+ return serve(createHandler(root, { cache, dev, liveReload }), argv.port, argv.host);
44
+ })().catch(async (error) => {
45
+ liveReload?.close();
46
+ await liveWatcher?.close();
38
47
  await watcher?.close();
39
48
  throw error;
40
49
  });
50
+ server.once('close', () => {
51
+ liveReload?.close();
52
+ void liveWatcher?.close();
53
+ void watcher?.close();
54
+ });
41
55
  const address = server.address();
42
56
  if (!address || typeof address === 'string')
43
57
  throw new Error('Could not determine the viewer port');
package/dist/run.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { type Server } from 'node:http';
2
2
  import { isDataFile } from './core/paths.js';
3
+ import { type LiveReload } from './live-reload.js';
3
4
  /** The prebuilt viewer SPA (built by `pnpm build` into packages/cli/viewer, shipped in the npm package). */
4
5
  export declare const viewerDir: string;
5
6
  export declare function assertViewerBuilt(): void;
@@ -21,14 +22,16 @@ export interface HandlerOptions {
21
22
  * hashed: `/data/image-hashes.json` is an empty `{}` (a 404 would log a console error in the browser), `?v=` is ignored and `image-hashes.json` is not even loaded.
22
23
  */
23
24
  dev?: boolean;
25
+ /** Dev-only result change channel. */
26
+ liveReload?: LiveReload;
24
27
  }
25
28
  /**
26
- * `/data/*` = the suite (allowlisted files); everything else = the viewer SPA (hash routing, so no fallback needed).
29
+ * `/data/*` = the suite (allowlisted files); everything else = the viewer SPA (the detail page is `/?scene=`, so no path fallback is needed).
27
30
  * Serve mode: images are shared-cacheable per `cache`; `index.json`, READMEs and `index.html` always revalidate (cheap
28
31
  * 304s) so a re-run of `process` shows up immediately; hashed `/assets/*` are immutable. Dev mode: nothing is cached.
29
32
  * Serve mode also keeps a lazy content-hash map (pre-populated from `<root>/image-hashes.json`), lists it at
30
33
  * `/data/image-hashes.json`, and serves `image?v=<hash>` as immutable only when `<hash>` is the file's current hash.
31
34
  */
32
- export declare function createHandler(root: string, { assets, cache, dev }?: HandlerOptions): (req: Request) => Promise<Response>;
35
+ export declare function createHandler(root: string, { assets, cache, dev, liveReload }?: HandlerOptions): (req: Request) => Promise<Response>;
33
36
  export declare function serve(handler: (req: Request) => Promise<Response>, port: number | undefined, host: string): Promise<Server>;
34
37
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAgBtD,OAAO,EAAE,UAAU,EAAe,MAAM,iBAAiB,CAAC;AAE1D,4GAA4G;AAC5G,eAAO,MAAM,SAAS,QAAuD,CAAC;AAE9E,wBAAgB,iBAAiB,SAEhC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,qHAAqH;IACrH,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AACD,eAAO,MAAM,kBAAkB,EAAE,WAA0D,CAAC;AAE5F,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;OAGG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,EAAE,MAAkB,EAAE,KAA0B,EAAE,GAAW,EAAE,GAAE,cAAmB,SA8BjE,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAwB/C;AAED,wBAAsB,KAAK,CACzB,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,EAC5C,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CASjB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAgBtD,OAAO,EAAE,UAAU,EAAe,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnE,4GAA4G;AAC5G,eAAO,MAAM,SAAS,QAAuD,CAAC;AAE9E,wBAAgB,iBAAiB,SAEhC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,qHAAqH;IACrH,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AACD,eAAO,MAAM,kBAAkB,EAAE,WAA0D,CAAC;AAE5F,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;OAGG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,sCAAsC;IACtC,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,EAAE,MAAkB,EAAE,KAA0B,EAAE,GAAW,EAAE,UAAU,EAAE,GAAE,cAAmB,SA8B7E,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAqC/C;AAED,wBAAsB,KAAK,CACzB,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,EAC5C,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CASjB"}
package/dist/server.js CHANGED
@@ -7,6 +7,7 @@ import { relative, resolve as resolvePath, sep } from 'node:path';
7
7
  import { realpath } from 'node:fs/promises';
8
8
  import { fileResponse, freshFileResponse, HashStore, IMMUTABLE, notModified, readHashFile, resolveInside, } from './core/index.js';
9
9
  import { isDataFile, isImageFile } from './core/paths.js';
10
+ import { liveReloadPath } from './live-reload.js';
10
11
  /** The prebuilt viewer SPA (built by `pnpm build` into packages/cli/viewer, shipped in the npm package). */
11
12
  export const viewerDir = fileURLToPath(new URL('../viewer', import.meta.url));
12
13
  export function assertViewerBuilt() {
@@ -16,13 +17,13 @@ export function assertViewerBuilt() {
16
17
  export { isDataFile };
17
18
  export const defaultCachePolicy = { maxAge: 300, staleWhileRevalidate: 86400 };
18
19
  /**
19
- * `/data/*` = the suite (allowlisted files); everything else = the viewer SPA (hash routing, so no fallback needed).
20
+ * `/data/*` = the suite (allowlisted files); everything else = the viewer SPA (the detail page is `/?scene=`, so no path fallback is needed).
20
21
  * Serve mode: images are shared-cacheable per `cache`; `index.json`, READMEs and `index.html` always revalidate (cheap
21
22
  * 304s) so a re-run of `process` shows up immediately; hashed `/assets/*` are immutable. Dev mode: nothing is cached.
22
23
  * Serve mode also keeps a lazy content-hash map (pre-populated from `<root>/image-hashes.json`), lists it at
23
24
  * `/data/image-hashes.json`, and serves `image?v=<hash>` as immutable only when `<hash>` is the file's current hash.
24
25
  */
25
- export function createHandler(root, { assets = viewerDir, cache = defaultCachePolicy, dev = false } = {}) {
26
+ export function createHandler(root, { assets = viewerDir, cache = defaultCachePolicy, dev = false, liveReload } = {}) {
26
27
  const imageCache = `public, max-age=${cache.maxAge}, stale-while-revalidate=${cache.staleWhileRevalidate}, stale-if-error=${cache.staleWhileRevalidate}`;
27
28
  const store = new HashStore();
28
29
  const bootId = Date.now().toString(36); // keeps ETags of the hash listing from colliding across restarts
@@ -54,6 +55,8 @@ export function createHandler(root, { assets = viewerDir, cache = defaultCachePo
54
55
  status: 404,
55
56
  headers: { 'Cache-Control': dev ? 'no-store' : 'no-cache' },
56
57
  });
58
+ if (path === liveReloadPath)
59
+ return dev && liveReload ? liveReload.response(req) : notFound;
57
60
  if (path.startsWith('/data/')) {
58
61
  const rel = path.slice('/data/'.length);
59
62
  if (rel === 'image-hashes.json')
@@ -68,7 +71,14 @@ export function createHandler(root, { assets = viewerDir, cache = defaultCachePo
68
71
  return notFound;
69
72
  await loaded;
70
73
  const isImage = isImageFile(rel);
71
- return send(req, full, isImage ? imageCache : undefined, isImage ? new URL(req.url).searchParams.get('v') : null);
74
+ // Snapshot before reading so an update during the fetch is caught by the SSE handshake.
75
+ const revision = liveReload?.revision();
76
+ const response = await send(req, full, isImage ? imageCache : undefined, isImage ? new URL(req.url).searchParams.get('v') : null);
77
+ if (dev && liveReload && rel === 'index.json' && response.ok) {
78
+ response.headers.set('X-Fidelity-Events', liveReloadPath.slice(1));
79
+ response.headers.set('X-Fidelity-Revision', revision);
80
+ }
81
+ return response;
72
82
  }
73
83
  const rel = path === '/' ? 'index.html' : path.slice(1);
74
84
  const full = resolveInside(assets, rel);
@@ -94,7 +104,7 @@ function listen(handler, port, host) {
94
104
  if (typeof v === 'string')
95
105
  headers.set(k, v);
96
106
  const res = nreq.method === 'GET' || nreq.method === 'HEAD'
97
- ? await handler(new Request(`http://${headers.get('host') ?? 'localhost'}${nreq.url}`, { headers })).catch((e) => new Response(String(e), { status: 500 }))
107
+ ? await handler(new Request(`http://${headers.get('host') ?? 'localhost'}${nreq.url}`, { headers, method: nreq.method })).catch((e) => new Response(String(e), { status: 500 }))
98
108
  : new Response('Method not allowed', { status: 405 });
99
109
  nres.writeHead(res.status, Object.fromEntries(res.headers));
100
110
  if (nreq.method === 'HEAD' || !res.body)
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,WAAW,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE1D,4GAA4G;AAC5G,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE9E,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC,UAAU,CAAC,GAAG,SAAS,aAAa,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,SAAS,wBAAwB,CAAC,CAAC;AACtH,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC;AAQtB,MAAM,CAAC,MAAM,kBAAkB,GAAgB,EAAE,MAAM,EAAE,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAAC;AAc5F;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,GAAG,kBAAkB,EAAE,GAAG,GAAG,KAAK,EAAE,GAAmB,EAAE;IAEpF,MAAM,UAAU,GAAG,mBAAmB,KAAK,CAAC,MAAM,4BAA4B,KAAK,CAAC,oBAAoB,oBAAoB,KAAK,CAAC,oBAAoB,EAAE,CAAC;IACzJ,MAAM,KAAK,GAAG,IAAI,SAAS,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,iEAAiE;IACzG,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,GAAG;QAChB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;YAChC,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACzF,CAAC,CAAC,CAAC;IACP,MAAM,IAAI,GAAG,CAAC,GAAY,EAAE,IAAY,EAAE,YAAqB,EAAE,WAA2B,EAAE,EAAE,CAC9F,GAAG,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;IAChG,kHAAkH;IAClH,MAAM,WAAW,GAAG,KAAK,EAAE,GAAY,EAAE,EAAE;QACzC,MAAM,MAAM,CAAC;QACb,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CACzB,MAAM,CAAC,WAAW,CAChB,CAAC,GAAG,KAAK,CAAC;aACP,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;aAC/B,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAU,CAAC;aACrE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC5C,CACF,CAAC;QACF,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC;QACnG,IAAI,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;YAAE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAClG,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;IAC7F,CAAC,CAAC;IACF,OAAO,KAAK,EAAE,GAAY,EAAqB,EAAE;QAC/C,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,WAAW,EAAE;YACzC,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,EAAE,eAAe,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE;SAC5D,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACxC,IAAI,GAAG,KAAK,mBAAmB;gBAC7B,OAAO,GAAG;oBACR,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,UAAU,EAAE,EAAE,CAAC;oBACtG,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACvB,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC/D,IAAI,CAAC,IAAI;gBAAE,OAAO,QAAQ,CAAC;YAC3B,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC7F,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,GAAG,GAAG,CAAC,IAAI,QAAQ,KAAK,QAAQ,CAAC;gBAAE,OAAO,QAAQ,CAAC;YAClG,MAAM,MAAM,CAAC;YACb,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpH,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC9F,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,OAA4C,EAC5C,IAAwB,EACxB,IAAY;IAEZ,KAAK,IAAI,SAAS,GAAG,IAAI,IAAI,IAAI,EAAE,SAAS,IAAI,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC;QACnE,IAAI,CAAC;YACH,OAAO,MAAM,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,IAAI,KAAK,SAAS,IAAK,KAA+B,CAAC,IAAI,KAAK,YAAY;gBAAE,MAAM,KAAK,CAAC;QAChG,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,MAAM,CAAC,OAA4C,EAAE,IAAY,EAAE,IAAY;IACtF,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAC/C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAChG,MAAM,GAAG,GACP,IAAI,CAAC,MAAM,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;YAC7C,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,OAAO,CAAC,UAAU,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CACtG,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAChD;YACH,CAAC,CAAC,IAAI,QAAQ,CAAC,oBAAoB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI;YAAE,OAAO,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;QAChE,mFAAmF;QACnF,MAAM,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAa,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;YACnC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC5B,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fidelity-kit",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Toolkit for renderer fidelity suites: metrics + delta CLI and a viewer served from any results folder.",
5
5
  "keywords": [
6
6
  "fidelity",