@tenphi/tasty 0.0.0-snapshot.05c1c22

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 (314) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +629 -0
  3. package/dist/_virtual/_rolldown/runtime.js +7 -0
  4. package/dist/chunks/cacheKey.d.ts +1 -0
  5. package/dist/chunks/cacheKey.js +77 -0
  6. package/dist/chunks/cacheKey.js.map +1 -0
  7. package/dist/chunks/definitions.d.ts +37 -0
  8. package/dist/chunks/definitions.js +258 -0
  9. package/dist/chunks/definitions.js.map +1 -0
  10. package/dist/chunks/index.d.ts +1 -0
  11. package/dist/chunks/renderChunk.d.ts +1 -0
  12. package/dist/chunks/renderChunk.js +59 -0
  13. package/dist/chunks/renderChunk.js.map +1 -0
  14. package/dist/config.d.ts +366 -0
  15. package/dist/config.js +503 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/core/index.d.ts +33 -0
  18. package/dist/core/index.js +26 -0
  19. package/dist/counter-style/index.js +51 -0
  20. package/dist/counter-style/index.js.map +1 -0
  21. package/dist/debug.d.ts +89 -0
  22. package/dist/debug.js +453 -0
  23. package/dist/debug.js.map +1 -0
  24. package/dist/font-face/index.js +63 -0
  25. package/dist/font-face/index.js.map +1 -0
  26. package/dist/hooks/index.d.ts +7 -0
  27. package/dist/hooks/resolve-ssr-collector.js +14 -0
  28. package/dist/hooks/resolve-ssr-collector.js.map +1 -0
  29. package/dist/hooks/useCounterStyle.d.ts +50 -0
  30. package/dist/hooks/useCounterStyle.js +46 -0
  31. package/dist/hooks/useCounterStyle.js.map +1 -0
  32. package/dist/hooks/useFontFace.d.ts +43 -0
  33. package/dist/hooks/useFontFace.js +70 -0
  34. package/dist/hooks/useFontFace.js.map +1 -0
  35. package/dist/hooks/useGlobalStyles.d.ts +30 -0
  36. package/dist/hooks/useGlobalStyles.js +78 -0
  37. package/dist/hooks/useGlobalStyles.js.map +1 -0
  38. package/dist/hooks/useKeyframes.d.ts +56 -0
  39. package/dist/hooks/useKeyframes.js +64 -0
  40. package/dist/hooks/useKeyframes.js.map +1 -0
  41. package/dist/hooks/useProperty.d.ts +79 -0
  42. package/dist/hooks/useProperty.js +109 -0
  43. package/dist/hooks/useProperty.js.map +1 -0
  44. package/dist/hooks/useRawCSS.d.ts +53 -0
  45. package/dist/hooks/useRawCSS.js +35 -0
  46. package/dist/hooks/useRawCSS.js.map +1 -0
  47. package/dist/hooks/useStyles.d.ts +45 -0
  48. package/dist/hooks/useStyles.js +237 -0
  49. package/dist/hooks/useStyles.js.map +1 -0
  50. package/dist/index.d.ts +50 -0
  51. package/dist/index.js +35 -0
  52. package/dist/injector/index.d.ts +183 -0
  53. package/dist/injector/index.js +179 -0
  54. package/dist/injector/index.js.map +1 -0
  55. package/dist/injector/injector.d.ts +166 -0
  56. package/dist/injector/injector.js +464 -0
  57. package/dist/injector/injector.js.map +1 -0
  58. package/dist/injector/sheet-manager.d.ts +136 -0
  59. package/dist/injector/sheet-manager.js +733 -0
  60. package/dist/injector/sheet-manager.js.map +1 -0
  61. package/dist/injector/types.d.ts +204 -0
  62. package/dist/keyframes/index.js +206 -0
  63. package/dist/keyframes/index.js.map +1 -0
  64. package/dist/parser/classify.js +319 -0
  65. package/dist/parser/classify.js.map +1 -0
  66. package/dist/parser/const.js +49 -0
  67. package/dist/parser/const.js.map +1 -0
  68. package/dist/parser/lru.js +109 -0
  69. package/dist/parser/lru.js.map +1 -0
  70. package/dist/parser/parser.d.ts +25 -0
  71. package/dist/parser/parser.js +115 -0
  72. package/dist/parser/parser.js.map +1 -0
  73. package/dist/parser/tokenizer.js +69 -0
  74. package/dist/parser/tokenizer.js.map +1 -0
  75. package/dist/parser/types.d.ts +51 -0
  76. package/dist/parser/types.js +46 -0
  77. package/dist/parser/types.js.map +1 -0
  78. package/dist/pipeline/conditions.d.ts +134 -0
  79. package/dist/pipeline/conditions.js +406 -0
  80. package/dist/pipeline/conditions.js.map +1 -0
  81. package/dist/pipeline/exclusive.js +230 -0
  82. package/dist/pipeline/exclusive.js.map +1 -0
  83. package/dist/pipeline/index.d.ts +55 -0
  84. package/dist/pipeline/index.js +708 -0
  85. package/dist/pipeline/index.js.map +1 -0
  86. package/dist/pipeline/materialize.js +1103 -0
  87. package/dist/pipeline/materialize.js.map +1 -0
  88. package/dist/pipeline/parseStateKey.d.ts +15 -0
  89. package/dist/pipeline/parseStateKey.js +446 -0
  90. package/dist/pipeline/parseStateKey.js.map +1 -0
  91. package/dist/pipeline/simplify.js +515 -0
  92. package/dist/pipeline/simplify.js.map +1 -0
  93. package/dist/pipeline/warnings.js +18 -0
  94. package/dist/pipeline/warnings.js.map +1 -0
  95. package/dist/plugins/index.d.ts +2 -0
  96. package/dist/plugins/okhsl-plugin.d.ts +35 -0
  97. package/dist/plugins/okhsl-plugin.js +97 -0
  98. package/dist/plugins/okhsl-plugin.js.map +1 -0
  99. package/dist/plugins/types.d.ts +76 -0
  100. package/dist/properties/index.js +222 -0
  101. package/dist/properties/index.js.map +1 -0
  102. package/dist/properties/property-type-resolver.d.ts +24 -0
  103. package/dist/properties/property-type-resolver.js +90 -0
  104. package/dist/properties/property-type-resolver.js.map +1 -0
  105. package/dist/ssr/astro.d.ts +29 -0
  106. package/dist/ssr/astro.js +64 -0
  107. package/dist/ssr/astro.js.map +1 -0
  108. package/dist/ssr/async-storage.d.ts +17 -0
  109. package/dist/ssr/async-storage.js +34 -0
  110. package/dist/ssr/async-storage.js.map +1 -0
  111. package/dist/ssr/collect-auto-properties.js +39 -0
  112. package/dist/ssr/collect-auto-properties.js.map +1 -0
  113. package/dist/ssr/collector.d.ts +102 -0
  114. package/dist/ssr/collector.js +226 -0
  115. package/dist/ssr/collector.js.map +1 -0
  116. package/dist/ssr/context.d.ts +8 -0
  117. package/dist/ssr/context.js +13 -0
  118. package/dist/ssr/context.js.map +1 -0
  119. package/dist/ssr/format-global-rules.js +22 -0
  120. package/dist/ssr/format-global-rules.js.map +1 -0
  121. package/dist/ssr/format-keyframes.js +69 -0
  122. package/dist/ssr/format-keyframes.js.map +1 -0
  123. package/dist/ssr/format-property.js +49 -0
  124. package/dist/ssr/format-property.js.map +1 -0
  125. package/dist/ssr/format-rules.js +73 -0
  126. package/dist/ssr/format-rules.js.map +1 -0
  127. package/dist/ssr/hydrate.d.ts +22 -0
  128. package/dist/ssr/hydrate.js +49 -0
  129. package/dist/ssr/hydrate.js.map +1 -0
  130. package/dist/ssr/index.d.ts +5 -0
  131. package/dist/ssr/index.js +11 -0
  132. package/dist/ssr/index.js.map +1 -0
  133. package/dist/ssr/next.d.ts +45 -0
  134. package/dist/ssr/next.js +69 -0
  135. package/dist/ssr/next.js.map +1 -0
  136. package/dist/ssr/ssr-collector-ref.js +12 -0
  137. package/dist/ssr/ssr-collector-ref.js.map +1 -0
  138. package/dist/states/index.d.ts +49 -0
  139. package/dist/states/index.js +170 -0
  140. package/dist/states/index.js.map +1 -0
  141. package/dist/static/index.d.ts +5 -0
  142. package/dist/static/index.js +4 -0
  143. package/dist/static/inject.d.ts +5 -0
  144. package/dist/static/inject.js +17 -0
  145. package/dist/static/inject.js.map +1 -0
  146. package/dist/static/tastyStatic.d.ts +46 -0
  147. package/dist/static/tastyStatic.js +30 -0
  148. package/dist/static/tastyStatic.js.map +1 -0
  149. package/dist/static/types.d.ts +49 -0
  150. package/dist/static/types.js +24 -0
  151. package/dist/static/types.js.map +1 -0
  152. package/dist/styles/align.d.ts +15 -0
  153. package/dist/styles/align.js +14 -0
  154. package/dist/styles/align.js.map +1 -0
  155. package/dist/styles/border.d.ts +25 -0
  156. package/dist/styles/border.js +113 -0
  157. package/dist/styles/border.js.map +1 -0
  158. package/dist/styles/color.d.ts +14 -0
  159. package/dist/styles/color.js +26 -0
  160. package/dist/styles/color.js.map +1 -0
  161. package/dist/styles/createStyle.js +79 -0
  162. package/dist/styles/createStyle.js.map +1 -0
  163. package/dist/styles/dimension.js +96 -0
  164. package/dist/styles/dimension.js.map +1 -0
  165. package/dist/styles/display.d.ts +37 -0
  166. package/dist/styles/display.js +66 -0
  167. package/dist/styles/display.js.map +1 -0
  168. package/dist/styles/fade.d.ts +15 -0
  169. package/dist/styles/fade.js +57 -0
  170. package/dist/styles/fade.js.map +1 -0
  171. package/dist/styles/fill.d.ts +42 -0
  172. package/dist/styles/fill.js +51 -0
  173. package/dist/styles/fill.js.map +1 -0
  174. package/dist/styles/flow.d.ts +16 -0
  175. package/dist/styles/flow.js +12 -0
  176. package/dist/styles/flow.js.map +1 -0
  177. package/dist/styles/gap.d.ts +31 -0
  178. package/dist/styles/gap.js +36 -0
  179. package/dist/styles/gap.js.map +1 -0
  180. package/dist/styles/height.d.ts +17 -0
  181. package/dist/styles/height.js +19 -0
  182. package/dist/styles/height.js.map +1 -0
  183. package/dist/styles/index.d.ts +1 -0
  184. package/dist/styles/index.js +8 -0
  185. package/dist/styles/index.js.map +1 -0
  186. package/dist/styles/inset.d.ts +52 -0
  187. package/dist/styles/inset.js +149 -0
  188. package/dist/styles/inset.js.map +1 -0
  189. package/dist/styles/justify.d.ts +15 -0
  190. package/dist/styles/justify.js +14 -0
  191. package/dist/styles/justify.js.map +1 -0
  192. package/dist/styles/list.d.ts +16 -0
  193. package/dist/styles/list.js +98 -0
  194. package/dist/styles/list.js.map +1 -0
  195. package/dist/styles/margin.d.ts +24 -0
  196. package/dist/styles/margin.js +103 -0
  197. package/dist/styles/margin.js.map +1 -0
  198. package/dist/styles/outline.d.ts +29 -0
  199. package/dist/styles/outline.js +64 -0
  200. package/dist/styles/outline.js.map +1 -0
  201. package/dist/styles/padding.d.ts +24 -0
  202. package/dist/styles/padding.js +103 -0
  203. package/dist/styles/padding.js.map +1 -0
  204. package/dist/styles/predefined.d.ts +71 -0
  205. package/dist/styles/predefined.js +237 -0
  206. package/dist/styles/predefined.js.map +1 -0
  207. package/dist/styles/preset.d.ts +52 -0
  208. package/dist/styles/preset.js +126 -0
  209. package/dist/styles/preset.js.map +1 -0
  210. package/dist/styles/radius.d.ts +12 -0
  211. package/dist/styles/radius.js +71 -0
  212. package/dist/styles/radius.js.map +1 -0
  213. package/dist/styles/scrollbar.d.ts +25 -0
  214. package/dist/styles/scrollbar.js +46 -0
  215. package/dist/styles/scrollbar.js.map +1 -0
  216. package/dist/styles/shadow.d.ts +14 -0
  217. package/dist/styles/shadow.js +23 -0
  218. package/dist/styles/shadow.js.map +1 -0
  219. package/dist/styles/transition.d.ts +14 -0
  220. package/dist/styles/transition.js +157 -0
  221. package/dist/styles/transition.js.map +1 -0
  222. package/dist/styles/types.d.ts +549 -0
  223. package/dist/styles/width.d.ts +17 -0
  224. package/dist/styles/width.js +19 -0
  225. package/dist/styles/width.js.map +1 -0
  226. package/dist/tasty.d.ts +119 -0
  227. package/dist/tasty.js +231 -0
  228. package/dist/tasty.js.map +1 -0
  229. package/dist/types.d.ts +184 -0
  230. package/dist/utils/cache-wrapper.js +21 -0
  231. package/dist/utils/cache-wrapper.js.map +1 -0
  232. package/dist/utils/case-converter.js +8 -0
  233. package/dist/utils/case-converter.js.map +1 -0
  234. package/dist/utils/color-math.d.ts +46 -0
  235. package/dist/utils/color-math.js +749 -0
  236. package/dist/utils/color-math.js.map +1 -0
  237. package/dist/utils/color-space.d.ts +5 -0
  238. package/dist/utils/color-space.js +228 -0
  239. package/dist/utils/color-space.js.map +1 -0
  240. package/dist/utils/colors.d.ts +5 -0
  241. package/dist/utils/colors.js +10 -0
  242. package/dist/utils/colors.js.map +1 -0
  243. package/dist/utils/css-types.d.ts +7 -0
  244. package/dist/utils/dotize.d.ts +26 -0
  245. package/dist/utils/dotize.js +122 -0
  246. package/dist/utils/dotize.js.map +1 -0
  247. package/dist/utils/filter-base-props.d.ts +15 -0
  248. package/dist/utils/filter-base-props.js +45 -0
  249. package/dist/utils/filter-base-props.js.map +1 -0
  250. package/dist/utils/get-display-name.d.ts +7 -0
  251. package/dist/utils/get-display-name.js +10 -0
  252. package/dist/utils/get-display-name.js.map +1 -0
  253. package/dist/utils/has-keys.js +13 -0
  254. package/dist/utils/has-keys.js.map +1 -0
  255. package/dist/utils/is-dev-env.js +19 -0
  256. package/dist/utils/is-dev-env.js.map +1 -0
  257. package/dist/utils/is-valid-element-type.js +15 -0
  258. package/dist/utils/is-valid-element-type.js.map +1 -0
  259. package/dist/utils/merge-styles.d.ts +7 -0
  260. package/dist/utils/merge-styles.js +145 -0
  261. package/dist/utils/merge-styles.js.map +1 -0
  262. package/dist/utils/mod-attrs.d.ts +6 -0
  263. package/dist/utils/mod-attrs.js +20 -0
  264. package/dist/utils/mod-attrs.js.map +1 -0
  265. package/dist/utils/process-tokens.d.ts +21 -0
  266. package/dist/utils/process-tokens.js +90 -0
  267. package/dist/utils/process-tokens.js.map +1 -0
  268. package/dist/utils/resolve-recipes.d.ts +17 -0
  269. package/dist/utils/resolve-recipes.js +146 -0
  270. package/dist/utils/resolve-recipes.js.map +1 -0
  271. package/dist/utils/selector-transform.js +32 -0
  272. package/dist/utils/selector-transform.js.map +1 -0
  273. package/dist/utils/string.js +8 -0
  274. package/dist/utils/string.js.map +1 -0
  275. package/dist/utils/styles.d.ts +99 -0
  276. package/dist/utils/styles.js +220 -0
  277. package/dist/utils/styles.js.map +1 -0
  278. package/dist/utils/typography.d.ts +47 -0
  279. package/dist/utils/typography.js +51 -0
  280. package/dist/utils/typography.js.map +1 -0
  281. package/dist/utils/warnings.d.ts +16 -0
  282. package/dist/utils/warnings.js +16 -0
  283. package/dist/utils/warnings.js.map +1 -0
  284. package/dist/zero/babel.d.ts +182 -0
  285. package/dist/zero/babel.js +438 -0
  286. package/dist/zero/babel.js.map +1 -0
  287. package/dist/zero/css-writer.d.ts +45 -0
  288. package/dist/zero/css-writer.js +73 -0
  289. package/dist/zero/css-writer.js.map +1 -0
  290. package/dist/zero/extractor.d.ts +24 -0
  291. package/dist/zero/extractor.js +266 -0
  292. package/dist/zero/extractor.js.map +1 -0
  293. package/dist/zero/index.d.ts +3 -0
  294. package/dist/zero/index.js +3 -0
  295. package/dist/zero/next.d.ts +86 -0
  296. package/dist/zero/next.js +143 -0
  297. package/dist/zero/next.js.map +1 -0
  298. package/docs/PIPELINE.md +519 -0
  299. package/docs/README.md +31 -0
  300. package/docs/adoption.md +296 -0
  301. package/docs/comparison.md +420 -0
  302. package/docs/configuration.md +326 -0
  303. package/docs/debug.md +318 -0
  304. package/docs/design-system.md +424 -0
  305. package/docs/dsl.md +673 -0
  306. package/docs/getting-started.md +217 -0
  307. package/docs/injector.md +528 -0
  308. package/docs/methodology.md +567 -0
  309. package/docs/runtime.md +485 -0
  310. package/docs/ssr.md +384 -0
  311. package/docs/styles.md +582 -0
  312. package/docs/tasty-static.md +520 -0
  313. package/package.json +215 -0
  314. package/tasty.config.ts +14 -0
@@ -0,0 +1,166 @@
1
+ import { CacheMetrics, CounterStyleDescriptors, FontFaceDescriptors, 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
+ * Increment refCount for an already-injected cacheKey and return a dispose.
55
+ * Used by useStyles on cache hits (hydration or runtime reuse) where
56
+ * the pipeline was skipped but refCount tracking is still needed.
57
+ * Returns null if the cacheKey is not found.
58
+ */
59
+ trackRef(cacheKey: string, options?: {
60
+ root?: Document | ShadowRoot;
61
+ }): InjectResult | null;
62
+ /**
63
+ * Dispose of a className
64
+ */
65
+ private dispose;
66
+ /**
67
+ * Force bulk cleanup of unused styles
68
+ */
69
+ cleanup(root?: Document | ShadowRoot): void;
70
+ /**
71
+ * Get CSS text from all sheets (for SSR)
72
+ */
73
+ getCssText(options?: {
74
+ root?: Document | ShadowRoot;
75
+ }): string;
76
+ /**
77
+ * Get CSS only for the provided tasty classNames (e.g., ["t0","t3"])
78
+ */
79
+ getCssTextForClasses(classNames: Iterable<string>, options?: {
80
+ root?: Document | ShadowRoot;
81
+ }): string;
82
+ /**
83
+ * Get cache performance metrics
84
+ */
85
+ getMetrics(options?: {
86
+ root?: Document | ShadowRoot;
87
+ }): CacheMetrics | null;
88
+ /**
89
+ * Reset cache performance metrics
90
+ */
91
+ resetMetrics(options?: {
92
+ root?: Document | ShadowRoot;
93
+ }): void;
94
+ /**
95
+ * Define a CSS @property custom property.
96
+ *
97
+ * Accepts tasty token syntax for the property name:
98
+ * - `$name` → defines `--name`
99
+ * - `#name` → defines `--name-color` (auto-sets syntax: '<color>', defaults initialValue: 'transparent')
100
+ * - `--name` → defines `--name` (legacy format)
101
+ *
102
+ * Example:
103
+ * @property --rotation { syntax: "<angle>"; inherits: false; initial-value: 45deg; }
104
+ *
105
+ * Note: No caching or dispose — this defines a global property.
106
+ *
107
+ * If the same property is registered with different options, a warning is emitted
108
+ * but the original definition is preserved (CSS @property cannot be redefined).
109
+ */
110
+ property(name: string, options?: PropertyDefinition & {
111
+ root?: Document | ShadowRoot;
112
+ }): void;
113
+ /**
114
+ * Check whether a given @property name was already injected by this injector.
115
+ *
116
+ * Accepts tasty token syntax:
117
+ * - `$name` → checks `--name`
118
+ * - `#name` → checks `--name-color`
119
+ * - `--name` → checks `--name` (legacy format)
120
+ */
121
+ isPropertyDefined(name: string, options?: {
122
+ root?: Document | ShadowRoot;
123
+ }): boolean;
124
+ /**
125
+ * Inject a CSS @font-face rule.
126
+ *
127
+ * Permanent and global — no dispose or ref-counting.
128
+ * Deduplicates by content hash (family + descriptors).
129
+ */
130
+ fontFace(family: string, descriptors: FontFaceDescriptors, options?: {
131
+ root?: Document | ShadowRoot;
132
+ }): void;
133
+ /**
134
+ * Inject a CSS @counter-style rule.
135
+ *
136
+ * Permanent and global — no dispose or ref-counting.
137
+ * Deduplicates by name (first definition wins).
138
+ */
139
+ counterStyle(name: string, descriptors: CounterStyleDescriptors, options?: {
140
+ root?: Document | ShadowRoot;
141
+ }): void;
142
+ /**
143
+ * Inject keyframes and return object with toString() and dispose()
144
+ *
145
+ * Keyframes are cached by content (steps). If the same content is injected
146
+ * multiple times with different provided names, the first injected name is reused.
147
+ *
148
+ * If the same name is provided with different content (collision), a unique
149
+ * name is generated to avoid overwriting the existing keyframes.
150
+ */
151
+ keyframes(steps: KeyframesSteps, nameOrOptions?: string | {
152
+ root?: Document | ShadowRoot;
153
+ name?: string;
154
+ }): KeyframesResult;
155
+ /**
156
+ * Dispose keyframes
157
+ */
158
+ private disposeKeyframes;
159
+ /**
160
+ * Destroy all resources for a root
161
+ */
162
+ destroy(root?: Document | ShadowRoot): void;
163
+ }
164
+ //#endregion
165
+ export { StyleInjector };
166
+ //# sourceMappingURL=injector.d.ts.map
@@ -0,0 +1,464 @@
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
+ import { fontFaceContentHash, formatFontFaceDeclarations } from "../font-face/index.js";
6
+ import { formatCounterStyleDeclarations } from "../counter-style/index.js";
7
+ //#region src/injector/injector.ts
8
+ /**
9
+ * Generate sequential class name with format t{number}
10
+ */
11
+ function generateClassName(counter) {
12
+ return `t${counter}`;
13
+ }
14
+ var StyleInjector = class {
15
+ sheetManager;
16
+ config;
17
+ cleanupScheduled = false;
18
+ globalRuleCounter = 0;
19
+ /** @internal — exposed for debug utilities only */
20
+ get _sheetManager() {
21
+ return this.sheetManager;
22
+ }
23
+ constructor(config = {}) {
24
+ this.config = config;
25
+ this.sheetManager = new SheetManager(config);
26
+ }
27
+ /**
28
+ * Allocate a className for a cacheKey without injecting styles yet.
29
+ * This allows separating className allocation (render phase) from style injection (insertion phase).
30
+ */
31
+ allocateClassName(cacheKey, options) {
32
+ const root = options?.root || document;
33
+ const registry = this.sheetManager.getRegistry(root);
34
+ if (registry.cacheKeyToClassName.has(cacheKey)) return {
35
+ className: registry.cacheKeyToClassName.get(cacheKey),
36
+ isNewAllocation: false
37
+ };
38
+ const className = generateClassName(registry.classCounter++);
39
+ const placeholderRuleInfo = {
40
+ className,
41
+ ruleIndex: -1,
42
+ sheetIndex: -1
43
+ };
44
+ registry.rules.set(className, placeholderRuleInfo);
45
+ registry.cacheKeyToClassName.set(cacheKey, className);
46
+ return {
47
+ className,
48
+ isNewAllocation: true
49
+ };
50
+ }
51
+ /**
52
+ * Inject styles from StyleResult objects
53
+ */
54
+ inject(rules, options) {
55
+ const root = options?.root || document;
56
+ const registry = this.sheetManager.getRegistry(root);
57
+ if (rules.length === 0) return {
58
+ className: "",
59
+ dispose: () => {}
60
+ };
61
+ const cacheKey = options?.cacheKey;
62
+ let className;
63
+ let isPreAllocated = false;
64
+ if (cacheKey && registry.cacheKeyToClassName.has(cacheKey)) {
65
+ className = registry.cacheKeyToClassName.get(cacheKey);
66
+ const existingRuleInfo = registry.rules.get(className);
67
+ isPreAllocated = existingRuleInfo.ruleIndex === -1 && existingRuleInfo.sheetIndex === -1;
68
+ if (!isPreAllocated) {
69
+ const currentRefCount = registry.refCounts.get(className) || 0;
70
+ registry.refCounts.set(className, currentRefCount + 1);
71
+ if (registry.metrics) registry.metrics.hits++;
72
+ return {
73
+ className,
74
+ dispose: () => this.dispose(className, registry)
75
+ };
76
+ }
77
+ } else className = generateClassName(registry.classCounter++);
78
+ const rulesToInsert = rules.map((rule) => {
79
+ let newSelector = rule.selector;
80
+ if (rule.needsClassName) {
81
+ const selectorParts = newSelector ? newSelector.split("|||") : [""];
82
+ const classPrefix = `.${className}.${className}`;
83
+ newSelector = selectorParts.map((part) => {
84
+ const classSelector = part ? `${classPrefix}${part}` : classPrefix;
85
+ if (rule.rootPrefix) return `${rule.rootPrefix} ${classSelector}`;
86
+ return classSelector;
87
+ }).join(", ");
88
+ }
89
+ return {
90
+ ...rule,
91
+ selector: newSelector,
92
+ needsClassName: void 0,
93
+ rootPrefix: void 0
94
+ };
95
+ });
96
+ if (this.config.autoPropertyTypes !== false) {
97
+ const resolver = registry.propertyTypeResolver;
98
+ const defined = registry.injectedProperties;
99
+ for (const rule of rulesToInsert) {
100
+ if (!rule.declarations) continue;
101
+ resolver.scanDeclarations(rule.declarations, (name) => defined.has(name), (name, syntax, initialValue) => {
102
+ this.property(name, {
103
+ syntax,
104
+ inherits: true,
105
+ initialValue,
106
+ root
107
+ });
108
+ });
109
+ }
110
+ }
111
+ const ruleInfo = this.sheetManager.insertRule(registry, rulesToInsert, className, root);
112
+ if (!ruleInfo) {
113
+ if (registry.metrics) registry.metrics.misses++;
114
+ return {
115
+ className,
116
+ dispose: () => {}
117
+ };
118
+ }
119
+ registry.refCounts.set(className, 1);
120
+ if (isPreAllocated) registry.rules.set(className, ruleInfo);
121
+ else {
122
+ registry.rules.set(className, ruleInfo);
123
+ if (cacheKey) registry.cacheKeyToClassName.set(cacheKey, className);
124
+ }
125
+ if (registry.metrics) {
126
+ registry.metrics.totalInsertions++;
127
+ registry.metrics.misses++;
128
+ }
129
+ return {
130
+ className,
131
+ dispose: () => this.dispose(className, registry)
132
+ };
133
+ }
134
+ /**
135
+ * Inject global styles (rules without a generated tasty class selector)
136
+ * This ensures we don't reserve a tasty class name (t{number}) for global rules,
137
+ * which could otherwise collide with element-level styles and break lookups.
138
+ */
139
+ injectGlobal(rules, options) {
140
+ const root = options?.root || document;
141
+ const registry = this.sheetManager.getRegistry(root);
142
+ if (!rules || rules.length === 0) return { dispose: () => {} };
143
+ if (this.config.autoPropertyTypes !== false) {
144
+ const resolver = registry.propertyTypeResolver;
145
+ const defined = registry.injectedProperties;
146
+ for (const rule of rules) {
147
+ if (!rule.declarations) continue;
148
+ resolver.scanDeclarations(rule.declarations, (name) => defined.has(name), (name, syntax, initialValue) => {
149
+ this.property(name, {
150
+ syntax,
151
+ inherits: true,
152
+ initialValue,
153
+ root
154
+ });
155
+ });
156
+ }
157
+ }
158
+ const key = `global:${this.globalRuleCounter++}`;
159
+ const info = this.sheetManager.insertGlobalRule(registry, rules, key, root);
160
+ if (registry.metrics) registry.metrics.totalInsertions++;
161
+ return { dispose: () => {
162
+ if (info) this.sheetManager.deleteGlobalRule(registry, key);
163
+ } };
164
+ }
165
+ /**
166
+ * Inject raw CSS text directly without parsing
167
+ * This is a low-overhead alternative to createGlobalStyle for raw CSS
168
+ * The CSS is inserted into a separate style element to avoid conflicts with tasty's chunking
169
+ */
170
+ injectRawCSS(css, options) {
171
+ const root = options?.root || document;
172
+ return this.sheetManager.injectRawCSS(css, root);
173
+ }
174
+ /**
175
+ * Get raw CSS text for SSR
176
+ */
177
+ getRawCSSText(options) {
178
+ const root = options?.root || document;
179
+ return this.sheetManager.getRawCSSText(root);
180
+ }
181
+ /**
182
+ * Increment refCount for an already-injected cacheKey and return a dispose.
183
+ * Used by useStyles on cache hits (hydration or runtime reuse) where
184
+ * the pipeline was skipped but refCount tracking is still needed.
185
+ * Returns null if the cacheKey is not found.
186
+ */
187
+ trackRef(cacheKey, options) {
188
+ const root = options?.root || document;
189
+ const registry = this.sheetManager.getRegistry(root);
190
+ if (!registry.cacheKeyToClassName.has(cacheKey)) return null;
191
+ const className = registry.cacheKeyToClassName.get(cacheKey);
192
+ const currentRefCount = registry.refCounts.get(className) || 0;
193
+ registry.refCounts.set(className, currentRefCount + 1);
194
+ if (registry.metrics) registry.metrics.hits++;
195
+ return {
196
+ className,
197
+ dispose: () => this.dispose(className, registry)
198
+ };
199
+ }
200
+ /**
201
+ * Dispose of a className
202
+ */
203
+ dispose(className, registry) {
204
+ const currentRefCount = registry.refCounts.get(className);
205
+ if (currentRefCount == null || currentRefCount <= 0) return;
206
+ const newRefCount = currentRefCount - 1;
207
+ registry.refCounts.set(className, newRefCount);
208
+ if (newRefCount === 0) {
209
+ if (registry.metrics) registry.metrics.totalUnused++;
210
+ this.sheetManager.checkCleanupNeeded(registry);
211
+ }
212
+ }
213
+ /**
214
+ * Force bulk cleanup of unused styles
215
+ */
216
+ cleanup(root) {
217
+ const registry = this.sheetManager.getRegistry(root || document);
218
+ this.sheetManager.forceCleanup(registry);
219
+ }
220
+ /**
221
+ * Get CSS text from all sheets (for SSR)
222
+ */
223
+ getCssText(options) {
224
+ const root = options?.root || document;
225
+ const registry = this.sheetManager.getRegistry(root);
226
+ return this.sheetManager.getCssText(registry);
227
+ }
228
+ /**
229
+ * Get CSS only for the provided tasty classNames (e.g., ["t0","t3"])
230
+ */
231
+ getCssTextForClasses(classNames, options) {
232
+ const root = options?.root || document;
233
+ const registry = this.sheetManager.getRegistry(root);
234
+ const cssChunks = [];
235
+ for (const cls of classNames) {
236
+ const info = registry.rules.get(cls);
237
+ if (info) {
238
+ const styleSheet = registry.sheets[info.sheetIndex]?.sheet?.sheet;
239
+ if (styleSheet) {
240
+ const start = Math.max(0, info.ruleIndex);
241
+ const end = Math.min(styleSheet.cssRules.length - 1, info.endRuleIndex ?? info.ruleIndex);
242
+ if (start >= 0 && end >= start && start < styleSheet.cssRules.length) for (let i = start; i <= end; i++) {
243
+ const rule = styleSheet.cssRules[i];
244
+ if (rule) cssChunks.push(rule.cssText);
245
+ }
246
+ } else if (info.cssText && info.cssText.length) cssChunks.push(...info.cssText);
247
+ }
248
+ }
249
+ return cssChunks.join("\n");
250
+ }
251
+ /**
252
+ * Get cache performance metrics
253
+ */
254
+ getMetrics(options) {
255
+ const root = options?.root || document;
256
+ const registry = this.sheetManager.getRegistry(root);
257
+ return this.sheetManager.getMetrics(registry);
258
+ }
259
+ /**
260
+ * Reset cache performance metrics
261
+ */
262
+ resetMetrics(options) {
263
+ const root = options?.root || document;
264
+ const registry = this.sheetManager.getRegistry(root);
265
+ this.sheetManager.resetMetrics(registry);
266
+ }
267
+ /**
268
+ * Define a CSS @property custom property.
269
+ *
270
+ * Accepts tasty token syntax for the property name:
271
+ * - `$name` → defines `--name`
272
+ * - `#name` → defines `--name-color` (auto-sets syntax: '<color>', defaults initialValue: 'transparent')
273
+ * - `--name` → defines `--name` (legacy format)
274
+ *
275
+ * Example:
276
+ * @property --rotation { syntax: "<angle>"; inherits: false; initial-value: 45deg; }
277
+ *
278
+ * Note: No caching or dispose — this defines a global property.
279
+ *
280
+ * If the same property is registered with different options, a warning is emitted
281
+ * but the original definition is preserved (CSS @property cannot be redefined).
282
+ */
283
+ property(name, options) {
284
+ const root = options?.root || document;
285
+ const registry = this.sheetManager.getRegistry(root);
286
+ const effectiveResult = getEffectiveDefinition(name, {
287
+ syntax: options?.syntax,
288
+ inherits: options?.inherits,
289
+ initialValue: options?.initialValue
290
+ });
291
+ if (!effectiveResult.isValid) {
292
+ if (isDevEnv()) console.warn(`[Tasty] property(): ${effectiveResult.error}. Got: "${name}"`);
293
+ return;
294
+ }
295
+ const cssName = effectiveResult.cssName;
296
+ const definition = effectiveResult.definition;
297
+ const normalizedDef = normalizePropertyDefinition(definition);
298
+ if (registry.injectedProperties.get(cssName) !== void 0) return;
299
+ const parts = [];
300
+ if (definition.syntax != null) {
301
+ let syntax = String(definition.syntax).trim();
302
+ if (!/^['"]/u.test(syntax)) syntax = `"${syntax}"`;
303
+ parts.push(`syntax: ${syntax};`);
304
+ }
305
+ const inherits = definition.inherits ?? true;
306
+ parts.push(`inherits: ${inherits ? "true" : "false"};`);
307
+ if (definition.initialValue != null) {
308
+ let initialValueStr;
309
+ if (typeof definition.initialValue === "number") initialValueStr = String(definition.initialValue);
310
+ else initialValueStr = parseStyle(definition.initialValue).output;
311
+ parts.push(`initial-value: ${initialValueStr};`);
312
+ }
313
+ const declarations = parts.join(" ").trim();
314
+ const rule = {
315
+ selector: `@property ${cssName}`,
316
+ declarations
317
+ };
318
+ if (!this.sheetManager.insertGlobalRule(registry, [rule], `property:${name}`, root)) return;
319
+ registry.injectedProperties.set(cssName, normalizedDef);
320
+ }
321
+ /**
322
+ * Check whether a given @property name was already injected by this injector.
323
+ *
324
+ * Accepts tasty token syntax:
325
+ * - `$name` → checks `--name`
326
+ * - `#name` → checks `--name-color`
327
+ * - `--name` → checks `--name` (legacy format)
328
+ */
329
+ isPropertyDefined(name, options) {
330
+ const root = options?.root || document;
331
+ const registry = this.sheetManager.getRegistry(root);
332
+ const effectiveResult = getEffectiveDefinition(name, {});
333
+ if (!effectiveResult.isValid) return false;
334
+ return registry.injectedProperties.has(effectiveResult.cssName);
335
+ }
336
+ /**
337
+ * Inject a CSS @font-face rule.
338
+ *
339
+ * Permanent and global — no dispose or ref-counting.
340
+ * Deduplicates by content hash (family + descriptors).
341
+ */
342
+ fontFace(family, descriptors, options) {
343
+ const root = options?.root || document;
344
+ const registry = this.sheetManager.getRegistry(root);
345
+ const hash = fontFaceContentHash(family, descriptors);
346
+ if (registry.injectedFontFaces.has(hash)) return;
347
+ const rule = {
348
+ selector: "@font-face",
349
+ declarations: formatFontFaceDeclarations(family, descriptors)
350
+ };
351
+ if (this.sheetManager.insertGlobalRule(registry, [rule], `fontface:${hash}`, root)) registry.injectedFontFaces.add(hash);
352
+ }
353
+ /**
354
+ * Inject a CSS @counter-style rule.
355
+ *
356
+ * Permanent and global — no dispose or ref-counting.
357
+ * Deduplicates by name (first definition wins).
358
+ */
359
+ counterStyle(name, descriptors, options) {
360
+ const root = options?.root || document;
361
+ const registry = this.sheetManager.getRegistry(root);
362
+ if (registry.injectedCounterStyles.has(name)) return;
363
+ const rule = {
364
+ selector: `@counter-style ${name}`,
365
+ declarations: formatCounterStyleDeclarations(descriptors)
366
+ };
367
+ if (this.sheetManager.insertGlobalRule(registry, [rule], `counterstyle:${name}`, root)) registry.injectedCounterStyles.add(name);
368
+ }
369
+ /**
370
+ * Inject keyframes and return object with toString() and dispose()
371
+ *
372
+ * Keyframes are cached by content (steps). If the same content is injected
373
+ * multiple times with different provided names, the first injected name is reused.
374
+ *
375
+ * If the same name is provided with different content (collision), a unique
376
+ * name is generated to avoid overwriting the existing keyframes.
377
+ */
378
+ keyframes(steps, nameOrOptions) {
379
+ const isStringName = typeof nameOrOptions === "string";
380
+ const providedName = isStringName ? nameOrOptions : nameOrOptions?.name;
381
+ const root = isStringName ? document : nameOrOptions?.root || document;
382
+ const registry = this.sheetManager.getRegistry(root);
383
+ if (Object.keys(steps).length === 0) return {
384
+ toString: () => "",
385
+ dispose: () => {}
386
+ };
387
+ const contentHash = JSON.stringify(steps);
388
+ const existing = registry.keyframesCache.get(contentHash);
389
+ if (existing) {
390
+ existing.refCount++;
391
+ return {
392
+ toString: () => existing.name,
393
+ dispose: () => this.disposeKeyframes(contentHash, registry)
394
+ };
395
+ }
396
+ let actualName;
397
+ if (providedName) {
398
+ const existingContentForName = registry.keyframesNameToContent.get(providedName);
399
+ if (existingContentForName && existingContentForName !== contentHash) actualName = `${providedName}-k${registry.keyframesCounter++}`;
400
+ else {
401
+ actualName = providedName;
402
+ registry.keyframesNameToContent.set(providedName, contentHash);
403
+ }
404
+ } else actualName = `k${registry.keyframesCounter++}`;
405
+ const result = this.sheetManager.insertKeyframes(registry, steps, actualName, root);
406
+ if (!result) return {
407
+ toString: () => "",
408
+ dispose: () => {}
409
+ };
410
+ const { info, declarations } = result;
411
+ if (this.config.autoPropertyTypes !== false && declarations) registry.propertyTypeResolver.scanDeclarations(declarations, (name) => registry.injectedProperties.has(name), (name, syntax, initialValue) => {
412
+ this.property(name, {
413
+ syntax,
414
+ inherits: true,
415
+ initialValue,
416
+ root
417
+ });
418
+ });
419
+ registry.keyframesCache.set(contentHash, {
420
+ name: actualName,
421
+ refCount: 1,
422
+ info
423
+ });
424
+ if (registry.metrics) {
425
+ registry.metrics.totalInsertions++;
426
+ registry.metrics.misses++;
427
+ }
428
+ return {
429
+ toString: () => actualName,
430
+ dispose: () => this.disposeKeyframes(contentHash, registry)
431
+ };
432
+ }
433
+ /**
434
+ * Dispose keyframes
435
+ */
436
+ disposeKeyframes(contentHash, registry) {
437
+ const entry = registry.keyframesCache.get(contentHash);
438
+ if (!entry) return;
439
+ entry.refCount--;
440
+ if (entry.refCount <= 0) {
441
+ this.sheetManager.deleteKeyframes(registry, entry.info);
442
+ registry.keyframesCache.delete(contentHash);
443
+ for (const [name, hash] of registry.keyframesNameToContent.entries()) if (hash === contentHash) {
444
+ registry.keyframesNameToContent.delete(name);
445
+ break;
446
+ }
447
+ if (registry.metrics) {
448
+ registry.metrics.totalUnused++;
449
+ registry.metrics.stylesCleanedUp++;
450
+ }
451
+ }
452
+ }
453
+ /**
454
+ * Destroy all resources for a root
455
+ */
456
+ destroy(root) {
457
+ const targetRoot = root || document;
458
+ this.sheetManager.cleanup(targetRoot);
459
+ }
460
+ };
461
+ //#endregion
462
+ export { StyleInjector };
463
+
464
+ //# sourceMappingURL=injector.js.map