@domandigital/craft 0.10.0 → 0.12.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/dist/audit.d.cts CHANGED
@@ -11,7 +11,13 @@
11
11
  * to a report and judged again later without a browser. Capturing one needs a
12
12
  * browser (see `@domandigital/craft/audit`); judging one does not.
13
13
  */
14
- declare const SNAPSHOT_VERSION = 1;
14
+ /**
15
+ * 2 adds `role` and `geometry` per section, `rhythmVariance` for the page and
16
+ * the screenshot measures in `visual`. All four are optional: a version 1
17
+ * snapshot reads as version 2 without them (see `readSnapshot`), and nothing
18
+ * that judged a v1 snapshot judges it differently.
19
+ */
20
+ declare const SNAPSHOT_VERSION = 2;
15
21
  interface SnapshotColour {
16
22
  /** `rgb(r, g, b)` or `rgba(r, g, b, a)`, as the browser computed it. */
17
23
  value: string;
@@ -50,6 +56,27 @@ interface SnapshotControl {
50
56
  text: string;
51
57
  }
52
58
  type SectionKind = "hero" | "logos" | "stats" | "cards" | "marquee" | "text" | "other";
59
+ /**
60
+ * What a section is for, finer than `kind`. `kind` keeps its version 1
61
+ * meaning because the rendered tells, the null models and the estate were
62
+ * calibrated on it; `role` is what component-level comparison reads.
63
+ */
64
+ type SectionRole = SectionKind | "cta-band" | "footer-cta" | "pricing" | "testimonials" | "faq" | "process" | "features" | "team" | "contact";
65
+ /** How a section is laid out, measured, not judged. */
66
+ interface SectionGeometry {
67
+ /** Share of the section's text blocks that are centred, 0 to 1. */
68
+ centredShare: number;
69
+ /** Content area balance about the vertical centre line: 1 mirror-even, 0 all on one side. */
70
+ mirrorSymmetry: number;
71
+ /** Share of the section's area with no text, image or control in it, 0 to 1. */
72
+ whitespaceRatio: number;
73
+ /** Width the content spans, over the viewport width. */
74
+ contentWidthRatio: number;
75
+ /** The painted background behind the section, as computed. */
76
+ background: string;
77
+ /** Buttons and button-styled links in the section. */
78
+ controls: number;
79
+ }
53
80
  interface SnapshotSection {
54
81
  top: number;
55
82
  height: number;
@@ -62,6 +89,26 @@ interface SnapshotSection {
62
89
  iconCards: number;
63
90
  /** Hidden at load, waiting for a scroll to reveal it. */
64
91
  hiddenAtLoad: boolean;
92
+ /** Version 2. */
93
+ role?: SectionRole;
94
+ /** Version 2. */
95
+ geometry?: SectionGeometry;
96
+ }
97
+ /**
98
+ * Measures of the rendered pixels, from a full-page screenshot (capped at
99
+ * `height`). None of them passes or fails anything: they describe.
100
+ */
101
+ interface SnapshotVisual {
102
+ /** Hasler and Süsstrunk (2003) colourfulness, M = σ_rgyb + 0.3 μ_rgyb, on 0-255 channels. Grey is 0. */
103
+ colourfulness: number;
104
+ /** Share of sampled pixels on a luminance edge: a complexity proxy, 0 to 1. */
105
+ edgeDensity: number;
106
+ /** 1 minus the mean luminance difference between each pixel and its left-right mirror, 0 to 1. */
107
+ symmetry: number;
108
+ width: number;
109
+ height: number;
110
+ /** Pixels actually read: large pages are sampled on a grid. */
111
+ sampled: number;
65
112
  }
66
113
  interface SnapshotGradient {
67
114
  /** Colour stops, as computed. */
@@ -116,6 +163,12 @@ interface Snapshot {
116
163
  sections: SnapshotSection[];
117
164
  effects: SnapshotEffects;
118
165
  motion: SnapshotMotion;
166
+ /** Version 2: coefficient of variation of the section heights. Null with fewer than two sections. */
167
+ rhythmVariance?: number | null;
168
+ /** Version 2: absent when the page could not be screenshotted. */
169
+ visual?: SnapshotVisual;
170
+ /** Set when a version 1 snapshot was read and upgraded in memory. */
171
+ migratedFrom?: 1;
119
172
  /** The design-system measures trawl has collected since v7, kept so it can switch to this. */
120
173
  metrics: {
121
174
  fontSizes: number[];
@@ -266,9 +319,16 @@ type FontClass = "serif" | "sans" | "mono" | "script" | "system";
266
319
  * Pure. Built from a Snapshot, so it describes what a visitor gets.
267
320
  */
268
321
 
269
- declare const FINGERPRINT_VERSION = 1;
322
+ /** One section as layout comparison sees it. */
323
+ interface FingerprintSection {
324
+ role: SectionRole;
325
+ /** Share of centred text, 0 to 1. */
326
+ centred: number;
327
+ /** Content width over viewport width, 0 to 1. */
328
+ width: number;
329
+ }
270
330
  interface Fingerprint {
271
- version: typeof FINGERPRINT_VERSION;
331
+ version: 1 | 2;
272
332
  /** The most prominent chromatic colour: button fills first, then painted area, then text. */
273
333
  accent: Oklch | null;
274
334
  ground: Oklch;
@@ -288,6 +348,8 @@ interface Fingerprint {
288
348
  effects: string[];
289
349
  /** Section kinds in running order, hero first. */
290
350
  layout: SectionKind[];
351
+ /** Version 2: present when every section carries a role and geometry. */
352
+ sections?: FingerprintSection[];
291
353
  }
292
354
 
293
355
  /**
@@ -329,6 +391,8 @@ interface SnapshotOptions {
329
391
  /** A Chromium to launch instead of Playwright's own. Also read from CRAFT_CHROMIUM. */
330
392
  executablePath?: string;
331
393
  timeoutMs?: number;
394
+ /** Take a screenshot and measure its pixels (`visual`). Default true. */
395
+ visual?: boolean;
332
396
  }
333
397
  interface MinimalPage {
334
398
  close?(): Promise<void>;
@@ -338,7 +402,20 @@ interface MinimalPage {
338
402
  }): Promise<unknown>;
339
403
  evaluate<R>(fn: () => R): Promise<R>;
340
404
  waitForTimeout(ms: number): Promise<void>;
405
+ /** Optional: a driver without it gets a snapshot with no `visual` measures. */
406
+ screenshot?(options: {
407
+ fullPage?: boolean;
408
+ type?: "png";
409
+ clip?: {
410
+ x: number;
411
+ y: number;
412
+ width: number;
413
+ height: number;
414
+ };
415
+ }): Promise<Uint8Array>;
341
416
  }
417
+ /** The most of a page the screenshot measures read, in CSS px. A long page is judged on its opening. */
418
+ declare const VISUAL_MAX_HEIGHT = 6000;
342
419
  interface MinimalBrowser {
343
420
  newPage(options?: {
344
421
  viewport?: {
@@ -388,4 +465,4 @@ interface AuditResult {
388
465
  /** Snapshot a URL, judge it against the rendered tells, and fingerprint it. */
389
466
  declare function audit(url: string, options?: SnapshotOptions & CheckOptions): Promise<AuditResult>;
390
467
 
391
- export { type AuditResult, type SnapshotOptions, type SnapshotResult, audit, collectInPage, loadPlaywright, overlayInPage, snapshotPage, snapshotUrl, snapshotUrls };
468
+ export { type AuditResult, type SnapshotOptions, type SnapshotResult, VISUAL_MAX_HEIGHT, audit, collectInPage, loadPlaywright, overlayInPage, snapshotPage, snapshotUrl, snapshotUrls };
package/dist/audit.d.ts CHANGED
@@ -11,7 +11,13 @@
11
11
  * to a report and judged again later without a browser. Capturing one needs a
12
12
  * browser (see `@domandigital/craft/audit`); judging one does not.
13
13
  */
14
- declare const SNAPSHOT_VERSION = 1;
14
+ /**
15
+ * 2 adds `role` and `geometry` per section, `rhythmVariance` for the page and
16
+ * the screenshot measures in `visual`. All four are optional: a version 1
17
+ * snapshot reads as version 2 without them (see `readSnapshot`), and nothing
18
+ * that judged a v1 snapshot judges it differently.
19
+ */
20
+ declare const SNAPSHOT_VERSION = 2;
15
21
  interface SnapshotColour {
16
22
  /** `rgb(r, g, b)` or `rgba(r, g, b, a)`, as the browser computed it. */
17
23
  value: string;
@@ -50,6 +56,27 @@ interface SnapshotControl {
50
56
  text: string;
51
57
  }
52
58
  type SectionKind = "hero" | "logos" | "stats" | "cards" | "marquee" | "text" | "other";
59
+ /**
60
+ * What a section is for, finer than `kind`. `kind` keeps its version 1
61
+ * meaning because the rendered tells, the null models and the estate were
62
+ * calibrated on it; `role` is what component-level comparison reads.
63
+ */
64
+ type SectionRole = SectionKind | "cta-band" | "footer-cta" | "pricing" | "testimonials" | "faq" | "process" | "features" | "team" | "contact";
65
+ /** How a section is laid out, measured, not judged. */
66
+ interface SectionGeometry {
67
+ /** Share of the section's text blocks that are centred, 0 to 1. */
68
+ centredShare: number;
69
+ /** Content area balance about the vertical centre line: 1 mirror-even, 0 all on one side. */
70
+ mirrorSymmetry: number;
71
+ /** Share of the section's area with no text, image or control in it, 0 to 1. */
72
+ whitespaceRatio: number;
73
+ /** Width the content spans, over the viewport width. */
74
+ contentWidthRatio: number;
75
+ /** The painted background behind the section, as computed. */
76
+ background: string;
77
+ /** Buttons and button-styled links in the section. */
78
+ controls: number;
79
+ }
53
80
  interface SnapshotSection {
54
81
  top: number;
55
82
  height: number;
@@ -62,6 +89,26 @@ interface SnapshotSection {
62
89
  iconCards: number;
63
90
  /** Hidden at load, waiting for a scroll to reveal it. */
64
91
  hiddenAtLoad: boolean;
92
+ /** Version 2. */
93
+ role?: SectionRole;
94
+ /** Version 2. */
95
+ geometry?: SectionGeometry;
96
+ }
97
+ /**
98
+ * Measures of the rendered pixels, from a full-page screenshot (capped at
99
+ * `height`). None of them passes or fails anything: they describe.
100
+ */
101
+ interface SnapshotVisual {
102
+ /** Hasler and Süsstrunk (2003) colourfulness, M = σ_rgyb + 0.3 μ_rgyb, on 0-255 channels. Grey is 0. */
103
+ colourfulness: number;
104
+ /** Share of sampled pixels on a luminance edge: a complexity proxy, 0 to 1. */
105
+ edgeDensity: number;
106
+ /** 1 minus the mean luminance difference between each pixel and its left-right mirror, 0 to 1. */
107
+ symmetry: number;
108
+ width: number;
109
+ height: number;
110
+ /** Pixels actually read: large pages are sampled on a grid. */
111
+ sampled: number;
65
112
  }
66
113
  interface SnapshotGradient {
67
114
  /** Colour stops, as computed. */
@@ -116,6 +163,12 @@ interface Snapshot {
116
163
  sections: SnapshotSection[];
117
164
  effects: SnapshotEffects;
118
165
  motion: SnapshotMotion;
166
+ /** Version 2: coefficient of variation of the section heights. Null with fewer than two sections. */
167
+ rhythmVariance?: number | null;
168
+ /** Version 2: absent when the page could not be screenshotted. */
169
+ visual?: SnapshotVisual;
170
+ /** Set when a version 1 snapshot was read and upgraded in memory. */
171
+ migratedFrom?: 1;
119
172
  /** The design-system measures trawl has collected since v7, kept so it can switch to this. */
120
173
  metrics: {
121
174
  fontSizes: number[];
@@ -266,9 +319,16 @@ type FontClass = "serif" | "sans" | "mono" | "script" | "system";
266
319
  * Pure. Built from a Snapshot, so it describes what a visitor gets.
267
320
  */
268
321
 
269
- declare const FINGERPRINT_VERSION = 1;
322
+ /** One section as layout comparison sees it. */
323
+ interface FingerprintSection {
324
+ role: SectionRole;
325
+ /** Share of centred text, 0 to 1. */
326
+ centred: number;
327
+ /** Content width over viewport width, 0 to 1. */
328
+ width: number;
329
+ }
270
330
  interface Fingerprint {
271
- version: typeof FINGERPRINT_VERSION;
331
+ version: 1 | 2;
272
332
  /** The most prominent chromatic colour: button fills first, then painted area, then text. */
273
333
  accent: Oklch | null;
274
334
  ground: Oklch;
@@ -288,6 +348,8 @@ interface Fingerprint {
288
348
  effects: string[];
289
349
  /** Section kinds in running order, hero first. */
290
350
  layout: SectionKind[];
351
+ /** Version 2: present when every section carries a role and geometry. */
352
+ sections?: FingerprintSection[];
291
353
  }
292
354
 
293
355
  /**
@@ -329,6 +391,8 @@ interface SnapshotOptions {
329
391
  /** A Chromium to launch instead of Playwright's own. Also read from CRAFT_CHROMIUM. */
330
392
  executablePath?: string;
331
393
  timeoutMs?: number;
394
+ /** Take a screenshot and measure its pixels (`visual`). Default true. */
395
+ visual?: boolean;
332
396
  }
333
397
  interface MinimalPage {
334
398
  close?(): Promise<void>;
@@ -338,7 +402,20 @@ interface MinimalPage {
338
402
  }): Promise<unknown>;
339
403
  evaluate<R>(fn: () => R): Promise<R>;
340
404
  waitForTimeout(ms: number): Promise<void>;
405
+ /** Optional: a driver without it gets a snapshot with no `visual` measures. */
406
+ screenshot?(options: {
407
+ fullPage?: boolean;
408
+ type?: "png";
409
+ clip?: {
410
+ x: number;
411
+ y: number;
412
+ width: number;
413
+ height: number;
414
+ };
415
+ }): Promise<Uint8Array>;
341
416
  }
417
+ /** The most of a page the screenshot measures read, in CSS px. A long page is judged on its opening. */
418
+ declare const VISUAL_MAX_HEIGHT = 6000;
342
419
  interface MinimalBrowser {
343
420
  newPage(options?: {
344
421
  viewport?: {
@@ -388,4 +465,4 @@ interface AuditResult {
388
465
  /** Snapshot a URL, judge it against the rendered tells, and fingerprint it. */
389
466
  declare function audit(url: string, options?: SnapshotOptions & CheckOptions): Promise<AuditResult>;
390
467
 
391
- export { type AuditResult, type SnapshotOptions, type SnapshotResult, audit, collectInPage, loadPlaywright, overlayInPage, snapshotPage, snapshotUrl, snapshotUrls };
468
+ export { type AuditResult, type SnapshotOptions, type SnapshotResult, VISUAL_MAX_HEIGHT, audit, collectInPage, loadPlaywright, overlayInPage, snapshotPage, snapshotUrl, snapshotUrls };