@variance-authority/core 0.1.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/CHANGELOG.md +79 -0
- package/LICENSE +21 -0
- package/README.md +169 -0
- package/dist/artifact.d.ts +47 -0
- package/dist/artifact.js +2 -0
- package/dist/artifact.js.map +1 -0
- package/dist/attribute/because.d.ts +43 -0
- package/dist/attribute/because.js +64 -0
- package/dist/attribute/because.js.map +1 -0
- package/dist/attribute/boundary.d.ts +191 -0
- package/dist/attribute/boundary.js +328 -0
- package/dist/attribute/boundary.js.map +1 -0
- package/dist/attribute/call-site.d.ts +96 -0
- package/dist/attribute/call-site.js +183 -0
- package/dist/attribute/call-site.js.map +1 -0
- package/dist/attribute/component-hash.d.ts +188 -0
- package/dist/attribute/component-hash.js +312 -0
- package/dist/attribute/component-hash.js.map +1 -0
- package/dist/attribute/composition-fixture.d.ts +18 -0
- package/dist/attribute/composition-fixture.js +53 -0
- package/dist/attribute/composition-fixture.js.map +1 -0
- package/dist/attribute/composition.d.ts +182 -0
- package/dist/attribute/composition.js +169 -0
- package/dist/attribute/composition.js.map +1 -0
- package/dist/attribute/control.d.ts +43 -0
- package/dist/attribute/control.js +54 -0
- package/dist/attribute/control.js.map +1 -0
- package/dist/attribute/coverage.d.ts +99 -0
- package/dist/attribute/coverage.js +86 -0
- package/dist/attribute/coverage.js.map +1 -0
- package/dist/attribute/divergence.d.ts +102 -0
- package/dist/attribute/divergence.js +152 -0
- package/dist/attribute/divergence.js.map +1 -0
- package/dist/attribute/index.d.ts +43 -0
- package/dist/attribute/index.js +29 -0
- package/dist/attribute/index.js.map +1 -0
- package/dist/attribute/instability.d.ts +89 -0
- package/dist/attribute/instability.js +183 -0
- package/dist/attribute/instability.js.map +1 -0
- package/dist/attribute/instances.d.ts +145 -0
- package/dist/attribute/instances.js +140 -0
- package/dist/attribute/instances.js.map +1 -0
- package/dist/attribute/locate.d.ts +22 -0
- package/dist/attribute/locate.js +100 -0
- package/dist/attribute/locate.js.map +1 -0
- package/dist/attribute/mask.d.ts +156 -0
- package/dist/attribute/mask.js +201 -0
- package/dist/attribute/mask.js.map +1 -0
- package/dist/attribute/movement.d.ts +211 -0
- package/dist/attribute/movement.js +181 -0
- package/dist/attribute/movement.js.map +1 -0
- package/dist/attribute/region.d.ts +188 -0
- package/dist/attribute/region.js +144 -0
- package/dist/attribute/region.js.map +1 -0
- package/dist/attribute/source-map.d.ts +98 -0
- package/dist/attribute/source-map.js +264 -0
- package/dist/attribute/source-map.js.map +1 -0
- package/dist/attribute/source.d.ts +77 -0
- package/dist/attribute/source.js +95 -0
- package/dist/attribute/source.js.map +1 -0
- package/dist/attribute/stack.d.ts +80 -0
- package/dist/attribute/stack.js +108 -0
- package/dist/attribute/stack.js.map +1 -0
- package/dist/compare/band.d.ts +85 -0
- package/dist/compare/band.js +70 -0
- package/dist/compare/band.js.map +1 -0
- package/dist/compare/cascade.d.ts +45 -0
- package/dist/compare/cascade.js +71 -0
- package/dist/compare/cascade.js.map +1 -0
- package/dist/compare/derive.d.ts +78 -0
- package/dist/compare/derive.js +39 -0
- package/dist/compare/derive.js.map +1 -0
- package/dist/compare/diff/attribution.d.ts +23 -0
- package/dist/compare/diff/attribution.js +244 -0
- package/dist/compare/diff/attribution.js.map +1 -0
- package/dist/compare/diff/compare-nodes.d.ts +15 -0
- package/dist/compare/diff/compare-nodes.js +227 -0
- package/dist/compare/diff/compare-nodes.js.map +1 -0
- package/dist/compare/diff/components.d.ts +20 -0
- package/dist/compare/diff/components.js +76 -0
- package/dist/compare/diff/components.js.map +1 -0
- package/dist/compare/diff/delta.d.ts +165 -0
- package/dist/compare/diff/delta.js +12 -0
- package/dist/compare/diff/delta.js.map +1 -0
- package/dist/compare/diff/index.d.ts +69 -0
- package/dist/compare/diff/index.js +101 -0
- package/dist/compare/diff/index.js.map +1 -0
- package/dist/compare/diff/match.d.ts +37 -0
- package/dist/compare/diff/match.js +167 -0
- package/dist/compare/diff/match.js.map +1 -0
- package/dist/compare/explain.d.ts +23 -0
- package/dist/compare/explain.js +190 -0
- package/dist/compare/explain.js.map +1 -0
- package/dist/compare/holding-diff.d.ts +25 -0
- package/dist/compare/holding-diff.js +74 -0
- package/dist/compare/holding-diff.js.map +1 -0
- package/dist/compare/impact.d.ts +56 -0
- package/dist/compare/impact.js +124 -0
- package/dist/compare/impact.js.map +1 -0
- package/dist/compare/index.d.ts +30 -0
- package/dist/compare/index.js +22 -0
- package/dist/compare/index.js.map +1 -0
- package/dist/compare/instance.d.ts +30 -0
- package/dist/compare/instance.js +145 -0
- package/dist/compare/instance.js.map +1 -0
- package/dist/compare/observability.d.ts +49 -0
- package/dist/compare/observability.js +57 -0
- package/dist/compare/observability.js.map +1 -0
- package/dist/compare/parting.d.ts +179 -0
- package/dist/compare/parting.js +244 -0
- package/dist/compare/parting.js.map +1 -0
- package/dist/compare/slice.d.ts +74 -0
- package/dist/compare/slice.js +79 -0
- package/dist/compare/slice.js.map +1 -0
- package/dist/compare/value.d.ts +60 -0
- package/dist/compare/value.js +111 -0
- package/dist/compare/value.js.map +1 -0
- package/dist/format/accessibility.d.ts +27 -0
- package/dist/format/accessibility.js +17 -0
- package/dist/format/accessibility.js.map +1 -0
- package/dist/format/canonical.d.ts +38 -0
- package/dist/format/canonical.js +65 -0
- package/dist/format/canonical.js.map +1 -0
- package/dist/format/capture.d.ts +212 -0
- package/dist/format/capture.js +2 -0
- package/dist/format/capture.js.map +1 -0
- package/dist/format/document.d.ts +279 -0
- package/dist/format/document.js +65 -0
- package/dist/format/document.js.map +1 -0
- package/dist/format/environment.d.ts +120 -0
- package/dist/format/environment.js +53 -0
- package/dist/format/environment.js.map +1 -0
- package/dist/format/hash.d.ts +45 -0
- package/dist/format/hash.js +41 -0
- package/dist/format/hash.js.map +1 -0
- package/dist/format/holding.d.ts +134 -0
- package/dist/format/holding.js +2 -0
- package/dist/format/holding.js.map +1 -0
- package/dist/format/index.d.ts +39 -0
- package/dist/format/index.js +25 -0
- package/dist/format/index.js.map +1 -0
- package/dist/format/intervention.d.ts +87 -0
- package/dist/format/intervention.js +11 -0
- package/dist/format/intervention.js.map +1 -0
- package/dist/format/profile.d.ts +59 -0
- package/dist/format/profile.js +66 -0
- package/dist/format/profile.js.map +1 -0
- package/dist/format/provenance.d.ts +179 -0
- package/dist/format/provenance.js +222 -0
- package/dist/format/provenance.js.map +1 -0
- package/dist/format/sha256.d.ts +34 -0
- package/dist/format/sha256.js +152 -0
- package/dist/format/sha256.js.map +1 -0
- package/dist/format/snapshot.d.ts +263 -0
- package/dist/format/snapshot.js +2 -0
- package/dist/format/snapshot.js.map +1 -0
- package/dist/format/stabilize.d.ts +190 -0
- package/dist/format/stabilize.js +333 -0
- package/dist/format/stabilize.js.map +1 -0
- package/dist/format/tier.d.ts +19 -0
- package/dist/format/tier.js +11 -0
- package/dist/format/tier.js.map +1 -0
- package/dist/format/value.d.ts +115 -0
- package/dist/format/value.js +182 -0
- package/dist/format/value.js.map +1 -0
- package/dist/format/wiring.d.ts +115 -0
- package/dist/format/wiring.js +60 -0
- package/dist/format/wiring.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/judge/docket.d.ts +85 -0
- package/dist/judge/docket.js +162 -0
- package/dist/judge/docket.js.map +1 -0
- package/dist/judge/fingerprint.d.ts +53 -0
- package/dist/judge/fingerprint.js +144 -0
- package/dist/judge/fingerprint.js.map +1 -0
- package/dist/judge/ignore.d.ts +206 -0
- package/dist/judge/ignore.js +237 -0
- package/dist/judge/ignore.js.map +1 -0
- package/dist/judge/index.d.ts +44 -0
- package/dist/judge/index.js +34 -0
- package/dist/judge/index.js.map +1 -0
- package/dist/judge/inspect.d.ts +148 -0
- package/dist/judge/inspect.js +208 -0
- package/dist/judge/inspect.js.map +1 -0
- package/dist/judge/intent.d.ts +146 -0
- package/dist/judge/intent.js +150 -0
- package/dist/judge/intent.js.map +1 -0
- package/dist/judge/locale.d.ts +111 -0
- package/dist/judge/locale.js +247 -0
- package/dist/judge/locale.js.map +1 -0
- package/dist/judge/scope.d.ts +41 -0
- package/dist/judge/scope.js +47 -0
- package/dist/judge/scope.js.map +1 -0
- package/dist/judge/sensitivity.d.ts +202 -0
- package/dist/judge/sensitivity.js +152 -0
- package/dist/judge/sensitivity.js.map +1 -0
- package/dist/judge/trail.d.ts +122 -0
- package/dist/judge/trail.js +96 -0
- package/dist/judge/trail.js.map +1 -0
- package/dist/judge/verdict.d.ts +39 -0
- package/dist/judge/verdict.js +32 -0
- package/dist/judge/verdict.js.map +1 -0
- package/dist/plan/index.d.ts +12 -0
- package/dist/plan/index.js +11 -0
- package/dist/plan/index.js.map +1 -0
- package/dist/plan/tool.d.ts +85 -0
- package/dist/plan/tool.js +87 -0
- package/dist/plan/tool.js.map +1 -0
- package/dist/relate/graph.d.ts +190 -0
- package/dist/relate/graph.js +234 -0
- package/dist/relate/graph.js.map +1 -0
- package/dist/relate/index.d.ts +16 -0
- package/dist/relate/index.js +16 -0
- package/dist/relate/index.js.map +1 -0
- package/dist/relate/merkle.d.ts +110 -0
- package/dist/relate/merkle.js +246 -0
- package/dist/relate/merkle.js.map +1 -0
- package/dist/relate/reach.d.ts +65 -0
- package/dist/relate/reach.js +111 -0
- package/dist/relate/reach.js.map +1 -0
- package/dist/relate/records.d.ts +129 -0
- package/dist/relate/records.js +112 -0
- package/dist/relate/records.js.map +1 -0
- package/dist/rules/index.d.ts +19 -0
- package/dist/rules/index.js +17 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/normalize/alias.d.ts +50 -0
- package/dist/rules/normalize/alias.js +111 -0
- package/dist/rules/normalize/alias.js.map +1 -0
- package/dist/rules/normalize/cascade.d.ts +85 -0
- package/dist/rules/normalize/cascade.js +324 -0
- package/dist/rules/normalize/cascade.js.map +1 -0
- package/dist/rules/normalize/color.d.ts +30 -0
- package/dist/rules/normalize/color.js +185 -0
- package/dist/rules/normalize/color.js.map +1 -0
- package/dist/rules/normalize/fixture.d.ts +83 -0
- package/dist/rules/normalize/fixture.js +74 -0
- package/dist/rules/normalize/fixture.js.map +1 -0
- package/dist/rules/normalize/index.d.ts +39 -0
- package/dist/rules/normalize/index.js +268 -0
- package/dist/rules/normalize/index.js.map +1 -0
- package/dist/rules/normalize/project.d.ts +42 -0
- package/dist/rules/normalize/project.js +83 -0
- package/dist/rules/normalize/project.js.map +1 -0
- package/dist/rules/normalize/shorthand.d.ts +38 -0
- package/dist/rules/normalize/shorthand.js +388 -0
- package/dist/rules/normalize/shorthand.js.map +1 -0
- package/dist/rules/normalize/value.d.ts +23 -0
- package/dist/rules/normalize/value.js +162 -0
- package/dist/rules/normalize/value.js.map +1 -0
- package/dist/rules/normalize/wrapper.d.ts +16 -0
- package/dist/rules/normalize/wrapper.js +137 -0
- package/dist/rules/normalize/wrapper.js.map +1 -0
- package/dist/rules/ruleset.d.ts +93 -0
- package/dist/rules/ruleset.js +175 -0
- package/dist/rules/ruleset.js.map +1 -0
- package/mark.svg +30 -0
- package/package.json +69 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sha256.js","sourceRoot":"","sources":["../../src/format/sha256.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SHA-256, in portable TypeScript.\n *\n * `core` originally used `node:crypto`, which was wrong — and the reason is not\n * ergonomic. `propsDigest` has to run *inside the page*: a React prop can be a\n * function or an element, and neither survives serialization out to a host\n * process, so the digest must be taken where the value still exists. A `core`\n * that imports `node:crypto` cannot run there, which quietly contradicted the\n * remote-sub-renderer story in ADR-0002 and the DOM-free boundary in ADR-0001.\n * (The `lib: [\"ES2022\"]` guard is one-directional: it stops `core` reaching into\n * a browser, not `core` depending on Node.)\n *\n * `crypto.subtle.digest` is the obvious replacement and is not usable: it is\n * async, and hashing is synchronous throughout by design — making it async would\n * colour the entire normalizer for no benefit.\n *\n * So the algorithm lives here. It is fully specified by FIPS 180-4, so this\n * produces byte-identical output to any other correct implementation on any\n * runtime, which is exactly the determinism Principle 2 requires. Performance is\n * not a consideration until a gate in ADR-0004 fires; none has.\n */\n\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\nconst INITIAL = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\n/** Hash a UTF-8 string, returning lowercase hex. */\nexport function sha256Hex(input: string): string {\n return sha256HexBytes(utf8Bytes(input));\n}\n\n/**\n * Hash raw bytes, returning lowercase hex.\n *\n * The string form is this with one encoding step in front of it, and not the\n * other way round: an image is bytes, and routing it through a string would mean\n * choosing an encoding that survives arbitrary octets — which is a second\n * decision, made in the wrong place, that changes the digest if it is ever\n * revisited.\n */\nexport function sha256HexBytes(bytes: Uint8Array): string {\n const state = new Uint32Array(INITIAL);\n\n // Padding: a single 1 bit, zeros, then the 64-bit big-endian bit length.\n const bitLength = bytes.length * 8;\n // Padding is minimal by definition: the smallest multiple of 64 that fits the\n // message, the 0x80 byte, and the 8-byte length. Rounding up unconditionally\n // would append a spare block whenever `length + 9` is already a multiple of\n // 64, which is a different message and therefore a different digest.\n const paddedLength = Math.ceil((bytes.length + 9) / 64) * 64;\n const padded = new Uint8Array(paddedLength);\n padded.set(bytes);\n padded[bytes.length] = 0x80;\n\n // Written as two 32-bit halves rather than a BigInt: inputs never approach\n // 2^32 bits (512 MiB), and the high word is always zero in practice, but\n // emitting it keeps the block format exactly as specified.\n const view = new DataView(padded.buffer);\n view.setUint32(paddedLength - 8, Math.floor(bitLength / 0x100000000), false);\n view.setUint32(paddedLength - 4, bitLength >>> 0, false);\n\n const w = new Uint32Array(64);\n\n for (let offset = 0; offset < paddedLength; offset += 64) {\n for (let i = 0; i < 16; i += 1) {\n w[i] = view.getUint32(offset + i * 4, false);\n }\n for (let i = 16; i < 64; i += 1) {\n const s0 = rotr(w[i - 15]!, 7) ^ rotr(w[i - 15]!, 18) ^ (w[i - 15]! >>> 3);\n const s1 = rotr(w[i - 2]!, 17) ^ rotr(w[i - 2]!, 19) ^ (w[i - 2]! >>> 10);\n w[i] = (w[i - 16]! + s0 + w[i - 7]! + s1) >>> 0;\n }\n\n let [a, b, c, d, e, f, g, h] = state as unknown as number[];\n\n for (let i = 0; i < 64; i += 1) {\n const S1 = rotr(e!, 6) ^ rotr(e!, 11) ^ rotr(e!, 25);\n const ch = (e! & f!) ^ (~e! & g!);\n const temp1 = (h! + S1 + ch + K[i]! + w[i]!) >>> 0;\n const S0 = rotr(a!, 2) ^ rotr(a!, 13) ^ rotr(a!, 22);\n const maj = (a! & b!) ^ (a! & c!) ^ (b! & c!);\n const temp2 = (S0 + maj) >>> 0;\n\n h = g;\n g = f;\n f = e;\n e = (d! + temp1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (temp1 + temp2) >>> 0;\n }\n\n state[0] = (state[0]! + a!) >>> 0;\n state[1] = (state[1]! + b!) >>> 0;\n state[2] = (state[2]! + c!) >>> 0;\n state[3] = (state[3]! + d!) >>> 0;\n state[4] = (state[4]! + e!) >>> 0;\n state[5] = (state[5]! + f!) >>> 0;\n state[6] = (state[6]! + g!) >>> 0;\n state[7] = (state[7]! + h!) >>> 0;\n }\n\n let hex = '';\n for (const word of state) {\n hex += word.toString(16).padStart(8, '0');\n }\n return hex;\n}\n\nfunction rotr(value: number, bits: number): number {\n return ((value >>> bits) | (value << (32 - bits))) >>> 0;\n}\n\n/**\n * Encode as UTF-8 without `TextEncoder`.\n *\n * `TextEncoder` is available everywhere this runs today, but hand-encoding keeps\n * `core` free of *every* host global, not merely the Node ones — which is the\n * property that just failed to hold. Lone surrogates are encoded as U+FFFD, the\n * same substitution `TextEncoder` makes, so a malformed string cannot produce\n * two different digests on two runtimes.\n */\nfunction utf8Bytes(input: string): Uint8Array {\n const bytes: number[] = [];\n\n for (let i = 0; i < input.length; i += 1) {\n let code = input.charCodeAt(i);\n\n if (code >= 0xd800 && code <= 0xdbff) {\n const next = input.charCodeAt(i + 1);\n if (next >= 0xdc00 && next <= 0xdfff) {\n code = 0x10000 + ((code - 0xd800) << 10) + (next - 0xdc00);\n i += 1;\n } else {\n code = 0xfffd;\n }\n } else if (code >= 0xdc00 && code <= 0xdfff) {\n code = 0xfffd;\n }\n\n if (code < 0x80) {\n bytes.push(code);\n } else if (code < 0x800) {\n bytes.push(0xc0 | (code >> 6), 0x80 | (code & 0x3f));\n } else if (code < 0x10000) {\n bytes.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));\n } else {\n bytes.push(\n 0xf0 | (code >> 18),\n 0x80 | ((code >> 12) & 0x3f),\n 0x80 | ((code >> 6) & 0x3f),\n 0x80 | (code & 0x3f),\n );\n }\n }\n\n return Uint8Array.from(bytes);\n}\n"]}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import type { SubjectRef, Rect, Diagnostic } from './capture.js';
|
|
2
|
+
import type { EnvironmentKey } from './environment.js';
|
|
3
|
+
import type { Digest } from './hash.js';
|
|
4
|
+
import type { ObservationProfile } from './profile.js';
|
|
5
|
+
import type { Provenance } from './provenance.js';
|
|
6
|
+
import type { Wiring } from './wiring.js';
|
|
7
|
+
import type { Holding } from './holding.js';
|
|
8
|
+
/**
|
|
9
|
+
* The normalized semantic snapshot: the verdict's input, and the thing a render
|
|
10
|
+
* hash addresses.
|
|
11
|
+
*
|
|
12
|
+
* Everything volatile is gone by this point. Ids have become structural aliases,
|
|
13
|
+
* class attributes have been dropped entirely, inapplicable CSS has been pruned,
|
|
14
|
+
* and the cascade has been resolved to winning values (ADR-0003). What remains is
|
|
15
|
+
* meant to be *read*: a snapshot a reviewer refuses to open is a snapshot that
|
|
16
|
+
* gets rubber-stamped.
|
|
17
|
+
*/
|
|
18
|
+
export interface SemanticSnapshot {
|
|
19
|
+
readonly formatVersion: 1;
|
|
20
|
+
readonly subject: SubjectRef;
|
|
21
|
+
readonly profile: ObservationProfile;
|
|
22
|
+
readonly environment: EnvironmentKey;
|
|
23
|
+
/** Content hash of `root` under `environment`. The identity of this state. */
|
|
24
|
+
readonly renderHash: Digest;
|
|
25
|
+
/**
|
|
26
|
+
* Structure and applicable style, hashed separately.
|
|
27
|
+
*
|
|
28
|
+
* These back the tier below full semantic comparison (ADR-0003): matching both
|
|
29
|
+
* settles a subject without resolving layout or taking a screenshot. Split
|
|
30
|
+
* rather than combined because the docket wants to say *which* held — "the DOM
|
|
31
|
+
* is identical, only styling moved" is the sentence that turns a diff into a
|
|
32
|
+
* token-band root.
|
|
33
|
+
*/
|
|
34
|
+
readonly structureHash: Digest;
|
|
35
|
+
readonly styleHash: Digest;
|
|
36
|
+
readonly root: SemanticNode;
|
|
37
|
+
/**
|
|
38
|
+
* Where each winning declaration came from. Deliberately outside the hash.
|
|
39
|
+
*
|
|
40
|
+
* Pruning discards exactly what attribution needs — *which rule set this?* — so
|
|
41
|
+
* it is preserved here instead. Keeping it out of the hash is the point: moving
|
|
42
|
+
* a rule between files renames a source without changing a render, and must not
|
|
43
|
+
* invalidate a baseline.
|
|
44
|
+
*/
|
|
45
|
+
readonly styleProvenance: readonly StyleProvenanceEntry[];
|
|
46
|
+
/**
|
|
47
|
+
* Subtrees the operator declared out of scope, resolved against *this* tree.
|
|
48
|
+
*
|
|
49
|
+
* Deliberately outside the hash, for the reason `styleProvenance` is: an ignore
|
|
50
|
+
* changes what a run says about a render, never the render. Folding it into the
|
|
51
|
+
* identity would invalidate every baseline in the repository the first time
|
|
52
|
+
* somebody masked a clock, which is the surest way to make a safety feature the
|
|
53
|
+
* thing people turn off.
|
|
54
|
+
*
|
|
55
|
+
* Present only when something was excluded, so a snapshot from a run with no
|
|
56
|
+
* ignores is byte-identical to one produced before this field existed.
|
|
57
|
+
*/
|
|
58
|
+
readonly ignoreSites?: readonly IgnoreSite[];
|
|
59
|
+
/**
|
|
60
|
+
* What the collector or the normalizer could not do, carried forward.
|
|
61
|
+
*
|
|
62
|
+
* Outside the hash: a diagnostic describes the *observation*, not the render,
|
|
63
|
+
* and a snapshot that hashed its own warnings would invalidate whenever the
|
|
64
|
+
* warning text was reworded. But it must survive to the verdict — a subject
|
|
65
|
+
* whose capture half-failed is not a subject that legitimately `unchanged`,
|
|
66
|
+
* and silently discarding that fact is how a broken collector reads as a clean
|
|
67
|
+
* build.
|
|
68
|
+
*/
|
|
69
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* A node's stable address: child indices from the root, e.g. `0/2/1`.
|
|
73
|
+
*
|
|
74
|
+
* Positional because nothing else survives. Ids are volatile (that is why they
|
|
75
|
+
* were aliased away), and class names have been dropped. Position is honest about
|
|
76
|
+
* what it costs: inserting a sibling renumbers everything after it, so the differ
|
|
77
|
+
* matches nodes by shape and provenance before falling back to path (see
|
|
78
|
+
* `diff.ts`), and treats a path change alone as evidence of nothing.
|
|
79
|
+
*/
|
|
80
|
+
export type NodePath = string;
|
|
81
|
+
export interface SemanticNode {
|
|
82
|
+
readonly path: NodePath;
|
|
83
|
+
readonly tag: string;
|
|
84
|
+
/** Structural alias, e.g. `#a0`. Absent when the node carried no id. */
|
|
85
|
+
readonly alias?: string;
|
|
86
|
+
readonly role?: string;
|
|
87
|
+
readonly name?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Accessible description, resolved. See `RawAria.description` for why this is
|
|
90
|
+
* a field of its own rather than an attribute.
|
|
91
|
+
*/
|
|
92
|
+
readonly description?: string;
|
|
93
|
+
readonly state?: Readonly<Record<string, string | boolean | number>>;
|
|
94
|
+
/** Semantic attributes surviving normalization. `class` is never among them. */
|
|
95
|
+
readonly attributes: Readonly<Record<string, string>>;
|
|
96
|
+
/** Winning values for allowlisted properties, canonicalized. */
|
|
97
|
+
readonly style: Readonly<Record<string, string>>;
|
|
98
|
+
/**
|
|
99
|
+
* Custom properties this node's winning declarations resolved through, as
|
|
100
|
+
* name → resolved value.
|
|
101
|
+
*
|
|
102
|
+
* Recording the name alongside the value is what lets a design-token change
|
|
103
|
+
* surface as one root with counted collateral instead of hundreds of unrelated
|
|
104
|
+
* colour diffs (spec §5, `token` band).
|
|
105
|
+
*/
|
|
106
|
+
readonly tokens?: Readonly<Record<string, string>>;
|
|
107
|
+
/**
|
|
108
|
+
* Which token each styled property resolved through, including by inheritance.
|
|
109
|
+
*
|
|
110
|
+
* Outside the hash, like `styleProvenance` and for the same reason: swapping a
|
|
111
|
+
* literal for a token of the same value renames a source without changing a
|
|
112
|
+
* render. It exists so the differ can tell *which* property a token edit
|
|
113
|
+
* explains — `tokens` alone says a node uses tokens, not which of its values
|
|
114
|
+
* one drove.
|
|
115
|
+
*/
|
|
116
|
+
readonly styleTokens?: Readonly<Record<string, string>>;
|
|
117
|
+
/** Present only under a profile with layout. Absent, never zeroed (ADR-0002). */
|
|
118
|
+
readonly rect?: Rect;
|
|
119
|
+
/** Text content, or its digest when policy declares the region volatile. */
|
|
120
|
+
readonly text?: string;
|
|
121
|
+
readonly provenance?: Provenance;
|
|
122
|
+
/**
|
|
123
|
+
* How the framework holds this node's component, when a framework adapter
|
|
124
|
+
* supplied it. See {@link Wiring}.
|
|
125
|
+
*
|
|
126
|
+
* On the node rather than on `Provenance`, though both come from the same
|
|
127
|
+
* adapter and the same fiber, because they answer to different readers.
|
|
128
|
+
* Provenance exists so a diff arrives carrying a name; wiring is a *dimension
|
|
129
|
+
* of the subject*, hashed into a band of its own, and a band's inputs belong
|
|
130
|
+
* beside the other bands' inputs — next to `style` and `attributes`, which is
|
|
131
|
+
* where `shapeOf` goes looking.
|
|
132
|
+
*/
|
|
133
|
+
readonly wiring?: Wiring;
|
|
134
|
+
/**
|
|
135
|
+
* What that component was holding. **Outside every hash**, always.
|
|
136
|
+
*
|
|
137
|
+
* The field beside it is the contrast worth reading: `wiring` is a band and
|
|
138
|
+
* this is evidence. `Wiring` refuses state values because a hook's value is
|
|
139
|
+
* exactly what may legitimately differ between two readings of one page, and
|
|
140
|
+
* that refusal is right and is not softened here — a `holding` reaches the
|
|
141
|
+
* snapshot and reaches no digest, so a subject whose clock ticked has the same
|
|
142
|
+
* `renderHash` it had before this field existed.
|
|
143
|
+
*
|
|
144
|
+
* It rides outside on the same terms as `styleProvenance`, `styleTokens` and
|
|
145
|
+
* `ignoredBy`, by the same mechanism: `structureOf`, `styleOf` and `shapeOf`
|
|
146
|
+
* project the fields they hash **by name**, so a field none of them names
|
|
147
|
+
* cannot reach an identity. `holding.hash.test.ts` asserts that rather than
|
|
148
|
+
* trusting it, because the cost of being wrong is every baseline in a
|
|
149
|
+
* repository invalidating the first time a component held a timestamp.
|
|
150
|
+
*/
|
|
151
|
+
readonly holding?: Holding;
|
|
152
|
+
/**
|
|
153
|
+
* `true` on the root of a subtree rendered through a portal.
|
|
154
|
+
*
|
|
155
|
+
* Recorded in the structure hash so that "the dialog moved from inline to
|
|
156
|
+
* portalled" is a change rather than a coincidence of identical content, and
|
|
157
|
+
* so the docket can say *where* something rendered, not only that it exists.
|
|
158
|
+
*/
|
|
159
|
+
readonly portalled?: boolean;
|
|
160
|
+
/**
|
|
161
|
+
* Ignore rules this node was found under. Outside every hash, like its origin
|
|
162
|
+
* on `RawNode`. See {@link SemanticSnapshot.ignoreSites}.
|
|
163
|
+
*/
|
|
164
|
+
readonly ignoredBy?: readonly string[];
|
|
165
|
+
readonly children: readonly SemanticNode[];
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* A subtree the operator excluded, resolved to a path and a box (spec 0024).
|
|
169
|
+
*
|
|
170
|
+
* Lives in `format` rather than beside the rules that consume it, because it is
|
|
171
|
+
* part of what a snapshot *is*: the collector produced it, it travels with the
|
|
172
|
+
* document over every wire this project has, and `core/judge` is only its first
|
|
173
|
+
* reader. A type the wire format needs cannot live in the policy layer.
|
|
174
|
+
*/
|
|
175
|
+
export interface IgnoreSite {
|
|
176
|
+
/** Root of the excluded subtree, in this snapshot's own path space. */
|
|
177
|
+
readonly path: NodePath;
|
|
178
|
+
/** Which rule put it here, matched exactly against `IgnoreRule.id`. */
|
|
179
|
+
readonly rule: string;
|
|
180
|
+
/**
|
|
181
|
+
* The box it occupied, for the raster tier.
|
|
182
|
+
*
|
|
183
|
+
* Absent under a profile with no layout — which is ADR-0002 rather than a
|
|
184
|
+
* failure: a profile that cannot measure a box cannot decide pixels either, so
|
|
185
|
+
* there is nothing for the box to subtract from.
|
|
186
|
+
*/
|
|
187
|
+
readonly rect?: Rect;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* A component's own content, hashed per band (ADR-0018).
|
|
191
|
+
*
|
|
192
|
+
* In `format` rather than beside `hashComponents`, which computes it, because a
|
|
193
|
+
* baseline carries these: a stored image plus the component hashes of the
|
|
194
|
+
* document that painted it is what lets a later run tell the component that
|
|
195
|
+
* *caused* a change from the components the change merely moved. That makes this
|
|
196
|
+
* part of the wire format every store and every transport has to preserve, and a
|
|
197
|
+
* type the wire needs cannot live in the layer that derives it.
|
|
198
|
+
*/
|
|
199
|
+
export interface ComponentHash {
|
|
200
|
+
readonly component: string;
|
|
201
|
+
/** Boundaries of this component in the subject, counted in document order. */
|
|
202
|
+
readonly instances: number;
|
|
203
|
+
/**
|
|
204
|
+
* Tree shape: tags, structural aliases, portalling, allowlisted attributes,
|
|
205
|
+
* and which child boundaries sit where. The `geometry` band's structural half.
|
|
206
|
+
*
|
|
207
|
+
* **Split out of a single `structure` digest on 2026-08-06.** It used to carry
|
|
208
|
+
* the accessible semantics and the text too, and the fusion was invisible
|
|
209
|
+
* until something needed to ask *which band moved* — at which point a baseline
|
|
210
|
+
* could say "this component changed" and never say whether a heading was
|
|
211
|
+
* renamed, a paragraph reworded, or a node inserted. Those are three different
|
|
212
|
+
* bands, three different readers, and one of them is the band a route-level
|
|
213
|
+
* test exists to ignore.
|
|
214
|
+
*/
|
|
215
|
+
readonly structure: Digest;
|
|
216
|
+
/**
|
|
217
|
+
* Role, accessible name, and ARIA state. The `a11y` band.
|
|
218
|
+
*
|
|
219
|
+
* Its own digest because it is the band that must never be absorbed. Every
|
|
220
|
+
* sensitivity level asserts on it, including the ones that ignore everything
|
|
221
|
+
* else — and a level cannot assert on a band that is fused into another one.
|
|
222
|
+
*/
|
|
223
|
+
readonly semantics: Digest;
|
|
224
|
+
/** Text runs, in document order. The `content` band. */
|
|
225
|
+
readonly text: Digest;
|
|
226
|
+
readonly style: Digest;
|
|
227
|
+
/**
|
|
228
|
+
* Absent under a profile without layout — absent, never empty (ADR-0002).
|
|
229
|
+
*
|
|
230
|
+
* An empty geometry digest would compare equal between a run that observed no
|
|
231
|
+
* movement and a run that could not observe movement at all, which is the
|
|
232
|
+
* false `unchanged` this system must never produce.
|
|
233
|
+
*/
|
|
234
|
+
readonly geometry?: Digest;
|
|
235
|
+
/**
|
|
236
|
+
* The box each instance occupies, in document order. Never hashed.
|
|
237
|
+
*
|
|
238
|
+
* A digest can say a component is not what it was and can never say by how
|
|
239
|
+
* much. That is the gap a reviewer falls into: `Button — geometry, token` is
|
|
240
|
+
* true of a control that lost a shadow and of one that grew eight pixels and
|
|
241
|
+
* pushed the page down, and only the second explains why the subject is a
|
|
242
|
+
* different height. Four numbers per instance close it.
|
|
243
|
+
*
|
|
244
|
+
* Absent for a baseline written before this existed and for a profile with no
|
|
245
|
+
* layout — the same absence, and both mean *nobody measured*, never *it did
|
|
246
|
+
* not move*. A `null` entry is a boundary the browser laid out nothing for,
|
|
247
|
+
* kept in place so the list stays parallel to the instances it counts.
|
|
248
|
+
*/
|
|
249
|
+
readonly boxes?: readonly (Rect | null)[];
|
|
250
|
+
}
|
|
251
|
+
export interface StyleProvenanceEntry {
|
|
252
|
+
readonly path: NodePath;
|
|
253
|
+
readonly property: string;
|
|
254
|
+
readonly sheet: string;
|
|
255
|
+
/** Generated segments replaced by placeholders, so it can name a root safely. */
|
|
256
|
+
readonly selector: string;
|
|
257
|
+
readonly tokenName?: string;
|
|
258
|
+
readonly source?: {
|
|
259
|
+
readonly file: string;
|
|
260
|
+
readonly line: number;
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/format/snapshot.ts"],"names":[],"mappings":"","sourcesContent":["import type { SubjectRef, Rect, Diagnostic } from './capture.js';\nimport type { EnvironmentKey } from './environment.js';\nimport type { Digest } from './hash.js';\nimport type { ObservationProfile } from './profile.js';\nimport type { Provenance } from './provenance.js';\nimport type { Wiring } from './wiring.js';\nimport type { Holding } from './holding.js';\n\n/**\n * The normalized semantic snapshot: the verdict's input, and the thing a render\n * hash addresses.\n *\n * Everything volatile is gone by this point. Ids have become structural aliases,\n * class attributes have been dropped entirely, inapplicable CSS has been pruned,\n * and the cascade has been resolved to winning values (ADR-0003). What remains is\n * meant to be *read*: a snapshot a reviewer refuses to open is a snapshot that\n * gets rubber-stamped.\n */\nexport interface SemanticSnapshot {\n readonly formatVersion: 1;\n readonly subject: SubjectRef;\n readonly profile: ObservationProfile;\n readonly environment: EnvironmentKey;\n\n /** Content hash of `root` under `environment`. The identity of this state. */\n readonly renderHash: Digest;\n\n /**\n * Structure and applicable style, hashed separately.\n *\n * These back the tier below full semantic comparison (ADR-0003): matching both\n * settles a subject without resolving layout or taking a screenshot. Split\n * rather than combined because the docket wants to say *which* held — \"the DOM\n * is identical, only styling moved\" is the sentence that turns a diff into a\n * token-band root.\n */\n readonly structureHash: Digest;\n readonly styleHash: Digest;\n\n readonly root: SemanticNode;\n\n /**\n * Where each winning declaration came from. Deliberately outside the hash.\n *\n * Pruning discards exactly what attribution needs — *which rule set this?* — so\n * it is preserved here instead. Keeping it out of the hash is the point: moving\n * a rule between files renames a source without changing a render, and must not\n * invalidate a baseline.\n */\n readonly styleProvenance: readonly StyleProvenanceEntry[];\n\n /**\n * Subtrees the operator declared out of scope, resolved against *this* tree.\n *\n * Deliberately outside the hash, for the reason `styleProvenance` is: an ignore\n * changes what a run says about a render, never the render. Folding it into the\n * identity would invalidate every baseline in the repository the first time\n * somebody masked a clock, which is the surest way to make a safety feature the\n * thing people turn off.\n *\n * Present only when something was excluded, so a snapshot from a run with no\n * ignores is byte-identical to one produced before this field existed.\n */\n readonly ignoreSites?: readonly IgnoreSite[];\n\n /**\n * What the collector or the normalizer could not do, carried forward.\n *\n * Outside the hash: a diagnostic describes the *observation*, not the render,\n * and a snapshot that hashed its own warnings would invalidate whenever the\n * warning text was reworded. But it must survive to the verdict — a subject\n * whose capture half-failed is not a subject that legitimately `unchanged`,\n * and silently discarding that fact is how a broken collector reads as a clean\n * build.\n */\n readonly diagnostics: readonly Diagnostic[];\n}\n\n/**\n * A node's stable address: child indices from the root, e.g. `0/2/1`.\n *\n * Positional because nothing else survives. Ids are volatile (that is why they\n * were aliased away), and class names have been dropped. Position is honest about\n * what it costs: inserting a sibling renumbers everything after it, so the differ\n * matches nodes by shape and provenance before falling back to path (see\n * `diff.ts`), and treats a path change alone as evidence of nothing.\n */\nexport type NodePath = string;\n\nexport interface SemanticNode {\n readonly path: NodePath;\n readonly tag: string;\n\n /** Structural alias, e.g. `#a0`. Absent when the node carried no id. */\n readonly alias?: string;\n\n readonly role?: string;\n readonly name?: string;\n\n /**\n * Accessible description, resolved. See `RawAria.description` for why this is\n * a field of its own rather than an attribute.\n */\n readonly description?: string;\n\n readonly state?: Readonly<Record<string, string | boolean | number>>;\n\n /** Semantic attributes surviving normalization. `class` is never among them. */\n readonly attributes: Readonly<Record<string, string>>;\n\n /** Winning values for allowlisted properties, canonicalized. */\n readonly style: Readonly<Record<string, string>>;\n\n /**\n * Custom properties this node's winning declarations resolved through, as\n * name → resolved value.\n *\n * Recording the name alongside the value is what lets a design-token change\n * surface as one root with counted collateral instead of hundreds of unrelated\n * colour diffs (spec §5, `token` band).\n */\n readonly tokens?: Readonly<Record<string, string>>;\n\n /**\n * Which token each styled property resolved through, including by inheritance.\n *\n * Outside the hash, like `styleProvenance` and for the same reason: swapping a\n * literal for a token of the same value renames a source without changing a\n * render. It exists so the differ can tell *which* property a token edit\n * explains — `tokens` alone says a node uses tokens, not which of its values\n * one drove.\n */\n readonly styleTokens?: Readonly<Record<string, string>>;\n\n /** Present only under a profile with layout. Absent, never zeroed (ADR-0002). */\n readonly rect?: Rect;\n\n /** Text content, or its digest when policy declares the region volatile. */\n readonly text?: string;\n\n readonly provenance?: Provenance;\n\n /**\n * How the framework holds this node's component, when a framework adapter\n * supplied it. See {@link Wiring}.\n *\n * On the node rather than on `Provenance`, though both come from the same\n * adapter and the same fiber, because they answer to different readers.\n * Provenance exists so a diff arrives carrying a name; wiring is a *dimension\n * of the subject*, hashed into a band of its own, and a band's inputs belong\n * beside the other bands' inputs — next to `style` and `attributes`, which is\n * where `shapeOf` goes looking.\n */\n readonly wiring?: Wiring;\n\n /**\n * What that component was holding. **Outside every hash**, always.\n *\n * The field beside it is the contrast worth reading: `wiring` is a band and\n * this is evidence. `Wiring` refuses state values because a hook's value is\n * exactly what may legitimately differ between two readings of one page, and\n * that refusal is right and is not softened here — a `holding` reaches the\n * snapshot and reaches no digest, so a subject whose clock ticked has the same\n * `renderHash` it had before this field existed.\n *\n * It rides outside on the same terms as `styleProvenance`, `styleTokens` and\n * `ignoredBy`, by the same mechanism: `structureOf`, `styleOf` and `shapeOf`\n * project the fields they hash **by name**, so a field none of them names\n * cannot reach an identity. `holding.hash.test.ts` asserts that rather than\n * trusting it, because the cost of being wrong is every baseline in a\n * repository invalidating the first time a component held a timestamp.\n */\n readonly holding?: Holding;\n\n /**\n * `true` on the root of a subtree rendered through a portal.\n *\n * Recorded in the structure hash so that \"the dialog moved from inline to\n * portalled\" is a change rather than a coincidence of identical content, and\n * so the docket can say *where* something rendered, not only that it exists.\n */\n readonly portalled?: boolean;\n\n /**\n * Ignore rules this node was found under. Outside every hash, like its origin\n * on `RawNode`. See {@link SemanticSnapshot.ignoreSites}.\n */\n readonly ignoredBy?: readonly string[];\n\n readonly children: readonly SemanticNode[];\n}\n\n/**\n * A subtree the operator excluded, resolved to a path and a box (spec 0024).\n *\n * Lives in `format` rather than beside the rules that consume it, because it is\n * part of what a snapshot *is*: the collector produced it, it travels with the\n * document over every wire this project has, and `core/judge` is only its first\n * reader. A type the wire format needs cannot live in the policy layer.\n */\nexport interface IgnoreSite {\n /** Root of the excluded subtree, in this snapshot's own path space. */\n readonly path: NodePath;\n\n /** Which rule put it here, matched exactly against `IgnoreRule.id`. */\n readonly rule: string;\n\n /**\n * The box it occupied, for the raster tier.\n *\n * Absent under a profile with no layout — which is ADR-0002 rather than a\n * failure: a profile that cannot measure a box cannot decide pixels either, so\n * there is nothing for the box to subtract from.\n */\n readonly rect?: Rect;\n}\n\n/**\n * A component's own content, hashed per band (ADR-0018).\n *\n * In `format` rather than beside `hashComponents`, which computes it, because a\n * baseline carries these: a stored image plus the component hashes of the\n * document that painted it is what lets a later run tell the component that\n * *caused* a change from the components the change merely moved. That makes this\n * part of the wire format every store and every transport has to preserve, and a\n * type the wire needs cannot live in the layer that derives it.\n */\nexport interface ComponentHash {\n readonly component: string;\n\n /** Boundaries of this component in the subject, counted in document order. */\n readonly instances: number;\n\n /**\n * Tree shape: tags, structural aliases, portalling, allowlisted attributes,\n * and which child boundaries sit where. The `geometry` band's structural half.\n *\n * **Split out of a single `structure` digest on 2026-08-06.** It used to carry\n * the accessible semantics and the text too, and the fusion was invisible\n * until something needed to ask *which band moved* — at which point a baseline\n * could say \"this component changed\" and never say whether a heading was\n * renamed, a paragraph reworded, or a node inserted. Those are three different\n * bands, three different readers, and one of them is the band a route-level\n * test exists to ignore.\n */\n readonly structure: Digest;\n\n /**\n * Role, accessible name, and ARIA state. The `a11y` band.\n *\n * Its own digest because it is the band that must never be absorbed. Every\n * sensitivity level asserts on it, including the ones that ignore everything\n * else — and a level cannot assert on a band that is fused into another one.\n */\n readonly semantics: Digest;\n\n /** Text runs, in document order. The `content` band. */\n readonly text: Digest;\n\n readonly style: Digest;\n\n /**\n * Absent under a profile without layout — absent, never empty (ADR-0002).\n *\n * An empty geometry digest would compare equal between a run that observed no\n * movement and a run that could not observe movement at all, which is the\n * false `unchanged` this system must never produce.\n */\n readonly geometry?: Digest;\n\n /**\n * The box each instance occupies, in document order. Never hashed.\n *\n * A digest can say a component is not what it was and can never say by how\n * much. That is the gap a reviewer falls into: `Button — geometry, token` is\n * true of a control that lost a shadow and of one that grew eight pixels and\n * pushed the page down, and only the second explains why the subject is a\n * different height. Four numbers per instance close it.\n *\n * Absent for a baseline written before this existed and for a profile with no\n * layout — the same absence, and both mean *nobody measured*, never *it did\n * not move*. A `null` entry is a boundary the browser laid out nothing for,\n * kept in place so the list stays parallel to the instances it counts.\n */\n readonly boxes?: readonly (Rect | null)[];\n}\n\nexport interface StyleProvenanceEntry {\n readonly path: NodePath;\n readonly property: string;\n readonly sheet: string;\n /** Generated segments replaced by placeholders, so it can name a root safely. */\n readonly selector: string;\n readonly tokenName?: string;\n readonly source?: { readonly file: string; readonly line: number };\n}\n"]}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { type Digest } from './hash.js';
|
|
2
|
+
import { type Tier } from './tier.js';
|
|
3
|
+
import type { Intervention, ScreenshotOptions, SettleTarget } from './intervention.js';
|
|
4
|
+
/**
|
|
5
|
+
* Interventions as separate, nameable tricks — not a fixed set of switches.
|
|
6
|
+
*
|
|
7
|
+
* A subject that is still changing cannot be compared, so every system of this
|
|
8
|
+
* kind reaches into the page: it holds animations, waits for fonts, hides a
|
|
9
|
+
* caret, suppresses scrollbars. Written as one struct of booleans that becomes a
|
|
10
|
+
* closed vocabulary: adding a trick edits a type every caller depends on, and a
|
|
11
|
+
* project with a need nobody anticipated has to fork.
|
|
12
|
+
*
|
|
13
|
+
* So each is a value. It carries an id, the tier that can actually observe what
|
|
14
|
+
* it fixes, what it costs, and how it is applied — and a *recipe* is any list of
|
|
15
|
+
* them. Two tricks may express the same intent through different mechanisms and
|
|
16
|
+
* remain separate values, because they produce different images and choosing
|
|
17
|
+
* between them is the caller's business.
|
|
18
|
+
*
|
|
19
|
+
* ## What this buys
|
|
20
|
+
*
|
|
21
|
+
* A recipe can be filtered by tier, so the structure-and-style rung waits for
|
|
22
|
+
* nothing; composed from another project's tricks alongside these; digested, so
|
|
23
|
+
* a baseline made under one recipe is `incomparable` with a run made under
|
|
24
|
+
* another rather than `changed`; and checked for tricks that fight each other.
|
|
25
|
+
*
|
|
26
|
+
* ## Where the damage lands
|
|
27
|
+
*
|
|
28
|
+
* Ordered by increasing cost, earliest sufficient option first:
|
|
29
|
+
*
|
|
30
|
+
* - **Outside the subject** — injected CSS, browser screenshot options. Nothing
|
|
31
|
+
* in the product imports it and deleting the tool deletes the intervention.
|
|
32
|
+
* - **Runtime substitution** — wrapping `Promise`, replacing a suspense
|
|
33
|
+
* boundary. Buys the same knowledge without touching a component and is
|
|
34
|
+
* deliberately not shipped here: it moves the damage from design into
|
|
35
|
+
* semantics, where a difference caused by the patch cannot be told apart from
|
|
36
|
+
* a difference caused by the code. Expressible as a trick if a project decides
|
|
37
|
+
* the trade is worth it — that is the point of an open set.
|
|
38
|
+
* - **A contract the subject implements** — a readiness marker. Real design
|
|
39
|
+
* damage, and reserved for what the outside genuinely cannot know.
|
|
40
|
+
*
|
|
41
|
+
* ## Why this is in `format` and not in the raster package
|
|
42
|
+
*
|
|
43
|
+
* It was in `@variance-authority/raster` until 2026-08-06, on the reading that
|
|
44
|
+
* holding a page still is something you do before you photograph it. That
|
|
45
|
+
* reading was wrong in a way that cost correctness: an animation in flight is a
|
|
46
|
+
* *computed style value*, so it reaches the cheap representation too — and the
|
|
47
|
+
* allowlist excludes `animation-*` and `transition-*` precisely because it
|
|
48
|
+
* assumed a snapshot is taken with animation already disabled. Nothing disabled
|
|
49
|
+
* it. See {@link COLLECT_RECIPE} and ADR-0028.
|
|
50
|
+
*
|
|
51
|
+
* So a recipe is a render input on every tier, `EnvironmentInputs` carries its
|
|
52
|
+
* digest, and the vocabulary belongs beside the key it is part of.
|
|
53
|
+
*/
|
|
54
|
+
export type { Intervention, ScreenshotOptions, SettleTarget, Trick } from './intervention.js';
|
|
55
|
+
/**
|
|
56
|
+
* Hand animations to the browser rather than emulating the hold in CSS.
|
|
57
|
+
*
|
|
58
|
+
* A browser disabling animations for a screenshot fast-forwards a finite
|
|
59
|
+
* animation to completion — the state a user comes to rest on — and cancels an
|
|
60
|
+
* infinite one to its initial frame, replaying it afterwards. That is the
|
|
61
|
+
* behaviour worth having, and CSS cannot express it.
|
|
62
|
+
*/
|
|
63
|
+
export declare const holdAnimations: Intervention;
|
|
64
|
+
/**
|
|
65
|
+
* The same intent without a browser that can do it, and it is not equivalent.
|
|
66
|
+
*
|
|
67
|
+
* Pins every animation at its first frame, so a fade-in is captured at the
|
|
68
|
+
* moment it is invisible. `animation: none` is avoided deliberately — removing
|
|
69
|
+
* an animation drops whatever layout its keyframes contribute, which changes the
|
|
70
|
+
* page rather than stopping it.
|
|
71
|
+
*/
|
|
72
|
+
export declare const pinAnimations: Intervention;
|
|
73
|
+
export declare const hideCaret: Intervention;
|
|
74
|
+
export declare const hideScrollbars: Intervention;
|
|
75
|
+
/**
|
|
76
|
+
* Drop the pixels of images the page itself called decorative, keeping their boxes.
|
|
77
|
+
*
|
|
78
|
+
* The other half of blanking, and it lives here because of what it needs to
|
|
79
|
+
* know. A driver rewriting responses (`@variance-authority/playwright`'s
|
|
80
|
+
* `blank` rules) can decide by URL and by intrinsic size, which answers "every
|
|
81
|
+
* illustration over 40,000 pixels" and answers it before the bytes are even
|
|
82
|
+
* fetched. It cannot answer `role="presentation"`, because a request carries no
|
|
83
|
+
* idea which element wanted it — that fact exists only in the document, so the
|
|
84
|
+
* trick that uses it is a stylesheet.
|
|
85
|
+
*
|
|
86
|
+
* `visibility:hidden` rather than `display:none`, and the distinction is the
|
|
87
|
+
* entire design: a hidden element still occupies exactly the box it would have,
|
|
88
|
+
* so a page whose column height comes from an image's intrinsic size is
|
|
89
|
+
* unchanged. `display:none` would collapse it and report a layout regression
|
|
90
|
+
* this tool caused.
|
|
91
|
+
*
|
|
92
|
+
* **Opt-in, and it belongs in no default recipe.** Every other trick here
|
|
93
|
+
* removes something that is not part of the assertion — a caret, a scrollbar, an
|
|
94
|
+
* animation mid-flight. This one removes page content, which is a judgement
|
|
95
|
+
* about what a suite is for, and a default that quietly stopped watching every
|
|
96
|
+
* `alt=""` image would hide real regressions under a green run.
|
|
97
|
+
*/
|
|
98
|
+
export declare const hidePresentationalImages: Intervention;
|
|
99
|
+
export declare const waitForFonts: Intervention;
|
|
100
|
+
export declare const waitForImages: Intervention;
|
|
101
|
+
export declare const INTERVENTIONS: readonly Intervention[];
|
|
102
|
+
export type Recipe = readonly Intervention[];
|
|
103
|
+
/**
|
|
104
|
+
* Nothing at all, and correct for the tier that reads structure and declared style.
|
|
105
|
+
*
|
|
106
|
+
* A font that has not loaded cannot change which rules match or what they
|
|
107
|
+
* declare; an image that has not decoded cannot either. Waiting for both before
|
|
108
|
+
* a structure-and-style hash buys nothing and costs the wait per subject, on the
|
|
109
|
+
* rung the tier ladder exists to make cheap.
|
|
110
|
+
*/
|
|
111
|
+
export declare const SEMANTIC_RECIPE: Recipe;
|
|
112
|
+
export declare const LAYOUT_RECIPE: Recipe;
|
|
113
|
+
export declare const RASTER_RECIPE: Recipe;
|
|
114
|
+
/**
|
|
115
|
+
* What is applied to a live page *before a subject is observed*, as opposed to
|
|
116
|
+
* before it is painted.
|
|
117
|
+
*
|
|
118
|
+
* The two are different recipes and it is not a preference. {@link
|
|
119
|
+
* holdAnimations} is a *screenshot option* — it asks the browser to settle
|
|
120
|
+
* animations for the image it is about to take — and there is no screenshot at
|
|
121
|
+
* collection time, so it would be a trick that silently does nothing. The CSS
|
|
122
|
+
* variant is the one that works where nobody is holding a camera, which is the
|
|
123
|
+
* whole reason both exist as separate values rather than as one switch.
|
|
124
|
+
*
|
|
125
|
+
* ## Why the cheap tier needs this at all
|
|
126
|
+
*
|
|
127
|
+
* The claim in [`ruleset.ts`](../rules/ruleset.ts) that `transition-*` and
|
|
128
|
+
* `animation-*` "describe a journey the snapshot does not contain" is only true
|
|
129
|
+
* if the snapshot is taken with the journey stopped. `transform`, `opacity`,
|
|
130
|
+
* `filter`, `color` and every geometric longhand *are* admitted, and an
|
|
131
|
+
* animation in flight moves all of them — so an unstabilized collection turns a
|
|
132
|
+
* 300ms fade into a component-attributed regression with a real file name on it,
|
|
133
|
+
* which is worse than an unexplained pixel diff because it is credible.
|
|
134
|
+
*
|
|
135
|
+
* Filtered by {@link forTier}, so jsdom applies none of it: with no layout
|
|
136
|
+
* engine and no animation clock there is nothing to hold still, and paying a
|
|
137
|
+
* `fonts.ready` wait per subject on the rung that exists to be cheap is exactly
|
|
138
|
+
* the trade {@link SEMANTIC_RECIPE} refuses.
|
|
139
|
+
*/
|
|
140
|
+
export declare const COLLECT_RECIPE: Recipe;
|
|
141
|
+
/**
|
|
142
|
+
* Resolve a trick by the name a caller wrote down.
|
|
143
|
+
*
|
|
144
|
+
* The boundary a collection recipe crosses is a `page.evaluate`, and an
|
|
145
|
+
* `Intervention` does not survive it — `settle` is a function. Ids do survive,
|
|
146
|
+
* and the page holds this same registry, so a recipe travels as the list of
|
|
147
|
+
* names it is. A name nothing answers to is a caller error worth failing on
|
|
148
|
+
* rather than a trick to skip quietly: under-stabilizing is how a suite gets a
|
|
149
|
+
* flake it has already paid to prevent.
|
|
150
|
+
*/
|
|
151
|
+
export declare function interventionById(id: string): Intervention | undefined;
|
|
152
|
+
/**
|
|
153
|
+
* A recipe from the names it travels as.
|
|
154
|
+
*
|
|
155
|
+
* Throws on a name nothing answers to, and names it. The quiet alternative —
|
|
156
|
+
* skip what cannot be resolved — turns a typo in a config into a suite that is
|
|
157
|
+
* one trick less stable than its operator believes, discovered later as a flake
|
|
158
|
+
* they have already paid to prevent. Failing here costs one run and one reading
|
|
159
|
+
* of the message.
|
|
160
|
+
*/
|
|
161
|
+
export declare function recipeOf(ids: readonly string[]): Recipe;
|
|
162
|
+
/** Only the tricks a tier can observe the effect of. */
|
|
163
|
+
export declare function forTier(recipe: Recipe, tier: Tier): Recipe;
|
|
164
|
+
/**
|
|
165
|
+
* Tricks in a recipe that claim the same property.
|
|
166
|
+
*
|
|
167
|
+
* Returned rather than thrown, so a caller can decide — an override is a
|
|
168
|
+
* legitimate composition, and silently applying both is not. Two tricks over one
|
|
169
|
+
* property means one of them wins by accident of ordering, and which one is
|
|
170
|
+
* invisible in the result.
|
|
171
|
+
*/
|
|
172
|
+
export declare function conflicts(recipe: Recipe): readonly {
|
|
173
|
+
governs: string;
|
|
174
|
+
ids: readonly string[];
|
|
175
|
+
}[];
|
|
176
|
+
export declare function recipeCss(recipe: Recipe): string;
|
|
177
|
+
export declare function recipeScreenshot(recipe: Recipe): ScreenshotOptions;
|
|
178
|
+
export declare function settleRecipe(recipe: Recipe, target: SettleTarget): Promise<void>;
|
|
179
|
+
/**
|
|
180
|
+
* The identity of a recipe.
|
|
181
|
+
*
|
|
182
|
+
* Sorted, so the order tricks were composed in does not change the identity —
|
|
183
|
+
* only which ones are present. Folded into `RenderIdentity`, which is what makes
|
|
184
|
+
* a cross-recipe comparison report `incomparable` instead of inventing a
|
|
185
|
+
* component to blame.
|
|
186
|
+
*/
|
|
187
|
+
export declare function recipeDigest(recipe: Recipe): Digest;
|
|
188
|
+
/** The recipe as a sentence, so the gap between image and product stays visible. */
|
|
189
|
+
export declare function describeRecipe(recipe: Recipe): string;
|
|
190
|
+
//# sourceMappingURL=stabilize.d.ts.map
|