@tenphi/tasty 0.0.0-snapshot.1c5dff6 → 0.0.0-snapshot.1f1c00a

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 (331) hide show
  1. package/README.md +377 -238
  2. package/dist/babel-rZcEwPLM.d.ts +82 -0
  3. package/dist/chunks/async-storage-CG5HnUT5.js +20 -0
  4. package/dist/chunks/async-storage-CG5HnUT5.js.map +1 -0
  5. package/dist/chunks/build-config-CL4eRu2z.js +42 -0
  6. package/dist/chunks/build-config-CL4eRu2z.js.map +1 -0
  7. package/dist/chunks/collector-D2ARGT2L.js +208 -0
  8. package/dist/chunks/collector-D2ARGT2L.js.map +1 -0
  9. package/dist/chunks/config-engine-DEmmPPdp.js +272 -0
  10. package/dist/chunks/config-engine-DEmmPPdp.js.map +1 -0
  11. package/dist/chunks/css-definitions-DotDkIXt.js +876 -0
  12. package/dist/chunks/css-definitions-DotDkIXt.js.map +1 -0
  13. package/dist/chunks/css-resources-P7IBUUZs.js +142 -0
  14. package/dist/chunks/css-resources-P7IBUUZs.js.map +1 -0
  15. package/dist/chunks/debug-D8pg9RGI.js +502 -0
  16. package/dist/chunks/debug-D8pg9RGI.js.map +1 -0
  17. package/dist/chunks/dsl-DRhFWQzo.js +1378 -0
  18. package/dist/chunks/dsl-DRhFWQzo.js.map +1 -0
  19. package/dist/chunks/hydration-TRcz5vnk.js +41 -0
  20. package/dist/chunks/hydration-TRcz5vnk.js.map +1 -0
  21. package/dist/chunks/react-runtime-BpxlOTbO.js +562 -0
  22. package/dist/chunks/react-runtime-BpxlOTbO.js.map +1 -0
  23. package/dist/chunks/runtime-engine-CKFXUH-A.js +2416 -0
  24. package/dist/chunks/runtime-engine-CKFXUH-A.js.map +1 -0
  25. package/dist/chunks/runtime-state-BxaLhVdP.js +127 -0
  26. package/dist/chunks/runtime-state-BxaLhVdP.js.map +1 -0
  27. package/dist/{utils/merge-styles.js → chunks/shared-utils-y-HjvPN4.js} +61 -58
  28. package/dist/chunks/shared-utils-y-HjvPN4.js.map +1 -0
  29. package/dist/chunks/style-engine-BBbBuSkT.js +5260 -0
  30. package/dist/chunks/style-engine-BBbBuSkT.js.map +1 -0
  31. package/dist/{zero/extractor.js → chunks/zero-engine-gJrKBRiw.js} +126 -66
  32. package/dist/chunks/zero-engine-gJrKBRiw.js.map +1 -0
  33. package/dist/collector-w4mBj5gd.d.ts +164 -0
  34. package/dist/config-CZWCzBr6.d.ts +1349 -0
  35. package/dist/core/index.d.ts +5 -33
  36. package/dist/core/index.js +9 -26
  37. package/dist/index-G9JuwM9p.d.ts +1920 -0
  38. package/dist/index.d.ts +5 -48
  39. package/dist/index.js +11 -33
  40. package/dist/{utils/merge-styles.d.ts → merge-styles-VXwJ0Frr.d.ts} +3 -4
  41. package/dist/ssr/astro-client.d.ts +1 -0
  42. package/dist/ssr/astro-client.js +6 -0
  43. package/dist/ssr/astro-client.js.map +1 -0
  44. package/dist/ssr/astro-middleware-extract-static.d.ts +10 -0
  45. package/dist/ssr/astro-middleware-extract-static.js +9 -0
  46. package/dist/ssr/astro-middleware-extract-static.js.map +1 -0
  47. package/dist/ssr/astro-middleware-extract.d.ts +10 -0
  48. package/dist/ssr/astro-middleware-extract.js +9 -0
  49. package/dist/ssr/astro-middleware-extract.js.map +1 -0
  50. package/dist/ssr/astro-middleware-static.d.ts +17 -0
  51. package/dist/ssr/astro-middleware-static.js +7 -0
  52. package/dist/ssr/astro-middleware-static.js.map +1 -0
  53. package/dist/ssr/astro-middleware.d.ts +18 -0
  54. package/dist/ssr/astro-middleware.js +7 -0
  55. package/dist/ssr/astro-middleware.js.map +1 -0
  56. package/dist/ssr/astro.d.ts +127 -0
  57. package/dist/ssr/astro.js +221 -0
  58. package/dist/ssr/astro.js.map +1 -0
  59. package/dist/ssr/index.d.ts +36 -0
  60. package/dist/ssr/index.js +10 -0
  61. package/dist/ssr/index.js.map +1 -0
  62. package/dist/ssr/next-config.d.ts +64 -0
  63. package/dist/ssr/next-config.js +128 -0
  64. package/dist/ssr/next-config.js.map +1 -0
  65. package/dist/ssr/next.d.ts +46 -0
  66. package/dist/ssr/next.js +60 -0
  67. package/dist/ssr/next.js.map +1 -0
  68. package/dist/static/index.d.ts +90 -5
  69. package/dist/static/index.js +31 -4
  70. package/dist/static/index.js.map +1 -0
  71. package/dist/static/inject.d.ts +4 -0
  72. package/dist/static/inject.js +17 -0
  73. package/dist/static/inject.js.map +1 -0
  74. package/dist/types-JEY8PVYP.d.ts +1567 -0
  75. package/dist/zero/babel.d.ts +2 -113
  76. package/dist/zero/babel.js +230 -106
  77. package/dist/zero/babel.js.map +1 -1
  78. package/dist/zero/index.d.ts +80 -3
  79. package/dist/zero/index.js +2 -4
  80. package/dist/zero/next.d.ts +57 -33
  81. package/dist/zero/next.js +93 -59
  82. package/dist/zero/next.js.map +1 -1
  83. package/docs/README.md +39 -0
  84. package/docs/adoption.md +323 -0
  85. package/docs/ai-agents.md +250 -0
  86. package/docs/comparison.md +448 -0
  87. package/docs/configuration.md +684 -56
  88. package/docs/debug.md +170 -343
  89. package/docs/design-system.md +455 -0
  90. package/docs/dsl.md +1065 -0
  91. package/docs/getting-started.md +240 -0
  92. package/docs/injector.md +159 -53
  93. package/docs/methodology.md +648 -0
  94. package/docs/migration-v3.md +285 -0
  95. package/docs/pipeline.md +765 -0
  96. package/docs/plugins.md +353 -0
  97. package/docs/react-api.md +683 -0
  98. package/docs/runtime-benchmarks.md +388 -0
  99. package/docs/ssr.md +610 -0
  100. package/docs/styles.md +211 -63
  101. package/docs/tasty-static.md +273 -67
  102. package/package.json +182 -58
  103. package/tasty.config.ts +6 -0
  104. package/dist/_virtual/_rolldown/runtime.js +0 -8
  105. package/dist/chunks/cacheKey.js +0 -70
  106. package/dist/chunks/cacheKey.js.map +0 -1
  107. package/dist/chunks/definitions.d.ts +0 -37
  108. package/dist/chunks/definitions.js +0 -260
  109. package/dist/chunks/definitions.js.map +0 -1
  110. package/dist/chunks/renderChunk.js +0 -61
  111. package/dist/chunks/renderChunk.js.map +0 -1
  112. package/dist/config.d.ts +0 -288
  113. package/dist/config.js +0 -403
  114. package/dist/config.js.map +0 -1
  115. package/dist/debug.d.ts +0 -204
  116. package/dist/debug.js +0 -733
  117. package/dist/debug.js.map +0 -1
  118. package/dist/hooks/useGlobalStyles.d.ts +0 -27
  119. package/dist/hooks/useGlobalStyles.js +0 -56
  120. package/dist/hooks/useGlobalStyles.js.map +0 -1
  121. package/dist/hooks/useKeyframes.d.ts +0 -56
  122. package/dist/hooks/useKeyframes.js +0 -54
  123. package/dist/hooks/useKeyframes.js.map +0 -1
  124. package/dist/hooks/useProperty.d.ts +0 -79
  125. package/dist/hooks/useProperty.js +0 -91
  126. package/dist/hooks/useProperty.js.map +0 -1
  127. package/dist/hooks/useRawCSS.d.ts +0 -53
  128. package/dist/hooks/useRawCSS.js +0 -28
  129. package/dist/hooks/useRawCSS.js.map +0 -1
  130. package/dist/hooks/useStyles.d.ts +0 -40
  131. package/dist/hooks/useStyles.js +0 -169
  132. package/dist/hooks/useStyles.js.map +0 -1
  133. package/dist/injector/index.d.ts +0 -157
  134. package/dist/injector/index.js +0 -154
  135. package/dist/injector/index.js.map +0 -1
  136. package/dist/injector/injector.d.ts +0 -139
  137. package/dist/injector/injector.js +0 -417
  138. package/dist/injector/injector.js.map +0 -1
  139. package/dist/injector/sheet-manager.d.ts +0 -135
  140. package/dist/injector/sheet-manager.js +0 -728
  141. package/dist/injector/sheet-manager.js.map +0 -1
  142. package/dist/injector/types.d.ts +0 -144
  143. package/dist/keyframes/index.js +0 -206
  144. package/dist/keyframes/index.js.map +0 -1
  145. package/dist/parser/classify.js +0 -319
  146. package/dist/parser/classify.js.map +0 -1
  147. package/dist/parser/const.js +0 -33
  148. package/dist/parser/const.js.map +0 -1
  149. package/dist/parser/lru.js +0 -109
  150. package/dist/parser/lru.js.map +0 -1
  151. package/dist/parser/parser.d.ts +0 -25
  152. package/dist/parser/parser.js +0 -116
  153. package/dist/parser/parser.js.map +0 -1
  154. package/dist/parser/tokenizer.js +0 -69
  155. package/dist/parser/tokenizer.js.map +0 -1
  156. package/dist/parser/types.d.ts +0 -51
  157. package/dist/parser/types.js +0 -46
  158. package/dist/parser/types.js.map +0 -1
  159. package/dist/pipeline/conditions.d.ts +0 -134
  160. package/dist/pipeline/conditions.js +0 -406
  161. package/dist/pipeline/conditions.js.map +0 -1
  162. package/dist/pipeline/exclusive.js +0 -231
  163. package/dist/pipeline/exclusive.js.map +0 -1
  164. package/dist/pipeline/index.d.ts +0 -53
  165. package/dist/pipeline/index.js +0 -660
  166. package/dist/pipeline/index.js.map +0 -1
  167. package/dist/pipeline/materialize.js +0 -856
  168. package/dist/pipeline/materialize.js.map +0 -1
  169. package/dist/pipeline/parseStateKey.d.ts +0 -15
  170. package/dist/pipeline/parseStateKey.js +0 -451
  171. package/dist/pipeline/parseStateKey.js.map +0 -1
  172. package/dist/pipeline/simplify.js +0 -516
  173. package/dist/pipeline/simplify.js.map +0 -1
  174. package/dist/pipeline/warnings.js +0 -18
  175. package/dist/pipeline/warnings.js.map +0 -1
  176. package/dist/plugins/okhsl-plugin.d.ts +0 -35
  177. package/dist/plugins/okhsl-plugin.js +0 -371
  178. package/dist/plugins/okhsl-plugin.js.map +0 -1
  179. package/dist/plugins/types.d.ts +0 -69
  180. package/dist/properties/index.js +0 -221
  181. package/dist/properties/index.js.map +0 -1
  182. package/dist/properties/property-type-resolver.d.ts +0 -24
  183. package/dist/properties/property-type-resolver.js +0 -83
  184. package/dist/properties/property-type-resolver.js.map +0 -1
  185. package/dist/states/index.d.ts +0 -49
  186. package/dist/states/index.js +0 -416
  187. package/dist/states/index.js.map +0 -1
  188. package/dist/static/tastyStatic.d.ts +0 -46
  189. package/dist/static/tastyStatic.js +0 -31
  190. package/dist/static/tastyStatic.js.map +0 -1
  191. package/dist/static/types.d.ts +0 -49
  192. package/dist/static/types.js +0 -24
  193. package/dist/static/types.js.map +0 -1
  194. package/dist/styles/align.d.ts +0 -15
  195. package/dist/styles/align.js +0 -14
  196. package/dist/styles/align.js.map +0 -1
  197. package/dist/styles/border.d.ts +0 -25
  198. package/dist/styles/border.js +0 -114
  199. package/dist/styles/border.js.map +0 -1
  200. package/dist/styles/color.d.ts +0 -14
  201. package/dist/styles/color.js +0 -23
  202. package/dist/styles/color.js.map +0 -1
  203. package/dist/styles/createStyle.js +0 -77
  204. package/dist/styles/createStyle.js.map +0 -1
  205. package/dist/styles/dimension.js +0 -97
  206. package/dist/styles/dimension.js.map +0 -1
  207. package/dist/styles/display.d.ts +0 -37
  208. package/dist/styles/display.js +0 -67
  209. package/dist/styles/display.js.map +0 -1
  210. package/dist/styles/fade.d.ts +0 -15
  211. package/dist/styles/fade.js +0 -58
  212. package/dist/styles/fade.js.map +0 -1
  213. package/dist/styles/fill.d.ts +0 -42
  214. package/dist/styles/fill.js +0 -52
  215. package/dist/styles/fill.js.map +0 -1
  216. package/dist/styles/flow.d.ts +0 -16
  217. package/dist/styles/flow.js +0 -12
  218. package/dist/styles/flow.js.map +0 -1
  219. package/dist/styles/gap.d.ts +0 -31
  220. package/dist/styles/gap.js +0 -37
  221. package/dist/styles/gap.js.map +0 -1
  222. package/dist/styles/height.d.ts +0 -17
  223. package/dist/styles/height.js +0 -20
  224. package/dist/styles/height.js.map +0 -1
  225. package/dist/styles/index.d.ts +0 -2
  226. package/dist/styles/index.js +0 -9
  227. package/dist/styles/index.js.map +0 -1
  228. package/dist/styles/inset.d.ts +0 -52
  229. package/dist/styles/inset.js +0 -150
  230. package/dist/styles/inset.js.map +0 -1
  231. package/dist/styles/justify.d.ts +0 -15
  232. package/dist/styles/justify.js +0 -14
  233. package/dist/styles/justify.js.map +0 -1
  234. package/dist/styles/list.d.ts +0 -16
  235. package/dist/styles/list.js +0 -98
  236. package/dist/styles/list.js.map +0 -1
  237. package/dist/styles/margin.d.ts +0 -24
  238. package/dist/styles/margin.js +0 -104
  239. package/dist/styles/margin.js.map +0 -1
  240. package/dist/styles/outline.d.ts +0 -29
  241. package/dist/styles/outline.js +0 -65
  242. package/dist/styles/outline.js.map +0 -1
  243. package/dist/styles/padding.d.ts +0 -24
  244. package/dist/styles/padding.js +0 -104
  245. package/dist/styles/padding.js.map +0 -1
  246. package/dist/styles/predefined.d.ts +0 -73
  247. package/dist/styles/predefined.js +0 -241
  248. package/dist/styles/predefined.js.map +0 -1
  249. package/dist/styles/preset.d.ts +0 -47
  250. package/dist/styles/preset.js +0 -126
  251. package/dist/styles/preset.js.map +0 -1
  252. package/dist/styles/radius.d.ts +0 -14
  253. package/dist/styles/radius.js +0 -51
  254. package/dist/styles/radius.js.map +0 -1
  255. package/dist/styles/scrollbar.d.ts +0 -23
  256. package/dist/styles/scrollbar.js +0 -34
  257. package/dist/styles/scrollbar.js.map +0 -1
  258. package/dist/styles/shadow.d.ts +0 -14
  259. package/dist/styles/shadow.js +0 -24
  260. package/dist/styles/shadow.js.map +0 -1
  261. package/dist/styles/styledScrollbar.d.ts +0 -47
  262. package/dist/styles/styledScrollbar.js +0 -38
  263. package/dist/styles/styledScrollbar.js.map +0 -1
  264. package/dist/styles/transition.d.ts +0 -14
  265. package/dist/styles/transition.js +0 -158
  266. package/dist/styles/transition.js.map +0 -1
  267. package/dist/styles/types.d.ts +0 -498
  268. package/dist/styles/width.d.ts +0 -17
  269. package/dist/styles/width.js +0 -20
  270. package/dist/styles/width.js.map +0 -1
  271. package/dist/tasty.d.ts +0 -982
  272. package/dist/tasty.js +0 -206
  273. package/dist/tasty.js.map +0 -1
  274. package/dist/tokens/typography.d.ts +0 -19
  275. package/dist/tokens/typography.js +0 -237
  276. package/dist/tokens/typography.js.map +0 -1
  277. package/dist/types.d.ts +0 -184
  278. package/dist/utils/cache-wrapper.js +0 -26
  279. package/dist/utils/cache-wrapper.js.map +0 -1
  280. package/dist/utils/case-converter.js +0 -8
  281. package/dist/utils/case-converter.js.map +0 -1
  282. package/dist/utils/colors.d.ts +0 -5
  283. package/dist/utils/colors.js +0 -9
  284. package/dist/utils/colors.js.map +0 -1
  285. package/dist/utils/css-types.d.ts +0 -7
  286. package/dist/utils/dotize.d.ts +0 -26
  287. package/dist/utils/dotize.js +0 -122
  288. package/dist/utils/dotize.js.map +0 -1
  289. package/dist/utils/filter-base-props.d.ts +0 -15
  290. package/dist/utils/filter-base-props.js +0 -45
  291. package/dist/utils/filter-base-props.js.map +0 -1
  292. package/dist/utils/get-display-name.d.ts +0 -7
  293. package/dist/utils/get-display-name.js +0 -10
  294. package/dist/utils/get-display-name.js.map +0 -1
  295. package/dist/utils/hsl-to-rgb.js +0 -38
  296. package/dist/utils/hsl-to-rgb.js.map +0 -1
  297. package/dist/utils/is-dev-env.js +0 -19
  298. package/dist/utils/is-dev-env.js.map +0 -1
  299. package/dist/utils/is-valid-element-type.js +0 -15
  300. package/dist/utils/is-valid-element-type.js.map +0 -1
  301. package/dist/utils/merge-styles.js.map +0 -1
  302. package/dist/utils/mod-attrs.d.ts +0 -8
  303. package/dist/utils/mod-attrs.js +0 -21
  304. package/dist/utils/mod-attrs.js.map +0 -1
  305. package/dist/utils/okhsl-to-rgb.js +0 -296
  306. package/dist/utils/okhsl-to-rgb.js.map +0 -1
  307. package/dist/utils/process-tokens.d.ts +0 -31
  308. package/dist/utils/process-tokens.js +0 -171
  309. package/dist/utils/process-tokens.js.map +0 -1
  310. package/dist/utils/resolve-recipes.d.ts +0 -17
  311. package/dist/utils/resolve-recipes.js +0 -147
  312. package/dist/utils/resolve-recipes.js.map +0 -1
  313. package/dist/utils/selector-transform.js +0 -32
  314. package/dist/utils/selector-transform.js.map +0 -1
  315. package/dist/utils/string.js +0 -8
  316. package/dist/utils/string.js.map +0 -1
  317. package/dist/utils/styles.d.ts +0 -177
  318. package/dist/utils/styles.js +0 -730
  319. package/dist/utils/styles.js.map +0 -1
  320. package/dist/utils/typography.d.ts +0 -36
  321. package/dist/utils/typography.js +0 -53
  322. package/dist/utils/typography.js.map +0 -1
  323. package/dist/utils/warnings.d.ts +0 -16
  324. package/dist/utils/warnings.js +0 -16
  325. package/dist/utils/warnings.js.map +0 -1
  326. package/dist/zero/css-writer.d.ts +0 -45
  327. package/dist/zero/css-writer.js +0 -74
  328. package/dist/zero/css-writer.js.map +0 -1
  329. package/dist/zero/extractor.d.ts +0 -24
  330. package/dist/zero/extractor.js.map +0 -1
  331. package/docs/usage.md +0 -695
@@ -1,139 +0,0 @@
1
- import { CacheMetrics, GlobalInjectResult, InjectResult, KeyframesResult, KeyframesSteps, PropertyDefinition, RawCSSResult, StyleInjectorConfig } from "./types.js";
2
- import { StyleResult } from "../pipeline/index.js";
3
- import { SheetManager } from "./sheet-manager.js";
4
-
5
- //#region src/injector/injector.d.ts
6
- declare class StyleInjector {
7
- private sheetManager;
8
- private config;
9
- private cleanupScheduled;
10
- private globalRuleCounter;
11
- /** @internal — exposed for debug utilities only */
12
- get _sheetManager(): SheetManager;
13
- constructor(config?: StyleInjectorConfig);
14
- /**
15
- * Allocate a className for a cacheKey without injecting styles yet.
16
- * This allows separating className allocation (render phase) from style injection (insertion phase).
17
- */
18
- allocateClassName(cacheKey: string, options?: {
19
- root?: Document | ShadowRoot;
20
- }): {
21
- className: string;
22
- isNewAllocation: boolean;
23
- };
24
- /**
25
- * Inject styles from StyleResult objects
26
- */
27
- inject(rules: StyleResult[], options?: {
28
- root?: Document | ShadowRoot;
29
- cacheKey?: string;
30
- }): InjectResult;
31
- /**
32
- * Inject global styles (rules without a generated tasty class selector)
33
- * This ensures we don't reserve a tasty class name (t{number}) for global rules,
34
- * which could otherwise collide with element-level styles and break lookups.
35
- */
36
- injectGlobal(rules: StyleResult[], options?: {
37
- root?: Document | ShadowRoot;
38
- }): GlobalInjectResult;
39
- /**
40
- * Inject raw CSS text directly without parsing
41
- * This is a low-overhead alternative to createGlobalStyle for raw CSS
42
- * The CSS is inserted into a separate style element to avoid conflicts with tasty's chunking
43
- */
44
- injectRawCSS(css: string, options?: {
45
- root?: Document | ShadowRoot;
46
- }): RawCSSResult;
47
- /**
48
- * Get raw CSS text for SSR
49
- */
50
- getRawCSSText(options?: {
51
- root?: Document | ShadowRoot;
52
- }): string;
53
- /**
54
- * Dispose of a className
55
- */
56
- private dispose;
57
- /**
58
- * Force bulk cleanup of unused styles
59
- */
60
- cleanup(root?: Document | ShadowRoot): void;
61
- /**
62
- * Get CSS text from all sheets (for SSR)
63
- */
64
- getCssText(options?: {
65
- root?: Document | ShadowRoot;
66
- }): string;
67
- /**
68
- * Get CSS only for the provided tasty classNames (e.g., ["t0","t3"])
69
- */
70
- getCssTextForClasses(classNames: Iterable<string>, options?: {
71
- root?: Document | ShadowRoot;
72
- }): string;
73
- /**
74
- * Get cache performance metrics
75
- */
76
- getMetrics(options?: {
77
- root?: Document | ShadowRoot;
78
- }): CacheMetrics | null;
79
- /**
80
- * Reset cache performance metrics
81
- */
82
- resetMetrics(options?: {
83
- root?: Document | ShadowRoot;
84
- }): void;
85
- /**
86
- * Define a CSS @property custom property.
87
- *
88
- * Accepts tasty token syntax for the property name:
89
- * - `$name` → defines `--name`
90
- * - `#name` → defines `--name-color` (auto-sets syntax: '<color>', defaults initialValue: 'transparent')
91
- * - `--name` → defines `--name` (legacy format)
92
- *
93
- * Example:
94
- * @property --rotation { syntax: "<angle>"; inherits: false; initial-value: 45deg; }
95
- *
96
- * Note: No caching or dispose — this defines a global property.
97
- *
98
- * If the same property is registered with different options, a warning is emitted
99
- * but the original definition is preserved (CSS @property cannot be redefined).
100
- */
101
- property(name: string, options?: PropertyDefinition & {
102
- root?: Document | ShadowRoot;
103
- }): void;
104
- /**
105
- * Check whether a given @property name was already injected by this injector.
106
- *
107
- * Accepts tasty token syntax:
108
- * - `$name` → checks `--name`
109
- * - `#name` → checks `--name-color`
110
- * - `--name` → checks `--name` (legacy format)
111
- */
112
- isPropertyDefined(name: string, options?: {
113
- root?: Document | ShadowRoot;
114
- }): boolean;
115
- /**
116
- * Inject keyframes and return object with toString() and dispose()
117
- *
118
- * Keyframes are cached by content (steps). If the same content is injected
119
- * multiple times with different provided names, the first injected name is reused.
120
- *
121
- * If the same name is provided with different content (collision), a unique
122
- * name is generated to avoid overwriting the existing keyframes.
123
- */
124
- keyframes(steps: KeyframesSteps, nameOrOptions?: string | {
125
- root?: Document | ShadowRoot;
126
- name?: string;
127
- }): KeyframesResult;
128
- /**
129
- * Dispose keyframes
130
- */
131
- private disposeKeyframes;
132
- /**
133
- * Destroy all resources for a root
134
- */
135
- destroy(root?: Document | ShadowRoot): void;
136
- }
137
- //#endregion
138
- export { StyleInjector };
139
- //# sourceMappingURL=injector.d.ts.map
@@ -1,417 +0,0 @@
1
- import { getEffectiveDefinition, normalizePropertyDefinition } from "../properties/index.js";
2
- import { isDevEnv } from "../utils/is-dev-env.js";
3
- import { parseStyle } from "../utils/styles.js";
4
- import { SheetManager } from "./sheet-manager.js";
5
-
6
- //#region src/injector/injector.ts
7
- /**
8
- * Generate sequential class name with format t{number}
9
- */
10
- function generateClassName(counter) {
11
- return `t${counter}`;
12
- }
13
- var StyleInjector = class {
14
- sheetManager;
15
- config;
16
- cleanupScheduled = false;
17
- globalRuleCounter = 0;
18
- /** @internal — exposed for debug utilities only */
19
- get _sheetManager() {
20
- return this.sheetManager;
21
- }
22
- constructor(config = {}) {
23
- this.config = config;
24
- this.sheetManager = new SheetManager(config);
25
- }
26
- /**
27
- * Allocate a className for a cacheKey without injecting styles yet.
28
- * This allows separating className allocation (render phase) from style injection (insertion phase).
29
- */
30
- allocateClassName(cacheKey, options) {
31
- const root = options?.root || document;
32
- const registry = this.sheetManager.getRegistry(root);
33
- if (registry.cacheKeyToClassName.has(cacheKey)) return {
34
- className: registry.cacheKeyToClassName.get(cacheKey),
35
- isNewAllocation: false
36
- };
37
- const className = generateClassName(registry.classCounter++);
38
- const placeholderRuleInfo = {
39
- className,
40
- ruleIndex: -1,
41
- sheetIndex: -1
42
- };
43
- registry.rules.set(className, placeholderRuleInfo);
44
- registry.cacheKeyToClassName.set(cacheKey, className);
45
- return {
46
- className,
47
- isNewAllocation: true
48
- };
49
- }
50
- /**
51
- * Inject styles from StyleResult objects
52
- */
53
- inject(rules, options) {
54
- const root = options?.root || document;
55
- const registry = this.sheetManager.getRegistry(root);
56
- if (rules.length === 0) return {
57
- className: "",
58
- dispose: () => {}
59
- };
60
- const cacheKey = options?.cacheKey;
61
- let className;
62
- let isPreAllocated = false;
63
- if (cacheKey && registry.cacheKeyToClassName.has(cacheKey)) {
64
- className = registry.cacheKeyToClassName.get(cacheKey);
65
- const existingRuleInfo = registry.rules.get(className);
66
- isPreAllocated = existingRuleInfo.ruleIndex === -1 && existingRuleInfo.sheetIndex === -1;
67
- if (!isPreAllocated) {
68
- const currentRefCount = registry.refCounts.get(className) || 0;
69
- registry.refCounts.set(className, currentRefCount + 1);
70
- if (registry.metrics) registry.metrics.hits++;
71
- return {
72
- className,
73
- dispose: () => this.dispose(className, registry)
74
- };
75
- }
76
- } else className = generateClassName(registry.classCounter++);
77
- const rulesToInsert = rules.map((rule) => {
78
- let newSelector = rule.selector;
79
- if (rule.needsClassName) {
80
- const selectorParts = newSelector ? newSelector.split("|||") : [""];
81
- const classPrefix = `.${className}.${className}`;
82
- newSelector = selectorParts.map((part) => {
83
- const classSelector = part ? `${classPrefix}${part}` : classPrefix;
84
- if (rule.rootPrefix) return `${rule.rootPrefix} ${classSelector}`;
85
- return classSelector;
86
- }).join(", ");
87
- }
88
- return {
89
- ...rule,
90
- selector: newSelector,
91
- needsClassName: void 0,
92
- rootPrefix: void 0
93
- };
94
- });
95
- if (this.config.autoPropertyTypes !== false) {
96
- const resolver = registry.propertyTypeResolver;
97
- const defined = registry.injectedProperties;
98
- for (const rule of rulesToInsert) {
99
- if (!rule.declarations) continue;
100
- resolver.scanDeclarations(rule.declarations, (name) => defined.has(name), (name, syntax, initialValue) => {
101
- this.property(name, {
102
- syntax,
103
- inherits: true,
104
- initialValue,
105
- root
106
- });
107
- });
108
- }
109
- }
110
- const ruleInfo = this.sheetManager.insertRule(registry, rulesToInsert, className, root);
111
- if (!ruleInfo) {
112
- if (registry.metrics) registry.metrics.misses++;
113
- return {
114
- className,
115
- dispose: () => {}
116
- };
117
- }
118
- registry.refCounts.set(className, 1);
119
- if (isPreAllocated) registry.rules.set(className, ruleInfo);
120
- else {
121
- registry.rules.set(className, ruleInfo);
122
- if (cacheKey) registry.cacheKeyToClassName.set(cacheKey, className);
123
- }
124
- if (registry.metrics) {
125
- registry.metrics.totalInsertions++;
126
- registry.metrics.misses++;
127
- }
128
- return {
129
- className,
130
- dispose: () => this.dispose(className, registry)
131
- };
132
- }
133
- /**
134
- * Inject global styles (rules without a generated tasty class selector)
135
- * This ensures we don't reserve a tasty class name (t{number}) for global rules,
136
- * which could otherwise collide with element-level styles and break lookups.
137
- */
138
- injectGlobal(rules, options) {
139
- const root = options?.root || document;
140
- const registry = this.sheetManager.getRegistry(root);
141
- if (!rules || rules.length === 0) return { dispose: () => {} };
142
- if (this.config.autoPropertyTypes !== false) {
143
- const resolver = registry.propertyTypeResolver;
144
- const defined = registry.injectedProperties;
145
- for (const rule of rules) {
146
- if (!rule.declarations) continue;
147
- resolver.scanDeclarations(rule.declarations, (name) => defined.has(name), (name, syntax, initialValue) => {
148
- this.property(name, {
149
- syntax,
150
- inherits: true,
151
- initialValue,
152
- root
153
- });
154
- });
155
- }
156
- }
157
- const key = `global:${this.globalRuleCounter++}`;
158
- const info = this.sheetManager.insertGlobalRule(registry, rules, key, root);
159
- if (registry.metrics) registry.metrics.totalInsertions++;
160
- return { dispose: () => {
161
- if (info) this.sheetManager.deleteGlobalRule(registry, key);
162
- } };
163
- }
164
- /**
165
- * Inject raw CSS text directly without parsing
166
- * This is a low-overhead alternative to createGlobalStyle for raw CSS
167
- * The CSS is inserted into a separate style element to avoid conflicts with tasty's chunking
168
- */
169
- injectRawCSS(css, options) {
170
- const root = options?.root || document;
171
- return this.sheetManager.injectRawCSS(css, root);
172
- }
173
- /**
174
- * Get raw CSS text for SSR
175
- */
176
- getRawCSSText(options) {
177
- const root = options?.root || document;
178
- return this.sheetManager.getRawCSSText(root);
179
- }
180
- /**
181
- * Dispose of a className
182
- */
183
- dispose(className, registry) {
184
- const currentRefCount = registry.refCounts.get(className);
185
- if (currentRefCount == null || currentRefCount <= 0) return;
186
- const newRefCount = currentRefCount - 1;
187
- registry.refCounts.set(className, newRefCount);
188
- if (newRefCount === 0) {
189
- if (registry.metrics) registry.metrics.totalUnused++;
190
- this.sheetManager.checkCleanupNeeded(registry);
191
- }
192
- }
193
- /**
194
- * Force bulk cleanup of unused styles
195
- */
196
- cleanup(root) {
197
- const registry = this.sheetManager.getRegistry(root || document);
198
- this.sheetManager.forceCleanup(registry);
199
- }
200
- /**
201
- * Get CSS text from all sheets (for SSR)
202
- */
203
- getCssText(options) {
204
- const root = options?.root || document;
205
- const registry = this.sheetManager.getRegistry(root);
206
- return this.sheetManager.getCssText(registry);
207
- }
208
- /**
209
- * Get CSS only for the provided tasty classNames (e.g., ["t0","t3"])
210
- */
211
- getCssTextForClasses(classNames, options) {
212
- const root = options?.root || document;
213
- const registry = this.sheetManager.getRegistry(root);
214
- const cssChunks = [];
215
- for (const cls of classNames) {
216
- const info = registry.rules.get(cls);
217
- if (info) {
218
- const styleSheet = registry.sheets[info.sheetIndex]?.sheet?.sheet;
219
- if (styleSheet) {
220
- const start = Math.max(0, info.ruleIndex);
221
- const end = Math.min(styleSheet.cssRules.length - 1, info.endRuleIndex ?? info.ruleIndex);
222
- if (start >= 0 && end >= start && start < styleSheet.cssRules.length) for (let i = start; i <= end; i++) {
223
- const rule = styleSheet.cssRules[i];
224
- if (rule) cssChunks.push(rule.cssText);
225
- }
226
- } else if (info.cssText && info.cssText.length) cssChunks.push(...info.cssText);
227
- }
228
- }
229
- return cssChunks.join("\n");
230
- }
231
- /**
232
- * Get cache performance metrics
233
- */
234
- getMetrics(options) {
235
- const root = options?.root || document;
236
- const registry = this.sheetManager.getRegistry(root);
237
- return this.sheetManager.getMetrics(registry);
238
- }
239
- /**
240
- * Reset cache performance metrics
241
- */
242
- resetMetrics(options) {
243
- const root = options?.root || document;
244
- const registry = this.sheetManager.getRegistry(root);
245
- this.sheetManager.resetMetrics(registry);
246
- }
247
- /**
248
- * Define a CSS @property custom property.
249
- *
250
- * Accepts tasty token syntax for the property name:
251
- * - `$name` → defines `--name`
252
- * - `#name` → defines `--name-color` (auto-sets syntax: '<color>', defaults initialValue: 'transparent')
253
- * - `--name` → defines `--name` (legacy format)
254
- *
255
- * Example:
256
- * @property --rotation { syntax: "<angle>"; inherits: false; initial-value: 45deg; }
257
- *
258
- * Note: No caching or dispose — this defines a global property.
259
- *
260
- * If the same property is registered with different options, a warning is emitted
261
- * but the original definition is preserved (CSS @property cannot be redefined).
262
- */
263
- property(name, options) {
264
- const root = options?.root || document;
265
- const registry = this.sheetManager.getRegistry(root);
266
- const effectiveResult = getEffectiveDefinition(name, {
267
- syntax: options?.syntax,
268
- inherits: options?.inherits,
269
- initialValue: options?.initialValue
270
- });
271
- if (!effectiveResult.isValid) {
272
- if (isDevEnv()) console.warn(`[Tasty] property(): ${effectiveResult.error}. Got: "${name}"`);
273
- return;
274
- }
275
- const cssName = effectiveResult.cssName;
276
- const definition = effectiveResult.definition;
277
- const normalizedDef = normalizePropertyDefinition(definition);
278
- const existingDef = registry.injectedProperties.get(cssName);
279
- if (existingDef !== void 0) {
280
- if (existingDef !== normalizedDef) {
281
- if (isDevEnv()) console.warn(`[Tasty] @property ${cssName} was already defined with a different declaration. The new declaration will be ignored. Original: ${existingDef}, New: ${normalizedDef}`);
282
- }
283
- return;
284
- }
285
- const parts = [];
286
- if (definition.syntax != null) {
287
- let syntax = String(definition.syntax).trim();
288
- if (!/^['"]/u.test(syntax)) syntax = `"${syntax}"`;
289
- parts.push(`syntax: ${syntax};`);
290
- }
291
- const inherits = definition.inherits ?? true;
292
- parts.push(`inherits: ${inherits ? "true" : "false"};`);
293
- if (definition.initialValue != null) {
294
- let initialValueStr;
295
- if (typeof definition.initialValue === "number") initialValueStr = String(definition.initialValue);
296
- else initialValueStr = parseStyle(definition.initialValue).output;
297
- parts.push(`initial-value: ${initialValueStr};`);
298
- }
299
- const declarations = parts.join(" ").trim();
300
- const rule = {
301
- selector: `@property ${cssName}`,
302
- declarations
303
- };
304
- if (!this.sheetManager.insertGlobalRule(registry, [rule], `property:${name}`, root)) return;
305
- registry.injectedProperties.set(cssName, normalizedDef);
306
- }
307
- /**
308
- * Check whether a given @property name was already injected by this injector.
309
- *
310
- * Accepts tasty token syntax:
311
- * - `$name` → checks `--name`
312
- * - `#name` → checks `--name-color`
313
- * - `--name` → checks `--name` (legacy format)
314
- */
315
- isPropertyDefined(name, options) {
316
- const root = options?.root || document;
317
- const registry = this.sheetManager.getRegistry(root);
318
- const effectiveResult = getEffectiveDefinition(name, {});
319
- if (!effectiveResult.isValid) return false;
320
- return registry.injectedProperties.has(effectiveResult.cssName);
321
- }
322
- /**
323
- * Inject keyframes and return object with toString() and dispose()
324
- *
325
- * Keyframes are cached by content (steps). If the same content is injected
326
- * multiple times with different provided names, the first injected name is reused.
327
- *
328
- * If the same name is provided with different content (collision), a unique
329
- * name is generated to avoid overwriting the existing keyframes.
330
- */
331
- keyframes(steps, nameOrOptions) {
332
- const isStringName = typeof nameOrOptions === "string";
333
- const providedName = isStringName ? nameOrOptions : nameOrOptions?.name;
334
- const root = isStringName ? document : nameOrOptions?.root || document;
335
- const registry = this.sheetManager.getRegistry(root);
336
- if (Object.keys(steps).length === 0) return {
337
- toString: () => "",
338
- dispose: () => {}
339
- };
340
- const contentHash = JSON.stringify(steps);
341
- const existing = registry.keyframesCache.get(contentHash);
342
- if (existing) {
343
- existing.refCount++;
344
- return {
345
- toString: () => existing.name,
346
- dispose: () => this.disposeKeyframes(contentHash, registry)
347
- };
348
- }
349
- let actualName;
350
- if (providedName) {
351
- const existingContentForName = registry.keyframesNameToContent.get(providedName);
352
- if (existingContentForName && existingContentForName !== contentHash) actualName = `${providedName}-k${registry.keyframesCounter++}`;
353
- else {
354
- actualName = providedName;
355
- registry.keyframesNameToContent.set(providedName, contentHash);
356
- }
357
- } else actualName = `k${registry.keyframesCounter++}`;
358
- const result = this.sheetManager.insertKeyframes(registry, steps, actualName, root);
359
- if (!result) return {
360
- toString: () => "",
361
- dispose: () => {}
362
- };
363
- const { info, declarations } = result;
364
- if (this.config.autoPropertyTypes !== false && declarations) registry.propertyTypeResolver.scanDeclarations(declarations, (name) => registry.injectedProperties.has(name), (name, syntax, initialValue) => {
365
- this.property(name, {
366
- syntax,
367
- inherits: true,
368
- initialValue,
369
- root
370
- });
371
- });
372
- registry.keyframesCache.set(contentHash, {
373
- name: actualName,
374
- refCount: 1,
375
- info
376
- });
377
- if (registry.metrics) {
378
- registry.metrics.totalInsertions++;
379
- registry.metrics.misses++;
380
- }
381
- return {
382
- toString: () => actualName,
383
- dispose: () => this.disposeKeyframes(contentHash, registry)
384
- };
385
- }
386
- /**
387
- * Dispose keyframes
388
- */
389
- disposeKeyframes(contentHash, registry) {
390
- const entry = registry.keyframesCache.get(contentHash);
391
- if (!entry) return;
392
- entry.refCount--;
393
- if (entry.refCount <= 0) {
394
- this.sheetManager.deleteKeyframes(registry, entry.info);
395
- registry.keyframesCache.delete(contentHash);
396
- for (const [name, hash] of registry.keyframesNameToContent.entries()) if (hash === contentHash) {
397
- registry.keyframesNameToContent.delete(name);
398
- break;
399
- }
400
- if (registry.metrics) {
401
- registry.metrics.totalUnused++;
402
- registry.metrics.stylesCleanedUp++;
403
- }
404
- }
405
- }
406
- /**
407
- * Destroy all resources for a root
408
- */
409
- destroy(root) {
410
- const targetRoot = root || document;
411
- this.sheetManager.cleanup(targetRoot);
412
- }
413
- };
414
-
415
- //#endregion
416
- export { StyleInjector };
417
- //# sourceMappingURL=injector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injector.js","names":[],"sources":["../../src/injector/injector.ts"],"sourcesContent":["/**\n * Style injector that works with structured style objects\n * Eliminates CSS string parsing for better performance\n */\n\nimport type { StyleResult } from '../pipeline';\nimport {\n getEffectiveDefinition,\n normalizePropertyDefinition,\n} from '../properties';\nimport { isDevEnv } from '../utils/is-dev-env';\nimport type { StyleValue } from '../utils/styles';\nimport { parseStyle } from '../utils/styles';\n\nimport { SheetManager } from './sheet-manager';\nimport type {\n CacheMetrics,\n GlobalInjectResult,\n InjectResult,\n KeyframesResult,\n KeyframesSteps,\n PropertyDefinition,\n RawCSSResult,\n RootRegistry,\n StyleInjectorConfig,\n StyleRule,\n} from './types';\n\n/**\n * Generate sequential class name with format t{number}\n */\nfunction generateClassName(counter: number): string {\n return `t${counter}`;\n}\n\nexport class StyleInjector {\n private sheetManager: SheetManager;\n private config: StyleInjectorConfig;\n private cleanupScheduled = false;\n private globalRuleCounter = 0;\n\n /** @internal — exposed for debug utilities only */\n get _sheetManager(): SheetManager {\n return this.sheetManager;\n }\n\n constructor(config: StyleInjectorConfig = {}) {\n this.config = config;\n this.sheetManager = new SheetManager(config);\n }\n\n /**\n * Allocate a className for a cacheKey without injecting styles yet.\n * This allows separating className allocation (render phase) from style injection (insertion phase).\n */\n allocateClassName(\n cacheKey: string,\n options?: { root?: Document | ShadowRoot },\n ): { className: string; isNewAllocation: boolean } {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n // Check if we can reuse existing className for this cache key\n if (registry.cacheKeyToClassName.has(cacheKey)) {\n const className = registry.cacheKeyToClassName.get(cacheKey)!;\n return {\n className,\n isNewAllocation: false,\n };\n }\n\n // Generate new className and reserve it\n const className = generateClassName(registry.classCounter++);\n\n // Create placeholder RuleInfo to reserve the className\n const placeholderRuleInfo = {\n className,\n ruleIndex: -1, // Placeholder - will be set during actual injection\n sheetIndex: -1, // Placeholder - will be set during actual injection\n };\n\n // Store RuleInfo only once by className, and map cacheKey separately\n registry.rules.set(className, placeholderRuleInfo);\n registry.cacheKeyToClassName.set(cacheKey, className);\n\n return {\n className,\n isNewAllocation: true,\n };\n }\n\n /**\n * Inject styles from StyleResult objects\n */\n inject(\n rules: StyleResult[],\n options?: { root?: Document | ShadowRoot; cacheKey?: string },\n ): InjectResult {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n if (rules.length === 0) {\n return {\n className: '',\n dispose: () => {\n /* noop */\n },\n };\n }\n\n // Rules are now in StyleRule format directly\n\n // Check if we can reuse based on cache key\n const cacheKey = options?.cacheKey;\n let className: string;\n let isPreAllocated = false;\n\n if (cacheKey && registry.cacheKeyToClassName.has(cacheKey)) {\n // Reuse existing class for this cache key\n className = registry.cacheKeyToClassName.get(cacheKey)!;\n const existingRuleInfo = registry.rules.get(className)!;\n\n // Check if this is a placeholder (pre-allocated but not yet injected)\n isPreAllocated =\n existingRuleInfo.ruleIndex === -1 && existingRuleInfo.sheetIndex === -1;\n\n if (!isPreAllocated) {\n // Already injected - just increment refCount\n const currentRefCount = registry.refCounts.get(className) || 0;\n registry.refCounts.set(className, currentRefCount + 1);\n\n // Update metrics\n if (registry.metrics) {\n registry.metrics.hits++;\n }\n\n return {\n className,\n dispose: () => this.dispose(className, registry),\n };\n }\n } else {\n // Generate new className\n className = generateClassName(registry.classCounter++);\n }\n\n // Process rules: handle needsClassName flag and apply specificity\n const rulesToInsert = rules.map((rule) => {\n let newSelector = rule.selector;\n\n // If rule needs className prepended\n if (rule.needsClassName) {\n // Handle multiple selectors (separated by ||| for OR conditions)\n const selectorParts = newSelector ? newSelector.split('|||') : [''];\n\n const classPrefix = `.${className}.${className}`;\n\n newSelector = selectorParts\n .map((part) => {\n const classSelector = part ? `${classPrefix}${part}` : classPrefix;\n\n // If there's a root prefix, add it before the class selector\n if (rule.rootPrefix) {\n return `${rule.rootPrefix} ${classSelector}`;\n }\n return classSelector;\n })\n .join(', ');\n }\n\n return {\n ...rule,\n selector: newSelector,\n needsClassName: undefined, // Remove the flag after processing\n rootPrefix: undefined, // Remove rootPrefix after processing\n };\n });\n\n // Auto-register @property for custom properties with inferable types.\n // Colors are detected by --*-color name pattern, numeric types by value.\n if (this.config.autoPropertyTypes !== false) {\n const resolver = registry.propertyTypeResolver;\n const defined = registry.injectedProperties;\n for (const rule of rulesToInsert) {\n if (!rule.declarations) continue;\n resolver.scanDeclarations(\n rule.declarations,\n (name) => defined.has(name),\n (name, syntax, initialValue) => {\n this.property(name, {\n syntax,\n inherits: true,\n initialValue,\n root,\n });\n },\n );\n }\n }\n\n // Insert rules using existing sheet manager\n const ruleInfo = this.sheetManager.insertRule(\n registry,\n rulesToInsert,\n className,\n root,\n );\n\n if (!ruleInfo) {\n // Update metrics\n if (registry.metrics) {\n registry.metrics.misses++;\n }\n\n return {\n className,\n dispose: () => {\n /* noop */\n },\n };\n }\n\n // Store in registry\n registry.refCounts.set(className, 1);\n\n if (isPreAllocated) {\n // Update the existing placeholder entry with real rule info\n registry.rules.set(className, ruleInfo);\n // cacheKey mapping already exists from allocation\n } else {\n // Store new entries\n registry.rules.set(className, ruleInfo);\n if (cacheKey) {\n registry.cacheKeyToClassName.set(cacheKey, className);\n }\n }\n\n // Update metrics\n if (registry.metrics) {\n registry.metrics.totalInsertions++;\n registry.metrics.misses++;\n }\n\n return {\n className,\n dispose: () => this.dispose(className, registry),\n };\n }\n\n /**\n * Inject global styles (rules without a generated tasty class selector)\n * This ensures we don't reserve a tasty class name (t{number}) for global rules,\n * which could otherwise collide with element-level styles and break lookups.\n */\n injectGlobal(\n rules: StyleResult[],\n options?: { root?: Document | ShadowRoot },\n ): GlobalInjectResult {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n if (!rules || rules.length === 0) {\n return {\n dispose: () => {\n /* noop */\n },\n };\n }\n\n // Auto-register @property for custom properties in global rules\n if (this.config.autoPropertyTypes !== false) {\n const resolver = registry.propertyTypeResolver;\n const defined = registry.injectedProperties;\n for (const rule of rules) {\n if (!rule.declarations) continue;\n resolver.scanDeclarations(\n rule.declarations,\n (name) => defined.has(name),\n (name, syntax, initialValue) => {\n this.property(name, {\n syntax,\n inherits: true,\n initialValue,\n root,\n });\n },\n );\n }\n }\n\n // Use a non-tasty identifier to avoid any collisions with .t{number} classes\n const key = `global:${this.globalRuleCounter++}`;\n\n const info = this.sheetManager.insertGlobalRule(\n registry,\n rules as unknown as StyleRule[],\n key,\n root,\n );\n\n if (registry.metrics) {\n registry.metrics.totalInsertions++;\n }\n\n return {\n dispose: () => {\n if (info) this.sheetManager.deleteGlobalRule(registry, key);\n },\n };\n }\n\n /**\n * Inject raw CSS text directly without parsing\n * This is a low-overhead alternative to createGlobalStyle for raw CSS\n * The CSS is inserted into a separate style element to avoid conflicts with tasty's chunking\n */\n injectRawCSS(\n css: string,\n options?: { root?: Document | ShadowRoot },\n ): RawCSSResult {\n const root = options?.root || document;\n return this.sheetManager.injectRawCSS(css, root);\n }\n\n /**\n * Get raw CSS text for SSR\n */\n getRawCSSText(options?: { root?: Document | ShadowRoot }): string {\n const root = options?.root || document;\n return this.sheetManager.getRawCSSText(root);\n }\n\n /**\n * Dispose of a className\n */\n private dispose(className: string, registry: RootRegistry): void {\n const currentRefCount = registry.refCounts.get(className);\n // Guard against stale double-dispose or mismatched lifecycle\n if (currentRefCount == null || currentRefCount <= 0) {\n return;\n }\n\n const newRefCount = currentRefCount - 1;\n registry.refCounts.set(className, newRefCount);\n\n if (newRefCount === 0) {\n // Update metrics\n if (registry.metrics) {\n registry.metrics.totalUnused++;\n }\n\n // Check if cleanup should be scheduled\n this.sheetManager.checkCleanupNeeded(registry);\n }\n }\n\n /**\n * Force bulk cleanup of unused styles\n */\n cleanup(root?: Document | ShadowRoot): void {\n const registry = this.sheetManager.getRegistry(root || document);\n // Clean up ALL unused rules regardless of batch ratio\n this.sheetManager.forceCleanup(registry);\n }\n\n /**\n * Get CSS text from all sheets (for SSR)\n */\n getCssText(options?: { root?: Document | ShadowRoot }): string {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n return this.sheetManager.getCssText(registry);\n }\n\n /**\n * Get CSS only for the provided tasty classNames (e.g., [\"t0\",\"t3\"])\n */\n getCssTextForClasses(\n classNames: Iterable<string>,\n options?: { root?: Document | ShadowRoot },\n ): string {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n const cssChunks: string[] = [];\n for (const cls of classNames) {\n const info = registry.rules.get(cls);\n if (info) {\n // Always prefer reading from the live stylesheet, since indices can change\n const sheet = registry.sheets[info.sheetIndex];\n const styleSheet = sheet?.sheet?.sheet;\n if (styleSheet) {\n const start = Math.max(0, info.ruleIndex);\n const end = Math.min(\n styleSheet.cssRules.length - 1,\n (info.endRuleIndex as number) ?? info.ruleIndex,\n );\n // Additional validation: ensure indices are valid and in correct order\n if (\n start >= 0 &&\n end >= start &&\n start < styleSheet.cssRules.length\n ) {\n for (let i = start; i <= end; i++) {\n const rule = styleSheet.cssRules[i] as CSSRule | undefined;\n if (rule) cssChunks.push(rule.cssText);\n }\n }\n } else if (info.cssText && info.cssText.length) {\n // Fallback in environments without CSSOM access\n cssChunks.push(...info.cssText);\n }\n }\n }\n return cssChunks.join('\\n');\n }\n\n /**\n * Get cache performance metrics\n */\n getMetrics(options?: { root?: Document | ShadowRoot }): CacheMetrics | null {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n return this.sheetManager.getMetrics(registry);\n }\n\n /**\n * Reset cache performance metrics\n */\n resetMetrics(options?: { root?: Document | ShadowRoot }): void {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n this.sheetManager.resetMetrics(registry);\n }\n\n /**\n * Define a CSS @property custom property.\n *\n * Accepts tasty token syntax for the property name:\n * - `$name` → defines `--name`\n * - `#name` → defines `--name-color` (auto-sets syntax: '<color>', defaults initialValue: 'transparent')\n * - `--name` → defines `--name` (legacy format)\n *\n * Example:\n * @property --rotation { syntax: \"<angle>\"; inherits: false; initial-value: 45deg; }\n *\n * Note: No caching or dispose — this defines a global property.\n *\n * If the same property is registered with different options, a warning is emitted\n * but the original definition is preserved (CSS @property cannot be redefined).\n */\n property(\n name: string,\n options?: PropertyDefinition & {\n root?: Document | ShadowRoot;\n },\n ): void {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n // Parse the token and get effective definition\n // This handles $name, #name, --name formats and auto-sets syntax for colors\n const userDefinition: PropertyDefinition = {\n syntax: options?.syntax,\n inherits: options?.inherits,\n initialValue: options?.initialValue,\n };\n\n const effectiveResult = getEffectiveDefinition(name, userDefinition);\n\n if (!effectiveResult.isValid) {\n if (isDevEnv()) {\n console.warn(\n `[Tasty] property(): ${effectiveResult.error}. Got: \"${name}\"`,\n );\n }\n return;\n }\n\n const cssName = effectiveResult.cssName;\n const definition = effectiveResult.definition;\n\n // Normalize the definition for comparison\n const normalizedDef = normalizePropertyDefinition(definition);\n\n // Check if already defined\n const existingDef = registry.injectedProperties.get(cssName);\n if (existingDef !== undefined) {\n // Property already exists - check if definitions match\n if (existingDef !== normalizedDef) {\n // Different definition - warn but don't replace (CSS @property can't be redefined)\n if (isDevEnv()) {\n console.warn(\n `[Tasty] @property ${cssName} was already defined with a different declaration. ` +\n `The new declaration will be ignored. ` +\n `Original: ${existingDef}, New: ${normalizedDef}`,\n );\n }\n }\n // Either exact match or warned - skip injection\n return;\n }\n\n const parts: string[] = [];\n\n if (definition.syntax != null) {\n let syntax = String(definition.syntax).trim();\n if (!/^['\"]/u.test(syntax)) syntax = `\"${syntax}\"`;\n parts.push(`syntax: ${syntax};`);\n }\n\n // inherits is required by the CSS @property spec - default to true\n const inherits = definition.inherits ?? true;\n parts.push(`inherits: ${inherits ? 'true' : 'false'};`);\n\n if (definition.initialValue != null) {\n let initialValueStr: string;\n if (typeof definition.initialValue === 'number') {\n initialValueStr = String(definition.initialValue);\n } else {\n // Process via tasty parser to resolve custom units/functions\n initialValueStr = parseStyle(\n definition.initialValue as StyleValue,\n ).output;\n }\n parts.push(`initial-value: ${initialValueStr};`);\n }\n\n const declarations = parts.join(' ').trim();\n\n const rule: StyleRule = {\n selector: `@property ${cssName}`,\n declarations,\n } as StyleRule;\n\n // Insert as a global rule; only mark injected when insertion succeeds\n const info = this.sheetManager.insertGlobalRule(\n registry,\n [rule],\n `property:${name}`,\n root,\n );\n\n if (!info) {\n return;\n }\n\n // Track that this property was injected with its normalized definition\n registry.injectedProperties.set(cssName, normalizedDef);\n }\n\n /**\n * Check whether a given @property name was already injected by this injector.\n *\n * Accepts tasty token syntax:\n * - `$name` → checks `--name`\n * - `#name` → checks `--name-color`\n * - `--name` → checks `--name` (legacy format)\n */\n isPropertyDefined(\n name: string,\n options?: { root?: Document | ShadowRoot },\n ): boolean {\n const root = options?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n // Parse the token to get the CSS property name\n const effectiveResult = getEffectiveDefinition(name, {});\n if (!effectiveResult.isValid) {\n return false;\n }\n\n return registry.injectedProperties.has(effectiveResult.cssName);\n }\n\n /**\n * Inject keyframes and return object with toString() and dispose()\n *\n * Keyframes are cached by content (steps). If the same content is injected\n * multiple times with different provided names, the first injected name is reused.\n *\n * If the same name is provided with different content (collision), a unique\n * name is generated to avoid overwriting the existing keyframes.\n */\n keyframes(\n steps: KeyframesSteps,\n nameOrOptions?: string | { root?: Document | ShadowRoot; name?: string },\n ): KeyframesResult {\n // Parse parameters\n const isStringName = typeof nameOrOptions === 'string';\n const providedName = isStringName ? nameOrOptions : nameOrOptions?.name;\n const root = isStringName ? document : nameOrOptions?.root || document;\n const registry = this.sheetManager.getRegistry(root);\n\n if (Object.keys(steps).length === 0) {\n return {\n toString: () => '',\n dispose: () => {\n /* noop */\n },\n };\n }\n\n // Generate content-based cache key (independent of provided name)\n const contentHash = JSON.stringify(steps);\n\n // Check if this exact content is already cached\n const existing = registry.keyframesCache.get(contentHash);\n if (existing) {\n existing.refCount++;\n return {\n toString: () => existing.name,\n dispose: () => this.disposeKeyframes(contentHash, registry),\n };\n }\n\n // Determine the actual name to use\n let actualName: string;\n\n if (providedName) {\n // Check if this name is already used with different content\n const existingContentForName =\n registry.keyframesNameToContent.get(providedName);\n\n if (existingContentForName && existingContentForName !== contentHash) {\n // Name collision: same name, different content\n // Generate a unique name to avoid overwriting\n actualName = `${providedName}-k${registry.keyframesCounter++}`;\n } else {\n // Name is available or used with same content\n actualName = providedName;\n // Track this name -> content mapping\n registry.keyframesNameToContent.set(providedName, contentHash);\n }\n } else {\n // No name provided, generate one\n actualName = `k${registry.keyframesCounter++}`;\n }\n\n // Insert keyframes\n const result = this.sheetManager.insertKeyframes(\n registry,\n steps,\n actualName,\n root,\n );\n if (!result) {\n return {\n toString: () => '',\n dispose: () => {\n /* noop */\n },\n };\n }\n\n const { info, declarations } = result;\n\n // Auto-register @property for custom properties found in keyframe declarations\n if (this.config.autoPropertyTypes !== false && declarations) {\n const resolver = registry.propertyTypeResolver;\n resolver.scanDeclarations(\n declarations,\n (name) => registry.injectedProperties.has(name),\n (name, syntax, initialValue) => {\n this.property(name, {\n syntax,\n inherits: true,\n initialValue,\n root,\n });\n },\n );\n }\n\n // Cache the result by content hash\n registry.keyframesCache.set(contentHash, {\n name: actualName,\n refCount: 1,\n info,\n });\n\n // Update metrics\n if (registry.metrics) {\n registry.metrics.totalInsertions++;\n registry.metrics.misses++;\n }\n\n return {\n toString: () => actualName,\n dispose: () => this.disposeKeyframes(contentHash, registry),\n };\n }\n\n /**\n * Dispose keyframes\n */\n private disposeKeyframes(contentHash: string, registry: RootRegistry): void {\n const entry = registry.keyframesCache.get(contentHash);\n if (!entry) return;\n\n entry.refCount--;\n if (entry.refCount <= 0) {\n // Dispose immediately - keyframes are global and safe to clean up right away\n this.sheetManager.deleteKeyframes(registry, entry.info);\n registry.keyframesCache.delete(contentHash);\n\n // Clean up name-to-content mapping if this name was tracked\n // Find and remove the mapping for this content hash\n for (const [name, hash] of registry.keyframesNameToContent.entries()) {\n if (hash === contentHash) {\n registry.keyframesNameToContent.delete(name);\n break;\n }\n }\n\n // Update metrics\n if (registry.metrics) {\n registry.metrics.totalUnused++;\n registry.metrics.stylesCleanedUp++;\n }\n }\n }\n\n /**\n * Destroy all resources for a root\n */\n destroy(root?: Document | ShadowRoot): void {\n const targetRoot = root || document;\n this.sheetManager.cleanup(targetRoot);\n }\n}\n"],"mappings":"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"}