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

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 (303) hide show
  1. package/README.md +314 -159
  2. package/dist/async-storage-B7_o6FKt.js +44 -0
  3. package/dist/async-storage-B7_o6FKt.js.map +1 -0
  4. package/dist/collector-C-keQH9m.js +243 -0
  5. package/dist/collector-C-keQH9m.js.map +1 -0
  6. package/dist/collector-osfWTeRd.d.ts +108 -0
  7. package/dist/config-BBiyxMCe.js +10559 -0
  8. package/dist/config-BBiyxMCe.js.map +1 -0
  9. package/dist/config-BoZDUHW5.d.ts +945 -0
  10. package/dist/context-CkSg-kDT.js +24 -0
  11. package/dist/context-CkSg-kDT.js.map +1 -0
  12. package/dist/core/index.d.ts +5 -33
  13. package/dist/core/index.js +6 -26
  14. package/dist/core-BO4319td.js +1598 -0
  15. package/dist/core-BO4319td.js.map +1 -0
  16. package/dist/css-writer-BWvwQzz0.js +351 -0
  17. package/dist/css-writer-BWvwQzz0.js.map +1 -0
  18. package/dist/format-global-rules-Dbc_1tc3.js +22 -0
  19. package/dist/format-global-rules-Dbc_1tc3.js.map +1 -0
  20. package/dist/format-rules-BSjeH4Z7.js +143 -0
  21. package/dist/format-rules-BSjeH4Z7.js.map +1 -0
  22. package/dist/hydrate-CcvrP4qJ.js +45 -0
  23. package/dist/hydrate-CcvrP4qJ.js.map +1 -0
  24. package/dist/index-B_k47mc_.d.ts +1655 -0
  25. package/dist/index-tcHuMPFt.d.ts +1286 -0
  26. package/dist/index.d.ts +5 -48
  27. package/dist/index.js +731 -32
  28. package/dist/index.js.map +1 -0
  29. package/dist/keyframes-BUQhdOSJ.js +588 -0
  30. package/dist/keyframes-BUQhdOSJ.js.map +1 -0
  31. package/dist/{utils/merge-styles.d.ts → merge-styles-BMWcH6MF.d.ts} +3 -3
  32. package/dist/{utils/merge-styles.js → merge-styles-Cd2vBl9b.js} +4 -6
  33. package/dist/merge-styles-Cd2vBl9b.js.map +1 -0
  34. package/dist/{utils/resolve-recipes.js → resolve-recipes-C1nrvnYh.js} +5 -8
  35. package/dist/resolve-recipes-C1nrvnYh.js.map +1 -0
  36. package/dist/ssr/astro-client.d.ts +1 -0
  37. package/dist/ssr/astro-client.js +19 -0
  38. package/dist/ssr/astro-client.js.map +1 -0
  39. package/dist/ssr/astro-middleware.d.ts +15 -0
  40. package/dist/ssr/astro-middleware.js +19 -0
  41. package/dist/ssr/astro-middleware.js.map +1 -0
  42. package/dist/ssr/astro.d.ts +97 -0
  43. package/dist/ssr/astro.js +149 -0
  44. package/dist/ssr/astro.js.map +1 -0
  45. package/dist/ssr/index.d.ts +44 -0
  46. package/dist/ssr/index.js +10 -0
  47. package/dist/ssr/index.js.map +1 -0
  48. package/dist/ssr/next.d.ts +46 -0
  49. package/dist/ssr/next.js +75 -0
  50. package/dist/ssr/next.js.map +1 -0
  51. package/dist/static/index.d.ts +91 -5
  52. package/dist/static/index.js +49 -4
  53. package/dist/static/index.js.map +1 -0
  54. package/dist/static/inject.d.ts +5 -0
  55. package/dist/static/inject.js +17 -0
  56. package/dist/static/inject.js.map +1 -0
  57. package/dist/zero/babel.d.ts +57 -84
  58. package/dist/zero/babel.js +232 -40
  59. package/dist/zero/babel.js.map +1 -1
  60. package/dist/zero/index.d.ts +67 -3
  61. package/dist/zero/index.js +2 -4
  62. package/dist/zero/next.d.ts +56 -30
  63. package/dist/zero/next.js +105 -40
  64. package/dist/zero/next.js.map +1 -1
  65. package/docs/README.md +31 -0
  66. package/docs/adoption.md +298 -0
  67. package/docs/comparison.md +419 -0
  68. package/docs/configuration.md +438 -0
  69. package/docs/debug.md +320 -0
  70. package/docs/design-system.md +436 -0
  71. package/docs/dsl.md +690 -0
  72. package/docs/getting-started.md +217 -0
  73. package/docs/injector.md +544 -0
  74. package/docs/methodology.md +642 -0
  75. package/docs/pipeline.md +699 -0
  76. package/docs/react-api.md +581 -0
  77. package/docs/ssr.md +444 -0
  78. package/docs/styles.md +598 -0
  79. package/docs/tasty-static.md +547 -0
  80. package/package.json +70 -37
  81. package/tasty.config.ts +1 -0
  82. package/dist/_virtual/_rolldown/runtime.js +0 -8
  83. package/dist/chunks/cacheKey.js +0 -70
  84. package/dist/chunks/cacheKey.js.map +0 -1
  85. package/dist/chunks/definitions.d.ts +0 -37
  86. package/dist/chunks/definitions.js +0 -260
  87. package/dist/chunks/definitions.js.map +0 -1
  88. package/dist/chunks/renderChunk.js +0 -61
  89. package/dist/chunks/renderChunk.js.map +0 -1
  90. package/dist/config.d.ts +0 -280
  91. package/dist/config.js +0 -403
  92. package/dist/config.js.map +0 -1
  93. package/dist/debug.d.ts +0 -204
  94. package/dist/debug.js +0 -733
  95. package/dist/debug.js.map +0 -1
  96. package/dist/hooks/useGlobalStyles.d.ts +0 -27
  97. package/dist/hooks/useGlobalStyles.js +0 -56
  98. package/dist/hooks/useGlobalStyles.js.map +0 -1
  99. package/dist/hooks/useKeyframes.d.ts +0 -56
  100. package/dist/hooks/useKeyframes.js +0 -54
  101. package/dist/hooks/useKeyframes.js.map +0 -1
  102. package/dist/hooks/useProperty.d.ts +0 -79
  103. package/dist/hooks/useProperty.js +0 -91
  104. package/dist/hooks/useProperty.js.map +0 -1
  105. package/dist/hooks/useRawCSS.d.ts +0 -53
  106. package/dist/hooks/useRawCSS.js +0 -28
  107. package/dist/hooks/useRawCSS.js.map +0 -1
  108. package/dist/hooks/useStyles.d.ts +0 -40
  109. package/dist/hooks/useStyles.js +0 -169
  110. package/dist/hooks/useStyles.js.map +0 -1
  111. package/dist/injector/index.d.ts +0 -157
  112. package/dist/injector/index.js +0 -154
  113. package/dist/injector/index.js.map +0 -1
  114. package/dist/injector/injector.d.ts +0 -139
  115. package/dist/injector/injector.js +0 -404
  116. package/dist/injector/injector.js.map +0 -1
  117. package/dist/injector/sheet-manager.d.ts +0 -127
  118. package/dist/injector/sheet-manager.js +0 -714
  119. package/dist/injector/sheet-manager.js.map +0 -1
  120. package/dist/injector/types.d.ts +0 -135
  121. package/dist/keyframes/index.js +0 -206
  122. package/dist/keyframes/index.js.map +0 -1
  123. package/dist/parser/classify.js +0 -319
  124. package/dist/parser/classify.js.map +0 -1
  125. package/dist/parser/const.js +0 -33
  126. package/dist/parser/const.js.map +0 -1
  127. package/dist/parser/lru.js +0 -109
  128. package/dist/parser/lru.js.map +0 -1
  129. package/dist/parser/parser.d.ts +0 -25
  130. package/dist/parser/parser.js +0 -116
  131. package/dist/parser/parser.js.map +0 -1
  132. package/dist/parser/tokenizer.js +0 -69
  133. package/dist/parser/tokenizer.js.map +0 -1
  134. package/dist/parser/types.d.ts +0 -51
  135. package/dist/parser/types.js +0 -46
  136. package/dist/parser/types.js.map +0 -1
  137. package/dist/pipeline/conditions.d.ts +0 -134
  138. package/dist/pipeline/conditions.js +0 -406
  139. package/dist/pipeline/conditions.js.map +0 -1
  140. package/dist/pipeline/exclusive.js +0 -231
  141. package/dist/pipeline/exclusive.js.map +0 -1
  142. package/dist/pipeline/index.d.ts +0 -53
  143. package/dist/pipeline/index.js +0 -660
  144. package/dist/pipeline/index.js.map +0 -1
  145. package/dist/pipeline/materialize.js +0 -844
  146. package/dist/pipeline/materialize.js.map +0 -1
  147. package/dist/pipeline/parseStateKey.d.ts +0 -15
  148. package/dist/pipeline/parseStateKey.js +0 -438
  149. package/dist/pipeline/parseStateKey.js.map +0 -1
  150. package/dist/pipeline/simplify.js +0 -516
  151. package/dist/pipeline/simplify.js.map +0 -1
  152. package/dist/pipeline/warnings.js +0 -18
  153. package/dist/pipeline/warnings.js.map +0 -1
  154. package/dist/plugins/okhsl-plugin.d.ts +0 -35
  155. package/dist/plugins/okhsl-plugin.js +0 -371
  156. package/dist/plugins/okhsl-plugin.js.map +0 -1
  157. package/dist/plugins/types.d.ts +0 -69
  158. package/dist/properties/index.js +0 -158
  159. package/dist/properties/index.js.map +0 -1
  160. package/dist/states/index.d.ts +0 -49
  161. package/dist/states/index.js +0 -416
  162. package/dist/states/index.js.map +0 -1
  163. package/dist/static/tastyStatic.d.ts +0 -46
  164. package/dist/static/tastyStatic.js +0 -31
  165. package/dist/static/tastyStatic.js.map +0 -1
  166. package/dist/static/types.d.ts +0 -49
  167. package/dist/static/types.js +0 -24
  168. package/dist/static/types.js.map +0 -1
  169. package/dist/styles/align.d.ts +0 -15
  170. package/dist/styles/align.js +0 -14
  171. package/dist/styles/align.js.map +0 -1
  172. package/dist/styles/border.d.ts +0 -25
  173. package/dist/styles/border.js +0 -114
  174. package/dist/styles/border.js.map +0 -1
  175. package/dist/styles/color.d.ts +0 -14
  176. package/dist/styles/color.js +0 -23
  177. package/dist/styles/color.js.map +0 -1
  178. package/dist/styles/createStyle.js +0 -77
  179. package/dist/styles/createStyle.js.map +0 -1
  180. package/dist/styles/dimension.js +0 -97
  181. package/dist/styles/dimension.js.map +0 -1
  182. package/dist/styles/display.d.ts +0 -37
  183. package/dist/styles/display.js +0 -67
  184. package/dist/styles/display.js.map +0 -1
  185. package/dist/styles/fade.d.ts +0 -15
  186. package/dist/styles/fade.js +0 -58
  187. package/dist/styles/fade.js.map +0 -1
  188. package/dist/styles/fill.d.ts +0 -42
  189. package/dist/styles/fill.js +0 -51
  190. package/dist/styles/fill.js.map +0 -1
  191. package/dist/styles/flow.d.ts +0 -16
  192. package/dist/styles/flow.js +0 -12
  193. package/dist/styles/flow.js.map +0 -1
  194. package/dist/styles/gap.d.ts +0 -31
  195. package/dist/styles/gap.js +0 -37
  196. package/dist/styles/gap.js.map +0 -1
  197. package/dist/styles/height.d.ts +0 -17
  198. package/dist/styles/height.js +0 -20
  199. package/dist/styles/height.js.map +0 -1
  200. package/dist/styles/index.d.ts +0 -2
  201. package/dist/styles/index.js +0 -9
  202. package/dist/styles/index.js.map +0 -1
  203. package/dist/styles/inset.d.ts +0 -52
  204. package/dist/styles/inset.js +0 -150
  205. package/dist/styles/inset.js.map +0 -1
  206. package/dist/styles/justify.d.ts +0 -15
  207. package/dist/styles/justify.js +0 -14
  208. package/dist/styles/justify.js.map +0 -1
  209. package/dist/styles/list.d.ts +0 -16
  210. package/dist/styles/list.js +0 -98
  211. package/dist/styles/list.js.map +0 -1
  212. package/dist/styles/margin.d.ts +0 -24
  213. package/dist/styles/margin.js +0 -104
  214. package/dist/styles/margin.js.map +0 -1
  215. package/dist/styles/outline.d.ts +0 -29
  216. package/dist/styles/outline.js +0 -65
  217. package/dist/styles/outline.js.map +0 -1
  218. package/dist/styles/padding.d.ts +0 -24
  219. package/dist/styles/padding.js +0 -104
  220. package/dist/styles/padding.js.map +0 -1
  221. package/dist/styles/predefined.d.ts +0 -73
  222. package/dist/styles/predefined.js +0 -241
  223. package/dist/styles/predefined.js.map +0 -1
  224. package/dist/styles/preset.d.ts +0 -47
  225. package/dist/styles/preset.js +0 -126
  226. package/dist/styles/preset.js.map +0 -1
  227. package/dist/styles/radius.d.ts +0 -14
  228. package/dist/styles/radius.js +0 -51
  229. package/dist/styles/radius.js.map +0 -1
  230. package/dist/styles/scrollbar.d.ts +0 -21
  231. package/dist/styles/scrollbar.js +0 -112
  232. package/dist/styles/scrollbar.js.map +0 -1
  233. package/dist/styles/shadow.d.ts +0 -14
  234. package/dist/styles/shadow.js +0 -24
  235. package/dist/styles/shadow.js.map +0 -1
  236. package/dist/styles/styledScrollbar.d.ts +0 -47
  237. package/dist/styles/styledScrollbar.js +0 -38
  238. package/dist/styles/styledScrollbar.js.map +0 -1
  239. package/dist/styles/transition.d.ts +0 -14
  240. package/dist/styles/transition.js +0 -158
  241. package/dist/styles/transition.js.map +0 -1
  242. package/dist/styles/types.d.ts +0 -498
  243. package/dist/styles/width.d.ts +0 -17
  244. package/dist/styles/width.js +0 -20
  245. package/dist/styles/width.js.map +0 -1
  246. package/dist/tasty.d.ts +0 -982
  247. package/dist/tasty.js +0 -206
  248. package/dist/tasty.js.map +0 -1
  249. package/dist/tokens/typography.d.ts +0 -19
  250. package/dist/tokens/typography.js +0 -237
  251. package/dist/tokens/typography.js.map +0 -1
  252. package/dist/types.d.ts +0 -184
  253. package/dist/utils/cache-wrapper.js +0 -26
  254. package/dist/utils/cache-wrapper.js.map +0 -1
  255. package/dist/utils/case-converter.js +0 -8
  256. package/dist/utils/case-converter.js.map +0 -1
  257. package/dist/utils/colors.d.ts +0 -5
  258. package/dist/utils/colors.js +0 -9
  259. package/dist/utils/colors.js.map +0 -1
  260. package/dist/utils/css-types.d.ts +0 -7
  261. package/dist/utils/dotize.d.ts +0 -26
  262. package/dist/utils/dotize.js +0 -122
  263. package/dist/utils/dotize.js.map +0 -1
  264. package/dist/utils/filter-base-props.d.ts +0 -15
  265. package/dist/utils/filter-base-props.js +0 -45
  266. package/dist/utils/filter-base-props.js.map +0 -1
  267. package/dist/utils/get-display-name.d.ts +0 -7
  268. package/dist/utils/get-display-name.js +0 -10
  269. package/dist/utils/get-display-name.js.map +0 -1
  270. package/dist/utils/hsl-to-rgb.js +0 -38
  271. package/dist/utils/hsl-to-rgb.js.map +0 -1
  272. package/dist/utils/is-dev-env.js +0 -19
  273. package/dist/utils/is-dev-env.js.map +0 -1
  274. package/dist/utils/is-valid-element-type.js +0 -15
  275. package/dist/utils/is-valid-element-type.js.map +0 -1
  276. package/dist/utils/merge-styles.js.map +0 -1
  277. package/dist/utils/mod-attrs.d.ts +0 -8
  278. package/dist/utils/mod-attrs.js +0 -21
  279. package/dist/utils/mod-attrs.js.map +0 -1
  280. package/dist/utils/okhsl-to-rgb.js +0 -296
  281. package/dist/utils/okhsl-to-rgb.js.map +0 -1
  282. package/dist/utils/process-tokens.d.ts +0 -31
  283. package/dist/utils/process-tokens.js +0 -171
  284. package/dist/utils/process-tokens.js.map +0 -1
  285. package/dist/utils/resolve-recipes.d.ts +0 -17
  286. package/dist/utils/resolve-recipes.js.map +0 -1
  287. package/dist/utils/string.js +0 -8
  288. package/dist/utils/string.js.map +0 -1
  289. package/dist/utils/styles.d.ts +0 -178
  290. package/dist/utils/styles.js +0 -590
  291. package/dist/utils/styles.js.map +0 -1
  292. package/dist/utils/typography.d.ts +0 -36
  293. package/dist/utils/typography.js +0 -53
  294. package/dist/utils/typography.js.map +0 -1
  295. package/dist/utils/warnings.d.ts +0 -16
  296. package/dist/utils/warnings.js +0 -16
  297. package/dist/utils/warnings.js.map +0 -1
  298. package/dist/zero/css-writer.d.ts +0 -45
  299. package/dist/zero/css-writer.js +0 -74
  300. package/dist/zero/css-writer.js.map +0 -1
  301. package/dist/zero/extractor.d.ts +0 -24
  302. package/dist/zero/extractor.js +0 -150
  303. package/dist/zero/extractor.js.map +0 -1
@@ -1,11 +1,18 @@
1
- import { configure } from "../config.js";
2
- import { mergeStyles } from "../utils/merge-styles.js";
3
- import { resolveRecipes } from "../utils/resolve-recipes.js";
4
- import { extractKeyframesFromStyles, extractStylesForSelector, extractStylesWithChunks } from "./extractor.js";
5
- import { CSSWriter } from "./css-writer.js";
1
+ import { i as getGlobalConfigTokens, t as configure, u as getGlobalStyles, v as resetConfig } from "../config-BBiyxMCe.js";
2
+ import { t as mergeStyles } from "../merge-styles-Cd2vBl9b.js";
3
+ import { t as resolveRecipes } from "../resolve-recipes-C1nrvnYh.js";
4
+ import { a as extractPropertiesFromStyles, c as setExtractorNamePrefix, i as extractKeyframesFromStyles, n as extractCounterStyleFromStyles, o as extractStylesForSelector, r as extractFontFaceFromStyles, s as extractStylesWithChunks, t as CSSWriter } from "../css-writer-BWvwQzz0.js";
5
+ import * as fs from "fs";
6
+ import * as path from "path";
6
7
  import { declare } from "@babel/helper-plugin-utils";
7
8
  import * as t from "@babel/types";
8
-
9
+ import { createJiti } from "jiti";
10
+ //#region \0rolldown/runtime.js
11
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
12
+ if (typeof require !== "undefined") return require.apply(this, arguments);
13
+ throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
14
+ });
15
+ //#endregion
9
16
  //#region src/zero/babel.ts
10
17
  /**
11
18
  * Babel plugin for zero-runtime tasty static site generation.
@@ -25,34 +32,138 @@ import * as t from "@babel/types";
25
32
  * };
26
33
  * ```
27
34
  */
35
+ function mtime(filePath) {
36
+ try {
37
+ return fs.statSync(filePath).mtimeMs;
38
+ } catch {
39
+ return null;
40
+ }
41
+ }
42
+ function clearRequireCacheTree(filePath) {
43
+ let resolved;
44
+ try {
45
+ resolved = __require.resolve(filePath);
46
+ } catch {
47
+ return;
48
+ }
49
+ const mod = __require.cache[resolved];
50
+ if (!mod) return;
51
+ const dir = resolved.substring(0, resolved.lastIndexOf("/"));
52
+ if (mod.children) {
53
+ for (const child of mod.children) if (child.id.startsWith(dir) && !child.id.includes("node_modules")) clearRequireCacheTree(child.id);
54
+ }
55
+ delete __require.cache[resolved];
56
+ }
57
+ const writerCache = /* @__PURE__ */ new Map();
58
+ /** Clear the shared CSSWriter cache. Exposed for testing. */
59
+ function clearWriterCache() {
60
+ writerCache.clear();
61
+ }
28
62
  var babel_default = declare((api, options) => {
29
63
  api.assertVersion(7);
64
+ const mode = options.mode ?? "file";
30
65
  const outputPath = options.output || "tasty.css";
31
- const config = options.config || {};
66
+ const resolvedOutputPath = path.resolve(outputPath);
67
+ const injectImport = options.injectImport ?? true;
68
+ if (mode === "file" && injectImport) {
69
+ const dir = path.dirname(resolvedOutputPath);
70
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
71
+ if (!fs.existsSync(resolvedOutputPath)) fs.writeFileSync(resolvedOutputPath, "/* Generated by @tenphi/tasty/zero - DO NOT EDIT */\n");
72
+ }
73
+ const configDeps = [...options.configFile ? [options.configFile] : [], ...options.configDeps || []];
74
+ const configKey = configDeps.length > 0 ? configDeps.map(mtime).join(",") : "";
75
+ if (configDeps.length > 0) {
76
+ api.cache.using(() => configKey);
77
+ for (const dep of configDeps) try {
78
+ api.addExternalDependency(dep);
79
+ } catch {}
80
+ } else api.cache.forever();
81
+ if (configDeps.length > 0) for (const dep of configDeps) clearRequireCacheTree(dep);
82
+ const cached = writerCache.get(resolvedOutputPath);
83
+ if (!cached || cached.configKey !== configKey) {
84
+ const configOption = options.config;
85
+ let resolvedConfig;
86
+ if (configOption) resolvedConfig = typeof configOption === "function" ? configOption() : configOption;
87
+ else if (options.configFile) {
88
+ const loaded = createJiti(path.dirname(options.configFile), { moduleCache: false })(options.configFile);
89
+ resolvedConfig = loaded && typeof loaded === "object" && "default" in loaded ? loaded.default : loaded;
90
+ } else resolvedConfig = {};
91
+ const devMode = resolvedConfig.devMode ?? false;
92
+ if (cached) resetConfig();
93
+ const finalConfig = {
94
+ namePrefix: "ts",
95
+ ...resolvedConfig
96
+ };
97
+ configure(finalConfig);
98
+ setExtractorNamePrefix(finalConfig.namePrefix ?? "ts");
99
+ const newWriter = new CSSWriter(outputPath, { devMode });
100
+ if (mode !== "inject") {
101
+ const tokenCSS = extractCSSFromStyles(":root", getGlobalConfigTokens());
102
+ if (tokenCSS) newWriter.add(":root:tokens", tokenCSS);
103
+ const globalStyles = getGlobalStyles();
104
+ if (globalStyles) for (const [selector, styles] of Object.entries(globalStyles)) {
105
+ const css = extractCSSFromStyles(selector, styles);
106
+ if (css) newWriter.add(`global:${selector}`, css);
107
+ }
108
+ }
109
+ writerCache.set(resolvedOutputPath, {
110
+ writer: newWriter,
111
+ configKey,
112
+ registry: {},
113
+ config: finalConfig
114
+ });
115
+ }
116
+ const entry = writerCache.get(resolvedOutputPath);
117
+ const cssWriter = entry.writer;
118
+ const globalRegistry = entry.registry;
119
+ const config = entry.config;
32
120
  const devMode = config.devMode ?? false;
33
- configure(config);
34
- const cssWriter = new CSSWriter(outputPath, { devMode });
35
- const globalRegistry = {};
121
+ setExtractorNamePrefix(config.namePrefix ?? "ts");
122
+ let tokenCSS;
123
+ let globalStylesCSS;
124
+ if (mode === "inject") {
125
+ tokenCSS = extractCSSFromStyles(":root", getGlobalConfigTokens());
126
+ const gs = getGlobalStyles();
127
+ if (gs) {
128
+ globalStylesCSS = /* @__PURE__ */ new Map();
129
+ for (const [selector, styles] of Object.entries(gs)) {
130
+ const css = extractCSSFromStyles(selector, styles);
131
+ if (css) globalStylesCSS.set(selector, css);
132
+ }
133
+ if (globalStylesCSS.size === 0) globalStylesCSS = void 0;
134
+ }
135
+ }
36
136
  return {
37
137
  name: "tasty-zero",
38
138
  pre() {
39
139
  this.staticStyleRegistry = {};
140
+ this._fileAddedCSS = false;
40
141
  if (devMode && this.filename) this.sourceFile = this.filename.split("/").pop() || this.filename;
41
142
  },
42
143
  visitor: {
43
- ImportDeclaration(path) {
44
- const source = path.node.source.value;
45
- if (source === "@tenphi/tasty/static" || source.endsWith("/tasty/static")) path.remove();
144
+ ImportDeclaration(nodePath, state) {
145
+ const source = nodePath.node.source.value;
146
+ if (source === "@tenphi/tasty/static" || source.endsWith("/tasty/static")) if (mode === "inject") nodePath.replaceWith(t.importDeclaration([t.importSpecifier(t.identifier("_$i"), t.identifier("injectCSS"))], t.stringLiteral("@tenphi/tasty/static/inject")));
147
+ else if (injectImport) {
148
+ let importPath = resolvedOutputPath;
149
+ if (state.filename) {
150
+ const sourceDir = path.dirname(state.filename);
151
+ importPath = path.relative(sourceDir, resolvedOutputPath);
152
+ if (!importPath.startsWith(".")) importPath = "./" + importPath;
153
+ }
154
+ nodePath.replaceWith(t.importDeclaration([], t.stringLiteral(importPath)));
155
+ } else nodePath.remove();
46
156
  },
47
157
  CallExpression(path, state) {
48
158
  const callee = path.node.callee;
49
159
  if (!t.isIdentifier(callee, { name: "tastyStatic" })) return;
160
+ state._fileAddedCSS = true;
50
161
  const args = path.node.arguments;
51
162
  if (args.length === 0) throw path.buildCodeFrameError("tastyStatic() requires at least one argument");
52
163
  const firstArg = args[0];
53
- if (t.isStringLiteral(firstArg)) handleSelectorMode(path, args, cssWriter, state.sourceFile, config.keyframes);
54
- else if (t.isObjectExpression(firstArg)) handleStylesMode(path, args, cssWriter, state, globalRegistry, config.keyframes);
55
- else if (t.isIdentifier(firstArg)) handleExtensionMode(path, args, cssWriter, state, globalRegistry, config.keyframes);
164
+ if (t.isStringLiteral(firstArg)) handleSelectorMode(path, args, cssWriter, mode, state.sourceFile, config.keyframes, config.autoPropertyTypes, config.fontFace, config.counterStyle);
165
+ else if (t.isObjectExpression(firstArg)) handleStylesMode(path, args, cssWriter, state, globalRegistry, mode, config.keyframes, config.autoPropertyTypes, config.fontFace, config.counterStyle);
166
+ else if (t.isIdentifier(firstArg)) handleExtensionMode(path, args, cssWriter, state, globalRegistry, mode, config.keyframes, config.autoPropertyTypes, config.fontFace, config.counterStyle);
56
167
  else throw path.buildCodeFrameError("tastyStatic() first argument must be an object (styles), identifier (base StaticStyle), or string (selector)");
57
168
  },
58
169
  VariableDeclarator(path, state) {
@@ -76,7 +187,25 @@ var babel_default = declare((api, options) => {
76
187
  }
77
188
  },
78
189
  post() {
79
- if (cssWriter.size > 0) cssWriter.write();
190
+ if (mode === "inject") {
191
+ if (this._fileAddedCSS && (tokenCSS || globalStylesCSS)) {
192
+ const program = this.file.ast.program;
193
+ let insertIndex = 0;
194
+ for (let i = 0; i < program.body.length; i++) if (t.isImportDeclaration(program.body[i])) insertIndex = i + 1;
195
+ if (tokenCSS) {
196
+ const injectCall = createInjectCallAST(":root", tokenCSS);
197
+ program.body.splice(insertIndex, 0, t.expressionStatement(injectCall));
198
+ insertIndex++;
199
+ }
200
+ if (globalStylesCSS) for (const [selector, css] of globalStylesCSS) {
201
+ const injectCall = createInjectCallAST(selector, css);
202
+ program.body.splice(insertIndex, 0, t.expressionStatement(injectCall));
203
+ insertIndex++;
204
+ }
205
+ }
206
+ return;
207
+ }
208
+ if (this._fileAddedCSS && cssWriter.size > 0) cssWriter.write();
80
209
  }
81
210
  };
82
211
  });
@@ -105,26 +234,30 @@ function extractClassNameFromStaticStyleObject(node) {
105
234
  /**
106
235
  * Handle tastyStatic(styles) - returns StaticStyle object
107
236
  */
108
- function handleStylesMode(path, args, cssWriter, state, globalRegistry, globalKeyframes) {
237
+ function handleStylesMode(path, args, cssWriter, state, globalRegistry, mode, globalKeyframes, autoPropertyTypes, globalFontFace, globalCounterStyle) {
109
238
  const stylesArg = args[0];
110
239
  if (!t.isObjectExpression(stylesArg)) throw path.buildCodeFrameError("tastyStatic(styles) argument must be a static object literal");
111
240
  const styles = resolveRecipes(evaluateObjectExpression(stylesArg, path));
112
241
  const { keyframes, nameMap } = extractKeyframesFromStyles(styles, globalKeyframes);
113
- for (const kf of keyframes) cssWriter.add(kf.css, kf.css, state.sourceFile);
242
+ const properties = extractPropertiesFromStyles(styles, { autoPropertyTypes });
243
+ const fontFaces = extractFontFaceFromStyles(styles, globalFontFace);
244
+ const counterStyles = extractCounterStyleFromStyles(styles, globalCounterStyle);
114
245
  const chunks = extractStylesWithChunks(styles);
115
- for (const chunk of chunks) {
116
- const css = nameMap.size > 0 ? replaceAnimationNamesInCSS(chunk.css, nameMap) : chunk.css;
117
- cssWriter.add(chunk.className, css, state.sourceFile);
118
- }
119
246
  const className = chunks.length > 0 ? chunks.map((c) => c.className).join(" ") : "";
120
247
  const staticStyleObject = createStaticStyleAST(className, styles);
121
- path.replaceWith(staticStyleObject);
248
+ if (mode === "inject") {
249
+ const injectCall = createInjectCallAST(className, collectAllCSS(keyframes, properties, fontFaces, counterStyles, chunks, nameMap));
250
+ path.replaceWith(t.sequenceExpression([injectCall, staticStyleObject]));
251
+ } else {
252
+ writeCSSToWriter(cssWriter, keyframes, properties, fontFaces, counterStyles, chunks, nameMap, state.sourceFile);
253
+ path.replaceWith(staticStyleObject);
254
+ }
122
255
  registerIfVariableDeclaration(path, className, styles, state, globalRegistry);
123
256
  }
124
257
  /**
125
258
  * Handle tastyStatic(base, styles) - extends base with additional styles
126
259
  */
127
- function handleExtensionMode(path, args, cssWriter, state, globalRegistry, globalKeyframes) {
260
+ function handleExtensionMode(path, args, cssWriter, state, globalRegistry, mode, globalKeyframes, autoPropertyTypes, globalFontFace, globalCounterStyle) {
128
261
  if (args.length < 2) throw path.buildCodeFrameError("tastyStatic(base, styles) requires two arguments");
129
262
  const baseArg = args[0];
130
263
  const stylesArg = args[1];
@@ -136,21 +269,25 @@ function handleExtensionMode(path, args, cssWriter, state, globalRegistry, globa
136
269
  const overrideStyles = evaluateObjectExpression(stylesArg, path);
137
270
  const mergedStyles = resolveRecipes(mergeStyles(baseEntry.styles, overrideStyles));
138
271
  const { keyframes, nameMap } = extractKeyframesFromStyles(mergedStyles, globalKeyframes);
139
- for (const kf of keyframes) cssWriter.add(kf.css, kf.css, state.sourceFile);
272
+ const properties = extractPropertiesFromStyles(mergedStyles, { autoPropertyTypes });
273
+ const fontFaces = extractFontFaceFromStyles(mergedStyles, globalFontFace);
274
+ const counterStyles = extractCounterStyleFromStyles(mergedStyles, globalCounterStyle);
140
275
  const chunks = extractStylesWithChunks(mergedStyles);
141
- for (const chunk of chunks) {
142
- const css = nameMap.size > 0 ? replaceAnimationNamesInCSS(chunk.css, nameMap) : chunk.css;
143
- cssWriter.add(chunk.className, css, state.sourceFile);
144
- }
145
276
  const className = chunks.length > 0 ? chunks.map((c) => c.className).join(" ") : "";
146
277
  const staticStyleObject = createStaticStyleAST(className, mergedStyles);
147
- path.replaceWith(staticStyleObject);
278
+ if (mode === "inject") {
279
+ const injectCall = createInjectCallAST(className, collectAllCSS(keyframes, properties, fontFaces, counterStyles, chunks, nameMap));
280
+ path.replaceWith(t.sequenceExpression([injectCall, staticStyleObject]));
281
+ } else {
282
+ writeCSSToWriter(cssWriter, keyframes, properties, fontFaces, counterStyles, chunks, nameMap, state.sourceFile);
283
+ path.replaceWith(staticStyleObject);
284
+ }
148
285
  registerIfVariableDeclaration(path, className, mergedStyles, state, globalRegistry);
149
286
  }
150
287
  /**
151
288
  * Handle tastyStatic(selector, styles) - removes the call entirely
152
289
  */
153
- function handleSelectorMode(path, args, cssWriter, sourceFile, globalKeyframes) {
290
+ function handleSelectorMode(path, args, cssWriter, mode, sourceFile, globalKeyframes, autoPropertyTypes, globalFontFace, globalCounterStyle) {
154
291
  if (args.length < 2) throw path.buildCodeFrameError("tastyStatic(selector, styles) requires two arguments");
155
292
  const selectorArg = args[0];
156
293
  const stylesArg = args[1];
@@ -159,13 +296,68 @@ function handleSelectorMode(path, args, cssWriter, sourceFile, globalKeyframes)
159
296
  const selector = selectorArg.value;
160
297
  const styles = resolveRecipes(evaluateObjectExpression(stylesArg, path));
161
298
  const { keyframes, nameMap } = extractKeyframesFromStyles(styles, globalKeyframes);
162
- for (const kf of keyframes) cssWriter.add(kf.css, kf.css, sourceFile);
299
+ const properties = extractPropertiesFromStyles(styles, { autoPropertyTypes });
300
+ const fontFaces = extractFontFaceFromStyles(styles, globalFontFace);
301
+ const counterStyles = extractCounterStyleFromStyles(styles, globalCounterStyle);
163
302
  const result = extractStylesForSelector(selector, styles);
164
- const css = nameMap.size > 0 ? replaceAnimationNamesInCSS(result.css, nameMap) : result.css;
165
- cssWriter.add(selector, css, sourceFile);
166
- const parent = path.parentPath;
167
- if (parent && t.isExpressionStatement(parent.node)) parent.remove();
168
- else path.replaceWith(t.identifier("undefined"));
303
+ const selectorCSS = nameMap.size > 0 ? replaceAnimationNamesInCSS(result.css, nameMap) : result.css;
304
+ if (mode === "inject") {
305
+ const cssParts = [];
306
+ for (const kf of keyframes) cssParts.push(kf.css);
307
+ for (const prop of properties) cssParts.push(prop.css);
308
+ for (const ff of fontFaces) cssParts.push(ff.css);
309
+ for (const cs of counterStyles) cssParts.push(cs.css);
310
+ cssParts.push(selectorCSS);
311
+ const injectCall = createInjectCallAST(selector, cssParts.join("\n"));
312
+ const parent = path.parentPath;
313
+ if (parent && t.isExpressionStatement(parent.node)) parent.replaceWith(t.expressionStatement(injectCall));
314
+ else path.replaceWith(injectCall);
315
+ } else {
316
+ writeCSSToWriter(cssWriter, keyframes, properties, fontFaces, counterStyles, [], nameMap, sourceFile);
317
+ cssWriter.add(selector, selectorCSS, sourceFile);
318
+ const parent = path.parentPath;
319
+ if (parent && t.isExpressionStatement(parent.node)) parent.remove();
320
+ else path.replaceWith(t.identifier("undefined"));
321
+ }
322
+ }
323
+ /**
324
+ * Collect all extracted CSS parts into a single string (for inject mode).
325
+ */
326
+ function collectAllCSS(keyframes, properties, fontFaces, counterStyles, chunks, nameMap) {
327
+ const parts = [];
328
+ for (const kf of keyframes) parts.push(kf.css);
329
+ for (const prop of properties) parts.push(prop.css);
330
+ for (const ff of fontFaces) parts.push(ff.css);
331
+ for (const cs of counterStyles) parts.push(cs.css);
332
+ for (const chunk of chunks) parts.push(nameMap.size > 0 ? replaceAnimationNamesInCSS(chunk.css, nameMap) : chunk.css);
333
+ return parts.join("\n");
334
+ }
335
+ /**
336
+ * Write all extracted CSS parts to a CSSWriter (for file mode).
337
+ */
338
+ function writeCSSToWriter(cssWriter, keyframes, properties, fontFaces, counterStyles, chunks, nameMap, sourceFile) {
339
+ for (const kf of keyframes) cssWriter.add(kf.css, kf.css, sourceFile);
340
+ for (const prop of properties) cssWriter.add(prop.css, prop.css, sourceFile);
341
+ for (const ff of fontFaces) cssWriter.add(ff.css, ff.css, sourceFile);
342
+ for (const cs of counterStyles) cssWriter.add(cs.css, cs.css, sourceFile);
343
+ for (const chunk of chunks) {
344
+ const css = nameMap.size > 0 ? replaceAnimationNamesInCSS(chunk.css, nameMap) : chunk.css;
345
+ cssWriter.add(chunk.className, css, sourceFile);
346
+ }
347
+ }
348
+ /**
349
+ * Extract CSS for a selector from a styles/tokens object.
350
+ * Returns undefined when there are no styles or no CSS output.
351
+ */
352
+ function extractCSSFromStyles(selector, styles) {
353
+ if (!styles || Object.keys(styles).length === 0) return void 0;
354
+ return extractStylesForSelector(selector, styles).css || void 0;
355
+ }
356
+ /**
357
+ * Create an `_$i(id, css)` call expression AST node for inject mode.
358
+ */
359
+ function createInjectCallAST(id, css) {
360
+ return t.callExpression(t.identifier("_$i"), [t.stringLiteral(id), t.stringLiteral(css)]);
169
361
  }
170
362
  /**
171
363
  * Create a StaticStyle object AST node
@@ -276,7 +468,7 @@ function replaceAnimationNamesInCSS(css, nameMap) {
276
468
  function escapeRegex(str) {
277
469
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
278
470
  }
279
-
280
471
  //#endregion
281
- export { babel_default as default };
472
+ export { clearWriterCache, babel_default as default };
473
+
282
474
  //# sourceMappingURL=babel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"babel.js","names":[],"sources":["../../src/zero/babel.ts"],"sourcesContent":["/**\n * Babel plugin for zero-runtime tasty static site generation.\n *\n * Transforms:\n * - `tastyStatic(styles)` → StaticStyle object { className, styles, toString() }\n * - `tastyStatic(base, styles)` → StaticStyle object with merged styles\n * - `tastyStatic(selector, styles)` → removed entirely\n *\n * Usage:\n * ```javascript\n * // babel.config.js\n * module.exports = {\n * plugins: [\n * ['@tenphi/tasty/babel-plugin', { output: 'public/tasty.css' }]\n * ]\n * };\n * ```\n */\n\nimport { declare } from '@babel/helper-plugin-utils';\nimport * as t from '@babel/types';\n\nimport { configure } from '../config';\nimport type { RecipeStyles, Styles } from '../styles/types';\nimport { mergeStyles } from '../utils/merge-styles';\nimport { resolveRecipes } from '../utils/resolve-recipes';\nimport type { StyleHandlerDefinition } from '../utils/styles';\n\nimport { CSSWriter } from './css-writer';\nimport {\n extractKeyframesFromStyles,\n extractStylesForSelector,\n extractStylesWithChunks,\n} from './extractor';\n\nimport type { NodePath, PluginPass } from '@babel/core';\nimport type { KeyframesSteps } from '../injector/types';\nimport type { StyleDetails, UnitHandler } from '../parser/types';\nimport type { TastyPlugin } from '../plugins/types';\n\n/**\n * Build-time configuration for zero-runtime mode.\n * Subset of TastyConfig that applies at build time.\n */\nexport interface TastyZeroConfig {\n /**\n * Global predefined states for advanced state mapping.\n * Example: { '@mobile': '@media(w < 768px)', '@dark': '@root(theme=dark)' }\n */\n states?: Record<string, string>;\n /**\n * Enable development mode features: source comments in generated CSS.\n * Default: false\n */\n devMode?: boolean;\n /**\n * Parser LRU cache size (default: 1000).\n * Larger values improve performance for builds with many unique style values.\n */\n parserCacheSize?: number;\n /**\n * Custom units for the style parser (merged with built-in units).\n * Units transform numeric values like `2x` → `calc(2 * var(--gap))`.\n * @example { em: 'em', vw: 'vw', custom: (n) => `${n * 10}px` }\n */\n units?: Record<string, string | UnitHandler>;\n /**\n * Custom functions for the style parser (merged with existing).\n * Functions process parsed style groups and return CSS values.\n * @example { myFunc: (groups) => groups.map(g => g.output).join(' ') }\n */\n funcs?: Record<string, (groups: StyleDetails[]) => string>;\n /**\n * Plugins that extend tasty with custom functions, units, states, handlers, or tokens.\n * Plugins are processed in order, with later plugins overriding earlier ones.\n * @example\n * ```ts\n * import { okhslPlugin } from '@tenphi/tasty';\n *\n * // babel.config.js\n * module.exports = {\n * plugins: [\n * ['@tenphi/tasty/babel-plugin', {\n * config: { plugins: [okhslPlugin()] }\n * }]\n * ]\n * };\n * ```\n */\n plugins?: TastyPlugin[];\n /**\n * Global keyframes definitions for static extraction.\n * Keys are animation names, values are keyframes step definitions.\n * @example { fadeIn: { from: { opacity: 0 }, to: { opacity: 1 } } }\n */\n keyframes?: Record<string, KeyframesSteps>;\n /**\n * Custom style handlers that transform style properties into CSS declarations.\n * Handlers replace built-in handlers for the same style name.\n * @example\n * ```ts\n * handlers: {\n * fill: ({ fill }) => fill ? { 'background-color': fill } : undefined,\n * elevation: ({ elevation }) => ({\n * 'box-shadow': `0 ${elevation}px ${elevation * 2}px rgba(0,0,0,0.1)`,\n * }),\n * }\n * ```\n */\n handlers?: Record<string, StyleHandlerDefinition>;\n /**\n * Predefined tokens that are replaced during style parsing.\n * Use `$name` for custom properties and `#name` for color tokens.\n * @example { $spacing: '2x', '#accent': '#purple' }\n */\n tokens?: Record<`$${string}` | `#${string}`, string | number>;\n /**\n * Predefined style recipes -- named style bundles that can be applied via `recipe` style property.\n * Recipe values are flat tasty styles (no sub-element keys).\n * @example\n * ```ts\n * recipes: {\n * card: { padding: '4x', fill: '#surface', radius: '1r', border: true },\n * elevated: { shadow: '2x 2x 4x #shadow' },\n * }\n * ```\n */\n recipes?: Record<string, RecipeStyles>;\n}\n\nexport interface TastyZeroBabelOptions {\n /** Output path for generated CSS (default: 'tasty.css') */\n output?: string;\n /** Tasty configuration for build-time processing */\n config?: TastyZeroConfig;\n}\n\n/**\n * Registry to track StaticStyle objects by their variable names.\n * Used to resolve base styles when extending.\n */\ntype StaticStyleRegistry = Record<\n string,\n {\n styles: Styles;\n className: string;\n }\n>;\n\ninterface PluginState extends PluginPass {\n staticStyleRegistry: StaticStyleRegistry;\n /** Current source file path (for devMode source comments) */\n sourceFile?: string;\n}\n\n// @ts-expect-error PluginState vs PluginPass type mismatch in @babel/helper-plugin-utils\nexport default declare<TastyZeroBabelOptions>((api, options) => {\n api.assertVersion(7);\n\n const outputPath = options.output || 'tasty.css';\n const config = options.config || {};\n const devMode = config.devMode ?? false;\n\n // Apply configuration using the shared configure() function\n // This handles plugin merging, states, units, funcs, handlers, tokens, etc.\n configure(config);\n\n const cssWriter = new CSSWriter(outputPath, { devMode });\n\n // Global registry for cross-file references (same build)\n const globalRegistry: StaticStyleRegistry = {};\n\n return {\n name: 'tasty-zero',\n\n pre(this: PluginState) {\n // Initialize per-file registry\n this.staticStyleRegistry = {};\n // Extract source filename for devMode comments\n if (devMode && this.filename) {\n // Get relative path or just filename\n this.sourceFile = this.filename.split('/').pop() || this.filename;\n }\n },\n\n visitor: {\n // Remove import statements for tasty/static\n ImportDeclaration(path: NodePath<t.ImportDeclaration>) {\n const source = path.node.source.value;\n\n if (\n source === '@tenphi/tasty/static' ||\n source.endsWith('/tasty/static')\n ) {\n path.remove();\n }\n },\n\n // Transform tastyStatic() calls\n CallExpression(path: NodePath<t.CallExpression>, state: PluginState) {\n const callee = path.node.callee;\n\n // Match tastyStatic(...) calls\n if (!t.isIdentifier(callee, { name: 'tastyStatic' })) {\n return;\n }\n\n const args = path.node.arguments;\n\n if (args.length === 0) {\n throw path.buildCodeFrameError(\n 'tastyStatic() requires at least one argument',\n );\n }\n\n const firstArg = args[0];\n\n if (t.isStringLiteral(firstArg)) {\n // Selector mode: tastyStatic(selector, styles)\n handleSelectorMode(\n path,\n args,\n cssWriter,\n state.sourceFile,\n config.keyframes,\n );\n } else if (t.isObjectExpression(firstArg)) {\n // Styles mode: tastyStatic(styles)\n handleStylesMode(\n path,\n args,\n cssWriter,\n state,\n globalRegistry,\n config.keyframes,\n );\n } else if (t.isIdentifier(firstArg)) {\n // Extension mode: tastyStatic(base, styles)\n handleExtensionMode(\n path,\n args,\n cssWriter,\n state,\n globalRegistry,\n config.keyframes,\n );\n } else {\n throw path.buildCodeFrameError(\n 'tastyStatic() first argument must be an object (styles), ' +\n 'identifier (base StaticStyle), or string (selector)',\n );\n }\n },\n\n // Track variable declarations to register StaticStyle objects\n VariableDeclarator(\n path: NodePath<t.VariableDeclarator>,\n state: PluginState,\n ) {\n const init = path.node.init;\n const id = path.node.id;\n\n // Check if this is a StaticStyle object (has className and styles properties)\n if (\n t.isIdentifier(id) &&\n t.isObjectExpression(init) &&\n isStaticStyleObject(init)\n ) {\n const variableName = id.name;\n const styles = extractStylesFromStaticStyleObject(init, path);\n const className = extractClassNameFromStaticStyleObject(init);\n\n if (styles && className) {\n state.staticStyleRegistry[variableName] = { styles, className };\n globalRegistry[variableName] = { styles, className };\n }\n }\n },\n },\n\n post() {\n // Write all collected CSS at the end of the build\n if (cssWriter.size > 0) {\n cssWriter.write();\n }\n },\n };\n});\n\n/**\n * Check if an object expression looks like a StaticStyle object\n */\nfunction isStaticStyleObject(node: t.ObjectExpression): boolean {\n const hasClassName = node.properties.some(\n (p) =>\n t.isObjectProperty(p) && t.isIdentifier(p.key, { name: 'className' }),\n );\n const hasStyles = node.properties.some(\n (p) => t.isObjectProperty(p) && t.isIdentifier(p.key, { name: 'styles' }),\n );\n return hasClassName && hasStyles;\n}\n\n/**\n * Extract styles object from a StaticStyle object expression\n */\nfunction extractStylesFromStaticStyleObject(\n node: t.ObjectExpression,\n path: NodePath,\n): Styles | null {\n for (const prop of node.properties) {\n if (\n t.isObjectProperty(prop) &&\n t.isIdentifier(prop.key, { name: 'styles' }) &&\n t.isObjectExpression(prop.value)\n ) {\n return evaluateObjectExpression(prop.value, path) as Styles;\n }\n }\n return null;\n}\n\n/**\n * Extract className from a StaticStyle object expression\n */\nfunction extractClassNameFromStaticStyleObject(\n node: t.ObjectExpression,\n): string | null {\n for (const prop of node.properties) {\n if (\n t.isObjectProperty(prop) &&\n t.isIdentifier(prop.key, { name: 'className' }) &&\n t.isStringLiteral(prop.value)\n ) {\n return prop.value.value;\n }\n }\n return null;\n}\n\n/**\n * Handle tastyStatic(styles) - returns StaticStyle object\n */\nfunction handleStylesMode(\n path: NodePath<t.CallExpression>,\n args: t.CallExpression['arguments'],\n cssWriter: CSSWriter,\n state: PluginState,\n globalRegistry: StaticStyleRegistry,\n globalKeyframes?: Record<string, KeyframesSteps>,\n): void {\n const stylesArg = args[0];\n\n if (!t.isObjectExpression(stylesArg)) {\n throw path.buildCodeFrameError(\n 'tastyStatic(styles) argument must be a static object literal',\n );\n }\n\n // Evaluate styles object at build time\n const rawStyles = evaluateObjectExpression(stylesArg, path) as Styles;\n\n // Resolve recipes before extraction\n const styles = resolveRecipes(rawStyles);\n\n // Extract keyframes (deduplicated by content)\n const { keyframes, nameMap } = extractKeyframesFromStyles(\n styles,\n globalKeyframes,\n );\n\n // Add keyframes CSS\n for (const kf of keyframes) {\n cssWriter.add(kf.css, kf.css, state.sourceFile);\n }\n\n // Extract styles with chunking\n const chunks = extractStylesWithChunks(styles);\n\n // Add CSS to writer, replacing animation names if needed\n for (const chunk of chunks) {\n const css =\n nameMap.size > 0\n ? replaceAnimationNamesInCSS(chunk.css, nameMap)\n : chunk.css;\n cssWriter.add(chunk.className, css, state.sourceFile);\n }\n\n // Generate className\n const className =\n chunks.length > 0 ? chunks.map((c) => c.className).join(' ') : '';\n\n // Replace call with StaticStyle object\n const staticStyleObject = createStaticStyleAST(className, styles);\n path.replaceWith(staticStyleObject);\n\n // Register if this is being assigned to a variable\n registerIfVariableDeclaration(path, className, styles, state, globalRegistry);\n}\n\n/**\n * Handle tastyStatic(base, styles) - extends base with additional styles\n */\nfunction handleExtensionMode(\n path: NodePath<t.CallExpression>,\n args: t.CallExpression['arguments'],\n cssWriter: CSSWriter,\n state: PluginState,\n globalRegistry: StaticStyleRegistry,\n globalKeyframes?: Record<string, KeyframesSteps>,\n): void {\n if (args.length < 2) {\n throw path.buildCodeFrameError(\n 'tastyStatic(base, styles) requires two arguments',\n );\n }\n\n const baseArg = args[0];\n const stylesArg = args[1];\n\n if (!t.isIdentifier(baseArg)) {\n throw path.buildCodeFrameError(\n 'tastyStatic(base, styles) first argument must be an identifier',\n );\n }\n\n if (!t.isObjectExpression(stylesArg)) {\n throw path.buildCodeFrameError(\n 'tastyStatic(base, styles) second argument must be a static object literal',\n );\n }\n\n const baseName = baseArg.name;\n\n // Look up base styles in registry\n const baseEntry =\n state.staticStyleRegistry[baseName] || globalRegistry[baseName];\n\n if (!baseEntry) {\n throw path.buildCodeFrameError(\n `Cannot find base StaticStyle '${baseName}'. ` +\n 'Make sure it is defined before being extended.',\n );\n }\n\n // Evaluate override styles\n const overrideStyles = evaluateObjectExpression(stylesArg, path) as Styles;\n\n // Merge styles using mergeStyles, then resolve recipes\n const mergedStyles = resolveRecipes(\n mergeStyles(baseEntry.styles, overrideStyles),\n );\n\n // Extract keyframes (deduplicated by content)\n const { keyframes, nameMap } = extractKeyframesFromStyles(\n mergedStyles,\n globalKeyframes,\n );\n\n // Add keyframes CSS\n for (const kf of keyframes) {\n cssWriter.add(kf.css, kf.css, state.sourceFile);\n }\n\n // Extract styles with chunking\n const chunks = extractStylesWithChunks(mergedStyles);\n\n // Add CSS to writer, replacing animation names if needed\n for (const chunk of chunks) {\n const css =\n nameMap.size > 0\n ? replaceAnimationNamesInCSS(chunk.css, nameMap)\n : chunk.css;\n cssWriter.add(chunk.className, css, state.sourceFile);\n }\n\n // Generate className\n const className =\n chunks.length > 0 ? chunks.map((c) => c.className).join(' ') : '';\n\n // Replace call with StaticStyle object\n const staticStyleObject = createStaticStyleAST(className, mergedStyles);\n path.replaceWith(staticStyleObject);\n\n // Register if this is being assigned to a variable\n registerIfVariableDeclaration(\n path,\n className,\n mergedStyles,\n state,\n globalRegistry,\n );\n}\n\n/**\n * Handle tastyStatic(selector, styles) - removes the call entirely\n */\nfunction handleSelectorMode(\n path: NodePath<t.CallExpression>,\n args: t.CallExpression['arguments'],\n cssWriter: CSSWriter,\n sourceFile?: string,\n globalKeyframes?: Record<string, KeyframesSteps>,\n): void {\n if (args.length < 2) {\n throw path.buildCodeFrameError(\n 'tastyStatic(selector, styles) requires two arguments',\n );\n }\n\n const selectorArg = args[0];\n const stylesArg = args[1];\n\n if (!t.isStringLiteral(selectorArg)) {\n throw path.buildCodeFrameError(\n 'tastyStatic(selector, styles) first argument must be a string literal',\n );\n }\n\n if (!t.isObjectExpression(stylesArg)) {\n throw path.buildCodeFrameError(\n 'tastyStatic(selector, styles) second argument must be a static object literal',\n );\n }\n\n const selector = selectorArg.value;\n const rawStyles = evaluateObjectExpression(stylesArg, path) as Styles;\n\n // Resolve recipes before extraction\n const styles = resolveRecipes(rawStyles);\n\n // Extract keyframes (deduplicated by content)\n const { keyframes, nameMap } = extractKeyframesFromStyles(\n styles,\n globalKeyframes,\n );\n\n // Add keyframes CSS\n for (const kf of keyframes) {\n cssWriter.add(kf.css, kf.css, sourceFile);\n }\n\n // Extract styles for selector\n const result = extractStylesForSelector(selector, styles);\n\n // Replace animation names if needed and add CSS\n const css =\n nameMap.size > 0\n ? replaceAnimationNamesInCSS(result.css, nameMap)\n : result.css;\n cssWriter.add(selector, css, sourceFile);\n\n // Remove the entire statement\n const parent = path.parentPath;\n if (parent && t.isExpressionStatement(parent.node)) {\n parent.remove();\n } else {\n // If used in an expression context (which would be incorrect usage),\n // replace with undefined\n path.replaceWith(t.identifier('undefined'));\n }\n}\n\n/**\n * Create a StaticStyle object AST node\n */\nfunction createStaticStyleAST(\n className: string,\n styles: Styles,\n): t.ObjectExpression {\n return t.objectExpression([\n t.objectProperty(t.identifier('className'), t.stringLiteral(className)),\n t.objectProperty(t.identifier('styles'), valueToAST(styles)),\n t.objectMethod(\n 'method',\n t.identifier('toString'),\n [],\n t.blockStatement([\n t.returnStatement(\n t.memberExpression(t.thisExpression(), t.identifier('className')),\n ),\n ]),\n ),\n ]);\n}\n\n/**\n * Register a StaticStyle in the registry if it's being assigned to a variable\n */\nfunction registerIfVariableDeclaration(\n path: NodePath,\n className: string,\n styles: Styles,\n state: PluginState,\n globalRegistry: StaticStyleRegistry,\n): void {\n const parent = path.parentPath;\n if (parent && t.isVariableDeclarator(parent.node)) {\n const id = parent.node.id;\n if (t.isIdentifier(id)) {\n const variableName = id.name;\n state.staticStyleRegistry[variableName] = { styles, className };\n globalRegistry[variableName] = { styles, className };\n }\n }\n}\n\n/**\n * Convert a JavaScript value to an AST node\n */\nfunction valueToAST(value: unknown): t.Expression {\n if (value === null) {\n return t.nullLiteral();\n }\n if (value === undefined) {\n return t.identifier('undefined');\n }\n if (typeof value === 'string') {\n return t.stringLiteral(value);\n }\n if (typeof value === 'number') {\n return t.numericLiteral(value);\n }\n if (typeof value === 'boolean') {\n return t.booleanLiteral(value);\n }\n if (Array.isArray(value)) {\n return t.arrayExpression(value.map(valueToAST));\n }\n if (typeof value === 'object') {\n const properties = Object.entries(value).map(([key, val]) =>\n t.objectProperty(\n /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)\n ? t.identifier(key)\n : t.stringLiteral(key),\n valueToAST(val),\n ),\n );\n return t.objectExpression(properties);\n }\n // Fallback for unsupported types\n return t.identifier('undefined');\n}\n\n/**\n * Evaluate an ObjectExpression to a plain JavaScript object.\n * Only supports static values that can be determined at build time.\n */\nfunction evaluateObjectExpression(\n node: t.ObjectExpression,\n path: NodePath,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const prop of node.properties) {\n if (t.isSpreadElement(prop)) {\n throw path.buildCodeFrameError(\n 'Spread elements are not supported in tastyStatic() - styles must be fully static',\n );\n }\n\n if (!t.isObjectProperty(prop)) {\n throw path.buildCodeFrameError(\n 'Only object properties are supported in tastyStatic()',\n );\n }\n\n // Get key\n let key: string;\n if (t.isIdentifier(prop.key)) {\n key = prop.key.name;\n } else if (t.isStringLiteral(prop.key)) {\n key = prop.key.value;\n } else {\n throw path.buildCodeFrameError(\n 'Dynamic property keys are not supported in tastyStatic()',\n );\n }\n\n // Get value\n const value = evaluateExpression(prop.value, path);\n result[key] = value;\n }\n\n return result;\n}\n\n/**\n * Evaluate an expression to a JavaScript value.\n */\nfunction evaluateExpression(node: t.Node, path: NodePath): unknown {\n if (t.isStringLiteral(node)) {\n return node.value;\n }\n\n if (t.isNumericLiteral(node)) {\n return node.value;\n }\n\n if (t.isBooleanLiteral(node)) {\n return node.value;\n }\n\n if (t.isNullLiteral(node)) {\n return null;\n }\n\n if (t.isIdentifier(node, { name: 'undefined' })) {\n return undefined;\n }\n\n if (t.isArrayExpression(node)) {\n return node.elements.map((el) => {\n if (el === null) return null;\n if (t.isSpreadElement(el)) {\n throw path.buildCodeFrameError(\n 'Spread elements are not supported in tastyStatic()',\n );\n }\n return evaluateExpression(el, path);\n });\n }\n\n if (t.isObjectExpression(node)) {\n return evaluateObjectExpression(node, path);\n }\n\n if (t.isTemplateLiteral(node)) {\n // Only support template literals without expressions\n if (node.expressions.length > 0) {\n throw path.buildCodeFrameError(\n 'Template literals with expressions are not supported in tastyStatic()',\n );\n }\n return node.quasis.map((q) => q.value.cooked).join('');\n }\n\n if (t.isUnaryExpression(node, { operator: '-' })) {\n const arg = evaluateExpression(node.argument, path);\n if (typeof arg === 'number') {\n return -arg;\n }\n }\n\n throw path.buildCodeFrameError(\n `Dynamic expressions are not supported in tastyStatic() - got ${node.type}. ` +\n 'All values must be static literals.',\n );\n}\n\n/**\n * Replace animation names in CSS string.\n * Wraps the keyframes replaceAnimationNames to work on full CSS blocks.\n */\nfunction replaceAnimationNamesInCSS(\n css: string,\n nameMap: Map<string, string>,\n): string {\n if (nameMap.size === 0) return css;\n\n // The CSS contains full rules like \".class { animation: name 1s; }\"\n // We need to replace animation names within declaration blocks\n return css.replace(\n /(animation(?:-name)?)\\s*:\\s*([^;}]+)/gi,\n (match, prop, value) => {\n let newValue = value;\n for (const [original, replacement] of nameMap) {\n // Word boundary replacement\n const pattern = new RegExp(`\\\\b${escapeRegex(original)}\\\\b`, 'g');\n newValue = newValue.replace(pattern, replacement);\n }\n return `${prop}: ${newValue}`;\n },\n );\n}\n\n/**\n * Escape special regex characters.\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"babel.js","names":[],"sources":["../../src/zero/babel.ts"],"sourcesContent":["/**\n * Babel plugin for zero-runtime tasty static site generation.\n *\n * Transforms:\n * - `tastyStatic(styles)` → StaticStyle object { className, styles, toString() }\n * - `tastyStatic(base, styles)` → StaticStyle object with merged styles\n * - `tastyStatic(selector, styles)` → removed entirely\n *\n * Usage:\n * ```javascript\n * // babel.config.js\n * module.exports = {\n * plugins: [\n * ['@tenphi/tasty/babel-plugin', { output: 'public/tasty.css' }]\n * ]\n * };\n * ```\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nimport { declare } from '@babel/helper-plugin-utils';\nimport * as t from '@babel/types';\nimport { createJiti } from 'jiti';\n\nimport {\n configure,\n getGlobalStyles,\n getGlobalConfigTokens,\n resetConfig,\n} from '../config';\nimport type { TastyConfig } from '../config';\nimport type { Styles, ConfigTokens } from '../styles/types';\nimport { mergeStyles } from '../utils/merge-styles';\nimport { DEFAULT_ZERO_NAME_PREFIX } from '../utils/name-prefix';\nimport { resolveRecipes } from '../utils/resolve-recipes';\n\nimport { CSSWriter } from './css-writer';\nimport {\n extractCounterStyleFromStyles,\n extractFontFaceFromStyles,\n extractKeyframesFromStyles,\n extractPropertiesFromStyles,\n extractStylesForSelector,\n extractStylesWithChunks,\n setExtractorNamePrefix,\n} from './extractor';\nimport type {\n ExtractedChunk,\n ExtractedCounterStyle,\n ExtractedFontFace,\n ExtractedKeyframes,\n ExtractedProperty,\n} from './extractor';\n\nimport type { NodePath, PluginPass } from '@babel/core';\nimport type {\n CounterStyleDescriptors,\n FontFaceInput,\n KeyframesSteps,\n} from '../injector/types';\n\n/**\n * Build-time configuration for zero-runtime mode.\n * Subset of TastyConfig excluding runtime-only DOM options\n * (`nonce`, `maxRulesPerSheet`, `forceTextInjection`, `gc`)\n * and overriding `devMode` default to `false`.\n */\nexport type TastyZeroConfig = Omit<\n TastyConfig,\n 'nonce' | 'maxRulesPerSheet' | 'forceTextInjection' | 'gc' | 'devMode'\n> & {\n /**\n * Enable development mode features: source comments in generated CSS.\n * @default false\n */\n devMode?: boolean;\n};\n\nexport interface TastyZeroBabelOptions {\n /** Output path for generated CSS (default: 'tasty.css') */\n output?: string;\n /**\n * Tasty configuration for build-time processing.\n * Can be a static object or a factory function that returns fresh config.\n * A factory is called on each plugin invocation, enabling hot reload\n * of config values that depend on external files (e.g. theme tokens).\n */\n config?: TastyZeroConfig | (() => TastyZeroConfig);\n /**\n * Absolute path to a TypeScript/JavaScript module that default-exports\n * a `TastyZeroConfig` object. The module is loaded via jiti on each\n * plugin invocation, enabling hot reload when the file changes.\n *\n * This option is JSON-serializable and is the primary way Turbopack\n * passes config to the Babel plugin (since Turbopack loader options\n * must be plain primitives/objects/arrays).\n *\n * When both `config` and `configFile` are set, `config` takes precedence.\n *\n * @example '/absolute/path/to/tasty-zero.config.ts'\n */\n configFile?: string;\n /**\n * Absolute file paths whose content affects the generated CSS.\n * When any of these files change, babel-loader invalidates its cache\n * and re-runs the plugin with fresh config values.\n *\n * Typically includes theme files that define Glaze palettes or token values.\n * Paths must be absolute (resolved by the Next.js wrapper).\n */\n configDeps?: string[];\n /**\n * Automatically replace `@tenphi/tasty/static` imports with an import\n * of the generated CSS file. This eliminates the need for users to\n * manually import the CSS in their app entry point.\n *\n * @default true\n */\n injectImport?: boolean;\n /**\n * Output mode for extracted CSS.\n *\n * - `'file'` (default): CSS is written to a single output file and\n * the `@tenphi/tasty/static` import is rewritten to import that file.\n * - `'inject'`: CSS is embedded inline in the JS output and injected\n * at runtime via a tiny injector from `@tenphi/tasty/static/inject`.\n * No CSS file is written. Each `tastyStatic` call becomes\n * self-contained. Best for reusable components and extensions.\n *\n * When `mode` is `'inject'`, `output` and `injectImport` are ignored.\n *\n * @default 'file'\n */\n mode?: 'file' | 'inject';\n}\n\n/**\n * Registry to track StaticStyle objects by their variable names.\n * Used to resolve base styles when extending.\n */\ntype StaticStyleRegistry = Record<\n string,\n {\n styles: Styles;\n className: string;\n }\n>;\n\ninterface PluginState extends PluginPass {\n staticStyleRegistry: StaticStyleRegistry;\n /** Current source file path (for devMode source comments) */\n sourceFile?: string;\n /** Whether this file added CSS blocks to the writer (via tastyStatic calls) */\n _fileAddedCSS?: boolean;\n}\n\nfunction mtime(filePath: string): number | null {\n try {\n return fs.statSync(filePath).mtimeMs;\n } catch {\n return null;\n }\n}\n\nfunction clearRequireCacheTree(filePath: string): void {\n let resolved: string;\n\n try {\n resolved = require.resolve(filePath);\n } catch {\n return;\n }\n\n const mod = require.cache[resolved];\n\n if (!mod) return;\n\n const dir = resolved.substring(0, resolved.lastIndexOf('/'));\n\n if (mod.children) {\n for (const child of mod.children) {\n if (child.id.startsWith(dir) && !child.id.includes('node_modules')) {\n clearRequireCacheTree(child.id);\n }\n }\n }\n\n delete require.cache[resolved];\n}\n\n// Shared CSSWriter cache keyed by resolved output path.\n// Persists across per-file Babel invocations (Turbopack model) so that\n// CSS from all files accumulates instead of being overwritten.\ninterface WriterCacheEntry {\n writer: CSSWriter;\n configKey: string;\n registry: StaticStyleRegistry;\n config: TastyZeroConfig;\n}\nconst writerCache = new Map<string, WriterCacheEntry>();\n\n/** Clear the shared CSSWriter cache. Exposed for testing. */\nexport function clearWriterCache(): void {\n writerCache.clear();\n}\n\n// @ts-expect-error PluginState vs PluginPass type mismatch in @babel/helper-plugin-utils\nexport default declare<TastyZeroBabelOptions>((api, options) => {\n api.assertVersion(7);\n\n const mode = options.mode ?? 'file';\n const outputPath = options.output || 'tasty.css';\n const resolvedOutputPath = path.resolve(outputPath);\n const injectImport = options.injectImport ?? true;\n\n if (mode === 'file' && injectImport) {\n const dir = path.dirname(resolvedOutputPath);\n\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n if (!fs.existsSync(resolvedOutputPath)) {\n fs.writeFileSync(\n resolvedOutputPath,\n '/* Generated by @tenphi/tasty/zero - DO NOT EDIT */\\n',\n );\n }\n }\n\n const configDeps = [\n ...(options.configFile ? [options.configFile] : []),\n ...(options.configDeps || []),\n ];\n\n // Fingerprint for config deps — used to detect config changes\n // and invalidate the shared CSSWriter cache.\n const configKey =\n configDeps.length > 0 ? configDeps.map(mtime).join(',') : '';\n\n // Register external dependencies for babel-loader cache invalidation.\n // When any configDeps file changes, babel-loader discards the cached\n // transform result and re-runs the plugin, picking up fresh config.\n if (configDeps.length > 0) {\n api.cache.using(() => configKey);\n\n for (const dep of configDeps) {\n try {\n (\n api as unknown as { addExternalDependency(path: string): void }\n ).addExternalDependency(dep);\n } catch {\n // addExternalDependency may not be available in all environments\n }\n }\n } else {\n api.cache.forever();\n }\n\n // When configDeps are set, clear the require cache so we get fresh values.\n if (configDeps.length > 0) {\n for (const dep of configDeps) {\n clearRequireCacheTree(dep);\n }\n }\n\n // Look up or create the shared CSSWriter for this output path.\n // When config deps change (different configKey), discard the old writer\n // and reset pipeline state so configure() can run again.\n const cached = writerCache.get(resolvedOutputPath);\n const configChanged = !cached || cached.configKey !== configKey;\n\n if (configChanged) {\n const configOption = options.config;\n let resolvedConfig: TastyZeroConfig;\n\n if (configOption) {\n resolvedConfig =\n typeof configOption === 'function' ? configOption() : configOption;\n } else if (options.configFile) {\n const jiti = createJiti(path.dirname(options.configFile), {\n moduleCache: false,\n });\n\n const loaded = jiti(options.configFile) as\n | TastyZeroConfig\n | { default: TastyZeroConfig };\n // jiti returns the ESM namespace, so unwrap `default` when present.\n resolvedConfig =\n loaded && typeof loaded === 'object' && 'default' in loaded\n ? (loaded.default as TastyZeroConfig)\n : (loaded as TastyZeroConfig);\n } else {\n resolvedConfig = {};\n }\n\n const devMode = resolvedConfig.devMode ?? false;\n\n if (cached) {\n resetConfig();\n }\n\n // Default to the zero-runtime prefix ('ts') unless the user opts out.\n // Using the same `namePrefix` config entry as the runtime keeps the\n // API uniform; the different default prevents collisions when both\n // runtime and zero-runtime classes appear on the same page.\n const finalConfig: TastyZeroConfig = {\n namePrefix: DEFAULT_ZERO_NAME_PREFIX,\n ...resolvedConfig,\n };\n\n configure(finalConfig);\n setExtractorNamePrefix(finalConfig.namePrefix ?? DEFAULT_ZERO_NAME_PREFIX);\n\n const newWriter = new CSSWriter(outputPath, { devMode });\n\n // Emit configured tokens and global styles (file mode only;\n // inject mode handles injection per-file in the post hook).\n if (mode !== 'inject') {\n const tokenCSS = extractCSSFromStyles(':root', getGlobalConfigTokens());\n if (tokenCSS) newWriter.add(':root:tokens', tokenCSS);\n\n const globalStyles = getGlobalStyles();\n if (globalStyles) {\n for (const [selector, styles] of Object.entries(globalStyles)) {\n const css = extractCSSFromStyles(selector, styles);\n if (css) newWriter.add(`global:${selector}`, css);\n }\n }\n }\n\n writerCache.set(resolvedOutputPath, {\n writer: newWriter,\n configKey,\n registry: {},\n config: finalConfig,\n });\n }\n\n const entry = writerCache.get(resolvedOutputPath)!;\n const cssWriter = entry.writer;\n const globalRegistry = entry.registry;\n const config = entry.config;\n const devMode = config.devMode ?? false;\n // When the writer entry was reused from a previous Babel invocation\n // (configChanged=false), make sure the extractor's module-level prefix\n // still matches this build's config — module state can outlive a\n // single configure() call across worker reuse.\n setExtractorNamePrefix(config.namePrefix ?? DEFAULT_ZERO_NAME_PREFIX);\n\n // Precompute token CSS and global styles CSS for inject mode\n let tokenCSS: string | undefined;\n let globalStylesCSS: Map<string, string> | undefined;\n if (mode === 'inject') {\n tokenCSS = extractCSSFromStyles(':root', getGlobalConfigTokens());\n const gs = getGlobalStyles();\n if (gs) {\n globalStylesCSS = new Map();\n for (const [selector, styles] of Object.entries(gs)) {\n const css = extractCSSFromStyles(selector, styles);\n if (css) globalStylesCSS.set(selector, css);\n }\n if (globalStylesCSS.size === 0) globalStylesCSS = undefined;\n }\n }\n\n return {\n name: 'tasty-zero',\n\n pre(this: PluginState) {\n // Initialize per-file registry\n this.staticStyleRegistry = {};\n this._fileAddedCSS = false;\n // Extract source filename for devMode comments\n if (devMode && this.filename) {\n // Get relative path or just filename\n this.sourceFile = this.filename.split('/').pop() || this.filename;\n }\n },\n\n visitor: {\n ImportDeclaration(\n nodePath: NodePath<t.ImportDeclaration>,\n state: PluginState,\n ) {\n const source = nodePath.node.source.value;\n\n if (\n source === '@tenphi/tasty/static' ||\n source.endsWith('/tasty/static')\n ) {\n if (mode === 'inject') {\n nodePath.replaceWith(\n t.importDeclaration(\n [\n t.importSpecifier(\n t.identifier('_$i'),\n t.identifier('injectCSS'),\n ),\n ],\n t.stringLiteral('@tenphi/tasty/static/inject'),\n ),\n );\n } else if (injectImport) {\n let importPath = resolvedOutputPath;\n\n if (state.filename) {\n const sourceDir = path.dirname(state.filename);\n importPath = path.relative(sourceDir, resolvedOutputPath);\n\n if (!importPath.startsWith('.')) {\n importPath = './' + importPath;\n }\n }\n\n nodePath.replaceWith(\n t.importDeclaration([], t.stringLiteral(importPath)),\n );\n } else {\n nodePath.remove();\n }\n }\n },\n\n // Transform tastyStatic() calls\n CallExpression(path: NodePath<t.CallExpression>, state: PluginState) {\n const callee = path.node.callee;\n\n // Match tastyStatic(...) calls\n if (!t.isIdentifier(callee, { name: 'tastyStatic' })) {\n return;\n }\n\n state._fileAddedCSS = true;\n\n const args = path.node.arguments;\n\n if (args.length === 0) {\n throw path.buildCodeFrameError(\n 'tastyStatic() requires at least one argument',\n );\n }\n\n const firstArg = args[0];\n\n if (t.isStringLiteral(firstArg)) {\n // Selector mode: tastyStatic(selector, styles)\n handleSelectorMode(\n path,\n args,\n cssWriter,\n mode,\n state.sourceFile,\n config.keyframes,\n config.autoPropertyTypes,\n config.fontFace,\n config.counterStyle,\n );\n } else if (t.isObjectExpression(firstArg)) {\n // Styles mode: tastyStatic(styles)\n handleStylesMode(\n path,\n args,\n cssWriter,\n state,\n globalRegistry,\n mode,\n config.keyframes,\n config.autoPropertyTypes,\n config.fontFace,\n config.counterStyle,\n );\n } else if (t.isIdentifier(firstArg)) {\n // Extension mode: tastyStatic(base, styles)\n handleExtensionMode(\n path,\n args,\n cssWriter,\n state,\n globalRegistry,\n mode,\n config.keyframes,\n config.autoPropertyTypes,\n config.fontFace,\n config.counterStyle,\n );\n } else {\n throw path.buildCodeFrameError(\n 'tastyStatic() first argument must be an object (styles), ' +\n 'identifier (base StaticStyle), or string (selector)',\n );\n }\n },\n\n // Track variable declarations to register StaticStyle objects\n VariableDeclarator(\n path: NodePath<t.VariableDeclarator>,\n state: PluginState,\n ) {\n const init = path.node.init;\n const id = path.node.id;\n\n // Check if this is a StaticStyle object (has className and styles properties)\n if (\n t.isIdentifier(id) &&\n t.isObjectExpression(init) &&\n isStaticStyleObject(init)\n ) {\n const variableName = id.name;\n const styles = extractStylesFromStaticStyleObject(init, path);\n const className = extractClassNameFromStaticStyleObject(init);\n\n if (styles && className) {\n state.staticStyleRegistry[variableName] = { styles, className };\n globalRegistry[variableName] = { styles, className };\n }\n }\n },\n },\n\n post(this: PluginState) {\n if (mode === 'inject') {\n // In inject mode, inject token/global CSS as top-level statements\n // when this file had tastyStatic calls and config CSS exists.\n if (this._fileAddedCSS && (tokenCSS || globalStylesCSS)) {\n const program = this.file.ast.program;\n\n // Find the position after the inject import\n let insertIndex = 0;\n for (let i = 0; i < program.body.length; i++) {\n if (t.isImportDeclaration(program.body[i])) {\n insertIndex = i + 1;\n }\n }\n\n if (tokenCSS) {\n const injectCall = createInjectCallAST(':root', tokenCSS);\n program.body.splice(\n insertIndex,\n 0,\n t.expressionStatement(injectCall),\n );\n insertIndex++;\n }\n\n if (globalStylesCSS) {\n for (const [selector, css] of globalStylesCSS) {\n const injectCall = createInjectCallAST(selector, css);\n program.body.splice(\n insertIndex,\n 0,\n t.expressionStatement(injectCall),\n );\n insertIndex++;\n }\n }\n }\n return;\n }\n\n // Only write when this file contributed CSS (had tastyStatic calls).\n // In Turbopack, separate workers each have their own CSSWriter with\n // only token CSS. Letting those workers write would overwrite the\n // complete CSS produced by the worker that processed tastyStatic files.\n if (this._fileAddedCSS && cssWriter.size > 0) {\n cssWriter.write();\n }\n },\n };\n});\n\n/**\n * Check if an object expression looks like a StaticStyle object\n */\nfunction isStaticStyleObject(node: t.ObjectExpression): boolean {\n const hasClassName = node.properties.some(\n (p) =>\n t.isObjectProperty(p) && t.isIdentifier(p.key, { name: 'className' }),\n );\n const hasStyles = node.properties.some(\n (p) => t.isObjectProperty(p) && t.isIdentifier(p.key, { name: 'styles' }),\n );\n return hasClassName && hasStyles;\n}\n\n/**\n * Extract styles object from a StaticStyle object expression\n */\nfunction extractStylesFromStaticStyleObject(\n node: t.ObjectExpression,\n path: NodePath,\n): Styles | null {\n for (const prop of node.properties) {\n if (\n t.isObjectProperty(prop) &&\n t.isIdentifier(prop.key, { name: 'styles' }) &&\n t.isObjectExpression(prop.value)\n ) {\n return evaluateObjectExpression(prop.value, path) as Styles;\n }\n }\n return null;\n}\n\n/**\n * Extract className from a StaticStyle object expression\n */\nfunction extractClassNameFromStaticStyleObject(\n node: t.ObjectExpression,\n): string | null {\n for (const prop of node.properties) {\n if (\n t.isObjectProperty(prop) &&\n t.isIdentifier(prop.key, { name: 'className' }) &&\n t.isStringLiteral(prop.value)\n ) {\n return prop.value.value;\n }\n }\n return null;\n}\n\n/**\n * Handle tastyStatic(styles) - returns StaticStyle object\n */\nfunction handleStylesMode(\n path: NodePath<t.CallExpression>,\n args: t.CallExpression['arguments'],\n cssWriter: CSSWriter,\n state: PluginState,\n globalRegistry: StaticStyleRegistry,\n mode: 'file' | 'inject',\n globalKeyframes?: Record<string, KeyframesSteps>,\n autoPropertyTypes?: boolean,\n globalFontFace?: Record<string, FontFaceInput>,\n globalCounterStyle?: Record<string, CounterStyleDescriptors>,\n): void {\n const stylesArg = args[0];\n\n if (!t.isObjectExpression(stylesArg)) {\n throw path.buildCodeFrameError(\n 'tastyStatic(styles) argument must be a static object literal',\n );\n }\n\n // Evaluate styles object at build time\n const rawStyles = evaluateObjectExpression(stylesArg, path) as Styles;\n\n // Resolve recipes before extraction\n const styles = resolveRecipes(rawStyles);\n\n // Extract keyframes (deduplicated by content)\n const { keyframes, nameMap } = extractKeyframesFromStyles(\n styles,\n globalKeyframes,\n );\n\n // Extract and add auto-inferred @property rules\n const properties = extractPropertiesFromStyles(styles, { autoPropertyTypes });\n\n // Extract @font-face rules\n const fontFaces = extractFontFaceFromStyles(styles, globalFontFace);\n\n // Extract @counter-style rules\n const counterStyles = extractCounterStyleFromStyles(\n styles,\n globalCounterStyle,\n );\n\n // Extract styles with chunking\n const chunks = extractStylesWithChunks(styles);\n\n const className =\n chunks.length > 0 ? chunks.map((c) => c.className).join(' ') : '';\n const staticStyleObject = createStaticStyleAST(className, styles);\n\n if (mode === 'inject') {\n const allCSS = collectAllCSS(\n keyframes,\n properties,\n fontFaces,\n counterStyles,\n chunks,\n nameMap,\n );\n const injectCall = createInjectCallAST(className, allCSS);\n\n path.replaceWith(t.sequenceExpression([injectCall, staticStyleObject]));\n } else {\n writeCSSToWriter(\n cssWriter,\n keyframes,\n properties,\n fontFaces,\n counterStyles,\n chunks,\n nameMap,\n state.sourceFile,\n );\n path.replaceWith(staticStyleObject);\n }\n\n registerIfVariableDeclaration(path, className, styles, state, globalRegistry);\n}\n\n/**\n * Handle tastyStatic(base, styles) - extends base with additional styles\n */\nfunction handleExtensionMode(\n path: NodePath<t.CallExpression>,\n args: t.CallExpression['arguments'],\n cssWriter: CSSWriter,\n state: PluginState,\n globalRegistry: StaticStyleRegistry,\n mode: 'file' | 'inject',\n globalKeyframes?: Record<string, KeyframesSteps>,\n autoPropertyTypes?: boolean,\n globalFontFace?: Record<string, FontFaceInput>,\n globalCounterStyle?: Record<string, CounterStyleDescriptors>,\n): void {\n if (args.length < 2) {\n throw path.buildCodeFrameError(\n 'tastyStatic(base, styles) requires two arguments',\n );\n }\n\n const baseArg = args[0];\n const stylesArg = args[1];\n\n if (!t.isIdentifier(baseArg)) {\n throw path.buildCodeFrameError(\n 'tastyStatic(base, styles) first argument must be an identifier',\n );\n }\n\n if (!t.isObjectExpression(stylesArg)) {\n throw path.buildCodeFrameError(\n 'tastyStatic(base, styles) second argument must be a static object literal',\n );\n }\n\n const baseName = baseArg.name;\n\n // Look up base styles in registry\n const baseEntry =\n state.staticStyleRegistry[baseName] || globalRegistry[baseName];\n\n if (!baseEntry) {\n throw path.buildCodeFrameError(\n `Cannot find base StaticStyle '${baseName}'. ` +\n 'Make sure it is defined before being extended.',\n );\n }\n\n // Evaluate override styles\n const overrideStyles = evaluateObjectExpression(stylesArg, path) as Styles;\n\n // Merge styles using mergeStyles, then resolve recipes\n const mergedStyles = resolveRecipes(\n mergeStyles(baseEntry.styles, overrideStyles),\n );\n\n // Extract keyframes (deduplicated by content)\n const { keyframes, nameMap } = extractKeyframesFromStyles(\n mergedStyles,\n globalKeyframes,\n );\n\n // Extract auto-inferred @property rules\n const properties = extractPropertiesFromStyles(mergedStyles, {\n autoPropertyTypes,\n });\n\n // Extract @font-face rules\n const fontFaces = extractFontFaceFromStyles(mergedStyles, globalFontFace);\n\n // Extract @counter-style rules\n const counterStyles = extractCounterStyleFromStyles(\n mergedStyles,\n globalCounterStyle,\n );\n\n // Extract styles with chunking\n const chunks = extractStylesWithChunks(mergedStyles);\n\n const className =\n chunks.length > 0 ? chunks.map((c) => c.className).join(' ') : '';\n const staticStyleObject = createStaticStyleAST(className, mergedStyles);\n\n if (mode === 'inject') {\n const allCSS = collectAllCSS(\n keyframes,\n properties,\n fontFaces,\n counterStyles,\n chunks,\n nameMap,\n );\n const injectCall = createInjectCallAST(className, allCSS);\n\n path.replaceWith(t.sequenceExpression([injectCall, staticStyleObject]));\n } else {\n writeCSSToWriter(\n cssWriter,\n keyframes,\n properties,\n fontFaces,\n counterStyles,\n chunks,\n nameMap,\n state.sourceFile,\n );\n path.replaceWith(staticStyleObject);\n }\n\n registerIfVariableDeclaration(\n path,\n className,\n mergedStyles,\n state,\n globalRegistry,\n );\n}\n\n/**\n * Handle tastyStatic(selector, styles) - removes the call entirely\n */\nfunction handleSelectorMode(\n path: NodePath<t.CallExpression>,\n args: t.CallExpression['arguments'],\n cssWriter: CSSWriter,\n mode: 'file' | 'inject',\n sourceFile?: string,\n globalKeyframes?: Record<string, KeyframesSteps>,\n autoPropertyTypes?: boolean,\n globalFontFace?: Record<string, FontFaceInput>,\n globalCounterStyle?: Record<string, CounterStyleDescriptors>,\n): void {\n if (args.length < 2) {\n throw path.buildCodeFrameError(\n 'tastyStatic(selector, styles) requires two arguments',\n );\n }\n\n const selectorArg = args[0];\n const stylesArg = args[1];\n\n if (!t.isStringLiteral(selectorArg)) {\n throw path.buildCodeFrameError(\n 'tastyStatic(selector, styles) first argument must be a string literal',\n );\n }\n\n if (!t.isObjectExpression(stylesArg)) {\n throw path.buildCodeFrameError(\n 'tastyStatic(selector, styles) second argument must be a static object literal',\n );\n }\n\n const selector = selectorArg.value;\n const rawStyles = evaluateObjectExpression(stylesArg, path) as Styles;\n\n // Resolve recipes before extraction\n const styles = resolveRecipes(rawStyles);\n\n // Extract keyframes (deduplicated by content)\n const { keyframes, nameMap } = extractKeyframesFromStyles(\n styles,\n globalKeyframes,\n );\n\n // Extract auto-inferred @property rules\n const properties = extractPropertiesFromStyles(styles, { autoPropertyTypes });\n\n // Extract @font-face rules\n const fontFaces = extractFontFaceFromStyles(styles, globalFontFace);\n\n // Extract @counter-style rules\n const counterStyles = extractCounterStyleFromStyles(\n styles,\n globalCounterStyle,\n );\n\n // Extract styles for selector\n const result = extractStylesForSelector(selector, styles);\n\n const selectorCSS =\n nameMap.size > 0\n ? replaceAnimationNamesInCSS(result.css, nameMap)\n : result.css;\n\n if (mode === 'inject') {\n const cssParts: string[] = [];\n\n for (const kf of keyframes) cssParts.push(kf.css);\n for (const prop of properties) cssParts.push(prop.css);\n for (const ff of fontFaces) cssParts.push(ff.css);\n for (const cs of counterStyles) cssParts.push(cs.css);\n cssParts.push(selectorCSS);\n\n const injectCall = createInjectCallAST(selector, cssParts.join('\\n'));\n\n const parent = path.parentPath;\n if (parent && t.isExpressionStatement(parent.node)) {\n parent.replaceWith(t.expressionStatement(injectCall));\n } else {\n path.replaceWith(injectCall);\n }\n } else {\n writeCSSToWriter(\n cssWriter,\n keyframes,\n properties,\n fontFaces,\n counterStyles,\n [],\n nameMap,\n sourceFile,\n );\n cssWriter.add(selector, selectorCSS, sourceFile);\n\n const parent = path.parentPath;\n if (parent && t.isExpressionStatement(parent.node)) {\n parent.remove();\n } else {\n path.replaceWith(t.identifier('undefined'));\n }\n }\n}\n\n/**\n * Collect all extracted CSS parts into a single string (for inject mode).\n */\nfunction collectAllCSS(\n keyframes: ExtractedKeyframes[],\n properties: ExtractedProperty[],\n fontFaces: ExtractedFontFace[],\n counterStyles: ExtractedCounterStyle[],\n chunks: ExtractedChunk[],\n nameMap: Map<string, string>,\n): string {\n const parts: string[] = [];\n\n for (const kf of keyframes) parts.push(kf.css);\n for (const prop of properties) parts.push(prop.css);\n for (const ff of fontFaces) parts.push(ff.css);\n for (const cs of counterStyles) parts.push(cs.css);\n\n for (const chunk of chunks) {\n parts.push(\n nameMap.size > 0\n ? replaceAnimationNamesInCSS(chunk.css, nameMap)\n : chunk.css,\n );\n }\n\n return parts.join('\\n');\n}\n\n/**\n * Write all extracted CSS parts to a CSSWriter (for file mode).\n */\nfunction writeCSSToWriter(\n cssWriter: CSSWriter,\n keyframes: ExtractedKeyframes[],\n properties: ExtractedProperty[],\n fontFaces: ExtractedFontFace[],\n counterStyles: ExtractedCounterStyle[],\n chunks: ExtractedChunk[],\n nameMap: Map<string, string>,\n sourceFile?: string,\n): void {\n for (const kf of keyframes) {\n cssWriter.add(kf.css, kf.css, sourceFile);\n }\n for (const prop of properties) {\n cssWriter.add(prop.css, prop.css, sourceFile);\n }\n for (const ff of fontFaces) {\n cssWriter.add(ff.css, ff.css, sourceFile);\n }\n for (const cs of counterStyles) {\n cssWriter.add(cs.css, cs.css, sourceFile);\n }\n\n for (const chunk of chunks) {\n const css =\n nameMap.size > 0\n ? replaceAnimationNamesInCSS(chunk.css, nameMap)\n : chunk.css;\n cssWriter.add(chunk.className, css, sourceFile);\n }\n}\n\n/**\n * Extract CSS for a selector from a styles/tokens object.\n * Returns undefined when there are no styles or no CSS output.\n */\nfunction extractCSSFromStyles(\n selector: string,\n styles: Styles | ConfigTokens | null,\n): string | undefined {\n if (!styles || Object.keys(styles).length === 0) return undefined;\n const result = extractStylesForSelector(selector, styles as Styles);\n return result.css || undefined;\n}\n\n/**\n * Create an `_$i(id, css)` call expression AST node for inject mode.\n */\nfunction createInjectCallAST(id: string, css: string): t.CallExpression {\n return t.callExpression(t.identifier('_$i'), [\n t.stringLiteral(id),\n t.stringLiteral(css),\n ]);\n}\n\n/**\n * Create a StaticStyle object AST node\n */\nfunction createStaticStyleAST(\n className: string,\n styles: Styles,\n): t.ObjectExpression {\n return t.objectExpression([\n t.objectProperty(t.identifier('className'), t.stringLiteral(className)),\n t.objectProperty(t.identifier('styles'), valueToAST(styles)),\n t.objectMethod(\n 'method',\n t.identifier('toString'),\n [],\n t.blockStatement([\n t.returnStatement(\n t.memberExpression(t.thisExpression(), t.identifier('className')),\n ),\n ]),\n ),\n ]);\n}\n\n/**\n * Register a StaticStyle in the registry if it's being assigned to a variable\n */\nfunction registerIfVariableDeclaration(\n path: NodePath,\n className: string,\n styles: Styles,\n state: PluginState,\n globalRegistry: StaticStyleRegistry,\n): void {\n const parent = path.parentPath;\n if (parent && t.isVariableDeclarator(parent.node)) {\n const id = parent.node.id;\n if (t.isIdentifier(id)) {\n const variableName = id.name;\n state.staticStyleRegistry[variableName] = { styles, className };\n globalRegistry[variableName] = { styles, className };\n }\n }\n}\n\n/**\n * Convert a JavaScript value to an AST node\n */\nfunction valueToAST(value: unknown): t.Expression {\n if (value === null) {\n return t.nullLiteral();\n }\n if (value === undefined) {\n return t.identifier('undefined');\n }\n if (typeof value === 'string') {\n return t.stringLiteral(value);\n }\n if (typeof value === 'number') {\n return t.numericLiteral(value);\n }\n if (typeof value === 'boolean') {\n return t.booleanLiteral(value);\n }\n if (Array.isArray(value)) {\n return t.arrayExpression(value.map(valueToAST));\n }\n if (typeof value === 'object') {\n const properties = Object.entries(value).map(([key, val]) =>\n t.objectProperty(\n /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)\n ? t.identifier(key)\n : t.stringLiteral(key),\n valueToAST(val),\n ),\n );\n return t.objectExpression(properties);\n }\n // Fallback for unsupported types\n return t.identifier('undefined');\n}\n\n/**\n * Evaluate an ObjectExpression to a plain JavaScript object.\n * Only supports static values that can be determined at build time.\n */\nfunction evaluateObjectExpression(\n node: t.ObjectExpression,\n path: NodePath,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const prop of node.properties) {\n if (t.isSpreadElement(prop)) {\n throw path.buildCodeFrameError(\n 'Spread elements are not supported in tastyStatic() - styles must be fully static',\n );\n }\n\n if (!t.isObjectProperty(prop)) {\n throw path.buildCodeFrameError(\n 'Only object properties are supported in tastyStatic()',\n );\n }\n\n // Get key\n let key: string;\n if (t.isIdentifier(prop.key)) {\n key = prop.key.name;\n } else if (t.isStringLiteral(prop.key)) {\n key = prop.key.value;\n } else {\n throw path.buildCodeFrameError(\n 'Dynamic property keys are not supported in tastyStatic()',\n );\n }\n\n // Get value\n const value = evaluateExpression(prop.value, path);\n result[key] = value;\n }\n\n return result;\n}\n\n/**\n * Evaluate an expression to a JavaScript value.\n */\nfunction evaluateExpression(node: t.Node, path: NodePath): unknown {\n if (t.isStringLiteral(node)) {\n return node.value;\n }\n\n if (t.isNumericLiteral(node)) {\n return node.value;\n }\n\n if (t.isBooleanLiteral(node)) {\n return node.value;\n }\n\n if (t.isNullLiteral(node)) {\n return null;\n }\n\n if (t.isIdentifier(node, { name: 'undefined' })) {\n return undefined;\n }\n\n if (t.isArrayExpression(node)) {\n return node.elements.map((el) => {\n if (el === null) return null;\n if (t.isSpreadElement(el)) {\n throw path.buildCodeFrameError(\n 'Spread elements are not supported in tastyStatic()',\n );\n }\n return evaluateExpression(el, path);\n });\n }\n\n if (t.isObjectExpression(node)) {\n return evaluateObjectExpression(node, path);\n }\n\n if (t.isTemplateLiteral(node)) {\n // Only support template literals without expressions\n if (node.expressions.length > 0) {\n throw path.buildCodeFrameError(\n 'Template literals with expressions are not supported in tastyStatic()',\n );\n }\n return node.quasis.map((q) => q.value.cooked).join('');\n }\n\n if (t.isUnaryExpression(node, { operator: '-' })) {\n const arg = evaluateExpression(node.argument, path);\n if (typeof arg === 'number') {\n return -arg;\n }\n }\n\n throw path.buildCodeFrameError(\n `Dynamic expressions are not supported in tastyStatic() - got ${node.type}. ` +\n 'All values must be static literals.',\n );\n}\n\n/**\n * Replace animation names in CSS string.\n * Wraps the keyframes replaceAnimationNames to work on full CSS blocks.\n */\nfunction replaceAnimationNamesInCSS(\n css: string,\n nameMap: Map<string, string>,\n): string {\n if (nameMap.size === 0) return css;\n\n // The CSS contains full rules like \".class { animation: name 1s; }\"\n // We need to replace animation names within declaration blocks\n return css.replace(\n /(animation(?:-name)?)\\s*:\\s*([^;}]+)/gi,\n (match, prop, value) => {\n let newValue = value;\n for (const [original, replacement] of nameMap) {\n // Word boundary replacement\n const pattern = new RegExp(`\\\\b${escapeRegex(original)}\\\\b`, 'g');\n newValue = newValue.replace(pattern, replacement);\n }\n return `${prop}: ${newValue}`;\n },\n );\n}\n\n/**\n * Escape special regex characters.\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n"],"mappings":"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"}
@@ -1,3 +1,67 @@
1
- import { ExtractedChunk, ExtractedSelector, extractStylesForSelector, extractStylesWithChunks } from "./extractor.js";
2
- import { CSSWriter } from "./css-writer.js";
3
- export { CSSWriter, type ExtractedChunk, type ExtractedSelector, extractStylesForSelector, extractStylesWithChunks };
1
+ import { b as Styles } from "../index-tcHuMPFt.js";
2
+
3
+ //#region src/zero/extractor.d.ts
4
+ interface ExtractedChunk {
5
+ className: string;
6
+ css: string;
7
+ }
8
+ interface ExtractedSelector {
9
+ selector: string;
10
+ css: string;
11
+ }
12
+ /**
13
+ * Extract styles using chunking (for className mode).
14
+ * Returns multiple classes, one per chunk.
15
+ */
16
+ declare function extractStylesWithChunks(styles: Styles): ExtractedChunk[];
17
+ /**
18
+ * Extract styles for a specific selector (for global/selector mode).
19
+ * Returns a single CSS block.
20
+ */
21
+ declare function extractStylesForSelector(selector: string, styles: Styles): ExtractedSelector;
22
+ //#endregion
23
+ //#region src/zero/css-writer.d.ts
24
+ interface CSSWriterOptions {
25
+ /** Enable source comments in output (e.g., "from: Button.tsx") */
26
+ devMode?: boolean;
27
+ }
28
+ declare class CSSWriter {
29
+ private cssBlocks;
30
+ private outputPath;
31
+ private devMode;
32
+ constructor(outputPath: string, options?: CSSWriterOptions);
33
+ /**
34
+ * Add CSS block with deduplication key
35
+ * @param key - Unique key for deduplication
36
+ * @param css - CSS content
37
+ * @param source - Optional source file path (used in devMode)
38
+ */
39
+ add(key: string, css: string, source?: string): void;
40
+ /**
41
+ * Check if a key already exists
42
+ */
43
+ has(key: string): boolean;
44
+ /**
45
+ * Get the number of CSS blocks
46
+ */
47
+ get size(): number;
48
+ /**
49
+ * Write all collected CSS to the output file
50
+ */
51
+ write(): void;
52
+ /**
53
+ * Get all CSS as string (for testing or in-memory use)
54
+ */
55
+ getCSS(): string;
56
+ /**
57
+ * Clear all collected CSS
58
+ */
59
+ clear(): void;
60
+ /**
61
+ * Get the output path
62
+ */
63
+ getOutputPath(): string;
64
+ }
65
+ //#endregion
66
+ export { CSSWriter, type ExtractedChunk, type ExtractedSelector, extractStylesForSelector, extractStylesWithChunks };
67
+ //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,2 @@
1
- import { extractStylesForSelector, extractStylesWithChunks } from "./extractor.js";
2
- import { CSSWriter } from "./css-writer.js";
3
-
4
- export { CSSWriter, extractStylesForSelector, extractStylesWithChunks };
1
+ import { o as extractStylesForSelector, s as extractStylesWithChunks, t as CSSWriter } from "../css-writer-BWvwQzz0.js";
2
+ export { CSSWriter, extractStylesForSelector, extractStylesWithChunks };