sheetom 0.1.0-rc.0 → 0.1.0-rc.2

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
@@ -9,9 +9,7 @@ not implement the DOM, cascade, selector matching, layout, or computed styles.
9
9
 
10
10
  ## Install
11
11
 
12
- SheetOM is not published yet. The first registry release will be
13
- `0.1.0-rc.0` under the `next` dist-tag after the complete conformance gate
14
- passes. Once published:
12
+ Install the current release candidate from the `next` dist-tag:
15
13
 
16
14
  ```sh
17
15
  npm install sheetom@next
@@ -59,9 +57,10 @@ Constructed sheets follow browser replacement behavior and strip `@import`.
59
57
  `parseStyleSheet` creates a regular authoring sheet and preserves valid imports
60
58
  without loading them.
61
59
 
62
- ## Recovered values and safe serialization
60
+ ## Recovered values and reparsable serialization
63
61
 
64
- SheetOM distinguishes the browser-facing CSSOM text from safe output. Chromium
62
+ SheetOM distinguishes browser-facing CSSOM text from reparsable stylesheet
63
+ output. Chromium
65
64
  accepts some values using CSS Syntax end-of-input recovery while preserving the
66
65
  unclosed input in `getPropertyValue()` and `cssText`:
67
66
 
@@ -82,9 +81,25 @@ sheet.serialize();
82
81
  // reparsable CSS with the missing syntax repaired
83
82
  ```
84
83
 
84
+ The three text surfaces have distinct contracts:
85
+
86
+ | Surface | Contract |
87
+ | --- | --- |
88
+ | `rule.style.cssText` | Browser-compatible observable declaration text, including accepted recovery quirks. |
89
+ | `rule.cssText` | Browser-compatible observable text for one rule and its current descendants. |
90
+ | `sheet.serialize()` | Deterministic, reparsable stylesheet output with recoverable syntax confined to its declaration or rule. |
91
+
92
+ Reparsable serialization means that the output can be parsed again without one
93
+ declaration leaking into the next declaration or rule, while preserving the
94
+ valid semantic state owned by SheetOM. It does not sanitize URLs, enforce CSP,
95
+ block remote resources, or make valid hostile CSS safe to render.
96
+
85
97
  Invalid `setProperty` values and priorities are atomic no-ops, matching browser
86
98
  behavior. Opt into mutation diagnostics with `{ diagnostics: true }` and drain
87
- them using `takeDiagnostics()`.
99
+ them using `takeDiagnostics()`. `SheetOMDiagnostic.code` is a stable string
100
+ union. Diagnostics retain the complete rejected input until drained; when
101
+ processing untrusted or very large input, callers should leave diagnostics off
102
+ or drain them promptly to bound memory use.
88
103
 
89
104
  ## API scope
90
105
 
@@ -141,8 +156,13 @@ npm run pack:test
141
156
 
142
157
  `npm test` runs unit, deterministic fuzz, and local Chromium projects. Use
143
158
  `npm run test:browser:matrix` on a machine with all Playwright dependencies to
144
- run Chromium, Firefox, and WebKit. `npm run docs:build` generates the TypeDoc
145
- reference under `site/api`.
159
+ run Chromium, Firefox, and WebKit. The browser matrix also runs a deterministic,
160
+ grammar-oriented declaration differential; any minimized mismatch must become
161
+ an immutable Operation Fixture with an explicit Compatibility Resolution.
162
+ `npm run docs:build` generates the TypeDoc reference under `site/api`. The benchmark gates both a 10,000-rule stress case
163
+ and a publisher-shaped reference workload with one shared stylesheet, 20 page
164
+ stylesheets, nested layers/media, distributed mutations, and two idempotent
165
+ serialization passes.
146
166
 
147
167
  Only the latest published `0.x` minor and its active prereleases receive fixes
148
168
  before 1.0. During `0.x`, observable compatibility corrections and interface
@@ -0,0 +1,108 @@
1
+ {
2
+ "$schema": "../schemas/compatibility-report.schema.json",
3
+ "schemaVersion": 1,
4
+ "packageVersion": "0.1.0-rc.1",
5
+ "baseline": {
6
+ "wptCommit": "54f8f933629e7c010ae98a246729af01f8abcda5",
7
+ "lightningcss": "1.33.0",
8
+ "cssTree": "3.2.1",
9
+ "runtimes": {
10
+ "node": "v24.18.0",
11
+ "bun": "1.3.1",
12
+ "deno": "2.9.5"
13
+ },
14
+ "browsers": {
15
+ "chromium": "151.0.7922.34 (revision 1234)",
16
+ "firefox": "153.0 (revision 1538)",
17
+ "webkit": "26.5 (revision 2336)"
18
+ }
19
+ },
20
+ "summary": {
21
+ "passed": 5,
22
+ "divergences": 2,
23
+ "excluded": 0,
24
+ "unexplained": 0
25
+ },
26
+ "evidence": {
27
+ "operationFixtures": {
28
+ "passed": 7,
29
+ "total": 7,
30
+ "sha256": "b4ec45fce8ad92393966d1b538748f6b3256d7d51af2fb0f76b4539a3300c349",
31
+ "adapters": [
32
+ {
33
+ "adapter": "sheetom",
34
+ "passed": 7,
35
+ "total": 7
36
+ },
37
+ {
38
+ "adapter": "chromium",
39
+ "passed": 7,
40
+ "total": 7
41
+ },
42
+ {
43
+ "adapter": "firefox",
44
+ "passed": 7,
45
+ "total": 7
46
+ },
47
+ {
48
+ "adapter": "webkit",
49
+ "passed": 7,
50
+ "total": 7
51
+ }
52
+ ]
53
+ },
54
+ "nativeWpt": [
55
+ {
56
+ "engine": "chrome",
57
+ "version": "150.0.7871.128",
58
+ "sha256": "33aaf2418507bb1d335cd5350b21a86cee86cbe3059e9eb1b2001c9e2693c1f1",
59
+ "passed": 4,
60
+ "total": 4
61
+ },
62
+ {
63
+ "engine": "firefox",
64
+ "version": "153.0.3",
65
+ "sha256": "20ee01df1d83cc67a50e7949ff6a62c87c572c2fb0159ee5c2b15bc8e9a13a1f",
66
+ "passed": 4,
67
+ "total": 4
68
+ }
69
+ ]
70
+ },
71
+ "resolutions": [
72
+ {
73
+ "fixtureId": "declarations.basic-set-property",
74
+ "decision": "shared",
75
+ "rationale": "The observable declaration state is shared by the pinned browser engines."
76
+ },
77
+ {
78
+ "fixtureId": "declarations.malformed-padding",
79
+ "decision": "chromium-fallback",
80
+ "rationale": "CSS Syntax accepts the EOF-recovered value; Chromium preserves the unclosed observable spelling while Firefox materializes closing parentheses."
81
+ },
82
+ {
83
+ "fixtureId": "declarations.setproperty-null-undefined",
84
+ "decision": "shared",
85
+ "rationale": "The four adapted WPT subtests define the shared null and undefined conversion behavior."
86
+ },
87
+ {
88
+ "fixtureId": "declarations.required-arguments",
89
+ "decision": "shared",
90
+ "rationale": "Required WebIDL arguments throw TypeError before string conversion in the pinned browser engines."
91
+ },
92
+ {
93
+ "fixtureId": "declarations.set-property-multiple-declarations",
94
+ "decision": "shared",
95
+ "rationale": "A setProperty value is parsed independently and cannot escape into another declaration; invalid input leaves the previous declaration unchanged."
96
+ },
97
+ {
98
+ "fixtureId": "declarations.escaped-custom-property-name",
99
+ "decision": "shared",
100
+ "rationale": "Custom-property method arguments retain their logical names and cssText escapes those names only when serializing CSS syntax."
101
+ },
102
+ {
103
+ "fixtureId": "integration.weweb-authoring-tree",
104
+ "decision": "chromium-fallback",
105
+ "rationale": "The standard rule-tree operations and detachment identity are shared; the recovered padding spelling follows the existing Chromium fallback resolution."
106
+ }
107
+ ]
108
+ }
@@ -0,0 +1,142 @@
1
+ {
2
+ "$schema": "../schemas/compatibility-report.schema.json",
3
+ "schemaVersion": 2,
4
+ "packageVersion": "0.1.0-rc.2",
5
+ "baseline": {
6
+ "wptCommit": "54f8f933629e7c010ae98a246729af01f8abcda5",
7
+ "syntaxEngineSet": {
8
+ "lightningcss": "1.33.0",
9
+ "cssTree": "3.2.1",
10
+ "cssstyle": "6.2.0",
11
+ "cssTokenizer": "4.0.0"
12
+ },
13
+ "runtimes": {
14
+ "node": "v24.18.0",
15
+ "bun": "1.3.1",
16
+ "deno": "2.9.5"
17
+ },
18
+ "browsers": {
19
+ "chromium": "151.0.7922.34 (revision 1234)",
20
+ "firefox": "153.0 (revision 1538)",
21
+ "webkit": "26.5 (revision 2336)"
22
+ }
23
+ },
24
+ "summary": {
25
+ "passed": 6,
26
+ "divergences": 7,
27
+ "excluded": 0,
28
+ "unexplained": 0
29
+ },
30
+ "evidence": {
31
+ "operationFixtures": {
32
+ "passed": 13,
33
+ "total": 13,
34
+ "sha256": "7909f90571b8d6595d18b006bb4f2c5337cca9d413084558e913e760be45a3aa",
35
+ "adapters": [
36
+ {
37
+ "adapter": "sheetom",
38
+ "passed": 13,
39
+ "total": 13
40
+ },
41
+ {
42
+ "adapter": "chromium",
43
+ "passed": 13,
44
+ "total": 13
45
+ },
46
+ {
47
+ "adapter": "firefox",
48
+ "passed": 13,
49
+ "total": 13
50
+ },
51
+ {
52
+ "adapter": "webkit",
53
+ "passed": 13,
54
+ "total": 13
55
+ }
56
+ ]
57
+ },
58
+ "nativeWpt": [
59
+ {
60
+ "engine": "chrome",
61
+ "version": "150.0.7871.128",
62
+ "sha256": "3f66a5f324bb9023cdd4b168e780640700449f22f28ca378eca91504b7d68e3f",
63
+ "passed": 4,
64
+ "total": 4
65
+ },
66
+ {
67
+ "engine": "firefox",
68
+ "version": "153.0.3",
69
+ "sha256": "e5f88e3431f602dc29fd8dbd79667bef33930ee7f87ee6d2069f17126421a230",
70
+ "passed": 4,
71
+ "total": 4
72
+ }
73
+ ]
74
+ },
75
+ "resolutions": [
76
+ {
77
+ "fixtureId": "declarations.basic-set-property",
78
+ "decision": "shared",
79
+ "rationale": "The observable declaration state is shared by the pinned browser engines."
80
+ },
81
+ {
82
+ "fixtureId": "declarations.malformed-padding",
83
+ "decision": "chromium-fallback",
84
+ "rationale": "CSS Syntax accepts the EOF-recovered value; Chromium preserves the unclosed observable spelling while Firefox materializes closing parentheses."
85
+ },
86
+ {
87
+ "fixtureId": "declarations.modern-color-canonicalization",
88
+ "decision": "shared",
89
+ "rationale": "The pinned browser engines expose modern rgb syntax through the shared legacy rgba serialization in CSSStyleDeclaration."
90
+ },
91
+ {
92
+ "fixtureId": "declarations.typed-eof-recovery",
93
+ "decision": "chromium-fallback",
94
+ "rationale": "Typed property values expose the Chromium/WebKit canonical serialization after CSS Syntax EOF recovery; Firefox retains quotes around the recovered font-family string."
95
+ },
96
+ {
97
+ "fixtureId": "declarations.quoted-font-family",
98
+ "decision": "chromium-fallback",
99
+ "rationale": "Chromium and WebKit remove unnecessary quotes around a simple font-family while Firefox retains them; SheetOM follows the measured Chromium fallback."
100
+ },
101
+ {
102
+ "fixtureId": "declarations.custom-property-eof-recovery",
103
+ "decision": "chromium-fallback",
104
+ "rationale": "Chromium retains unclosed custom-property token structures, removes EOF comments, and replaces an escaped EOF with U+FFFD."
105
+ },
106
+ {
107
+ "fixtureId": "declarations.custom-property-priority-replacement",
108
+ "decision": "chromium-fallback",
109
+ "rationale": "Chromium and Firefox replace the existing custom-property priority when setProperty is called without a priority, while WebKit retains !important; SheetOM follows the measured Chromium fallback."
110
+ },
111
+ {
112
+ "fixtureId": "declarations.pending-substitution-eof-recovery",
113
+ "decision": "chromium-fallback",
114
+ "rationale": "Chromium retains the unclosed pending-substitution spelling while applying lexical EOF recovery such as comment removal."
115
+ },
116
+ {
117
+ "fixtureId": "declarations.setproperty-null-undefined",
118
+ "decision": "shared",
119
+ "rationale": "The four adapted WPT subtests define the shared null and undefined conversion behavior."
120
+ },
121
+ {
122
+ "fixtureId": "declarations.required-arguments",
123
+ "decision": "shared",
124
+ "rationale": "Required WebIDL arguments throw TypeError before string conversion in the pinned browser engines."
125
+ },
126
+ {
127
+ "fixtureId": "declarations.set-property-multiple-declarations",
128
+ "decision": "shared",
129
+ "rationale": "A setProperty value is parsed independently and cannot escape into another declaration; invalid input leaves the previous declaration unchanged."
130
+ },
131
+ {
132
+ "fixtureId": "declarations.escaped-custom-property-name",
133
+ "decision": "shared",
134
+ "rationale": "Custom-property method arguments retain their logical names and cssText escapes those names only when serializing CSS syntax."
135
+ },
136
+ {
137
+ "fixtureId": "integration.weweb-authoring-tree",
138
+ "decision": "chromium-fallback",
139
+ "rationale": "The standard rule-tree operations and detachment identity are shared; the recovered padding spelling follows the existing Chromium fallback resolution."
140
+ }
141
+ ]
142
+ }
@@ -7,16 +7,27 @@
7
7
  "required": ["schemaVersion", "packageVersion", "baseline", "summary", "evidence", "resolutions"],
8
8
  "properties": {
9
9
  "$schema": { "type": "string" },
10
- "schemaVersion": { "const": 1 },
10
+ "schemaVersion": { "enum": [1, 2] },
11
11
  "packageVersion": { "type": "string" },
12
12
  "baseline": {
13
13
  "type": "object",
14
14
  "additionalProperties": false,
15
- "required": ["wptCommit", "lightningcss", "cssTree", "runtimes", "browsers"],
15
+ "required": ["wptCommit", "runtimes", "browsers"],
16
16
  "properties": {
17
17
  "wptCommit": { "type": "string", "pattern": "^[0-9a-f]{40}$" },
18
18
  "lightningcss": { "type": "string" },
19
19
  "cssTree": { "type": "string" },
20
+ "syntaxEngineSet": {
21
+ "type": "object",
22
+ "additionalProperties": false,
23
+ "required": ["lightningcss", "cssTree", "cssstyle", "cssTokenizer"],
24
+ "properties": {
25
+ "lightningcss": { "type": "string" },
26
+ "cssTree": { "type": "string" },
27
+ "cssstyle": { "type": "string" },
28
+ "cssTokenizer": { "type": "string" }
29
+ }
30
+ },
20
31
  "runtimes": { "type": "object" },
21
32
  "browsers": { "type": "object" }
22
33
  }
@@ -43,7 +54,23 @@
43
54
  "required": ["passed", "total"],
44
55
  "properties": {
45
56
  "passed": { "type": "integer", "minimum": 0 },
46
- "total": { "type": "integer", "minimum": 0 }
57
+ "total": { "type": "integer", "minimum": 0 },
58
+ "sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
59
+ "adapters": {
60
+ "type": "array",
61
+ "items": {
62
+ "type": "object",
63
+ "additionalProperties": false,
64
+ "required": ["adapter", "passed", "total"],
65
+ "properties": {
66
+ "adapter": {
67
+ "enum": ["sheetom", "chromium", "firefox", "webkit"]
68
+ },
69
+ "passed": { "type": "integer", "minimum": 0 },
70
+ "total": { "type": "integer", "minimum": 0 }
71
+ }
72
+ }
73
+ }
47
74
  }
48
75
  },
49
76
  "nativeWpt": {
@@ -64,5 +91,36 @@
64
91
  }
65
92
  },
66
93
  "resolutions": { "type": "array" }
67
- }
94
+ },
95
+ "allOf": [
96
+ {
97
+ "if": { "properties": { "schemaVersion": { "const": 1 } } },
98
+ "then": {
99
+ "properties": {
100
+ "baseline": {
101
+ "type": "object",
102
+ "required": ["lightningcss", "cssTree"],
103
+ "properties": {
104
+ "lightningcss": { "type": "string" },
105
+ "cssTree": { "type": "string" }
106
+ }
107
+ }
108
+ }
109
+ }
110
+ },
111
+ {
112
+ "if": { "properties": { "schemaVersion": { "const": 2 } } },
113
+ "then": {
114
+ "properties": {
115
+ "baseline": {
116
+ "type": "object",
117
+ "required": ["syntaxEngineSet"],
118
+ "properties": {
119
+ "syntaxEngineSet": { "type": "object" }
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+ ]
68
126
  }