@tenphi/tasty 0.0.0-snapshot.c8bdaeb → 0.0.0-snapshot.c8c7b2a

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 (318) hide show
  1. package/README.md +309 -159
  2. package/dist/_virtual/_rolldown/runtime.js +1 -2
  3. package/dist/chunks/cacheKey.d.ts +1 -0
  4. package/dist/chunks/cacheKey.js +17 -10
  5. package/dist/chunks/cacheKey.js.map +1 -1
  6. package/dist/chunks/definitions.d.ts +1 -1
  7. package/dist/chunks/definitions.js +3 -5
  8. package/dist/chunks/definitions.js.map +1 -1
  9. package/dist/chunks/index.d.ts +1 -0
  10. package/dist/chunks/renderChunk.d.ts +1 -0
  11. package/dist/chunks/renderChunk.js +32 -34
  12. package/dist/chunks/renderChunk.js.map +1 -1
  13. package/dist/compute-styles.d.ts +31 -0
  14. package/dist/compute-styles.js +322 -0
  15. package/dist/compute-styles.js.map +1 -0
  16. package/dist/config.d.ts +157 -30
  17. package/dist/config.js +233 -45
  18. package/dist/config.js.map +1 -1
  19. package/dist/core/index.d.ts +12 -11
  20. package/dist/core/index.js +12 -11
  21. package/dist/counter-style/index.js +51 -0
  22. package/dist/counter-style/index.js.map +1 -0
  23. package/dist/debug.d.ts +26 -141
  24. package/dist/debug.js +359 -639
  25. package/dist/debug.js.map +1 -1
  26. package/dist/font-face/index.js +63 -0
  27. package/dist/font-face/index.js.map +1 -0
  28. package/dist/hooks/index.d.ts +7 -0
  29. package/dist/hooks/useCounterStyle.d.ts +36 -0
  30. package/dist/hooks/useCounterStyle.js +65 -0
  31. package/dist/hooks/useCounterStyle.js.map +1 -0
  32. package/dist/hooks/useFontFace.d.ts +45 -0
  33. package/dist/hooks/useFontFace.js +66 -0
  34. package/dist/hooks/useFontFace.js.map +1 -0
  35. package/dist/hooks/useGlobalStyles.d.ts +21 -2
  36. package/dist/hooks/useGlobalStyles.js +60 -28
  37. package/dist/hooks/useGlobalStyles.js.map +1 -1
  38. package/dist/hooks/useKeyframes.d.ts +4 -2
  39. package/dist/hooks/useKeyframes.js +44 -43
  40. package/dist/hooks/useKeyframes.js.map +1 -1
  41. package/dist/hooks/useProperty.d.ts +4 -2
  42. package/dist/hooks/useProperty.js +36 -31
  43. package/dist/hooks/useProperty.js.map +1 -1
  44. package/dist/hooks/useRawCSS.d.ts +13 -44
  45. package/dist/hooks/useRawCSS.js +91 -16
  46. package/dist/hooks/useRawCSS.js.map +1 -1
  47. package/dist/hooks/useStyles.d.ts +3 -3
  48. package/dist/hooks/useStyles.js +8 -146
  49. package/dist/hooks/useStyles.js.map +1 -1
  50. package/dist/index.d.ts +15 -12
  51. package/dist/index.js +15 -12
  52. package/dist/injector/index.d.ts +36 -11
  53. package/dist/injector/index.js +43 -12
  54. package/dist/injector/index.js.map +1 -1
  55. package/dist/injector/injector.d.ts +62 -3
  56. package/dist/injector/injector.js +293 -46
  57. package/dist/injector/injector.js.map +1 -1
  58. package/dist/injector/sheet-manager.d.ts +22 -17
  59. package/dist/injector/sheet-manager.js +64 -79
  60. package/dist/injector/sheet-manager.js.map +1 -1
  61. package/dist/injector/types.d.ts +121 -21
  62. package/dist/keyframes/index.js +1 -1
  63. package/dist/parser/classify.js +6 -6
  64. package/dist/parser/classify.js.map +1 -1
  65. package/dist/parser/const.js +30 -3
  66. package/dist/parser/const.js.map +1 -1
  67. package/dist/parser/lru.js +1 -1
  68. package/dist/parser/lru.js.map +1 -1
  69. package/dist/parser/parser.js +2 -3
  70. package/dist/parser/parser.js.map +1 -1
  71. package/dist/parser/tokenizer.js +1 -1
  72. package/dist/parser/tokenizer.js.map +1 -1
  73. package/dist/parser/types.js +1 -1
  74. package/dist/parser/types.js.map +1 -1
  75. package/dist/pipeline/conditions.js +1 -1
  76. package/dist/pipeline/conditions.js.map +1 -1
  77. package/dist/pipeline/exclusive.js +58 -4
  78. package/dist/pipeline/exclusive.js.map +1 -1
  79. package/dist/pipeline/index.d.ts +3 -1
  80. package/dist/pipeline/index.js +82 -34
  81. package/dist/pipeline/index.js.map +1 -1
  82. package/dist/pipeline/materialize.js +436 -123
  83. package/dist/pipeline/materialize.js.map +1 -1
  84. package/dist/pipeline/parseStateKey.d.ts +1 -1
  85. package/dist/pipeline/parseStateKey.js +21 -13
  86. package/dist/pipeline/parseStateKey.js.map +1 -1
  87. package/dist/pipeline/simplify.js +181 -7
  88. package/dist/pipeline/simplify.js.map +1 -1
  89. package/dist/pipeline/warnings.js +1 -1
  90. package/dist/plugins/index.d.ts +2 -0
  91. package/dist/plugins/okhsl-plugin.js +3 -277
  92. package/dist/plugins/okhsl-plugin.js.map +1 -1
  93. package/dist/plugins/types.d.ts +20 -2
  94. package/dist/properties/index.js +83 -19
  95. package/dist/properties/index.js.map +1 -1
  96. package/dist/properties/property-type-resolver.d.ts +24 -0
  97. package/dist/properties/property-type-resolver.js +90 -0
  98. package/dist/properties/property-type-resolver.js.map +1 -0
  99. package/dist/rsc-cache.js +79 -0
  100. package/dist/rsc-cache.js.map +1 -0
  101. package/dist/ssr/astro-client.d.ts +1 -0
  102. package/dist/ssr/astro-client.js +19 -0
  103. package/dist/ssr/astro-client.js.map +1 -0
  104. package/dist/ssr/astro-middleware.d.ts +15 -0
  105. package/dist/ssr/astro-middleware.js +19 -0
  106. package/dist/ssr/astro-middleware.js.map +1 -0
  107. package/dist/ssr/astro.d.ts +108 -0
  108. package/dist/ssr/astro.js +149 -0
  109. package/dist/ssr/astro.js.map +1 -0
  110. package/dist/ssr/async-storage.d.ts +17 -0
  111. package/dist/ssr/async-storage.js +44 -0
  112. package/dist/ssr/async-storage.js.map +1 -0
  113. package/dist/ssr/collect-auto-properties.js +58 -0
  114. package/dist/ssr/collect-auto-properties.js.map +1 -0
  115. package/dist/ssr/collector.d.ts +98 -0
  116. package/dist/ssr/collector.js +235 -0
  117. package/dist/ssr/collector.js.map +1 -0
  118. package/dist/ssr/context.js +16 -0
  119. package/dist/ssr/context.js.map +1 -0
  120. package/dist/ssr/format-global-rules.js +22 -0
  121. package/dist/ssr/format-global-rules.js.map +1 -0
  122. package/dist/ssr/format-keyframes.js +69 -0
  123. package/dist/ssr/format-keyframes.js.map +1 -0
  124. package/dist/ssr/format-property.js +49 -0
  125. package/dist/ssr/format-property.js.map +1 -0
  126. package/dist/ssr/format-rules.js +73 -0
  127. package/dist/ssr/format-rules.js.map +1 -0
  128. package/dist/ssr/hydrate.d.ts +29 -0
  129. package/dist/ssr/hydrate.js +45 -0
  130. package/dist/ssr/hydrate.js.map +1 -0
  131. package/dist/ssr/index.d.ts +4 -0
  132. package/dist/ssr/index.js +10 -0
  133. package/dist/ssr/index.js.map +1 -0
  134. package/dist/ssr/next.d.ts +46 -0
  135. package/dist/ssr/next.js +75 -0
  136. package/dist/ssr/next.js.map +1 -0
  137. package/dist/ssr/ssr-collector-ref.js +29 -0
  138. package/dist/ssr/ssr-collector-ref.js.map +1 -0
  139. package/dist/states/index.js +13 -259
  140. package/dist/states/index.js.map +1 -1
  141. package/dist/static/index.js +1 -2
  142. package/dist/static/inject.d.ts +5 -0
  143. package/dist/static/inject.js +17 -0
  144. package/dist/static/inject.js.map +1 -0
  145. package/dist/static/tastyStatic.js +1 -2
  146. package/dist/static/tastyStatic.js.map +1 -1
  147. package/dist/static/types.js +1 -1
  148. package/dist/styles/border.d.ts +1 -1
  149. package/dist/styles/border.js +30 -24
  150. package/dist/styles/border.js.map +1 -1
  151. package/dist/styles/color.d.ts +1 -1
  152. package/dist/styles/color.js +11 -8
  153. package/dist/styles/color.js.map +1 -1
  154. package/dist/styles/const.js +17 -0
  155. package/dist/styles/const.js.map +1 -0
  156. package/dist/styles/createStyle.js +28 -26
  157. package/dist/styles/createStyle.js.map +1 -1
  158. package/dist/styles/dimension.js +15 -3
  159. package/dist/styles/dimension.js.map +1 -1
  160. package/dist/styles/directional.js +133 -0
  161. package/dist/styles/directional.js.map +1 -0
  162. package/dist/styles/display.d.ts +3 -10
  163. package/dist/styles/display.js +45 -39
  164. package/dist/styles/display.js.map +1 -1
  165. package/dist/styles/fade.d.ts +1 -1
  166. package/dist/styles/fade.js +9 -5
  167. package/dist/styles/fade.js.map +1 -1
  168. package/dist/styles/fill.d.ts +2 -2
  169. package/dist/styles/fill.js +9 -9
  170. package/dist/styles/fill.js.map +1 -1
  171. package/dist/styles/flow.js +1 -1
  172. package/dist/styles/gap.d.ts +1 -1
  173. package/dist/styles/gap.js +4 -3
  174. package/dist/styles/gap.js.map +1 -1
  175. package/dist/styles/height.d.ts +1 -1
  176. package/dist/styles/height.js +1 -2
  177. package/dist/styles/height.js.map +1 -1
  178. package/dist/styles/index.d.ts +0 -1
  179. package/dist/styles/index.js +3 -4
  180. package/dist/styles/index.js.map +1 -1
  181. package/dist/styles/inset.d.ts +1 -29
  182. package/dist/styles/inset.js +19 -135
  183. package/dist/styles/inset.js.map +1 -1
  184. package/dist/styles/list.d.ts +5 -5
  185. package/dist/styles/list.js +4 -2
  186. package/dist/styles/list.js.map +1 -1
  187. package/dist/styles/margin.d.ts +1 -1
  188. package/dist/styles/margin.js +17 -89
  189. package/dist/styles/margin.js.map +1 -1
  190. package/dist/styles/outline.d.ts +1 -1
  191. package/dist/styles/outline.js +6 -16
  192. package/dist/styles/outline.js.map +1 -1
  193. package/dist/styles/padding.d.ts +1 -1
  194. package/dist/styles/padding.js +17 -89
  195. package/dist/styles/padding.js.map +1 -1
  196. package/dist/styles/placement.d.ts +37 -0
  197. package/dist/styles/placement.js +74 -0
  198. package/dist/styles/placement.js.map +1 -0
  199. package/dist/styles/predefined.d.ts +4 -6
  200. package/dist/styles/predefined.js +9 -13
  201. package/dist/styles/predefined.js.map +1 -1
  202. package/dist/styles/preset.d.ts +6 -1
  203. package/dist/styles/preset.js +54 -53
  204. package/dist/styles/preset.js.map +1 -1
  205. package/dist/styles/radius.d.ts +1 -3
  206. package/dist/styles/radius.js +38 -6
  207. package/dist/styles/radius.js.map +1 -1
  208. package/dist/styles/scrollMargin.d.ts +24 -0
  209. package/dist/styles/scrollMargin.js +32 -0
  210. package/dist/styles/scrollMargin.js.map +1 -0
  211. package/dist/styles/scrollbar.d.ts +9 -5
  212. package/dist/styles/scrollbar.js +31 -92
  213. package/dist/styles/scrollbar.js.map +1 -1
  214. package/dist/styles/shadow.d.ts +1 -1
  215. package/dist/styles/shadow.js +4 -3
  216. package/dist/styles/shadow.js.map +1 -1
  217. package/dist/styles/shared.js +17 -0
  218. package/dist/styles/shared.js.map +1 -0
  219. package/dist/styles/transition.d.ts +1 -1
  220. package/dist/styles/transition.js +6 -5
  221. package/dist/styles/transition.js.map +1 -1
  222. package/dist/styles/types.d.ts +94 -28
  223. package/dist/styles/width.d.ts +1 -1
  224. package/dist/styles/width.js +1 -2
  225. package/dist/styles/width.js.map +1 -1
  226. package/dist/tasty.d.ts +46 -894
  227. package/dist/tasty.js +101 -59
  228. package/dist/tasty.js.map +1 -1
  229. package/dist/types.d.ts +1 -1
  230. package/dist/utils/cache-wrapper.js +4 -9
  231. package/dist/utils/cache-wrapper.js.map +1 -1
  232. package/dist/utils/case-converter.js +1 -1
  233. package/dist/utils/color-math.d.ts +46 -0
  234. package/dist/utils/color-math.js +749 -0
  235. package/dist/utils/color-math.js.map +1 -0
  236. package/dist/utils/color-space.d.ts +5 -0
  237. package/dist/utils/color-space.js +228 -0
  238. package/dist/utils/color-space.js.map +1 -0
  239. package/dist/utils/colors.js +3 -2
  240. package/dist/utils/colors.js.map +1 -1
  241. package/dist/utils/deps-equal.js +15 -0
  242. package/dist/utils/deps-equal.js.map +1 -0
  243. package/dist/utils/dotize.js +1 -1
  244. package/dist/utils/dotize.js.map +1 -1
  245. package/dist/utils/filter-base-props.d.ts +1 -1
  246. package/dist/utils/filter-base-props.js +1 -1
  247. package/dist/utils/filter-base-props.js.map +1 -1
  248. package/dist/utils/get-display-name.js +1 -1
  249. package/dist/utils/has-keys.js +13 -0
  250. package/dist/utils/has-keys.js.map +1 -0
  251. package/dist/utils/hash.js +14 -0
  252. package/dist/utils/hash.js.map +1 -0
  253. package/dist/utils/is-dev-env.js +1 -1
  254. package/dist/utils/is-dev-env.js.map +1 -1
  255. package/dist/utils/is-valid-element-type.js +1 -1
  256. package/dist/utils/merge-styles.js +1 -2
  257. package/dist/utils/merge-styles.js.map +1 -1
  258. package/dist/utils/mod-attrs.d.ts +0 -2
  259. package/dist/utils/mod-attrs.js +3 -4
  260. package/dist/utils/mod-attrs.js.map +1 -1
  261. package/dist/utils/process-tokens.d.ts +3 -17
  262. package/dist/utils/process-tokens.js +19 -107
  263. package/dist/utils/process-tokens.js.map +1 -1
  264. package/dist/utils/resolve-recipes.js +1 -2
  265. package/dist/utils/resolve-recipes.js.map +1 -1
  266. package/dist/utils/selector-transform.js +32 -0
  267. package/dist/utils/selector-transform.js.map +1 -0
  268. package/dist/utils/string.js +1 -1
  269. package/dist/utils/styles.d.ts +3 -82
  270. package/dist/utils/styles.js +29 -399
  271. package/dist/utils/styles.js.map +1 -1
  272. package/dist/utils/typography.d.ts +35 -13
  273. package/dist/utils/typography.js +16 -18
  274. package/dist/utils/typography.js.map +1 -1
  275. package/dist/utils/warnings.js +1 -1
  276. package/dist/zero/babel.d.ts +57 -84
  277. package/dist/zero/babel.js +217 -37
  278. package/dist/zero/babel.js.map +1 -1
  279. package/dist/zero/css-writer.js +1 -2
  280. package/dist/zero/css-writer.js.map +1 -1
  281. package/dist/zero/extractor.js +119 -3
  282. package/dist/zero/extractor.js.map +1 -1
  283. package/dist/zero/index.js +1 -2
  284. package/dist/zero/next.d.ts +56 -30
  285. package/dist/zero/next.js +105 -40
  286. package/dist/zero/next.js.map +1 -1
  287. package/docs/README.md +31 -0
  288. package/docs/adoption.md +298 -0
  289. package/docs/comparison.md +419 -0
  290. package/docs/configuration.md +394 -0
  291. package/docs/debug.md +320 -0
  292. package/docs/design-system.md +436 -0
  293. package/docs/dsl.md +688 -0
  294. package/docs/getting-started.md +217 -0
  295. package/docs/injector.md +544 -0
  296. package/docs/methodology.md +616 -0
  297. package/docs/pipeline.md +519 -0
  298. package/docs/react-api.md +557 -0
  299. package/docs/ssr.md +442 -0
  300. package/docs/styles.md +596 -0
  301. package/docs/tasty-static.md +532 -0
  302. package/package.json +68 -36
  303. package/dist/styles/align.d.ts +0 -15
  304. package/dist/styles/align.js +0 -14
  305. package/dist/styles/align.js.map +0 -1
  306. package/dist/styles/justify.d.ts +0 -15
  307. package/dist/styles/justify.js +0 -14
  308. package/dist/styles/justify.js.map +0 -1
  309. package/dist/styles/styledScrollbar.d.ts +0 -47
  310. package/dist/styles/styledScrollbar.js +0 -38
  311. package/dist/styles/styledScrollbar.js.map +0 -1
  312. package/dist/tokens/typography.d.ts +0 -19
  313. package/dist/tokens/typography.js +0 -237
  314. package/dist/tokens/typography.js.map +0 -1
  315. package/dist/utils/hsl-to-rgb.js +0 -38
  316. package/dist/utils/hsl-to-rgb.js.map +0 -1
  317. package/dist/utils/okhsl-to-rgb.js +0 -296
  318. package/dist/utils/okhsl-to-rgb.js.map +0 -1
package/dist/debug.js CHANGED
@@ -1,733 +1,453 @@
1
1
  import { isDevEnv } from "./utils/is-dev-env.js";
2
2
  import { CHUNK_NAMES } from "./chunks/definitions.js";
3
3
  import { getCssTextForNode, injector } from "./injector/index.js";
4
-
5
4
  //#region src/debug.ts
6
- /**
7
- * Debug utilities for inspecting tasty-generated CSS at runtime
8
- */
9
- /**
10
- * Pretty-print CSS with proper indentation and formatting
11
- */
12
- function prettifyCSS(css) {
13
- if (!css || css.trim() === "") return "";
14
- let formatted = css.replace(/\s+/g, " ").trim();
15
- formatted = formatted.replace(/\s*\{\s*/g, " {\n");
16
- formatted = formatted.replace(/;(?![^"']*["'][^"']*$)(?![^()]*\))/g, ";\n");
17
- formatted = formatted.replace(/\s*\}\s*/g, "\n}\n");
18
- formatted = formatted.replace(/,(?![^"']*["'][^"']*$)(?![^()]*\))(?=.*:.*\{|.*\{)/g, ",\n");
19
- const lines = formatted.split("\n");
20
- let indentLevel = 0;
21
- const indentSize = 2;
22
- let result = lines.map((line) => {
23
- const trimmed = line.trim();
24
- if (!trimmed) return "";
25
- if (trimmed === "}") {
26
- indentLevel = Math.max(0, indentLevel - 1);
27
- return " ".repeat(indentLevel * indentSize) + trimmed;
28
- }
29
- const result = " ".repeat(indentLevel * indentSize) + trimmed;
30
- if (trimmed.endsWith("{")) indentLevel++;
31
- return result;
32
- }).filter((line) => line.trim()).join("\n").replace(/\n{3,}/g, "\n\n").trim();
33
- result = result.replace(/,\s+/g, ", ");
34
- return result;
5
+ function fmtSize(bytes) {
6
+ return bytes > 1024 ? `${(bytes / 1024).toFixed(1)}KB` : `${bytes}B`;
35
7
  }
36
- function findAllTastyClasses(root = document) {
37
- const classes = /* @__PURE__ */ new Set();
38
- (root.querySelectorAll?.("[class]") || []).forEach((element) => {
39
- const classList = element.getAttribute("class");
40
- if (classList) classList.split(/\s+/).filter((cls) => /^t\d+$/.test(cls)).forEach((cls) => classes.add(cls));
41
- });
42
- return Array.from(classes).sort((a, b) => {
43
- return parseInt(a.slice(1)) - parseInt(b.slice(1));
44
- });
8
+ function countRules(css) {
9
+ return (css.match(/\{[^}]*\}/g) || []).length;
45
10
  }
46
- function findAllStyledClasses(root = document) {
47
- const allCSS = injector.instance.getCssText({ root });
48
- const classes = /* @__PURE__ */ new Set();
49
- const classRegex = /\.t(\d+)/g;
50
- let match;
51
- while ((match = classRegex.exec(allCSS)) !== null) classes.add(`t${match[1]}`);
52
- return Array.from(classes).sort((a, b) => {
53
- return parseInt(a.slice(1)) - parseInt(b.slice(1));
54
- });
11
+ function sortTastyClasses(classes) {
12
+ return Array.from(classes).sort((a, b) => a.localeCompare(b));
55
13
  }
56
- function extractCSSRules(css) {
57
- const rules = [];
58
- const cleanCSS = css.replace(/\/\*[\s\S]*?\*\//g, "");
59
- let i = 0;
60
- while (i < cleanCSS.length) {
61
- while (i < cleanCSS.length && /\s/.test(cleanCSS[i])) i++;
62
- if (i >= cleanCSS.length) break;
63
- const selectorStart = i;
64
- let braceDepth = 0;
65
- let inString = false;
66
- let stringChar = "";
67
- while (i < cleanCSS.length) {
68
- const char = cleanCSS[i];
69
- if (inString) {
70
- if (char === stringChar && cleanCSS[i - 1] !== "\\") inString = false;
71
- } else if (char === "\"" || char === "'") {
72
- inString = true;
73
- stringChar = char;
74
- } else if (char === "{") {
75
- braceDepth++;
76
- if (braceDepth === 1) break;
77
- }
78
- i++;
79
- }
80
- if (i >= cleanCSS.length) break;
81
- const selector = cleanCSS.substring(selectorStart, i).trim();
82
- i++;
83
- const contentStart = i;
84
- braceDepth = 1;
85
- inString = false;
86
- while (i < cleanCSS.length && braceDepth > 0) {
87
- const char = cleanCSS[i];
88
- if (inString) {
89
- if (char === stringChar && cleanCSS[i - 1] !== "\\") inString = false;
90
- } else if (char === "\"" || char === "'") {
91
- inString = true;
92
- stringChar = char;
93
- } else if (char === "{") braceDepth++;
94
- else if (char === "}") braceDepth--;
95
- i++;
96
- }
97
- const content = cleanCSS.substring(contentStart, i - 1).trim();
98
- if (content && selector) rules.push({
99
- selector,
100
- declarations: content
101
- });
102
- }
103
- return rules;
14
+ function getRegistry(root = document) {
15
+ return injector.instance._sheetManager?.getRegistry(root);
104
16
  }
105
- function getGlobalCSS(root = document) {
106
- return prettifyCSS(extractCSSRules(injector.instance.getCssText({ root })).filter((rule) => {
107
- return !rule.selector.split(",").map((s) => s.trim()).every((selector) => {
108
- const parts = selector.replace(/[.#:\s>+~[\]()]/g, " ").split(/\s+/).filter(Boolean);
109
- return parts.length > 0 && parts.every((part) => /^t\d+$/.test(part));
110
- });
111
- }).map((rule) => `${rule.selector} { ${rule.declarations} }`).join("\n"));
17
+ function getUnusedClasses(root = document) {
18
+ const registry = getRegistry(root);
19
+ if (!registry) return [];
20
+ const result = [];
21
+ for (const [cls, rc] of registry.refCounts) if (rc === 0) result.push(cls);
22
+ return sortTastyClasses(result);
112
23
  }
113
- function getPageCSS(options) {
114
- const root = options?.root || document;
115
- const includeCrossOrigin = options?.includeCrossOrigin ?? false;
116
- const cssChunks = [];
117
- try {
118
- if ("styleSheets" in root) {
119
- const styleSheets = Array.from(root.styleSheets);
120
- for (const sheet of styleSheets) try {
121
- if (sheet.cssRules) {
122
- const rules = Array.from(sheet.cssRules);
123
- cssChunks.push(rules.map((rule) => rule.cssText).join("\n"));
124
- }
125
- } catch {
126
- if (includeCrossOrigin) cssChunks.push(`/* Cross-origin stylesheet: ${sheet.href || "inline"} */`);
127
- }
24
+ function findDomTastyClasses(root = document) {
25
+ const classes = /* @__PURE__ */ new Set();
26
+ (root.querySelectorAll?.("[class]") || []).forEach((el) => {
27
+ const attr = el.getAttribute("class");
28
+ if (attr) {
29
+ for (const cls of attr.split(/\s+/)) if (/^t[a-z0-9]+$/.test(cls)) classes.add(cls);
128
30
  }
129
- } catch {}
130
- return cssChunks.join("\n");
31
+ });
32
+ return sortTastyClasses(classes);
131
33
  }
132
- function getPageStats(options) {
133
- const root = options?.root || document;
134
- options?.includeCrossOrigin;
135
- let cssSize = 0;
136
- let ruleCount = 0;
137
- let stylesheetCount = 0;
138
- let skippedStylesheets = 0;
139
- try {
140
- if ("styleSheets" in root) {
141
- const styleSheets = Array.from(root.styleSheets);
142
- stylesheetCount = styleSheets.length;
143
- for (const sheet of styleSheets) try {
144
- if (sheet.cssRules) {
145
- const rules = Array.from(sheet.cssRules);
146
- ruleCount += rules.length;
147
- cssSize += rules.reduce((sum, rule) => sum + rule.cssText.length, 0);
148
- }
149
- } catch {
150
- skippedStylesheets++;
151
- }
34
+ function prettifyCSS(css) {
35
+ if (!css || !css.trim()) return "";
36
+ const out = [];
37
+ let depth = 0;
38
+ const indent = () => " ".repeat(depth);
39
+ let normalized = css.replace(/\s+/g, " ").trim();
40
+ normalized = normalized.replace(/\s*\{\s*/g, " { ");
41
+ normalized = normalized.replace(/\s*\}\s*/g, " } ");
42
+ normalized = normalized.replace(/;\s*/g, "; ");
43
+ const tokens = normalized.split(/\s+/);
44
+ let buf = "";
45
+ for (const t of tokens) if (t === "{") {
46
+ const header = buf.trim();
47
+ if (header) {
48
+ const parts = splitOutsideParens(header, ",");
49
+ if (parts.length > 1) out.push(parts.map((p, idx) => idx === 0 ? `${indent()}${p.trim()},` : `${indent()}${p.trim()}${idx < parts.length - 1 ? "," : ""}`).join("\n") + " {");
50
+ else out.push(`${indent()}${header} {`);
51
+ } else out.push(`${indent()}{`);
52
+ depth++;
53
+ buf = "";
54
+ } else if (t === "}") {
55
+ if (buf.trim()) {
56
+ for (const decl of buf.split(";").filter((s) => s.trim())) out.push(`${indent()}${decl.trim()};`);
57
+ buf = "";
152
58
  }
153
- } catch {}
154
- return {
155
- cssSize,
156
- ruleCount,
157
- stylesheetCount,
158
- skippedStylesheets
159
- };
59
+ depth = Math.max(0, depth - 1);
60
+ out.push(`${indent()}}`);
61
+ } else if (t.endsWith(";")) {
62
+ buf += ` ${t}`;
63
+ const full = buf.trim();
64
+ if (full) out.push(`${indent()}${full}`);
65
+ buf = "";
66
+ } else buf += ` ${t}`;
67
+ if (buf.trim()) out.push(buf.trim());
68
+ return out.filter((l) => l.trim()).join("\n").replace(/\n{3,}/g, "\n\n").trim();
160
69
  }
161
- /**
162
- * Extract chunk name from a cache key.
163
- *
164
- * Cache keys have the format: "chunkName\0key:value\0key:value..."
165
- * or "[states:...]\0chunkName\0..." for predefined states.
166
- *
167
- * @param cacheKey - The cache key to parse
168
- * @returns The chunk name, or null if not found
169
- */
170
- function extractChunkNameFromCacheKey(cacheKey) {
171
- const parts = cacheKey.split("\0");
172
- for (const part of parts) {
70
+ /** Split `str` by `sep` only when not inside parentheses */
71
+ function splitOutsideParens(str, sep) {
72
+ const parts = [];
73
+ let depth = 0;
74
+ let start = 0;
75
+ for (let i = 0; i < str.length; i++) {
76
+ const ch = str[i];
77
+ if (ch === "(") depth++;
78
+ else if (ch === ")") depth--;
79
+ else if (depth === 0 && str.startsWith(sep, i)) {
80
+ parts.push(str.slice(start, i));
81
+ start = i + sep.length;
82
+ }
83
+ }
84
+ parts.push(str.slice(start));
85
+ return parts;
86
+ }
87
+ function extractChunkName(cacheKey) {
88
+ for (const part of cacheKey.split("\0")) {
173
89
  if (part.startsWith("[states:")) continue;
174
90
  if (!part.includes(":") && part.length > 0) return part;
175
91
  }
176
92
  return null;
177
93
  }
178
- /**
179
- * Get chunk info for a className by reverse-looking up its cache key.
180
- *
181
- * @param className - The tasty class name (e.g., "t0", "t123")
182
- * @param root - The document or shadow root to search in
183
- * @returns Object with chunk name and cache key, or nulls if not found
184
- */
185
- function getChunkForClassName(className, root = document) {
186
- const registry = injector.instance._sheetManager?.getRegistry(root);
187
- if (!registry) return {
188
- chunkName: null,
189
- cacheKey: null
190
- };
191
- for (const [cacheKey, cn] of registry.cacheKeyToClassName) if (cn === className) return {
192
- chunkName: extractChunkNameFromCacheKey(cacheKey),
193
- cacheKey
194
- };
195
- return {
196
- chunkName: null,
197
- cacheKey: null
198
- };
94
+ function getChunkForClass(className, root = document) {
95
+ const registry = getRegistry(root);
96
+ if (!registry) return null;
97
+ for (const [key, cn] of registry.cacheKeyToClassName) if (cn === className) return extractChunkName(key);
98
+ return null;
199
99
  }
200
- /**
201
- * Get chunk breakdown statistics for all styles.
202
- *
203
- * @param root - The document or shadow root to search in
204
- * @returns Object with breakdown by chunk type and totals
205
- */
206
- function getChunkBreakdown(root = document) {
207
- const registry = injector.instance._sheetManager?.getRegistry(root);
100
+ function buildChunkBreakdown(root = document) {
101
+ const registry = getRegistry(root);
208
102
  if (!registry) return {
209
103
  byChunk: {},
210
- totalChunkTypes: 0
104
+ totalChunkTypes: 0,
105
+ totalClasses: 0
211
106
  };
212
107
  const byChunk = {};
213
108
  for (const [cacheKey, className] of registry.cacheKeyToClassName) {
214
- const chunkName = extractChunkNameFromCacheKey(cacheKey) || "unknown";
215
- if (!byChunk[chunkName]) byChunk[chunkName] = {
109
+ const chunk = extractChunkName(cacheKey) || "unknown";
110
+ if (!byChunk[chunk]) byChunk[chunk] = {
216
111
  classes: [],
217
112
  cssSize: 0,
218
113
  ruleCount: 0
219
114
  };
220
- byChunk[chunkName].classes.push(className);
115
+ byChunk[chunk].classes.push(className);
221
116
  const css = injector.instance.getCssTextForClasses([className], { root });
222
- byChunk[chunkName].cssSize += css.length;
223
- byChunk[chunkName].ruleCount += (css.match(/\{[^}]*\}/g) || []).length;
117
+ byChunk[chunk].cssSize += css.length;
118
+ byChunk[chunk].ruleCount += countRules(css);
224
119
  }
225
- for (const entry of Object.values(byChunk)) entry.classes.sort((a, b) => {
226
- return parseInt(a.slice(1)) - parseInt(b.slice(1));
227
- });
120
+ for (const entry of Object.values(byChunk)) entry.classes = sortTastyClasses(entry.classes);
121
+ const totalClasses = Object.values(byChunk).reduce((s, e) => s + e.classes.length, 0);
228
122
  return {
229
123
  byChunk,
230
- totalChunkTypes: Object.keys(byChunk).length
124
+ totalChunkTypes: Object.keys(byChunk).length,
125
+ totalClasses
231
126
  };
232
127
  }
233
- /**
234
- * Concise tastyDebug API for inspecting styles at runtime
235
- */
128
+ function getGlobalTypeCSS(type, root = document) {
129
+ const registry = getRegistry(root);
130
+ if (!registry) return {
131
+ css: "",
132
+ ruleCount: 0,
133
+ size: 0
134
+ };
135
+ const chunks = [];
136
+ let rc = 0;
137
+ if (type === "keyframes") for (const [, entry] of registry.keyframesCache) {
138
+ const info = entry.info;
139
+ const ss = registry.sheets[info.sheetIndex]?.sheet?.sheet;
140
+ if (ss && info.ruleIndex < ss.cssRules.length) {
141
+ const rule = ss.cssRules[info.ruleIndex];
142
+ if (rule) {
143
+ chunks.push(rule.cssText);
144
+ rc++;
145
+ }
146
+ } else if (info.cssText) {
147
+ chunks.push(info.cssText);
148
+ rc++;
149
+ }
150
+ }
151
+ else {
152
+ const prefix = type === "global" ? "global:" : type === "raw" ? "raw:" : "property:";
153
+ for (const [key, ri] of registry.globalRules) {
154
+ if (!key.startsWith(prefix)) continue;
155
+ const ss = registry.sheets[ri.sheetIndex]?.sheet?.sheet;
156
+ if (ss) {
157
+ const start = Math.max(0, ri.ruleIndex);
158
+ const end = Math.min(ss.cssRules.length - 1, ri.endRuleIndex ?? ri.ruleIndex);
159
+ if (start >= 0 && end >= start && start < ss.cssRules.length) for (let i = start; i <= end; i++) {
160
+ const rule = ss.cssRules[i];
161
+ if (rule) {
162
+ chunks.push(rule.cssText);
163
+ rc++;
164
+ }
165
+ }
166
+ } else if (ri.cssText?.length) {
167
+ chunks.push(...ri.cssText);
168
+ rc += ri.cssText.length;
169
+ }
170
+ }
171
+ }
172
+ const raw = chunks.join("\n");
173
+ return {
174
+ css: prettifyCSS(raw),
175
+ ruleCount: rc,
176
+ size: raw.length
177
+ };
178
+ }
179
+ function getSourceCssForClasses(classNames, root = document) {
180
+ const registry = getRegistry(root);
181
+ if (!registry) return null;
182
+ const chunks = [];
183
+ let found = false;
184
+ for (const cls of classNames) {
185
+ const info = registry.rules.get(cls);
186
+ if (info?.cssText?.length) {
187
+ chunks.push(...info.cssText);
188
+ found = true;
189
+ }
190
+ }
191
+ return found ? chunks.join("\n") : null;
192
+ }
193
+ function getDefs(root = document) {
194
+ const registry = getRegistry(root);
195
+ let properties = [];
196
+ if (registry?.injectedProperties) properties = Array.from(registry.injectedProperties.keys()).sort();
197
+ const keyframes = [];
198
+ if (registry) {
199
+ for (const entry of registry.keyframesCache.values()) keyframes.push({
200
+ name: entry.name,
201
+ refCount: entry.refCount
202
+ });
203
+ keyframes.sort((a, b) => a.name.localeCompare(b.name));
204
+ }
205
+ return {
206
+ properties,
207
+ keyframes
208
+ };
209
+ }
210
+ const CHUNK_ORDER = [
211
+ CHUNK_NAMES.COMBINED,
212
+ CHUNK_NAMES.APPEARANCE,
213
+ CHUNK_NAMES.FONT,
214
+ CHUNK_NAMES.DIMENSION,
215
+ CHUNK_NAMES.DISPLAY,
216
+ CHUNK_NAMES.LAYOUT,
217
+ CHUNK_NAMES.POSITION,
218
+ CHUNK_NAMES.MISC,
219
+ CHUNK_NAMES.SUBCOMPONENTS
220
+ ];
236
221
  const tastyDebug = {
237
222
  css(target, opts) {
238
- const { root = document, prettify = true, log = false } = opts || {};
223
+ const { root = document, prettify = true, raw = false, source = false } = opts || {};
239
224
  let css = "";
240
- if (typeof target === "string") if (target === "all") css = injector.instance.getCssText({ root });
241
- else if (target === "global") css = getGlobalCSS(root);
242
- else if (target === "active") {
243
- const activeClasses = findAllTastyClasses(root);
244
- css = injector.instance.getCssTextForClasses(activeClasses, { root });
225
+ if (source && typeof target === "string" && /^t[a-z0-9]+$/.test(target)) {
226
+ const src = getSourceCssForClasses([target], root);
227
+ if (src) css = src;
228
+ else {
229
+ if (!raw) console.warn("tastyDebug: source CSS not available (requires dev mode or TASTY_DEBUG=true). Falling back to live CSSOM.");
230
+ css = injector.instance.getCssTextForClasses([target], { root });
231
+ }
232
+ } else if (source && Array.isArray(target)) {
233
+ const src = getSourceCssForClasses(target, root);
234
+ if (src) css = src;
235
+ else {
236
+ if (!raw) console.warn("tastyDebug: source CSS not available. Falling back to live CSSOM.");
237
+ css = injector.instance.getCssTextForClasses(target, { root });
238
+ }
239
+ } else if (typeof target === "string") if (target === "all") css = injector.instance.getCssText({ root });
240
+ else if (target === "global") {
241
+ css = getGlobalTypeCSS("global", root).css;
242
+ return css;
243
+ } else if (target === "active") {
244
+ const active = findDomTastyClasses(root);
245
+ css = injector.instance.getCssTextForClasses(active, { root });
245
246
  } else if (target === "unused") {
246
- const registry = injector.instance._sheetManager?.getRegistry(root);
247
- const unusedClasses = registry ? Array.from(registry.refCounts.entries()).filter(([, refCount]) => refCount === 0).map(([className]) => className) : [];
248
- css = injector.instance.getCssTextForClasses(unusedClasses, { root });
249
- } else if (target === "page") css = getPageCSS({
250
- root,
251
- includeCrossOrigin: true
252
- });
253
- else if (/^t\d+$/.test(target)) css = injector.instance.getCssTextForClasses([target], { root });
247
+ const unused = getUnusedClasses(root);
248
+ css = injector.instance.getCssTextForClasses(unused, { root });
249
+ } else if (target === "page") css = getPageCSS(root);
250
+ else if (/^t[a-z0-9]+$/.test(target)) css = injector.instance.getCssTextForClasses([target], { root });
254
251
  else {
255
- const element = root.querySelector?.(target);
256
- if (element) css = getCssTextForNode(element, { root });
252
+ const el = root.querySelector?.(target);
253
+ if (el) css = getCssTextForNode(el, { root });
257
254
  }
258
255
  else if (Array.isArray(target)) css = injector.instance.getCssTextForClasses(target, { root });
259
256
  else if (target instanceof Element) css = getCssTextForNode(target, { root });
260
257
  const result = prettify ? prettifyCSS(css) : css;
261
- if (log) {
262
- console.group(`🎨 CSS for ${Array.isArray(target) ? `[${target.join(", ")}]` : target}`);
258
+ if (!raw) {
259
+ const label = Array.isArray(target) ? `[${target.join(", ")}]` : target;
260
+ const rc = countRules(css);
261
+ console.group(`CSS for ${label} (${rc} rules, ${fmtSize(css.length)})`);
263
262
  console.log(result || "(empty)");
264
263
  console.groupEnd();
265
264
  }
266
265
  return result;
267
266
  },
268
267
  inspect(target, opts) {
269
- const { root = document } = opts || {};
268
+ const { root = document, raw = false } = opts || {};
270
269
  const element = typeof target === "string" ? root.querySelector?.(target) : target;
271
- if (!element) return {
272
- element: null,
273
- classes: [],
274
- chunks: [],
275
- css: "",
276
- size: 0,
277
- rules: 0
278
- };
279
- const tastyClasses = (element.getAttribute("class") || "").split(/\s+/).filter((cls) => /^t\d+$/.test(cls));
270
+ if (!element) {
271
+ const empty = {
272
+ element: null,
273
+ classes: [],
274
+ chunks: [],
275
+ css: "",
276
+ size: 0,
277
+ rules: 0
278
+ };
279
+ if (!raw) console.warn("tastyDebug.inspect: element not found");
280
+ return empty;
281
+ }
282
+ const tastyClasses = (element.getAttribute("class") || "").split(/\s+/).filter((cls) => /^t[a-z0-9]+$/.test(cls));
280
283
  const chunks = tastyClasses.map((className) => ({
281
284
  className,
282
- chunkName: getChunkForClassName(className, root).chunkName
285
+ chunkName: getChunkForClass(className, root)
283
286
  }));
284
287
  const css = getCssTextForNode(element, { root });
285
- const prettifiedCSS = prettifyCSS(css);
286
- const ruleCount = (css.match(/\{[^}]*\}/g) || []).length;
287
- return {
288
+ const rules = countRules(css);
289
+ const result = {
288
290
  element,
289
291
  classes: tastyClasses,
290
292
  chunks,
291
- css: prettifiedCSS,
293
+ css: prettifyCSS(css),
292
294
  size: css.length,
293
- rules: ruleCount
295
+ rules
294
296
  };
295
- },
296
- cache(opts) {
297
- const { root = document } = opts || {};
298
- const activeClasses = findAllTastyClasses(root);
299
- findAllStyledClasses(root);
300
- const registry = injector.instance._sheetManager?.getRegistry(root);
301
- const unusedClasses = registry ? Array.from(registry.refCounts.entries()).filter(([, refCount]) => refCount === 0).map(([className]) => className) : [];
302
- return {
303
- classes: {
304
- active: activeClasses,
305
- unused: unusedClasses,
306
- all: [...activeClasses, ...unusedClasses]
307
- },
308
- metrics: injector.instance.getMetrics({ root })
309
- };
310
- },
311
- cleanup(opts) {
312
- const { root } = opts || {};
313
- injector.instance.cleanup(root);
314
- },
315
- metrics(opts) {
316
- const { root } = opts || {};
317
- return injector.instance.getMetrics({ root });
318
- },
319
- resetMetrics(opts) {
320
- const { root } = opts || {};
321
- injector.instance.resetMetrics({ root });
322
- },
323
- chunks(opts) {
324
- const { root = document, log = false } = opts || {};
325
- const breakdown = getChunkBreakdown(root);
326
- const totalClasses = Object.values(breakdown.byChunk).reduce((sum, entry) => sum + entry.classes.length, 0);
327
- if (log) {
328
- console.group("🧩 Style Chunk Breakdown");
329
- const displayOrder = [
330
- CHUNK_NAMES.COMBINED,
331
- CHUNK_NAMES.APPEARANCE,
332
- CHUNK_NAMES.FONT,
333
- CHUNK_NAMES.DIMENSION,
334
- CHUNK_NAMES.DISPLAY,
335
- CHUNK_NAMES.LAYOUT,
336
- CHUNK_NAMES.POSITION,
337
- CHUNK_NAMES.MISC,
338
- CHUNK_NAMES.SUBCOMPONENTS
339
- ];
340
- for (const chunkName of displayOrder) {
341
- const data = breakdown.byChunk[chunkName];
342
- if (data) {
343
- const sizeStr = data.cssSize > 1024 ? `${(data.cssSize / 1024).toFixed(1)}KB` : `${data.cssSize}B`;
344
- console.log(` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`);
345
- }
346
- }
347
- for (const [chunkName, data] of Object.entries(breakdown.byChunk)) if (!displayOrder.includes(chunkName)) {
348
- const sizeStr = data.cssSize > 1024 ? `${(data.cssSize / 1024).toFixed(1)}KB` : `${data.cssSize}B`;
349
- console.log(` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`);
350
- }
351
- console.log(`📊 Total: ${totalClasses} classes across ${breakdown.totalChunkTypes} chunk types`);
297
+ if (!raw) {
298
+ const tag = element.tagName.toLowerCase();
299
+ const id = element.id ? `#${element.id}` : "";
300
+ console.group(`inspect ${tag}${id} — ${tastyClasses.length} classes, ${rules} rules, ${fmtSize(css.length)}`);
301
+ if (chunks.length) console.log("Chunks:", chunks.map((c) => `${c.className}→${c.chunkName || "?"}`).join(", "));
302
+ console.groupCollapsed("CSS");
303
+ console.log(result.css || "(empty)");
304
+ console.groupEnd();
352
305
  console.groupEnd();
353
306
  }
354
- return {
355
- ...breakdown,
356
- totalClasses
357
- };
358
- },
359
- getGlobalTypeCSS(type, opts) {
360
- const { root = document } = opts || {};
361
- const registry = injector.instance._sheetManager?.getRegistry(root);
362
- if (!registry) return {
363
- css: "",
364
- ruleCount: 0,
365
- size: 0
366
- };
367
- const cssChunks = [];
368
- let ruleCount = 0;
369
- if (type === "keyframes") for (const [, entry] of registry.keyframesCache) {
370
- const info = entry.info;
371
- const styleSheet = registry.sheets[info.sheetIndex]?.sheet?.sheet;
372
- if (styleSheet && info.ruleIndex < styleSheet.cssRules.length) {
373
- const rule = styleSheet.cssRules[info.ruleIndex];
374
- if (rule) {
375
- cssChunks.push(rule.cssText);
376
- ruleCount++;
377
- }
378
- } else if (info.cssText) {
379
- cssChunks.push(info.cssText);
380
- ruleCount++;
381
- }
382
- }
383
- else {
384
- const prefix = type === "global" ? "global:" : type === "raw" ? "raw:" : "property:";
385
- for (const [key, ruleInfo] of registry.globalRules) if (key.startsWith(prefix)) {
386
- const styleSheet = registry.sheets[ruleInfo.sheetIndex]?.sheet?.sheet;
387
- if (styleSheet) {
388
- const start = Math.max(0, ruleInfo.ruleIndex);
389
- const end = Math.min(styleSheet.cssRules.length - 1, ruleInfo.endRuleIndex ?? ruleInfo.ruleIndex);
390
- if (start >= 0 && end >= start && start < styleSheet.cssRules.length) for (let i = start; i <= end; i++) {
391
- const rule = styleSheet.cssRules[i];
392
- if (rule) {
393
- cssChunks.push(rule.cssText);
394
- ruleCount++;
395
- }
396
- }
397
- } else if (ruleInfo.cssText && ruleInfo.cssText.length) {
398
- cssChunks.push(...ruleInfo.cssText);
399
- ruleCount += ruleInfo.cssText.length;
400
- }
401
- }
402
- }
403
- const rawCSS = cssChunks.join("\n");
404
- return {
405
- css: prettifyCSS(rawCSS),
406
- ruleCount,
407
- size: rawCSS.length
408
- };
409
- },
410
- defs(opts) {
411
- const { root = document } = opts || {};
412
- let properties = [];
413
- try {
414
- const registry = injector.instance._sheetManager?.getRegistry(root);
415
- if (registry?.injectedProperties) properties = Array.from(registry.injectedProperties.keys()).sort();
416
- } catch {
417
- const allCSS = injector.instance.getCssText({ root });
418
- const propRegex = /@property\s+(--[a-z0-9-]+)/gi;
419
- const propSet = /* @__PURE__ */ new Set();
420
- let match;
421
- while ((match = propRegex.exec(allCSS)) !== null) propSet.add(match[1]);
422
- properties = Array.from(propSet).sort();
423
- }
424
- let keyframes = [];
425
- try {
426
- const registry = injector.instance._sheetManager?.getRegistry(root);
427
- if (registry) {
428
- for (const entry of registry.keyframesCache.values()) keyframes.push({
429
- name: entry.name,
430
- refCount: entry.refCount
431
- });
432
- keyframes.sort((a, b) => a.name.localeCompare(b.name));
433
- }
434
- } catch {
435
- const allCSS = injector.instance.getCssText({ root });
436
- const keyframesRegex = /@keyframes\s+([a-zA-Z0-9_-]+)/gi;
437
- const keyframesSet = /* @__PURE__ */ new Set();
438
- let match;
439
- while ((match = keyframesRegex.exec(allCSS)) !== null) keyframesSet.add(match[1]);
440
- keyframes = Array.from(keyframesSet).sort().map((name) => ({
441
- name,
442
- refCount: 1
443
- }));
444
- }
445
- return {
446
- properties,
447
- keyframes
448
- };
307
+ return result;
449
308
  },
450
309
  summary(opts) {
451
- const { root = document, log = false, includePageCSS = false } = opts || {};
452
- const cacheStatus = this.cache({ root });
453
- const definitions = this.defs({ root });
454
- const metrics = this.metrics({ root });
455
- const activeCSS = this.css("active", {
456
- root,
457
- prettify: false
458
- });
459
- const unusedCSS = this.css("unused", {
460
- root,
461
- prettify: false
462
- });
463
- const allCSS = this.css("all", {
464
- root,
465
- prettify: false
466
- });
467
- const classCSSSize = activeCSS.length + unusedCSS.length;
468
- const totalGlobalCSSSize = allCSS.length - classCSSSize;
469
- const globalData = this.getGlobalTypeCSS("global", { root });
470
- const rawData = this.getGlobalTypeCSS("raw", { root });
471
- const keyframesData = this.getGlobalTypeCSS("keyframes", { root });
472
- const propertyData = this.getGlobalTypeCSS("property", { root });
473
- const globalTypesTotalSize = globalData.size + rawData.size + keyframesData.size + propertyData.size;
474
- const cleanupSummary = {
475
- enabled: !!metrics,
476
- totalCleanups: metrics?.cleanupHistory?.length || 0,
477
- totalClassesDeleted: metrics?.cleanupHistory?.reduce((sum, c) => sum + c.classesDeleted, 0) || 0,
478
- totalCssDeleted: metrics?.cleanupHistory?.reduce((sum, c) => sum + c.cssSize, 0) || 0,
479
- totalRulesDeleted: metrics?.cleanupHistory?.reduce((sum, c) => sum + c.rulesDeleted, 0) || 0,
480
- averageClassesPerCleanup: 0,
481
- averageCssPerCleanup: 0,
482
- averageRulesPerCleanup: 0,
483
- lastCleanup: void 0
484
- };
485
- if (cleanupSummary.totalCleanups > 0) {
486
- cleanupSummary.averageClassesPerCleanup = cleanupSummary.totalClassesDeleted / cleanupSummary.totalCleanups;
487
- cleanupSummary.averageCssPerCleanup = cleanupSummary.totalCssDeleted / cleanupSummary.totalCleanups;
488
- cleanupSummary.averageRulesPerCleanup = cleanupSummary.totalRulesDeleted / cleanupSummary.totalCleanups;
489
- const lastCleanup = metrics?.cleanupHistory?.[metrics.cleanupHistory.length - 1];
490
- if (lastCleanup) cleanupSummary.lastCleanup = {
491
- ...lastCleanup,
492
- date: new Date(lastCleanup.timestamp).toISOString()
493
- };
494
- }
495
- let page;
496
- if (includePageCSS) page = {
497
- ...getPageStats({
498
- root,
499
- includeCrossOrigin: true
500
- }),
501
- css: includePageCSS === "all" ? getPageCSS({
502
- root,
503
- includeCrossOrigin: true
504
- }) : void 0
505
- };
506
- const useIndividualSizes = Math.abs(globalTypesTotalSize - totalGlobalCSSSize) < 100;
507
- let adjustedGlobalSizes;
508
- if (useIndividualSizes) adjustedGlobalSizes = {
509
- globalCSSSize: globalData.size,
510
- rawCSSSize: rawData.size,
511
- keyframesCSSSize: keyframesData.size,
512
- propertyCSSSize: propertyData.size
513
- };
514
- else {
515
- const scaleFactor = totalGlobalCSSSize / globalTypesTotalSize;
516
- adjustedGlobalSizes = {
517
- globalCSSSize: Math.round(globalData.size * scaleFactor),
518
- rawCSSSize: Math.round(rawData.size * scaleFactor),
519
- keyframesCSSSize: Math.round(keyframesData.size * scaleFactor),
520
- propertyCSSSize: Math.round(propertyData.size * scaleFactor)
521
- };
522
- }
523
- const chunkBreakdown = getChunkBreakdown(root);
310
+ const { root = document, raw = false } = opts || {};
311
+ const activeClasses = findDomTastyClasses(root);
312
+ const unusedClasses = getUnusedClasses(root);
313
+ const totalStyledClasses = [...activeClasses, ...unusedClasses];
314
+ const activeCSS = injector.instance.getCssTextForClasses(activeClasses, { root });
315
+ const unusedCSS = injector.instance.getCssTextForClasses(unusedClasses, { root });
316
+ const allCSS = injector.instance.getCssText({ root });
317
+ const activeRuleCount = countRules(activeCSS);
318
+ const unusedRuleCount = countRules(unusedCSS);
319
+ const globalData = getGlobalTypeCSS("global", root);
320
+ const rawData = getGlobalTypeCSS("raw", root);
321
+ const kfData = getGlobalTypeCSS("keyframes", root);
322
+ const propData = getGlobalTypeCSS("property", root);
323
+ const totalRuleCount = activeRuleCount + unusedRuleCount + globalData.ruleCount + rawData.ruleCount + kfData.ruleCount + propData.ruleCount;
324
+ const metrics = injector.instance.getMetrics({ root });
325
+ const defs = getDefs(root);
326
+ const chunkBreakdown = buildChunkBreakdown(root);
524
327
  const summary = {
525
- activeClasses: cacheStatus.classes.active,
526
- unusedClasses: cacheStatus.classes.unused,
527
- totalStyledClasses: cacheStatus.classes.all,
328
+ activeClasses,
329
+ unusedClasses,
330
+ totalStyledClasses,
528
331
  activeCSSSize: activeCSS.length,
529
332
  unusedCSSSize: unusedCSS.length,
530
- ...adjustedGlobalSizes,
333
+ globalCSSSize: globalData.size,
334
+ rawCSSSize: rawData.size,
335
+ keyframesCSSSize: kfData.size,
336
+ propertyCSSSize: propData.size,
531
337
  totalCSSSize: allCSS.length,
532
- activeCSS: prettifyCSS(activeCSS),
533
- unusedCSS: prettifyCSS(unusedCSS),
534
- globalCSS: globalData.css,
535
- rawCSS: rawData.css,
536
- keyframesCSS: keyframesData.css,
537
- propertyCSS: propertyData.css,
538
- allCSS: prettifyCSS(allCSS),
338
+ activeRuleCount,
339
+ unusedRuleCount,
539
340
  globalRuleCount: globalData.ruleCount,
540
341
  rawRuleCount: rawData.ruleCount,
541
- keyframesRuleCount: keyframesData.ruleCount,
542
- propertyRuleCount: propertyData.ruleCount,
543
- page,
342
+ keyframesRuleCount: kfData.ruleCount,
343
+ propertyRuleCount: propData.ruleCount,
344
+ totalRuleCount,
544
345
  metrics,
545
- definedProperties: definitions.properties,
546
- definedKeyframes: definitions.keyframes,
547
- propertyCount: definitions.properties.length,
548
- keyframeCount: definitions.keyframes.length,
549
- cleanupSummary,
346
+ definedProperties: defs.properties,
347
+ definedKeyframes: defs.keyframes,
550
348
  chunkBreakdown
551
349
  };
552
- if (log) {
553
- console.group("🎨 Comprehensive Tasty Debug Summary");
554
- console.log(`📊 Style Cache Status:`);
555
- console.log(` • Active classes (in DOM): ${summary.activeClasses.length}`);
556
- console.log(` • Unused classes (refCount = 0): ${summary.unusedClasses.length}`);
557
- console.log(` • Total styled classes: ${summary.totalStyledClasses.length}`);
558
- console.log(`💾 CSS Size:`);
559
- console.log(` • Active CSS: ${summary.activeCSSSize} characters`);
560
- console.log(` • Unused CSS: ${summary.unusedCSSSize} characters`);
561
- console.log(` • Global CSS (injectGlobal): ${summary.globalCSSSize} characters (${summary.globalRuleCount} rules)`);
562
- console.log(` • Raw CSS (injectRawCSS/useRawCSS): ${summary.rawCSSSize} characters (${summary.rawRuleCount} rules)`);
563
- console.log(` • Keyframes CSS: ${summary.keyframesCSSSize} characters (${summary.keyframesRuleCount} rules)`);
564
- console.log(` • Property CSS: ${summary.propertyCSSSize} characters (${summary.propertyRuleCount} rules)`);
565
- const calculatedTotal = summary.activeCSSSize + summary.unusedCSSSize + summary.globalCSSSize + summary.rawCSSSize + summary.keyframesCSSSize + summary.propertyCSSSize;
566
- console.log(` • Calculated Total: ${calculatedTotal} characters`);
567
- console.log(` • Actual Total: ${summary.totalCSSSize} characters`);
568
- const difference = Math.abs(calculatedTotal - summary.totalCSSSize);
569
- if (difference > 100) {
570
- console.warn(` ⚠️ Size mismatch: ${difference} characters difference`);
571
- console.group("🔍 Debugging size mismatch:");
572
- console.log(`Active + Unused = ${summary.activeCSSSize + summary.unusedCSSSize}`);
573
- console.log(`All Global Types = ${summary.globalCSSSize + summary.rawCSSSize + summary.keyframesCSSSize + summary.propertyCSSSize}`);
574
- console.log(`Class-based vs Total difference = ${summary.totalCSSSize - (summary.activeCSSSize + summary.unusedCSSSize)}`);
575
- console.log(`Raw global extraction total: ${globalTypesTotalSize}`);
576
- console.log(`Calculated global size: ${totalGlobalCSSSize}`);
577
- console.log(`Used individual sizes: ${useIndividualSizes}`);
578
- if (!useIndividualSizes) console.log(`Scale factor applied: ${(totalGlobalCSSSize / globalTypesTotalSize).toFixed(3)}`);
579
- console.groupEnd();
580
- }
581
- if (page) {
582
- console.log(`📄 Page CSS:`);
583
- console.log(` • Total page CSS: ${page.cssSize} characters`);
584
- console.log(` • Total page rules: ${page.ruleCount}`);
585
- console.log(` • Stylesheets: ${page.stylesheetCount} (${page.skippedStylesheets} skipped)`);
586
- }
587
- console.log("🏷️ Properties & Keyframes:");
588
- console.log(` • Defined @property: ${summary.propertyCount}`);
589
- console.log(` • Defined @keyframes: ${summary.keyframeCount}`);
350
+ if (!raw) {
351
+ console.group("Tasty Summary");
352
+ console.log(`Active: ${activeClasses.length} classes, ${activeRuleCount} rules, ${fmtSize(activeCSS.length)}`);
353
+ console.log(`Unused: ${unusedClasses.length} classes, ${unusedRuleCount} rules, ${fmtSize(unusedCSS.length)}`);
354
+ console.log(`Global: ${globalData.ruleCount} rules, ${fmtSize(globalData.size)}`);
355
+ if (rawData.ruleCount) console.log(`Raw: ${rawData.ruleCount} rules, ${fmtSize(rawData.size)}`);
356
+ if (kfData.ruleCount) console.log(`Keyframes: ${kfData.ruleCount} rules, ${fmtSize(kfData.size)}`);
357
+ if (propData.ruleCount) console.log(`@property: ${propData.ruleCount} rules, ${fmtSize(propData.size)}`);
358
+ console.log(`Total: ${totalStyledClasses.length} classes, ${totalRuleCount} rules, ${fmtSize(allCSS.length)}`);
590
359
  if (metrics) {
591
- console.log(`⚡ Performance Metrics:`);
592
- console.log(` • Cache hits: ${metrics.hits}`);
593
- console.log(` • Cache misses: ${metrics.misses}`);
594
- console.log(` • Cached style reuses: ${metrics.unusedHits}`);
595
- const hitRate = metrics.hits + metrics.misses > 0 ? ((metrics.hits + (metrics.unusedHits || 0)) / (metrics.hits + metrics.misses) * 100).toFixed(1) : "0";
596
- console.log(` • Overall cache hit rate: ${hitRate}%`);
360
+ const total = metrics.hits + metrics.misses;
361
+ const rate = total > 0 ? (metrics.hits / total * 100).toFixed(1) : 0;
362
+ console.log(`Cache: ${rate}% hit rate (${total} lookups)`);
597
363
  }
598
- if (summary.chunkBreakdown.totalChunkTypes > 0) {
599
- console.log("🧩 Style Chunk Breakdown:");
600
- const displayOrder = [
601
- CHUNK_NAMES.COMBINED,
602
- CHUNK_NAMES.APPEARANCE,
603
- CHUNK_NAMES.FONT,
604
- CHUNK_NAMES.DIMENSION,
605
- CHUNK_NAMES.DISPLAY,
606
- CHUNK_NAMES.LAYOUT,
607
- CHUNK_NAMES.POSITION,
608
- CHUNK_NAMES.MISC,
609
- CHUNK_NAMES.SUBCOMPONENTS
610
- ];
611
- for (const chunkName of displayOrder) {
612
- const data = summary.chunkBreakdown.byChunk[chunkName];
613
- if (data) {
614
- const sizeStr = data.cssSize > 1024 ? `${(data.cssSize / 1024).toFixed(1)}KB` : `${data.cssSize}B`;
615
- console.log(` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`);
616
- }
364
+ if (chunkBreakdown.totalChunkTypes > 0) {
365
+ console.groupCollapsed(`Chunks (${chunkBreakdown.totalChunkTypes} types, ${chunkBreakdown.totalClasses} classes)`);
366
+ for (const name of CHUNK_ORDER) {
367
+ const d = chunkBreakdown.byChunk[name];
368
+ if (d) console.log(` ${name}: ${d.classes.length} cls, ${d.ruleCount} rules, ${fmtSize(d.cssSize)}`);
617
369
  }
370
+ for (const [name, d] of Object.entries(chunkBreakdown.byChunk)) if (!CHUNK_ORDER.includes(name)) console.log(` ${name}: ${d.classes.length} cls, ${d.ruleCount} rules, ${fmtSize(d.cssSize)}`);
371
+ console.groupEnd();
618
372
  }
619
- console.log("🔍 Details:");
620
- console.log(" • Active classes:", summary.activeClasses);
621
- console.log(" • Unused classes:", summary.unusedClasses);
373
+ if (defs.properties.length || defs.keyframes.length) console.log(`Defs: ${defs.properties.length} @property, ${defs.keyframes.length} @keyframes`);
622
374
  console.groupEnd();
623
375
  }
624
376
  return summary;
625
377
  },
626
- pageCSS(opts) {
627
- const { root = document, prettify = true, log = false, includeCrossOrigin = true } = opts || {};
628
- const css = getPageCSS({
629
- root,
630
- includeCrossOrigin
631
- });
632
- const result = prettify ? prettifyCSS(css) : css;
633
- if (log) {
634
- console.group("📄 Page CSS (All Stylesheets)");
635
- console.log(result || "(empty)");
378
+ chunks(opts) {
379
+ const { root = document, raw = false } = opts || {};
380
+ const breakdown = buildChunkBreakdown(root);
381
+ if (!raw) {
382
+ console.group(`Chunks (${breakdown.totalChunkTypes} types, ${breakdown.totalClasses} classes)`);
383
+ for (const name of CHUNK_ORDER) {
384
+ const d = breakdown.byChunk[name];
385
+ if (d) console.log(` ${name}: ${d.classes.length} cls, ${d.ruleCount} rules, ${fmtSize(d.cssSize)}`);
386
+ }
387
+ for (const [name, d] of Object.entries(breakdown.byChunk)) if (!CHUNK_ORDER.includes(name)) console.log(` ${name}: ${d.classes.length} cls, ${d.ruleCount} rules, ${fmtSize(d.cssSize)}`);
636
388
  console.groupEnd();
637
389
  }
638
- return result;
390
+ return breakdown;
639
391
  },
640
- pageStats(opts) {
641
- const { root = document, includeCrossOrigin = true } = opts || {};
642
- return getPageStats({
643
- root,
644
- includeCrossOrigin
645
- });
392
+ cache(opts) {
393
+ const { root = document, raw = false } = opts || {};
394
+ const active = findDomTastyClasses(root);
395
+ const unused = getUnusedClasses(root);
396
+ const metrics = injector.instance.getMetrics({ root });
397
+ const status = {
398
+ classes: {
399
+ active,
400
+ unused,
401
+ all: [...active, ...unused]
402
+ },
403
+ metrics
404
+ };
405
+ if (!raw) {
406
+ console.group("Cache");
407
+ console.log(`Active: ${active.length}, Unused: ${unused.length}`);
408
+ if (metrics) {
409
+ const total = metrics.hits + metrics.misses;
410
+ const rate = total > 0 ? (metrics.hits / total * 100).toFixed(1) : 0;
411
+ console.log(`Hits: ${metrics.hits}, Misses: ${metrics.misses}, Rate: ${rate}%`);
412
+ }
413
+ console.groupEnd();
414
+ }
415
+ return status;
416
+ },
417
+ cleanup(opts) {
418
+ injector.instance.cleanup(opts?.root);
419
+ },
420
+ help() {
421
+ console.log(`tastyDebug API:
422
+ .summary() — overview (classes, rules, sizes)
423
+ .css("active") — CSS for classes in DOM
424
+ .css("t42") — CSS for a specific class
425
+ .css("t42",{source:1})— original CSS before browser parsing (dev only)
426
+ .css(".selector") — CSS for a DOM element
427
+ .inspect(".selector") — element details (classes, chunks, rules)
428
+ .chunks() — style chunk breakdown
429
+ .cache() — cache status and metrics
430
+ .cleanup() — force unused style cleanup
431
+ Options: { raw: true } suppresses logging, { root: shadowRoot } targets Shadow DOM`);
646
432
  },
647
433
  install() {
648
434
  if (typeof window !== "undefined" && window.tastyDebug !== tastyDebug) {
649
435
  window.tastyDebug = tastyDebug;
650
- console.log("🎨 tastyDebug installed on window. Run tastyDebug.help() for quick start guide.");
651
- }
652
- },
653
- log(target, opts) {
654
- const { title, ...cssOpts } = opts || {};
655
- const css = tastyDebug.css(target, cssOpts);
656
- if (!css.trim()) {
657
- console.warn(`🎨 No CSS found for target: ${String(target)}`);
658
- return;
436
+ console.log("tastyDebug installed. Run tastyDebug.help() for commands.");
659
437
  }
660
- const targetStr = Array.isArray(target) ? target.join(", ") : String(target);
661
- const displayTitle = title || `CSS for "${targetStr}"`;
662
- const lines = css.split("\n").length;
663
- const size = new Blob([css]).size;
664
- const sizeStr = size > 1024 ? `${(size / 1024).toFixed(1)}KB` : `${size}B`;
665
- const ruleCount = (css.match(/\{/g) || []).length;
666
- console.group(`🎨 ${displayTitle} (${ruleCount} rules, ${lines} lines, ${sizeStr})`);
667
- const subElementMatches = css.match(/\[data-element="([^"]+)"\]/g) || [];
668
- const subElements = [...new Set(subElementMatches.map((match) => match.match(/\[data-element="([^"]+)"\]/)?.[1]).filter((v) => !!v))];
669
- if (subElements.length > 0) {
670
- console.log(`🧩 Sub-elements found: ${subElements.join(", ")}`);
671
- subElements.forEach((element) => {
672
- `${element}`;
673
- const elementRegex = new RegExp(`[^}]*\\[data-element="${element.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"\\][^{]*\\{[^}]*\\}`, "gm");
674
- const elementCSS = (css.match(elementRegex) || []).join("\n");
675
- if (elementCSS) {
676
- const elementRules = (elementCSS.match(/\{/g) || []).length;
677
- const elementLines = elementCSS.split("\n").length;
678
- const elementSize = new Blob([elementCSS]).size;
679
- const elementSizeStr = elementSize > 1024 ? `${(elementSize / 1024).toFixed(1)}KB` : `${elementSize}B`;
680
- console.groupCollapsed(`🧩 ${element} (${elementRules} rules, ${elementLines} lines, ${elementSizeStr})`);
681
- console.log(`%c${elementCSS}`, "color: #666; font-family: monospace; font-size: 12px; white-space: pre;");
682
- console.groupEnd();
683
- }
684
- });
685
- }
686
- console.groupCollapsed("📄 Full CSS (click to expand)");
687
- console.log(`%c${css}`, "color: #666; font-family: monospace; font-size: 12px; white-space: pre;");
688
- console.groupEnd();
689
- console.groupEnd();
690
- },
691
- help() {
692
- console.group("🎨 tastyDebug - Quick Start Guide");
693
- console.log("💡 Essential commands:");
694
- console.log(" • tastyDebug.summary({ log: true }) - comprehensive overview");
695
- console.log(" • tastyDebug.chunks({ log: true }) - style chunk breakdown");
696
- console.log(" • tastyDebug.log(\"active\") - beautiful CSS display");
697
- console.log(" • tastyDebug.css(\"active\") - get active CSS");
698
- console.log(" • tastyDebug.inspect(\".my-element\") - element inspection with chunk info");
699
- console.log(" • tastyDebug.cache() - cache status");
700
- console.log(" • tastyDebug.defs() - defined properties & keyframes");
701
- console.log(" • tastyDebug.pageCSS({ log: true }) - all page CSS");
702
- console.log("");
703
- console.log("📖 Common targets for css()/log():");
704
- console.log(" • \"all\" - all tasty CSS + global CSS");
705
- console.log(" • \"active\" - CSS for classes in DOM");
706
- console.log(" • \"unused\" - CSS for classes with refCount = 0");
707
- console.log(" • \"global\" - only global CSS (injectGlobal)");
708
- console.log(" • \"page\" - ALL page CSS (including non-tasty)");
709
- console.log(" • \"t123\" - specific tasty class");
710
- console.log(" • [\".my-selector\"] - CSS selector");
711
- console.log("");
712
- console.log("🔧 Available options:");
713
- console.log(" • { log: true } - auto-log results to console");
714
- console.log(" • { title: \"Custom\" } - custom title for log()");
715
- console.log(" • { root: shadowRoot } - target Shadow DOM");
716
- console.log(" • { prettify: false } - skip CSS formatting");
717
- console.log("");
718
- console.log("🧩 Style Chunking:");
719
- console.log(" Elements have multiple classes (one per chunk: appearance, font, dimension, etc.)");
720
- console.log(" • tastyDebug.chunks({ log: true }) - breakdown by chunk type");
721
- console.log(" • tastyDebug.inspect() - shows which chunk each class belongs to");
722
- console.log(" Chunk types: combined (non-chunked), appearance, font, dimension, container, scrollbar, position, misc, subcomponents");
723
- console.groupEnd();
724
438
  }
725
439
  };
726
- /**
727
- * Auto-install in development
728
- */
440
+ function getPageCSS(root = document) {
441
+ const chunks = [];
442
+ try {
443
+ if ("styleSheets" in root) for (const sheet of Array.from(root.styleSheets)) try {
444
+ if (sheet.cssRules) chunks.push(Array.from(sheet.cssRules).map((r) => r.cssText).join("\n"));
445
+ } catch {}
446
+ } catch {}
447
+ return chunks.join("\n");
448
+ }
729
449
  if (typeof window !== "undefined" && isDevEnv()) tastyDebug.install();
730
-
731
450
  //#endregion
732
451
  export { tastyDebug };
452
+
733
453
  //# sourceMappingURL=debug.js.map