zyzz 0.0.28 → 0.0.29
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/binding/wasi/wasi-worker.mjs +186 -0
- package/binding/wasi/zyzz.wasi.cjs +2302 -0
- package/binding/wasi/zyzz.wasm32-wasi.wasm +0 -0
- package/binding/zyzz.linux-x64-gnu.node +0 -0
- package/dist/babel/index.d.ts.map +1 -1
- package/dist/babel/index.js +2 -4
- package/dist/babel/index.js.map +1 -1
- package/dist/babel/internal/Compilation.d.ts +0 -1
- package/dist/babel/internal/Compilation.d.ts.map +1 -1
- package/dist/compiler/Graph.d.ts +14 -11
- package/dist/compiler/Graph.d.ts.map +1 -1
- package/dist/compiler/Graph.js +57 -1442
- package/dist/compiler/Graph.js.map +1 -1
- package/dist/compiler/Native.d.ts +7 -9
- package/dist/compiler/Native.d.ts.map +1 -1
- package/dist/compiler/Native.js +12 -716
- package/dist/compiler/Native.js.map +1 -1
- package/dist/compiler/Source.d.ts +122 -24
- package/dist/compiler/Source.d.ts.map +1 -1
- package/dist/compiler/Source.js +10 -1267
- package/dist/compiler/Source.js.map +1 -1
- package/dist/compiler/Transform.d.ts +4 -3
- package/dist/compiler/Transform.d.ts.map +1 -1
- package/dist/compiler/Transform.js +13 -961
- package/dist/compiler/Transform.js.map +1 -1
- package/dist/compiler/internal/AtRules.d.ts +5 -1
- package/dist/compiler/internal/AtRules.d.ts.map +1 -1
- package/dist/compiler/internal/AtRules.js +12 -106
- package/dist/compiler/internal/AtRules.js.map +1 -1
- package/dist/compiler/internal/Context.d.ts +11 -0
- package/dist/compiler/internal/Context.d.ts.map +1 -0
- package/dist/compiler/internal/Context.js +11 -0
- package/dist/compiler/internal/Context.js.map +1 -0
- package/dist/compiler/internal/Results.d.ts +148 -0
- package/dist/compiler/internal/Results.d.ts.map +1 -0
- package/dist/compiler/internal/Results.js +259 -0
- package/dist/compiler/internal/Results.js.map +1 -0
- package/dist/compiler/internal/Syntax.d.ts +0 -2
- package/dist/compiler/internal/Syntax.d.ts.map +1 -1
- package/dist/compiler/internal/Syntax.js +0 -2
- package/dist/compiler/internal/Syntax.js.map +1 -1
- package/dist/compiler/internal/Wire.d.ts +17 -0
- package/dist/compiler/internal/Wire.d.ts.map +1 -0
- package/dist/compiler/internal/Wire.js +795 -0
- package/dist/compiler/internal/Wire.js.map +1 -0
- package/dist/internal/Addon.d.ts +28 -0
- package/dist/internal/Addon.d.ts.map +1 -0
- package/dist/internal/Addon.js +87 -0
- package/dist/internal/Addon.js.map +1 -0
- package/dist/internal/Literal.d.ts +4 -1
- package/dist/internal/Literal.d.ts.map +1 -1
- package/dist/internal/Literal.js +4 -2
- package/dist/internal/Literal.js.map +1 -1
- package/dist/internal/Token.d.ts +2 -1
- package/dist/internal/Token.d.ts.map +1 -1
- package/dist/internal/Token.js +2 -2
- package/dist/internal/Token.js.map +1 -1
- package/dist/internal/Vlq.d.ts +14 -0
- package/dist/internal/Vlq.d.ts.map +1 -0
- package/dist/internal/Vlq.js +47 -0
- package/dist/internal/Vlq.js.map +1 -0
- package/dist/internal/Wasm.d.ts +22 -0
- package/dist/internal/Wasm.d.ts.map +1 -0
- package/dist/internal/Wasm.js +83 -0
- package/dist/internal/Wasm.js.map +1 -0
- package/dist/metro/Graph.d.ts +0 -1
- package/dist/metro/Graph.d.ts.map +1 -1
- package/dist/metro/transformer.d.ts.map +1 -1
- package/dist/metro/transformer.js +0 -1
- package/dist/metro/transformer.js.map +1 -1
- package/dist/next/internal/Project.d.ts.map +1 -1
- package/dist/next/internal/Project.js +2 -5
- package/dist/next/internal/Project.js.map +1 -1
- package/dist/node/Host.d.ts.map +1 -1
- package/dist/node/Host.js +0 -2
- package/dist/node/Host.js.map +1 -1
- package/dist/node/internal/Contracts.d.ts.map +1 -1
- package/dist/node/internal/Contracts.js +3 -7
- package/dist/node/internal/Contracts.js.map +1 -1
- package/dist/node/internal/Snapshot.d.ts +0 -1
- package/dist/node/internal/Snapshot.d.ts.map +1 -1
- package/dist/node/internal/Snapshot.js +0 -6
- package/dist/node/internal/Snapshot.js.map +1 -1
- package/dist/runtime/Composition.d.ts +2 -3
- package/dist/runtime/Composition.d.ts.map +1 -1
- package/dist/runtime/Composition.js +51 -30
- package/dist/runtime/Composition.js.map +1 -1
- package/dist/runtime/Recipe.d.ts.map +1 -1
- package/dist/runtime/Recipe.js +16 -12
- package/dist/runtime/Recipe.js.map +1 -1
- package/dist/unplugin/index.d.ts.map +1 -1
- package/dist/unplugin/index.js +3 -6
- package/dist/unplugin/index.js.map +1 -1
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +696 -201
- package/dist/vite/index.js.map +1 -1
- package/dist/web/Css.d.ts +8 -3
- package/dist/web/Css.d.ts.map +1 -1
- package/dist/web/Css.js +5 -721
- package/dist/web/Css.js.map +1 -1
- package/dist/web/internal/Block.d.ts +0 -2
- package/dist/web/internal/Block.d.ts.map +1 -1
- package/dist/web/internal/Block.js +1 -12
- package/dist/web/internal/Block.js.map +1 -1
- package/dist/web/internal/ClassName.d.ts +23 -18
- package/dist/web/internal/ClassName.d.ts.map +1 -1
- package/dist/web/internal/ClassName.js +26 -55
- package/dist/web/internal/ClassName.js.map +1 -1
- package/dist/web/internal/Contributions.d.ts +3 -5
- package/dist/web/internal/Contributions.d.ts.map +1 -1
- package/dist/web/internal/Contributions.js +0 -45
- package/dist/web/internal/Contributions.js.map +1 -1
- package/dist/web/internal/Engine.browser.d.ts +8 -0
- package/dist/web/internal/Engine.browser.d.ts.map +1 -0
- package/dist/web/internal/Engine.browser.js +42 -0
- package/dist/web/internal/Engine.browser.js.map +1 -0
- package/dist/web/internal/Engine.d.ts +9 -0
- package/dist/web/internal/Engine.d.ts.map +1 -0
- package/dist/web/internal/Engine.js +14 -0
- package/dist/web/internal/Engine.js.map +1 -0
- package/dist/web/internal/Themes.d.ts +1 -9
- package/dist/web/internal/Themes.d.ts.map +1 -1
- package/dist/web/internal/Themes.js +3 -221
- package/dist/web/internal/Themes.js.map +1 -1
- package/dist/web/internal/Wasm.generated.d.ts +4 -0
- package/dist/web/internal/Wasm.generated.d.ts.map +1 -0
- package/dist/web/internal/Wasm.generated.js +4 -0
- package/dist/web/internal/Wasm.generated.js.map +1 -0
- package/dist/web/internal/Wire.d.ts +19 -0
- package/dist/web/internal/Wire.d.ts.map +1 -0
- package/dist/web/internal/Wire.js +387 -0
- package/dist/web/internal/Wire.js.map +1 -0
- package/package.json +20 -1
- package/src/babel/index.ts +2 -5
- package/src/babel/internal/Compilation.ts +0 -1
- package/src/compiler/Graph.ts +89 -1930
- package/src/compiler/Native.ts +18 -871
- package/src/compiler/Source.ts +144 -1803
- package/src/compiler/Transform.ts +16 -1315
- package/src/compiler/internal/AtRules.ts +27 -115
- package/src/compiler/internal/Context.ts +11 -0
- package/src/compiler/internal/Results.ts +406 -0
- package/src/compiler/internal/Syntax.ts +0 -3
- package/src/compiler/internal/Wire.ts +1045 -0
- package/src/internal/Addon.ts +118 -0
- package/src/internal/Literal.ts +4 -2
- package/src/internal/Token.ts +2 -2
- package/src/internal/Vlq.ts +59 -0
- package/src/internal/Wasm.ts +111 -0
- package/src/metro/transformer.ts +0 -1
- package/src/next/internal/Project.ts +2 -9
- package/src/node/Host.ts +0 -2
- package/src/node/internal/Contracts.ts +3 -7
- package/src/node/internal/Snapshot.ts +0 -8
- package/src/runtime/Composition.ts +48 -25
- package/src/runtime/Recipe.ts +21 -14
- package/src/unplugin/index.ts +6 -6
- package/src/vite/index.ts +922 -221
- package/src/web/Css.ts +12 -908
- package/src/web/internal/Block.ts +0 -14
- package/src/web/internal/ClassName.ts +52 -85
- package/src/web/internal/Contributions.ts +3 -59
- package/src/web/internal/Engine.browser.ts +51 -0
- package/src/web/internal/Engine.ts +17 -0
- package/src/web/internal/Themes.ts +3 -279
- package/src/web/internal/Wasm.generated.ts +3 -0
- package/src/web/internal/Wire.ts +466 -0
- package/src/web/internal/wasm.d.ts +9 -0
- package/dist/compiler/internal/Applications.d.ts +0 -55
- package/dist/compiler/internal/Applications.d.ts.map +0 -1
- package/dist/compiler/internal/Applications.js +0 -393
- package/dist/compiler/internal/Applications.js.map +0 -1
- package/dist/compiler/internal/ColorProfiles.d.ts +0 -3
- package/dist/compiler/internal/ColorProfiles.d.ts.map +0 -1
- package/dist/compiler/internal/ColorProfiles.js +0 -84
- package/dist/compiler/internal/ColorProfiles.js.map +0 -1
- package/dist/compiler/internal/CompositionBindings.d.ts +0 -16
- package/dist/compiler/internal/CompositionBindings.d.ts.map +0 -1
- package/dist/compiler/internal/CompositionBindings.js +0 -89
- package/dist/compiler/internal/CompositionBindings.js.map +0 -1
- package/dist/compiler/internal/Compositions.d.ts +0 -37
- package/dist/compiler/internal/Compositions.d.ts.map +0 -1
- package/dist/compiler/internal/Compositions.js +0 -494
- package/dist/compiler/internal/Compositions.js.map +0 -1
- package/dist/compiler/internal/Configurations.d.ts +0 -26
- package/dist/compiler/internal/Configurations.d.ts.map +0 -1
- package/dist/compiler/internal/Configurations.js +0 -259
- package/dist/compiler/internal/Configurations.js.map +0 -1
- package/dist/compiler/internal/Contract.d.ts +0 -30
- package/dist/compiler/internal/Contract.d.ts.map +0 -1
- package/dist/compiler/internal/Contract.js +0 -753
- package/dist/compiler/internal/Contract.js.map +0 -1
- package/dist/compiler/internal/Contributions.d.ts +0 -54
- package/dist/compiler/internal/Contributions.d.ts.map +0 -1
- package/dist/compiler/internal/Contributions.js +0 -1151
- package/dist/compiler/internal/Contributions.js.map +0 -1
- package/dist/compiler/internal/Descriptors.d.ts +0 -15
- package/dist/compiler/internal/Descriptors.d.ts.map +0 -1
- package/dist/compiler/internal/Descriptors.js +0 -192
- package/dist/compiler/internal/Descriptors.js.map +0 -1
- package/dist/compiler/internal/Dynamic.d.ts +0 -14
- package/dist/compiler/internal/Dynamic.d.ts.map +0 -1
- package/dist/compiler/internal/Dynamic.js +0 -175
- package/dist/compiler/internal/Dynamic.js.map +0 -1
- package/dist/compiler/internal/Expression.d.ts +0 -19
- package/dist/compiler/internal/Expression.d.ts.map +0 -1
- package/dist/compiler/internal/Expression.js +0 -164
- package/dist/compiler/internal/Expression.js.map +0 -1
- package/dist/compiler/internal/Functions.d.ts +0 -5
- package/dist/compiler/internal/Functions.d.ts.map +0 -1
- package/dist/compiler/internal/Functions.js +0 -191
- package/dist/compiler/internal/Functions.js.map +0 -1
- package/dist/compiler/internal/Keyframes.d.ts +0 -5
- package/dist/compiler/internal/Keyframes.d.ts.map +0 -1
- package/dist/compiler/internal/Keyframes.js +0 -51
- package/dist/compiler/internal/Keyframes.js.map +0 -1
- package/dist/compiler/internal/Names.d.ts +0 -5
- package/dist/compiler/internal/Names.d.ts.map +0 -1
- package/dist/compiler/internal/Names.js +0 -37
- package/dist/compiler/internal/Names.js.map +0 -1
- package/dist/compiler/internal/NativeBindings.d.ts +0 -72
- package/dist/compiler/internal/NativeBindings.d.ts.map +0 -1
- package/dist/compiler/internal/NativeBindings.js +0 -171
- package/dist/compiler/internal/NativeBindings.js.map +0 -1
- package/dist/compiler/internal/NativeMedia.d.ts +0 -14
- package/dist/compiler/internal/NativeMedia.d.ts.map +0 -1
- package/dist/compiler/internal/NativeMedia.js +0 -287
- package/dist/compiler/internal/NativeMedia.js.map +0 -1
- package/dist/compiler/internal/NativeVars.d.ts +0 -28
- package/dist/compiler/internal/NativeVars.d.ts.map +0 -1
- package/dist/compiler/internal/NativeVars.js +0 -160
- package/dist/compiler/internal/NativeVars.js.map +0 -1
- package/dist/compiler/internal/PackedStyles.d.ts +0 -37
- package/dist/compiler/internal/PackedStyles.d.ts.map +0 -1
- package/dist/compiler/internal/PackedStyles.js +0 -344
- package/dist/compiler/internal/PackedStyles.js.map +0 -1
- package/dist/compiler/internal/Properties.d.ts +0 -5
- package/dist/compiler/internal/Properties.d.ts.map +0 -1
- package/dist/compiler/internal/Properties.js +0 -82
- package/dist/compiler/internal/Properties.js.map +0 -1
- package/dist/compiler/internal/RecipeConditions.d.ts +0 -41
- package/dist/compiler/internal/RecipeConditions.d.ts.map +0 -1
- package/dist/compiler/internal/RecipeConditions.js +0 -82
- package/dist/compiler/internal/RecipeConditions.js.map +0 -1
- package/dist/compiler/internal/RecipePayloads.d.ts +0 -31
- package/dist/compiler/internal/RecipePayloads.d.ts.map +0 -1
- package/dist/compiler/internal/RecipePayloads.js +0 -99
- package/dist/compiler/internal/RecipePayloads.js.map +0 -1
- package/dist/compiler/internal/Recipes.d.ts +0 -32
- package/dist/compiler/internal/Recipes.d.ts.map +0 -1
- package/dist/compiler/internal/Recipes.js +0 -339
- package/dist/compiler/internal/Recipes.js.map +0 -1
- package/dist/compiler/internal/Selectors.d.ts +0 -13
- package/dist/compiler/internal/Selectors.d.ts.map +0 -1
- package/dist/compiler/internal/Selectors.js +0 -280
- package/dist/compiler/internal/Selectors.js.map +0 -1
- package/dist/compiler/internal/Static.d.ts +0 -39
- package/dist/compiler/internal/Static.d.ts.map +0 -1
- package/dist/compiler/internal/Static.js +0 -534
- package/dist/compiler/internal/Static.js.map +0 -1
- package/dist/compiler/internal/Themes.d.ts +0 -190
- package/dist/compiler/internal/Themes.d.ts.map +0 -1
- package/dist/compiler/internal/Themes.js +0 -1577
- package/dist/compiler/internal/Themes.js.map +0 -1
- package/dist/compiler/internal/Vars.d.ts +0 -33
- package/dist/compiler/internal/Vars.d.ts.map +0 -1
- package/dist/compiler/internal/Vars.js +0 -387
- package/dist/compiler/internal/Vars.js.map +0 -1
- package/dist/compiler/internal/ViewTransitions.d.ts +0 -3
- package/dist/compiler/internal/ViewTransitions.d.ts.map +0 -1
- package/dist/compiler/internal/ViewTransitions.js +0 -68
- package/dist/compiler/internal/ViewTransitions.js.map +0 -1
- package/dist/internal/Cascade.d.ts +0 -74
- package/dist/internal/Cascade.d.ts.map +0 -1
- package/dist/internal/Cascade.js +0 -210
- package/dist/internal/Cascade.js.map +0 -1
- package/src/compiler/internal/Applications.ts +0 -610
- package/src/compiler/internal/ColorProfiles.ts +0 -93
- package/src/compiler/internal/CompositionBindings.ts +0 -120
- package/src/compiler/internal/Compositions.ts +0 -678
- package/src/compiler/internal/Configurations.ts +0 -349
- package/src/compiler/internal/Contract.ts +0 -1028
- package/src/compiler/internal/Contributions.ts +0 -1561
- package/src/compiler/internal/Descriptors.ts +0 -242
- package/src/compiler/internal/Dynamic.ts +0 -275
- package/src/compiler/internal/Expression.ts +0 -218
- package/src/compiler/internal/Functions.ts +0 -206
- package/src/compiler/internal/Keyframes.ts +0 -62
- package/src/compiler/internal/Names.ts +0 -48
- package/src/compiler/internal/NativeBindings.ts +0 -235
- package/src/compiler/internal/NativeMedia.ts +0 -342
- package/src/compiler/internal/NativeVars.ts +0 -231
- package/src/compiler/internal/PackedStyles.ts +0 -473
- package/src/compiler/internal/Properties.ts +0 -121
- package/src/compiler/internal/RecipeConditions.ts +0 -139
- package/src/compiler/internal/RecipePayloads.ts +0 -132
- package/src/compiler/internal/Recipes.ts +0 -531
- package/src/compiler/internal/Selectors.ts +0 -353
- package/src/compiler/internal/Static.ts +0 -784
- package/src/compiler/internal/Themes.ts +0 -2398
- package/src/compiler/internal/Vars.ts +0 -516
- package/src/compiler/internal/ViewTransitions.ts +0 -82
package/src/web/Css.ts
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Emits deterministic CSS, class mappings, and live theme scopes from ordered styles.
|
|
3
|
+
* The Rust compiler emits the CSS: Node runs its native addon and browsers its WebAssembly build.
|
|
3
4
|
* @module
|
|
4
5
|
*/
|
|
5
|
-
import * as Targets from '../internal/Targets.js'
|
|
6
|
-
import * as ClassName from './internal/ClassName.js'
|
|
7
|
-
import * as Identity from '../internal/Identity.js'
|
|
8
|
-
import * as Contributions from './internal/Contributions.js'
|
|
9
|
-
import * as Binding from '../internal/Binding.js'
|
|
10
|
-
import * as Cascade from '../internal/Cascade.js'
|
|
11
|
-
import * as Literal from '../internal/Literal.js'
|
|
12
|
-
import * as Token from '../internal/Token.js'
|
|
13
6
|
import type * as Style from '../Style.js'
|
|
14
7
|
import type * as Vars from '../Vars.js'
|
|
15
8
|
import type * as Theme from '../internal/Theme.js'
|
|
16
|
-
import * as
|
|
9
|
+
import * as ClassName from './internal/ClassName.js'
|
|
10
|
+
import type * as Contributions from './internal/Contributions.js'
|
|
11
|
+
import * as Engine from './internal/Engine.js'
|
|
12
|
+
import type * as Themes from './internal/Themes.js'
|
|
13
|
+
import * as Wire from './internal/Wire.js'
|
|
17
14
|
|
|
18
15
|
/** Explicit ordered stylesheet contribution data. */
|
|
19
16
|
export type Contribution = Contributions.Definition
|
|
@@ -35,898 +32,13 @@ export function compile<
|
|
|
35
32
|
>(
|
|
36
33
|
options: compile.Options<name, themeName>,
|
|
37
34
|
): compile.ReturnType<name, themeName> {
|
|
38
|
-
const
|
|
39
|
-
const units =
|
|
40
|
-
options[ClassName.units] ??
|
|
41
|
-
ClassName.registry().scope({ owner: '', qualifier: '' })
|
|
42
|
-
options = {
|
|
43
|
-
...options,
|
|
44
|
-
styles: { styles: options.styles.styles.map(Targets.web) },
|
|
45
|
-
}
|
|
46
|
-
let theme: ReturnType<typeof Themes.create> | undefined
|
|
47
|
-
|
|
48
|
-
const references = new Map<object, boolean>()
|
|
49
|
-
|
|
50
|
-
function isReference(value: unknown): value is Token.Reference {
|
|
51
|
-
if (typeof value !== 'object' || value === null) return false
|
|
52
|
-
|
|
53
|
-
const previous = references.get(value)
|
|
54
|
-
if (previous !== undefined) return previous
|
|
55
|
-
|
|
56
|
-
const result = Token.is(value)
|
|
57
|
-
|
|
58
|
-
references.set(value, result)
|
|
59
|
-
|
|
60
|
-
return result
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const bodies = new Map<Style.NamedStyle, string>()
|
|
64
|
-
const declarations = new Map<Style.Declaration, string>()
|
|
65
|
-
type Property = {
|
|
66
|
-
readonly important: Map<Style.Declaration['value'], string>
|
|
67
|
-
readonly name: string
|
|
68
|
-
readonly normal: Map<Style.Declaration['value'], string>
|
|
69
|
-
}
|
|
70
|
-
const declarationProperties = new Map<string, Property>()
|
|
71
|
-
const serialized = new Map<object, string>()
|
|
72
|
-
|
|
73
|
-
// Only primitive declaration lists can be interned without erasing token identity.
|
|
74
|
-
// Reuse their emitted bodies throughout analysis and output.
|
|
75
|
-
const repeated = new Map<string, Style.NamedStyle>()
|
|
76
|
-
|
|
77
|
-
const canonicalStyles = options.styles.styles.map((style) => {
|
|
78
|
-
if (
|
|
79
|
-
'rules' in style ||
|
|
80
|
-
style.declarations.some(
|
|
81
|
-
(declaration) => typeof declaration.value === 'object',
|
|
82
|
-
)
|
|
83
|
-
)
|
|
84
|
-
return style
|
|
85
|
-
|
|
86
|
-
const key = nested(style)
|
|
87
|
-
const previous = repeated.get(key)
|
|
88
|
-
if (previous) return previous
|
|
89
|
-
|
|
90
|
-
repeated.set(key, style)
|
|
91
|
-
|
|
92
|
-
return style
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
const analyzed = [...new Set(canonicalStyles)]
|
|
96
|
-
const classes = Object.create(null) as Record<name, string>
|
|
97
|
-
const diagnostics: Diagnostic[] = []
|
|
98
|
-
const groups = new Map<string, false | string>()
|
|
99
|
-
const nestedComposition = options.styles.styles.some(
|
|
100
|
-
(style) => style.rules && !isolated(style),
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
const properties = new Set<Style.Declaration['property']>()
|
|
104
|
-
// Conditional and composed declarations join the same conflict domains.
|
|
105
|
-
function collect(style: Style.NamedStyle): void {
|
|
106
|
-
for (const { property } of style.declarations) properties.add(property)
|
|
107
|
-
for (const rule of style.rules ?? []) collect(rule.style)
|
|
108
|
-
}
|
|
109
|
-
for (const style of analyzed) collect(style)
|
|
110
|
-
|
|
111
|
-
// Logical dimensions may alias either physical axis in inherited writing modes.
|
|
112
|
-
// Preserve physical-only factoring when no logical dimension is authored.
|
|
113
|
-
const logicalSizing = [...properties].some((property) =>
|
|
114
|
-
/^(min|max)?(blockSize|inlineSize)$/i.test(canonical(property)),
|
|
115
|
-
)
|
|
116
|
-
const resets = properties.has('all')
|
|
117
|
-
const combinedLines = new Set<string>()
|
|
118
|
-
|
|
119
|
-
for (const property of properties)
|
|
120
|
-
if (Literal.rule(property)?.kind === 'line') {
|
|
121
|
-
const name = canonical(property)
|
|
122
|
-
combinedLines.add(name.startsWith('border') ? 'border' : name)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function canonical(property: string): string {
|
|
126
|
-
return property in Literal.aliases
|
|
127
|
-
? Literal.aliases[property as keyof typeof Literal.aliases]
|
|
128
|
-
: property
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function domain(property: string): string {
|
|
132
|
-
if (
|
|
133
|
-
resets &&
|
|
134
|
-
!property.startsWith('--') &&
|
|
135
|
-
property !== 'direction' &&
|
|
136
|
-
property !== 'unicodeBidi'
|
|
137
|
-
)
|
|
138
|
-
return 'all'
|
|
139
|
-
|
|
140
|
-
if (/^marker(?:Start|Mid|End)?$/.test(property)) return 'marker'
|
|
141
|
-
if (property.startsWith('corner')) return 'cornerShape'
|
|
142
|
-
if (property.startsWith('containIntrinsic')) return 'containIntrinsicSize'
|
|
143
|
-
if (property.startsWith('interestDelay')) return 'interestDelay'
|
|
144
|
-
if (property.startsWith('backgroundPosition')) return 'backgroundPosition'
|
|
145
|
-
|
|
146
|
-
if (combinedLines.has('columnRule') && property.startsWith('columnRule'))
|
|
147
|
-
return 'columnRule'
|
|
148
|
-
|
|
149
|
-
if (combinedLines.has('outline') && property.startsWith('outline'))
|
|
150
|
-
return 'outline'
|
|
151
|
-
|
|
152
|
-
if (property.startsWith('borderImage')) return 'borderImage'
|
|
153
|
-
|
|
154
|
-
if (property.startsWith('border')) {
|
|
155
|
-
if (combinedLines.has('border')) return 'border'
|
|
156
|
-
|
|
157
|
-
if (property.endsWith('Color')) {
|
|
158
|
-
return 'borderColor'
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (property.endsWith('Style')) {
|
|
162
|
-
return 'borderStyle'
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (property.endsWith('Width')) {
|
|
166
|
-
return 'borderWidth'
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return 'borderRadius'
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (['flexDirection', 'flexFlow', 'flexWrap'].includes(property))
|
|
173
|
-
return 'flexFlow'
|
|
174
|
-
|
|
175
|
-
if (/^(pageBreak|break)(After|Before|Inside)$/.test(property))
|
|
176
|
-
return property.replace('pageBreak', 'break')
|
|
177
|
-
|
|
178
|
-
if (['fontStretch', 'fontWidth'].includes(property)) return 'fontWidth'
|
|
179
|
-
if (property.startsWith('fontSynthesis')) return 'fontSynthesis'
|
|
180
|
-
|
|
181
|
-
if (
|
|
182
|
-
[
|
|
183
|
-
'whiteSpace',
|
|
184
|
-
'whiteSpaceCollapse',
|
|
185
|
-
'whiteSpaceTrim',
|
|
186
|
-
'textWrap',
|
|
187
|
-
'textWrapMode',
|
|
188
|
-
'textWrapStyle',
|
|
189
|
-
].includes(property)
|
|
190
|
-
)
|
|
191
|
-
return 'whiteSpace'
|
|
192
|
-
|
|
193
|
-
if (['wordWrap', 'overflowWrap'].includes(property)) return 'overflowWrap'
|
|
194
|
-
|
|
195
|
-
if (property.startsWith('margin')) {
|
|
196
|
-
return 'margin'
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (property.startsWith('padding')) {
|
|
200
|
-
return 'padding'
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (
|
|
204
|
-
property === 'overflow' ||
|
|
205
|
-
property === 'overflowX' ||
|
|
206
|
-
property === 'overflowY' ||
|
|
207
|
-
property === 'overflowBlock' ||
|
|
208
|
-
property === 'overflowInline'
|
|
209
|
-
) {
|
|
210
|
-
return 'overflow'
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (property.startsWith('overscrollBehavior')) {
|
|
214
|
-
return 'overscrollBehavior'
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
if (property.startsWith('scrollMargin')) {
|
|
218
|
-
return 'scrollMargin'
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (property.startsWith('scrollPadding')) {
|
|
222
|
-
return 'scrollPadding'
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (['columnGap', 'gap', 'rowGap'].includes(property)) {
|
|
226
|
-
return 'gap'
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (/^(inset|top$|right$|bottom$|left$)/.test(property)) {
|
|
230
|
-
return 'inset'
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
if (
|
|
234
|
-
logicalSizing &&
|
|
235
|
-
/^(min|max)?(width|height|blockSize|inlineSize)$/i.test(property)
|
|
236
|
-
) {
|
|
237
|
-
if (property.startsWith('min')) {
|
|
238
|
-
return 'min-size'
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (property.startsWith('max')) {
|
|
242
|
-
return 'max-size'
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return 'size'
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return property
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const parents = new Map<string, string>()
|
|
252
|
-
|
|
253
|
-
function root(domain: string): string {
|
|
254
|
-
const parent = parents.get(domain)
|
|
255
|
-
if (!parent) return domain
|
|
256
|
-
|
|
257
|
-
const result = root(parent)
|
|
258
|
-
|
|
259
|
-
parents.set(domain, result)
|
|
260
|
-
|
|
261
|
-
return result
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Union only authored shorthands. Unrelated axes retain their original factoring.
|
|
265
|
-
// Recursion includes nested and reset-only shorthands without parsing CSS values.
|
|
266
|
-
function join(property: string, target: string, visited = new Set<string>()) {
|
|
267
|
-
if (visited.has(property)) return
|
|
268
|
-
|
|
269
|
-
visited.add(property)
|
|
270
|
-
|
|
271
|
-
const current = root(domain(canonical(property)))
|
|
272
|
-
const group = root(target)
|
|
273
|
-
|
|
274
|
-
if (current !== group) parents.set(current, group)
|
|
275
|
-
|
|
276
|
-
if (Object.hasOwn(Cascade.shorthands, property))
|
|
277
|
-
for (const child of Cascade.shorthands[
|
|
278
|
-
property as keyof typeof Cascade.shorthands
|
|
279
|
-
])
|
|
280
|
-
join(child, target, visited)
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
for (const property of new Set([...properties].map(canonical)))
|
|
284
|
-
if (Object.hasOwn(Cascade.shorthands, property))
|
|
285
|
-
join(property, domain(property))
|
|
286
|
-
|
|
287
|
-
function serialize(input: Style.Declaration['value']): number | string {
|
|
288
|
-
if (typeof input !== 'object' || input === null) return input
|
|
289
|
-
|
|
290
|
-
const cached = serialized.get(input)
|
|
291
|
-
if (cached !== undefined) return cached
|
|
292
|
-
|
|
293
|
-
const value = serializeReference(input)
|
|
294
|
-
|
|
295
|
-
if (typeof value === 'string') serialized.set(input, value)
|
|
296
|
-
|
|
297
|
-
return value
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
function serializeReference(
|
|
301
|
-
input: Style.Declaration['value'],
|
|
302
|
-
): number | string {
|
|
303
|
-
if (Binding.is(input)) return `var(${input.name})`
|
|
304
|
-
if (isReference(input)) return (theme ??= Themes.create()).serialize(input)
|
|
305
|
-
|
|
306
|
-
if (Token.isExpression(input))
|
|
307
|
-
return input.parts
|
|
308
|
-
.map((part) => (typeof part === 'string' ? part : serialize(part)))
|
|
309
|
-
.join('')
|
|
310
|
-
|
|
311
|
-
return input as number | string
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
function declarationBody(declaration: Style.Declaration): string {
|
|
315
|
-
const previous = declarations.get(declaration)
|
|
316
|
-
if (previous !== undefined) return previous
|
|
317
|
-
|
|
318
|
-
const { important, property, value } = declaration
|
|
319
|
-
let entry = declarationProperties.get(property)
|
|
320
|
-
if (!entry) {
|
|
321
|
-
entry = {
|
|
322
|
-
important: new Map(),
|
|
323
|
-
name: Literal.name(property),
|
|
324
|
-
normal: new Map(),
|
|
325
|
-
}
|
|
326
|
-
declarationProperties.set(property, entry)
|
|
327
|
-
}
|
|
35
|
+
const input = Wire.encode(options as compile.Options)
|
|
328
36
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
declarations.set(declaration, body)
|
|
337
|
-
return body
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
function nested(style: Style.NamedStyle): string {
|
|
341
|
-
const previous = bodies.get(style)
|
|
342
|
-
if (previous !== undefined) return previous
|
|
343
|
-
const body = renderNested(style)
|
|
344
|
-
bodies.set(style, body)
|
|
345
|
-
return body
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
function renderNested(style: Style.NamedStyle): string {
|
|
349
|
-
if (style.rules)
|
|
350
|
-
return style.rules
|
|
351
|
-
.map((rule) => {
|
|
352
|
-
const body = nested(rule.style)
|
|
353
|
-
|
|
354
|
-
return rule.condition === undefined
|
|
355
|
-
? body
|
|
356
|
-
: `${rule.condition}{${body}}`
|
|
357
|
-
})
|
|
358
|
-
.join('')
|
|
359
|
-
|
|
360
|
-
return style.declarations.map(declarationBody).join('')
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const domainsByProperty = new Map<string, string>()
|
|
364
|
-
function conflict(property: string): string {
|
|
365
|
-
const previous = domainsByProperty.get(property)
|
|
366
|
-
if (previous !== undefined) return previous
|
|
367
|
-
const value = root(domain(canonical(property)))
|
|
368
|
-
domainsByProperty.set(property, value)
|
|
369
|
-
return value
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// Sharing is safe only when every use of a conflict domain has the same
|
|
373
|
-
// declaration sequence. Conditions conservatively retain contextual identities.
|
|
374
|
-
// Isolated class lists never combine, so atomic sharing considers ordered styles only.
|
|
375
|
-
const ordered = new Map<string, false | string>()
|
|
376
|
-
const combinable = new Set<Style.NamedStyle>()
|
|
377
|
-
for (const [index, style] of options.styles.styles.entries())
|
|
378
|
-
if (!isolated(style)) combinable.add(canonicalStyles[index]!)
|
|
379
|
-
|
|
380
|
-
for (const style of analyzed) {
|
|
381
|
-
const domains = new Map<
|
|
382
|
-
string,
|
|
383
|
-
{ body: string; mixed: boolean; property: string }
|
|
384
|
-
>()
|
|
385
|
-
|
|
386
|
-
for (const item of style.declarations) {
|
|
387
|
-
const property = item.property
|
|
388
|
-
const key = conflict(property)
|
|
389
|
-
const entry = domains.get(key) ?? { body: '', mixed: false, property }
|
|
390
|
-
entry.body += declarationBody(item)
|
|
391
|
-
entry.mixed ||= entry.property !== property
|
|
392
|
-
domains.set(key, entry)
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
for (const [key, entry] of domains)
|
|
396
|
-
for (const map of combinable.has(style) ? [groups, ordered] : [groups]) {
|
|
397
|
-
const previous = map.get(key)
|
|
398
|
-
map.set(
|
|
399
|
-
key,
|
|
400
|
-
previous === false ||
|
|
401
|
-
entry.mixed ||
|
|
402
|
-
(previous !== undefined && previous !== entry.body)
|
|
403
|
-
? false
|
|
404
|
-
: entry.body,
|
|
405
|
-
)
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
const defaultMode = options.cssOutput ?? 'atomic'
|
|
410
|
-
if (defaultMode !== 'atomic' && defaultMode !== 'grouped')
|
|
411
|
-
throw new CompileError([
|
|
412
|
-
{
|
|
413
|
-
code: 'invalid_output',
|
|
414
|
-
message: 'cssOutput must be atomic or grouped.',
|
|
415
|
-
path: ['cssOutput'],
|
|
416
|
-
},
|
|
417
|
-
])
|
|
418
|
-
|
|
419
|
-
function outputMode(style: Style.NamedStyle) {
|
|
420
|
-
return Object.getOwnPropertyDescriptor(style, 'cssOutput')?.value as
|
|
421
|
-
| 'atomic'
|
|
422
|
-
| 'grouped'
|
|
423
|
-
| undefined
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
function compositionMode(style: Style.NamedStyle) {
|
|
427
|
-
const mode = Object.getOwnPropertyDescriptor(style, 'composition')
|
|
428
|
-
?.value as 'independent' | 'ordered' | undefined
|
|
429
|
-
|
|
430
|
-
return mode ?? options.composition ?? 'ordered'
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// Development keeps every style ordered so names survive value edits.
|
|
434
|
-
function isolated(style: Style.NamedStyle) {
|
|
435
|
-
return compositionMode(style) === 'independent' && !options.development
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
type Item = {
|
|
439
|
-
readonly conditions: readonly string[]
|
|
440
|
-
readonly property: string
|
|
441
|
-
readonly value: string
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
// Lists declaration groups in authored order; undefined marks styles whose
|
|
445
|
-
// nested grouped output or anonymous layers emit one opaque rule.
|
|
446
|
-
function flatten(
|
|
447
|
-
style: Style.NamedStyle,
|
|
448
|
-
conditions: readonly string[] = [],
|
|
449
|
-
): Item[] | undefined {
|
|
450
|
-
if (outputMode(style) === 'grouped') return undefined
|
|
451
|
-
|
|
452
|
-
if (style.rules) {
|
|
453
|
-
const items: Item[] = []
|
|
454
|
-
for (const rule of style.rules) {
|
|
455
|
-
if (rule.condition?.trim() === '@layer') return undefined
|
|
456
|
-
|
|
457
|
-
const nested = flatten(
|
|
458
|
-
rule.style,
|
|
459
|
-
rule.condition === undefined
|
|
460
|
-
? conditions
|
|
461
|
-
: [...conditions, rule.condition],
|
|
462
|
-
)
|
|
463
|
-
if (!nested) return undefined
|
|
464
|
-
|
|
465
|
-
items.push(...nested)
|
|
466
|
-
}
|
|
467
|
-
return items
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
const items: Item[] = []
|
|
471
|
-
for (let index = 0; index < style.declarations.length; ) {
|
|
472
|
-
const property = style.declarations[index]!.property
|
|
473
|
-
let value = ''
|
|
474
|
-
// Keep same-property fallbacks ordered; they form one semantic value.
|
|
475
|
-
while (style.declarations[index]?.property === property) {
|
|
476
|
-
const declaration = style.declarations[index++]!
|
|
477
|
-
value += `${Literal.name(property)}:${serialize(declaration.value)}${declaration.important ? '!important' : ''};`
|
|
478
|
-
}
|
|
479
|
-
items.push({ conditions, property, value })
|
|
480
|
-
}
|
|
481
|
-
return items
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
function byDomain(items: readonly Item[]) {
|
|
485
|
-
const result = new Map<string, Item[]>()
|
|
486
|
-
for (const item of items) {
|
|
487
|
-
const key = conflict(item.property)
|
|
488
|
-
const domain = result.get(key)
|
|
489
|
-
if (domain) domain.push(item)
|
|
490
|
-
else result.set(key, [item])
|
|
491
|
-
}
|
|
492
|
-
return result
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
function representation(style: Style.NamedStyle): unknown {
|
|
496
|
-
return [
|
|
497
|
-
outputMode(style),
|
|
498
|
-
style.rules?.map((rule) => representation(rule.style)),
|
|
499
|
-
]
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
function validate(style: Style.NamedStyle) {
|
|
503
|
-
const mode = outputMode(style)
|
|
504
|
-
if (mode !== undefined && mode !== 'atomic' && mode !== 'grouped')
|
|
505
|
-
throw new CompileError([
|
|
506
|
-
{
|
|
507
|
-
code: 'invalid_output',
|
|
508
|
-
message: 'cssOutput must be atomic or grouped.',
|
|
509
|
-
path: [style.name, 'cssOutput'],
|
|
510
|
-
},
|
|
511
|
-
])
|
|
512
|
-
for (const rule of style.rules ?? []) validate(rule.style)
|
|
513
|
-
}
|
|
514
|
-
for (const style of options.styles.styles) validate(style)
|
|
515
|
-
|
|
516
|
-
const identities = new Map<string, string>()
|
|
517
|
-
const rules = new Map<string, string>()
|
|
518
|
-
type ConditionalRule = { conditions: readonly string[]; value: string }
|
|
519
|
-
const conditionalRules = new Map<string, ConditionalRule>()
|
|
520
|
-
type SharedRules = Record<'atomic' | 'grouped', Map<string, string>>
|
|
521
|
-
const identical = new Map<string | undefined, SharedRules>()
|
|
522
|
-
const explicitBodies = new Map<string, string>()
|
|
523
|
-
const selectors = new Map<string, string>()
|
|
524
|
-
const explicitModes = new Set<string>()
|
|
525
|
-
const applications = new Map<string, string>()
|
|
526
|
-
const occurrences = new Map<string, number>()
|
|
527
|
-
for (const style of options.styles.styles)
|
|
528
|
-
for (const declaration of style.declarations) {
|
|
529
|
-
const key = conflict(declaration.property)
|
|
530
|
-
occurrences.set(key, (occurrences.get(key) ?? 0) + 1)
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
// An ordered atomic style reuses the rules of the previous style that set a
|
|
534
|
-
// domain to the same sequence: no differing rule sits between them.
|
|
535
|
-
const runs = new Map<number, Map<string, number>>()
|
|
536
|
-
const owned = new Map<number, Map<string, string[]>>()
|
|
537
|
-
if (!options.development) {
|
|
538
|
-
const last = new Map<string, { key: string; owner: number }>()
|
|
539
|
-
|
|
540
|
-
for (const [index, style] of options.styles.styles.entries()) {
|
|
541
|
-
if (isolated(style)) continue
|
|
542
|
-
|
|
543
|
-
const items =
|
|
544
|
-
(outputMode(style) ?? defaultMode) === 'atomic' &&
|
|
545
|
-
options.names?.[style.name] === undefined
|
|
546
|
-
? flatten(style)
|
|
547
|
-
: undefined
|
|
548
|
-
// Grouped, explicit, and opaque rules may set any domain.
|
|
549
|
-
if (!items) {
|
|
550
|
-
last.clear()
|
|
551
|
-
continue
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
for (const [domain, list] of byDomain(items)) {
|
|
555
|
-
const key = JSON.stringify(
|
|
556
|
-
list.map((item) => [item.conditions, item.value]),
|
|
557
|
-
)
|
|
558
|
-
const previous = last.get(domain)
|
|
559
|
-
if (previous?.key !== key) {
|
|
560
|
-
last.set(domain, { key, owner: index })
|
|
561
|
-
continue
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
const reuse = runs.get(index) ?? new Map<string, number>()
|
|
565
|
-
reuse.set(domain, previous.owner)
|
|
566
|
-
runs.set(index, reuse)
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
for (const [styleIndex, style] of options.styles.styles.entries()) {
|
|
572
|
-
const mode = outputMode(style) ?? defaultMode
|
|
573
|
-
const independent =
|
|
574
|
-
compositionMode(style) === 'independent' && !options.development
|
|
575
|
-
if (!style.name || Object.hasOwn(classes, style.name)) {
|
|
576
|
-
diagnostics.push({
|
|
577
|
-
code: 'invalid_name',
|
|
578
|
-
message: 'Style names must be nonempty and unique.',
|
|
579
|
-
path: [style.name],
|
|
580
|
-
})
|
|
581
|
-
continue
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
const explicit = options.names?.[style.name]
|
|
585
|
-
if (explicit !== undefined) {
|
|
586
|
-
const body = nested(style)
|
|
587
|
-
const previous = explicitBodies.get(explicit)
|
|
588
|
-
if (previous !== undefined && previous !== body)
|
|
589
|
-
diagnostics.push({
|
|
590
|
-
code: 'identity_collision',
|
|
591
|
-
message: 'An explicit id is used for different styles.',
|
|
592
|
-
path: [style.name],
|
|
593
|
-
})
|
|
594
|
-
explicitBodies.set(explicit, body)
|
|
595
|
-
classes[style.name] = explicit
|
|
596
|
-
const key = `${explicit}:${mode}`
|
|
597
|
-
if (explicitModes.has(key)) continue
|
|
598
|
-
explicitModes.add(key)
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
const application =
|
|
602
|
-
explicit === undefined && independent
|
|
603
|
-
? `${mode}:${style.rules ? JSON.stringify(representation(style)) : ''}:${nested(canonicalStyles[styleIndex]!)}`
|
|
604
|
-
: undefined
|
|
605
|
-
if (application !== undefined && applications.has(application)) {
|
|
606
|
-
classes[style.name] = applications.get(application)!
|
|
607
|
-
continue
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
const names: string[] = explicit === undefined ? [] : [explicit]
|
|
611
|
-
let ordinal = 0
|
|
612
|
-
const cssName = labels?.[style.name]?.name ?? encode(style.name)
|
|
613
|
-
const cssNamespace =
|
|
614
|
-
labels?.[style.name]?.namespace ??
|
|
615
|
-
(options.scope ? Identity.name(options.scope) : undefined)
|
|
616
|
-
let sharedRules = identical.get(cssNamespace)
|
|
617
|
-
if (!sharedRules) {
|
|
618
|
-
sharedRules = { atomic: new Map(), grouped: new Map() }
|
|
619
|
-
identical.set(cssNamespace, sharedRules)
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
function emit(
|
|
623
|
-
body: string,
|
|
624
|
-
label: string,
|
|
625
|
-
shared: boolean,
|
|
626
|
-
output = mode,
|
|
627
|
-
conditional?: ConditionalRule,
|
|
628
|
-
): string | undefined {
|
|
629
|
-
if (!body) return undefined
|
|
630
|
-
|
|
631
|
-
const reusable =
|
|
632
|
-
explicit === undefined &&
|
|
633
|
-
(shared || (independent && mode === 'grouped' && output === mode))
|
|
634
|
-
const previous = reusable ? sharedRules![output].get(body) : undefined
|
|
635
|
-
if (previous && !names.includes(previous)) {
|
|
636
|
-
names.push(previous)
|
|
637
|
-
return previous
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
if (previous) shared = false
|
|
641
|
-
|
|
642
|
-
// Contextual slots preserve authored ordering; development names survive value edits.
|
|
643
|
-
const slot = ordinal++
|
|
644
|
-
const identity = (() => {
|
|
645
|
-
if (explicit !== undefined)
|
|
646
|
-
return `${explicit}-${mode}-${encode(label)}-${slot}`
|
|
647
|
-
if (output === 'grouped' && mode === 'grouped') {
|
|
648
|
-
return `z-${cssNamespace ? `${cssNamespace}-` : ''}${cssName}${slot ? `__${slot}` : ''}`
|
|
649
|
-
}
|
|
650
|
-
return ClassName.create({
|
|
651
|
-
body,
|
|
652
|
-
context: !shared ? cssName : undefined,
|
|
653
|
-
namespace: cssNamespace,
|
|
654
|
-
property: label,
|
|
655
|
-
slot: !shared ? slot : undefined,
|
|
656
|
-
})
|
|
657
|
-
})()
|
|
658
|
-
const owner =
|
|
659
|
-
mode === 'atomic' && !shared ? `${style.name}:${slot}` : undefined
|
|
660
|
-
if (
|
|
661
|
-
(rules.has(identity) && rules.get(identity) !== body) ||
|
|
662
|
-
(owner !== undefined &&
|
|
663
|
-
identities.has(identity) &&
|
|
664
|
-
identities.get(identity) !== owner)
|
|
665
|
-
)
|
|
666
|
-
diagnostics.push({
|
|
667
|
-
code: 'identity_collision',
|
|
668
|
-
message:
|
|
669
|
-
'Generated class names conflict. Supply distinct config or style ids.',
|
|
670
|
-
path: [style.name],
|
|
671
|
-
})
|
|
672
|
-
|
|
673
|
-
if (owner !== undefined) identities.set(identity, owner)
|
|
674
|
-
rules.set(identity, body)
|
|
675
|
-
if (
|
|
676
|
-
conditional?.conditions.some((condition) =>
|
|
677
|
-
/^@(media|supports)\b/.test(condition),
|
|
678
|
-
)
|
|
679
|
-
)
|
|
680
|
-
conditionalRules.set(identity, conditional)
|
|
681
|
-
if (explicit !== undefined) selectors.set(identity, explicit)
|
|
682
|
-
else {
|
|
683
|
-
if (reusable) sharedRules![output].set(body, identity)
|
|
684
|
-
names.push(identity)
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
return identity
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
function atoms(
|
|
691
|
-
style: Style.NamedStyle,
|
|
692
|
-
conditions: readonly string[] = [],
|
|
693
|
-
) {
|
|
694
|
-
if (outputMode(style) === 'grouped') {
|
|
695
|
-
const body = conditions.reduceRight(
|
|
696
|
-
(body, condition) => `${condition}{${body}}`,
|
|
697
|
-
nested(style),
|
|
698
|
-
)
|
|
699
|
-
emit(body, 'style', false, 'grouped')
|
|
700
|
-
return
|
|
701
|
-
}
|
|
702
|
-
if (style.rules) {
|
|
703
|
-
for (const rule of style.rules) {
|
|
704
|
-
if (rule.condition?.trim() === '@layer') {
|
|
705
|
-
// Repeating an anonymous layer would change cascade precedence.
|
|
706
|
-
const body = [...conditions, rule.condition].reduceRight(
|
|
707
|
-
(body, condition) => `${condition}{${body}}`,
|
|
708
|
-
nested(rule.style),
|
|
709
|
-
)
|
|
710
|
-
emit(body, 'layer', false)
|
|
711
|
-
continue
|
|
712
|
-
}
|
|
713
|
-
atoms(
|
|
714
|
-
rule.style,
|
|
715
|
-
rule.condition === undefined
|
|
716
|
-
? conditions
|
|
717
|
-
: [...conditions, rule.condition],
|
|
718
|
-
)
|
|
719
|
-
}
|
|
720
|
-
return
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
for (let index = 0; index < style.declarations.length; ) {
|
|
724
|
-
const declaration = style.declarations[index++]!
|
|
725
|
-
const property = declaration.property
|
|
726
|
-
const values = [declaration]
|
|
727
|
-
// Keep same-property fallbacks ordered; they form one semantic value.
|
|
728
|
-
while (style.declarations[index]?.property === property)
|
|
729
|
-
values.push(style.declarations[index++]!)
|
|
730
|
-
|
|
731
|
-
const domain = conflict(property)
|
|
732
|
-
const owner = runs.get(styleIndex)?.get(domain)
|
|
733
|
-
const reused =
|
|
734
|
-
owner === undefined ? undefined : owned.get(owner)?.get(domain)
|
|
735
|
-
if (reused) {
|
|
736
|
-
for (const identity of reused)
|
|
737
|
-
if (!names.includes(identity)) names.push(identity)
|
|
738
|
-
continue
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
const value = values
|
|
742
|
-
.map(
|
|
743
|
-
({ important, value }) =>
|
|
744
|
-
`${Literal.name(property)}:${serialize(value)}${important ? '!important' : ''};`,
|
|
745
|
-
)
|
|
746
|
-
.join('')
|
|
747
|
-
const body = conditions.reduceRight(
|
|
748
|
-
(body, condition) => `${condition}{${body}}`,
|
|
749
|
-
value,
|
|
750
|
-
)
|
|
751
|
-
const shared =
|
|
752
|
-
!nestedComposition &&
|
|
753
|
-
!conditions.length &&
|
|
754
|
-
ordered.get(domain) !== false
|
|
755
|
-
const identity = emit(body, property, shared, mode, {
|
|
756
|
-
conditions,
|
|
757
|
-
value,
|
|
758
|
-
})
|
|
759
|
-
if (identity === undefined) continue
|
|
760
|
-
|
|
761
|
-
const domains = owned.get(styleIndex) ?? new Map<string, string[]>()
|
|
762
|
-
domains.set(domain, [...(domains.get(domain) ?? []), identity])
|
|
763
|
-
owned.set(styleIndex, domains)
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
// Independent class lists never combine, so only declarations within one
|
|
768
|
-
// conflict domain need relative order. Equal domain bodies share one rule.
|
|
769
|
-
function share(style: Style.NamedStyle) {
|
|
770
|
-
const items = flatten(style)
|
|
771
|
-
if (!items) return atoms(style)
|
|
772
|
-
|
|
773
|
-
for (const domain of byDomain(items).values()) {
|
|
774
|
-
// Conditional rules stay contextual to keep their order against base declarations.
|
|
775
|
-
if (domain.some((item) => item.conditions.length)) {
|
|
776
|
-
for (const item of domain)
|
|
777
|
-
emit(
|
|
778
|
-
item.conditions.reduceRight(
|
|
779
|
-
(body, condition) => `${condition}{${body}}`,
|
|
780
|
-
item.value,
|
|
781
|
-
),
|
|
782
|
-
item.property,
|
|
783
|
-
false,
|
|
784
|
-
mode,
|
|
785
|
-
item,
|
|
786
|
-
)
|
|
787
|
-
continue
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
const body = domain.map((item) => item.value).join('')
|
|
791
|
-
const identity = units.name(body, cssNamespace)
|
|
792
|
-
if (rules.has(identity) && rules.get(identity) !== body)
|
|
793
|
-
diagnostics.push({
|
|
794
|
-
code: 'identity_collision',
|
|
795
|
-
message:
|
|
796
|
-
'Generated class names conflict. Supply distinct config or style ids.',
|
|
797
|
-
path: [style.name],
|
|
798
|
-
})
|
|
799
|
-
|
|
800
|
-
rules.set(identity, body)
|
|
801
|
-
names.push(identity)
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
try {
|
|
806
|
-
if (mode === 'grouped') {
|
|
807
|
-
const shared: Style.Declaration[] = []
|
|
808
|
-
const local: Style.Declaration[] = []
|
|
809
|
-
for (const declaration of style.declarations) {
|
|
810
|
-
const key = conflict(declaration.property)
|
|
811
|
-
const reusable =
|
|
812
|
-
!style.rules &&
|
|
813
|
-
independent &&
|
|
814
|
-
groups.get(key) !== false &&
|
|
815
|
-
(occurrences.get(key) ?? 0) > 1
|
|
816
|
-
if (reusable) shared.push(declaration)
|
|
817
|
-
else local.push(declaration)
|
|
818
|
-
}
|
|
819
|
-
if (shared.length && local.length) {
|
|
820
|
-
emit(shared.map(declarationBody).join(''), 'shared', false)
|
|
821
|
-
emit(local.map(declarationBody).join(''), 'style', false)
|
|
822
|
-
} else emit(nested(style), 'style', false)
|
|
823
|
-
} else if (explicit === undefined && independent) share(style)
|
|
824
|
-
else atoms(style)
|
|
825
|
-
} catch (error) {
|
|
826
|
-
diagnostics.push({
|
|
827
|
-
code: 'invalid_declaration',
|
|
828
|
-
message: (error as Error).message,
|
|
829
|
-
path: [style.name],
|
|
830
|
-
})
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
classes[style.name] = [...new Set(names)].join(' ')
|
|
834
|
-
if (application !== undefined)
|
|
835
|
-
applications.set(application, classes[style.name])
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
if (diagnostics.length) throw new CompileError(diagnostics)
|
|
839
|
-
|
|
840
|
-
const contributionCss = (() => {
|
|
841
|
-
try {
|
|
842
|
-
return Contributions.render(options.contributions ?? [], nested)
|
|
843
|
-
} catch (error) {
|
|
844
|
-
throw new CompileError([
|
|
845
|
-
{
|
|
846
|
-
code: 'invalid_declaration',
|
|
847
|
-
message: (error as Error).message,
|
|
848
|
-
path: ['contributions'],
|
|
849
|
-
},
|
|
850
|
-
])
|
|
851
|
-
}
|
|
852
|
-
})()
|
|
853
|
-
|
|
854
|
-
let scopes: ReturnType<NonNullable<typeof theme>['emit']>
|
|
855
|
-
|
|
856
|
-
try {
|
|
857
|
-
scopes =
|
|
858
|
-
theme || options.vars || options.schemes
|
|
859
|
-
? (theme ??= Themes.create()).emit(
|
|
860
|
-
options.vars ?? {},
|
|
861
|
-
options.schemes ?? false,
|
|
862
|
-
options[Themes.shared],
|
|
863
|
-
)
|
|
864
|
-
: { classes: Object.freeze({}), css: '', resources: [], rules: [] }
|
|
865
|
-
} catch (error) {
|
|
866
|
-
throw new CompileError([
|
|
867
|
-
{
|
|
868
|
-
code: 'invalid_theme',
|
|
869
|
-
message: (error as Error).message,
|
|
870
|
-
path: ['vars'],
|
|
871
|
-
},
|
|
872
|
-
])
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
const scopedCss = [
|
|
876
|
-
scopes.css,
|
|
877
|
-
...[...rules].map((entry) => {
|
|
878
|
-
const [name, body] = entry
|
|
879
|
-
const selector = `.${ClassName.selector(selectors.get(name) ?? name)}`
|
|
880
|
-
const conditional = conditionalRules.get(name)
|
|
881
|
-
if (
|
|
882
|
-
!conditional ||
|
|
883
|
-
conditional.conditions.some(
|
|
884
|
-
(condition) =>
|
|
885
|
-
condition.startsWith('@') &&
|
|
886
|
-
!/^@(media|supports)\b/.test(condition),
|
|
887
|
-
)
|
|
888
|
-
)
|
|
889
|
-
return `${selector}{${body}}`
|
|
890
|
-
|
|
891
|
-
// Inactive conditions must surround the class rather than leave a matched empty wrapper.
|
|
892
|
-
const conditions = conditional.conditions.filter((condition) =>
|
|
893
|
-
condition.startsWith('@'),
|
|
894
|
-
)
|
|
895
|
-
const nested = conditional.conditions
|
|
896
|
-
.filter((condition) => !condition.startsWith('@'))
|
|
897
|
-
.reduceRight(
|
|
898
|
-
(body, condition) => `${condition}{${body}}`,
|
|
899
|
-
conditional.value,
|
|
900
|
-
)
|
|
901
|
-
return conditions.reduceRight(
|
|
902
|
-
(body, condition) => `${condition}{${body}}`,
|
|
903
|
-
`${selector}{${nested}}`,
|
|
904
|
-
)
|
|
905
|
-
}),
|
|
906
|
-
]
|
|
907
|
-
.filter(Boolean)
|
|
908
|
-
.join('\n')
|
|
909
|
-
|
|
910
|
-
const result = {
|
|
911
|
-
...(scopes.resources.length ? { [Themes.shared]: scopes.resources } : {}),
|
|
912
|
-
...(contributionCss ? { contributionCss, scopedCss } : {}),
|
|
913
|
-
[ClassName.units]: units.used,
|
|
914
|
-
[ClassName.rules]: Object.freeze({
|
|
915
|
-
...Object.fromEntries(rules),
|
|
916
|
-
...Object.fromEntries(
|
|
917
|
-
scopes.rules.map((rule) => [
|
|
918
|
-
`@scope:${rule.selector.slice(1)}:${Identity.name(rule.property)}:${Identity.name(JSON.stringify(rule.conditions))}`,
|
|
919
|
-
rule.value,
|
|
920
|
-
]),
|
|
921
|
-
),
|
|
922
|
-
}),
|
|
923
|
-
classes: Object.freeze(classes),
|
|
924
|
-
css: [contributionCss, scopedCss].filter(Boolean).join('\n'),
|
|
925
|
-
vars: scopes.classes as Readonly<Record<themeName, string>>,
|
|
926
|
-
}
|
|
927
|
-
Object.defineProperty(result, ClassName.rules, { enumerable: false })
|
|
928
|
-
Object.defineProperty(result, ClassName.units, { enumerable: false })
|
|
929
|
-
return Object.freeze(result)
|
|
37
|
+
// A supplied unit scope receives the naming decisions the engine made against its table.
|
|
38
|
+
return Wire.decode(
|
|
39
|
+
Engine.call('css.compile', input),
|
|
40
|
+
options[ClassName.units],
|
|
41
|
+
) as compile.ReturnType<name, themeName>
|
|
930
42
|
}
|
|
931
43
|
|
|
932
44
|
/** Input and output contracts for literal compilation. */
|
|
@@ -1036,11 +148,3 @@ export type Diagnostic = {
|
|
|
1036
148
|
/** Authored style name, followed by a property when applicable. */
|
|
1037
149
|
readonly path: readonly string[]
|
|
1038
150
|
}
|
|
1039
|
-
|
|
1040
|
-
// Encoding underscores and delimiters makes the value form injective.
|
|
1041
|
-
function encode(value: string): string {
|
|
1042
|
-
return value.replace(
|
|
1043
|
-
/[^a-zA-Z0-9-]/g,
|
|
1044
|
-
(character) => `_${character.charCodeAt(0).toString(16)}_`,
|
|
1045
|
-
)
|
|
1046
|
-
}
|