zyzz 0.0.21 → 0.0.22

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.
Files changed (220) hide show
  1. package/Zyzz.podspec +16 -0
  2. package/dist/Style.d.ts +3 -1
  3. package/dist/Style.d.ts.map +1 -1
  4. package/dist/Style.js.map +1 -1
  5. package/dist/babel/NativeJsx.d.ts.map +1 -1
  6. package/dist/babel/NativeJsx.js +204 -12
  7. package/dist/babel/NativeJsx.js.map +1 -1
  8. package/dist/babel/index.d.ts +6 -2
  9. package/dist/babel/index.d.ts.map +1 -1
  10. package/dist/babel/index.js +10 -1
  11. package/dist/babel/index.js.map +1 -1
  12. package/dist/compiler/Graph.d.ts.map +1 -1
  13. package/dist/compiler/Graph.js +64 -0
  14. package/dist/compiler/Graph.js.map +1 -1
  15. package/dist/compiler/Native.d.ts +6 -3
  16. package/dist/compiler/Native.d.ts.map +1 -1
  17. package/dist/compiler/Native.js +142 -24
  18. package/dist/compiler/Native.js.map +1 -1
  19. package/dist/compiler/Source.d.ts +2 -0
  20. package/dist/compiler/Source.d.ts.map +1 -1
  21. package/dist/compiler/Source.js +17 -5
  22. package/dist/compiler/Source.js.map +1 -1
  23. package/dist/compiler/internal/Configurations.d.ts +2 -0
  24. package/dist/compiler/internal/Configurations.d.ts.map +1 -1
  25. package/dist/compiler/internal/Configurations.js +21 -3
  26. package/dist/compiler/internal/Configurations.js.map +1 -1
  27. package/dist/compiler/internal/Contract.d.ts.map +1 -1
  28. package/dist/compiler/internal/Contract.js +75 -38
  29. package/dist/compiler/internal/Contract.js.map +1 -1
  30. package/dist/compiler/internal/Contributions.d.ts.map +1 -1
  31. package/dist/compiler/internal/Contributions.js +7 -1
  32. package/dist/compiler/internal/Contributions.js.map +1 -1
  33. package/dist/compiler/internal/Descriptors.d.ts.map +1 -1
  34. package/dist/compiler/internal/Descriptors.js +11 -2
  35. package/dist/compiler/internal/Descriptors.js.map +1 -1
  36. package/dist/compiler/internal/NativeBindings.d.ts +24 -26
  37. package/dist/compiler/internal/NativeBindings.d.ts.map +1 -1
  38. package/dist/compiler/internal/NativeBindings.js +61 -8
  39. package/dist/compiler/internal/NativeBindings.js.map +1 -1
  40. package/dist/compiler/internal/NativeMedia.d.ts +14 -0
  41. package/dist/compiler/internal/NativeMedia.d.ts.map +1 -0
  42. package/dist/compiler/internal/NativeMedia.js +287 -0
  43. package/dist/compiler/internal/NativeMedia.js.map +1 -0
  44. package/dist/compiler/internal/NativeVars.d.ts +28 -0
  45. package/dist/compiler/internal/NativeVars.d.ts.map +1 -0
  46. package/dist/compiler/internal/NativeVars.js +157 -0
  47. package/dist/compiler/internal/NativeVars.js.map +1 -0
  48. package/dist/compiler/internal/PackedStyles.d.ts +2 -0
  49. package/dist/compiler/internal/PackedStyles.d.ts.map +1 -1
  50. package/dist/compiler/internal/PackedStyles.js +2 -0
  51. package/dist/compiler/internal/PackedStyles.js.map +1 -1
  52. package/dist/compiler/internal/Themes.d.ts +22 -1
  53. package/dist/compiler/internal/Themes.d.ts.map +1 -1
  54. package/dist/compiler/internal/Themes.js +118 -3
  55. package/dist/compiler/internal/Themes.js.map +1 -1
  56. package/dist/compiler/internal/Vars.d.ts +1 -1
  57. package/dist/compiler/internal/Vars.d.ts.map +1 -1
  58. package/dist/compiler/internal/Vars.js +7 -2
  59. package/dist/compiler/internal/Vars.js.map +1 -1
  60. package/dist/default.js.zyzz.json +1 -1
  61. package/dist/internal/Completion.d.ts +1 -1
  62. package/dist/internal/Completion.d.ts.map +1 -1
  63. package/dist/internal/Targets.d.ts.map +1 -1
  64. package/dist/internal/Targets.js +2 -0
  65. package/dist/internal/Targets.js.map +1 -1
  66. package/dist/internal/Token.d.ts +0 -2
  67. package/dist/internal/Token.d.ts.map +1 -1
  68. package/dist/internal/Token.js.map +1 -1
  69. package/dist/internal/Value.d.ts +7 -0
  70. package/dist/internal/Value.d.ts.map +1 -1
  71. package/dist/internal/Value.js.map +1 -1
  72. package/dist/metro/Graph.d.ts +22 -7
  73. package/dist/metro/Graph.d.ts.map +1 -1
  74. package/dist/metro/Graph.js +179 -42
  75. package/dist/metro/Graph.js.map +1 -1
  76. package/dist/metro/Watch.d.ts +28 -4
  77. package/dist/metro/Watch.d.ts.map +1 -1
  78. package/dist/metro/Watch.js +39 -7
  79. package/dist/metro/Watch.js.map +1 -1
  80. package/dist/metro/index.d.ts +15 -4
  81. package/dist/metro/index.d.ts.map +1 -1
  82. package/dist/metro/index.js +27 -0
  83. package/dist/metro/index.js.map +1 -1
  84. package/dist/metro/transformer.d.ts +5 -1
  85. package/dist/metro/transformer.d.ts.map +1 -1
  86. package/dist/metro/transformer.js +5 -3
  87. package/dist/metro/transformer.js.map +1 -1
  88. package/dist/react-native/StyleSheet.d.ts +3 -2
  89. package/dist/react-native/StyleSheet.d.ts.map +1 -1
  90. package/dist/react-native/StyleSheet.js +17 -34
  91. package/dist/react-native/StyleSheet.js.map +1 -1
  92. package/dist/react-native/index.d.ts +1 -1
  93. package/dist/react-native/index.d.ts.map +1 -1
  94. package/dist/react-native/index.js +1 -1
  95. package/dist/react-native/index.js.map +1 -1
  96. package/dist/react-native/index.native.d.ts +5 -0
  97. package/dist/react-native/index.native.js +20 -0
  98. package/dist/react-native/index.native.js.map +7 -0
  99. package/dist/react-native/internal/Calculation.d.ts +7 -0
  100. package/dist/react-native/internal/Calculation.d.ts.map +1 -0
  101. package/dist/react-native/internal/Calculation.js +134 -0
  102. package/dist/react-native/internal/Calculation.js.map +1 -0
  103. package/dist/react-native/internal/Device.js +191 -0
  104. package/dist/react-native/internal/Device.js.map +7 -0
  105. package/dist/react-native/internal/NativeZyzz.js +7 -0
  106. package/dist/react-native/internal/NativeZyzz.js.map +7 -0
  107. package/dist/react-native/internal/Scalar.d.ts.map +1 -1
  108. package/dist/react-native/internal/Scalar.js +9 -2
  109. package/dist/react-native/internal/Scalar.js.map +1 -1
  110. package/dist/react-native/internal/Store.d.ts +32 -0
  111. package/dist/react-native/internal/Store.d.ts.map +1 -0
  112. package/dist/react-native/internal/Store.js +57 -0
  113. package/dist/react-native/internal/Store.js.map +1 -0
  114. package/dist/react-native/internal/Tokens.d.ts +21 -0
  115. package/dist/react-native/internal/Tokens.d.ts.map +1 -0
  116. package/dist/react-native/internal/Tokens.js +58 -0
  117. package/dist/react-native/internal/Tokens.js.map +1 -0
  118. package/dist/react-native/internal/Viewport.d.ts +6 -0
  119. package/dist/react-native/internal/Viewport.d.ts.map +1 -0
  120. package/dist/react-native/internal/Viewport.js +4 -0
  121. package/dist/react-native/internal/Viewport.js.map +1 -0
  122. package/dist/react-native/react.d.ts +74 -11
  123. package/dist/react-native/react.d.ts.map +1 -1
  124. package/dist/react-native/react.js +111 -12
  125. package/dist/react-native/react.js.map +1 -1
  126. package/dist/react-native/reanimated.d.ts +39 -0
  127. package/dist/react-native/reanimated.d.ts.map +1 -0
  128. package/dist/react-native/reanimated.js +76 -0
  129. package/dist/react-native/reanimated.js.map +1 -0
  130. package/dist/runtime/NativeContext.d.ts +10 -1
  131. package/dist/runtime/NativeContext.d.ts.map +1 -1
  132. package/dist/runtime/NativeContext.js +67 -14
  133. package/dist/runtime/NativeContext.js.map +1 -1
  134. package/dist/runtime/NativeDynamic.d.ts +3 -2
  135. package/dist/runtime/NativeDynamic.d.ts.map +1 -1
  136. package/dist/runtime/NativeDynamic.js +32 -7
  137. package/dist/runtime/NativeDynamic.js.map +1 -1
  138. package/dist/runtime/NativeStatic.d.ts +23 -0
  139. package/dist/runtime/NativeStatic.d.ts.map +1 -0
  140. package/dist/runtime/NativeStatic.js +106 -0
  141. package/dist/runtime/NativeStatic.js.map +1 -0
  142. package/dist/runtime/NativeVars.d.ts +53 -0
  143. package/dist/runtime/NativeVars.d.ts.map +1 -0
  144. package/dist/runtime/NativeVars.js +77 -0
  145. package/dist/runtime/NativeVars.js.map +1 -0
  146. package/dist/runtime/index.d.ts +4 -0
  147. package/dist/runtime/index.d.ts.map +1 -1
  148. package/dist/runtime/index.js +4 -0
  149. package/dist/runtime/index.js.map +1 -1
  150. package/dist/runtime/internal/NativeMedia.d.ts +25 -0
  151. package/dist/runtime/internal/NativeMedia.d.ts.map +1 -0
  152. package/dist/runtime/internal/NativeMedia.js +36 -0
  153. package/dist/runtime/internal/NativeMedia.js.map +1 -0
  154. package/dist/vite/index.d.ts.map +1 -1
  155. package/dist/vite/index.js +7 -35
  156. package/dist/vite/index.js.map +1 -1
  157. package/dist/web/Css.d.ts.map +1 -1
  158. package/dist/web/Css.js +31 -19
  159. package/dist/web/Css.js.map +1 -1
  160. package/dist/web/internal/Themes.d.ts +0 -2
  161. package/dist/web/internal/Themes.d.ts.map +1 -1
  162. package/dist/web/internal/Themes.js +30 -28
  163. package/dist/web/internal/Themes.js.map +1 -1
  164. package/dist/web/page.d.ts +2 -0
  165. package/dist/web/page.d.ts.map +1 -1
  166. package/native/NativeZyzz.cpp +215 -0
  167. package/native/NativeZyzz.h +52 -0
  168. package/native/ZyzzSpecJSI.h +65 -0
  169. package/native/android/CMakeLists.txt +8 -0
  170. package/native/android/ZyzzSpec-generated.cpp +50 -0
  171. package/native/android/ZyzzSpec.h +31 -0
  172. package/native/ios/ZyzzModuleProvider.mm +13 -0
  173. package/package.json +39 -1
  174. package/react-native.config.ts +14 -0
  175. package/src/Style.ts +11 -8
  176. package/src/babel/NativeJsx.ts +305 -28
  177. package/src/babel/index.ts +21 -3
  178. package/src/compiler/Graph.ts +75 -0
  179. package/src/compiler/Native.ts +158 -26
  180. package/src/compiler/Source.ts +32 -5
  181. package/src/compiler/internal/Configurations.ts +25 -3
  182. package/src/compiler/internal/Contract.ts +98 -50
  183. package/src/compiler/internal/Contributions.ts +7 -1
  184. package/src/compiler/internal/Descriptors.ts +12 -8
  185. package/src/compiler/internal/NativeBindings.ts +98 -15
  186. package/src/compiler/internal/NativeMedia.ts +342 -0
  187. package/src/compiler/internal/NativeVars.ts +228 -0
  188. package/src/compiler/internal/PackedStyles.ts +4 -0
  189. package/src/compiler/internal/Themes.ts +187 -2
  190. package/src/compiler/internal/Vars.ts +12 -1
  191. package/src/internal/Completion.ts +6 -3
  192. package/src/internal/Targets.ts +2 -0
  193. package/src/internal/Token.ts +0 -2
  194. package/src/internal/Value.ts +20 -0
  195. package/src/metro/Graph.ts +235 -50
  196. package/src/metro/Watch.ts +95 -10
  197. package/src/metro/index.ts +62 -4
  198. package/src/metro/transformer.ts +21 -11
  199. package/src/react-native/StyleSheet.ts +28 -44
  200. package/src/react-native/index.native.ts +10 -0
  201. package/src/react-native/index.ts +1 -1
  202. package/src/react-native/internal/Calculation.ts +159 -0
  203. package/src/react-native/internal/Device.ts +231 -0
  204. package/src/react-native/internal/NativeZyzz.ts +20 -0
  205. package/src/react-native/internal/Scalar.ts +13 -2
  206. package/src/react-native/internal/Store.ts +78 -0
  207. package/src/react-native/internal/Tokens.ts +85 -0
  208. package/src/react-native/internal/Viewport.ts +8 -0
  209. package/src/react-native/react.ts +211 -19
  210. package/src/react-native/reanimated.ts +162 -0
  211. package/src/runtime/NativeContext.ts +88 -17
  212. package/src/runtime/NativeDynamic.ts +35 -10
  213. package/src/runtime/NativeStatic.ts +145 -0
  214. package/src/runtime/NativeVars.ts +189 -0
  215. package/src/runtime/index.ts +6 -0
  216. package/src/runtime/internal/NativeMedia.ts +63 -0
  217. package/src/vite/index.ts +9 -42
  218. package/src/web/Css.ts +42 -27
  219. package/src/web/internal/Themes.ts +34 -57
  220. package/src/web/page.ts +2 -0
package/src/web/Css.ts CHANGED
@@ -56,7 +56,18 @@ export function compile<
56
56
  return result
57
57
  }
58
58
 
59
+ const bodies = new Map<Style.NamedStyle, string>()
60
+ const declarations = new Map<Style.Declaration, string>()
61
+ type Property = {
62
+ readonly important: Map<Style.Declaration['value'], string>
63
+ readonly name: string
64
+ readonly normal: Map<Style.Declaration['value'], string>
65
+ }
66
+ const declarationProperties = new Map<string, Property>()
67
+ const serialized = new Map<object, string>()
68
+
59
69
  // Only primitive declaration lists can be interned without erasing token identity.
70
+ // Reuse their emitted bodies throughout analysis and output.
60
71
  const repeated = new Map<string, Style.NamedStyle>()
61
72
 
62
73
  const canonicalStyles = options.styles.styles.map((style) => {
@@ -68,13 +79,7 @@ export function compile<
68
79
  )
69
80
  return style
70
81
 
71
- const key = JSON.stringify(
72
- style.declarations.map(({ important, property, value }) => [
73
- property,
74
- value,
75
- important,
76
- ]),
77
- )
82
+ const key = nested(style)
78
83
  const previous = repeated.get(key)
79
84
  if (previous) return previous
80
85
 
@@ -269,8 +274,6 @@ export function compile<
269
274
  if (Object.hasOwn(Cascade.shorthands, property))
270
275
  join(property, domain(property))
271
276
 
272
- const serialized = new Map<object, string>()
273
-
274
277
  function serialize(input: Style.Declaration['value']): number | string {
275
278
  if (typeof input !== 'object' || input === null) return input
276
279
 
@@ -298,22 +301,32 @@ export function compile<
298
301
  return input as number | string
299
302
  }
300
303
 
301
- const declarations = new Map<Style.Declaration, string>()
302
- const propertyNames = new Map<string, string>()
303
-
304
304
  function declarationBody(declaration: Style.Declaration): string {
305
305
  const previous = declarations.get(declaration)
306
306
  if (previous !== undefined) return previous
307
+
307
308
  const { important, property, value } = declaration
308
- const name = propertyNames.get(property) ?? Literal.name(property)
309
- propertyNames.set(property, name)
310
- const body = `${name}:${serialize(value)}${important ? '!important' : ''};`
309
+ let entry = declarationProperties.get(property)
310
+ if (!entry) {
311
+ entry = {
312
+ important: new Map(),
313
+ name: Literal.name(property),
314
+ normal: new Map(),
315
+ }
316
+ declarationProperties.set(property, entry)
317
+ }
318
+
319
+ const values = important ? entry.important : entry.normal
320
+ let body = values.get(value)
321
+ if (body === undefined) {
322
+ body = `${entry.name}:${serialize(value)}${important ? '!important' : ''};`
323
+ values.set(value, body)
324
+ }
325
+
311
326
  declarations.set(declaration, body)
312
327
  return body
313
328
  }
314
329
 
315
- const bodies = new Map<Style.NamedStyle, string>()
316
-
317
330
  function nested(style: Style.NamedStyle): string {
318
331
  const previous = bodies.get(style)
319
332
  if (previous !== undefined) return previous
@@ -401,11 +414,8 @@ export function compile<
401
414
  }
402
415
 
403
416
  function validate(style: Style.NamedStyle) {
404
- if (
405
- outputMode(style) !== undefined &&
406
- outputMode(style) !== 'atomic' &&
407
- outputMode(style) !== 'grouped'
408
- )
417
+ const mode = outputMode(style)
418
+ if (mode !== undefined && mode !== 'atomic' && mode !== 'grouped')
409
419
  throw new CompileError([
410
420
  {
411
421
  code: 'invalid_output',
@@ -421,7 +431,8 @@ export function compile<
421
431
  const rules = new Map<string, string>()
422
432
  type ConditionalRule = { conditions: readonly string[]; value: string }
423
433
  const conditionalRules = new Map<string, ConditionalRule>()
424
- const identical = new Map<string, string>()
434
+ type SharedRules = Record<'atomic' | 'grouped', Map<string, string>>
435
+ const identical = new Map<string | undefined, SharedRules>()
425
436
  const explicitBodies = new Map<string, string>()
426
437
  const selectors = new Map<string, string>()
427
438
  const explicitModes = new Set<string>()
@@ -465,7 +476,7 @@ export function compile<
465
476
  explicit === undefined &&
466
477
  options.composition === 'independent' &&
467
478
  !options.development
468
- ? `${mode}:${JSON.stringify(representation(style))}:${nested(canonicalStyles[styleIndex]!)}`
479
+ ? `${mode}:${style.rules ? JSON.stringify(representation(style)) : ''}:${nested(canonicalStyles[styleIndex]!)}`
469
480
  : undefined
470
481
  if (application !== undefined && applications.has(application)) {
471
482
  classes[style.name] = applications.get(application)!
@@ -478,6 +489,11 @@ export function compile<
478
489
  const cssNamespace =
479
490
  labels?.[style.name]?.namespace ??
480
491
  (options.scope ? Identity.name(options.scope) : undefined)
492
+ let sharedRules = identical.get(cssNamespace)
493
+ if (!sharedRules) {
494
+ sharedRules = { atomic: new Map(), grouped: new Map() }
495
+ identical.set(cssNamespace, sharedRules)
496
+ }
481
497
 
482
498
  function emit(
483
499
  body: string,
@@ -493,9 +509,8 @@ export function compile<
493
509
  !options.development &&
494
510
  output === mode &&
495
511
  options.composition === 'independent'
496
- const key = JSON.stringify([cssNamespace, output, body])
497
512
  const reusable = explicit === undefined && (shared || independent)
498
- const previous = reusable ? identical.get(key) : undefined
513
+ const previous = reusable ? sharedRules![output].get(body) : undefined
499
514
  if (previous && !names.includes(previous)) {
500
515
  names.push(previous)
501
516
  return
@@ -544,7 +559,7 @@ export function compile<
544
559
  conditionalRules.set(identity, conditional)
545
560
  if (explicit !== undefined) selectors.set(identity, explicit)
546
561
  else {
547
- if (reusable) identical.set(key, identity)
562
+ if (reusable) sharedRules![output].set(body, identity)
548
563
  names.push(identity)
549
564
  }
550
565
  }
@@ -15,6 +15,24 @@ export function create() {
15
15
  { identity: string | undefined; paths: Map<string, string> }
16
16
  >()
17
17
 
18
+ const anonymous = new Map<Token.Contract, Map<string, string>>()
19
+ let nextVariable = 0
20
+ function property(contract: Token.Contract, path: string): string {
21
+ const identity = contract[Token.identity]
22
+ if (identity) return variable(identity, path)
23
+ let paths = anonymous.get(contract)
24
+ if (!paths) {
25
+ paths = new Map()
26
+ anonymous.set(contract, paths)
27
+ }
28
+ let name = paths.get(path)
29
+ if (!name) {
30
+ name = `--z${(nextVariable++).toString(36)}`
31
+ paths.set(path, name)
32
+ }
33
+ return name
34
+ }
35
+
18
36
  const defaults = new Map<string, readonly Rule[]>()
19
37
  const defaultGroups = new Map<Token.Contract, Set<string>>()
20
38
 
@@ -33,11 +51,7 @@ export function create() {
33
51
  let name = contract.paths.get(token.path)
34
52
 
35
53
  if (!name) {
36
- name = variable(
37
- contract.identity,
38
- token.path,
39
- token.contract.variableNaming,
40
- )
54
+ name = property(token.contract, token.path)
41
55
  contract.paths.set(token.path, name)
42
56
  }
43
57
 
@@ -51,6 +65,7 @@ export function create() {
51
65
  separate?: 'all' | 'defaults',
52
66
  ) {
53
67
  const classes: Record<string, string> = Object.create(null)
68
+ let nextScope = 0
54
69
  const scopeBodies = new Map<string, string>()
55
70
  const completeDefaults = new Set<Token.Contract>()
56
71
  const empty: string[] = []
@@ -68,14 +83,17 @@ export function create() {
68
83
 
69
84
  // Anonymous contracts are graph-local. Source-owned contracts retain stable
70
85
  // identities across separately compiled components and theme scopes.
71
- const className = scope(
72
- data.cssName ??
73
- (data.contract[Token.identity] &&
74
- name.startsWith(`${data.contract[Token.identity]}-`)
75
- ? name.slice(data.contract[Token.identity]!.length + 1)
76
- : name),
77
- data.contract[Token.identity],
78
- )
86
+ const className =
87
+ data.contract[Token.identity] || data.cssName
88
+ ? scope(
89
+ data.cssName ??
90
+ (data.contract[Token.identity] &&
91
+ name.startsWith(`${data.contract[Token.identity]}-`)
92
+ ? name.slice(data.contract[Token.identity]!.length + 1)
93
+ : name),
94
+ data.contract[Token.identity],
95
+ )
96
+ : `z${(nextScope++).toString(36)}`
79
97
 
80
98
  classes[name] = className
81
99
 
@@ -91,10 +109,7 @@ export function create() {
91
109
  for (const path of Object.keys(data.values)) {
92
110
  if (contract.paths.has(path)) continue
93
111
 
94
- contract.paths.set(
95
- path,
96
- variable(contract.identity, path, data.contract.variableNaming),
97
- )
112
+ contract.paths.set(path, property(data.contract, path))
98
113
  }
99
114
 
100
115
  contracts.set(data.contract, contract)
@@ -125,28 +140,6 @@ export function create() {
125
140
  selector: `.${className}`,
126
141
  value: literal(value, label, data.contract),
127
142
  })
128
- // Standalone styles have no contract metadata to select their original spelling.
129
- if (
130
- contract.identity?.startsWith('id-') &&
131
- data.contract.variableNaming === undefined
132
- )
133
- declarations.push({
134
- conditions: [],
135
- property: variable(
136
- `id-${Array.from(
137
- contract.identity
138
- .slice(3)
139
- .replace(/_([0-9a-f]+)_/g, (_, code: string) =>
140
- String.fromCodePoint(Number.parseInt(code, 16)),
141
- ),
142
- (character) => character.codePointAt(0)!.toString(16),
143
- ).join('-')}`,
144
- path,
145
- 'legacy',
146
- ),
147
- selector: `.${className}`,
148
- value: `var(${name})`,
149
- })
150
143
  }
151
144
 
152
145
  rules.push(...declarations)
@@ -266,7 +259,7 @@ export function create() {
266
259
  const base = literal(value.default, label, owner)
267
260
  // Rule consolidation must not change existing variable identities.
268
261
  const css = `:where(*){--fallback:${base};}${conditionalCss(value, '--fallback', ':where(*)', label, owner)}`
269
- const name = `${variable(owner?.[Token.identity], label ?? 'value')}-fallback-${Identity.name(css)}`
262
+ const name = `${owner ? property(owner, label ?? 'value') : variable(undefined, label ?? 'value')}-fallback-${Identity.name(css)}`
270
263
  const emitted: Rule[] = [
271
264
  { conditions: [], property: name, selector: ':where(*)', value: base },
272
265
  ]
@@ -341,14 +334,6 @@ export function create() {
341
334
  return { emit, serialize }
342
335
  }
343
336
 
344
- /** Escapes a scope key into the identifier segment of its compiled class. */
345
- export function encode(value: string): string {
346
- return value.replace(
347
- /[^a-zA-Z0-9-]/g,
348
- (character) => `_${character.charCodeAt(0).toString(16)}_`,
349
- )
350
- }
351
-
352
337
  /** Combines generated declarations without crossing competing declarations of the same property. */
353
338
  export function render(rules: readonly Rule[]): string {
354
339
  const groups: {
@@ -424,15 +409,7 @@ export function scope(value: string, identity?: string): string {
424
409
  return `z-theme-${namespace}${Identity.name(value)}`
425
410
  }
426
411
 
427
- function variable(
428
- identity: string | undefined,
429
- path: string,
430
- naming?: 'legacy' | 'hashed',
431
- ): string {
432
- if (naming === 'legacy' && identity)
433
- return `--z-t${encode(identity)}-${encode(path)}`
434
- if (naming === 'hashed')
435
- return `--z-${Identity.label(path)}-${Identity.compact(JSON.stringify([identity, path]))}`
412
+ function variable(identity: string | undefined, path: string): string {
436
413
  const namespace = identity?.startsWith('id-') ? `${identity.slice(3)}-` : ''
437
414
  return `--z-${namespace}${path.split('.').map(Identity.name).join('-')}`
438
415
  }
package/src/web/page.ts CHANGED
@@ -35,6 +35,8 @@ export declare namespace page {
35
35
  | 'crop cross'
36
36
  | 'cross crop'
37
37
  | undefined
38
+ /** Handling of page margins that exceed the printer's printable area. */
39
+ readonly pageMarginSafety?: 'none' | 'clamp' | 'add' | undefined
38
40
  /** Rotation applied to a laid-out page. */
39
41
  readonly pageOrientation?:
40
42
  | 'upright'