@tenphi/tasty 3.8.0 → 3.9.1

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 (102) hide show
  1. package/README.md +6 -6
  2. package/dist/{babel-Cp_dRhuS.d.ts → babel-Zs1Q03qt.d.ts} +2 -2
  3. package/dist/chunks/async-storage-CG5HnUT5.js +20 -0
  4. package/dist/chunks/async-storage-CG5HnUT5.js.map +1 -0
  5. package/dist/chunks/build-config-CUQVwdWF.js +42 -0
  6. package/dist/chunks/build-config-CUQVwdWF.js.map +1 -0
  7. package/dist/{collector-C7YBiY7D.js → chunks/collector-B0LTHw6Z.js} +6 -125
  8. package/dist/chunks/collector-B0LTHw6Z.js.map +1 -0
  9. package/dist/chunks/config-engine-C3pF9EK9.js +267 -0
  10. package/dist/chunks/config-engine-C3pF9EK9.js.map +1 -0
  11. package/dist/chunks/css-definitions-D_it4XZH.js +875 -0
  12. package/dist/chunks/css-definitions-D_it4XZH.js.map +1 -0
  13. package/dist/{css-resources-Cyl_axbI.js → chunks/css-resources-BN8apgxt.js} +1 -8
  14. package/dist/chunks/css-resources-BN8apgxt.js.map +1 -0
  15. package/dist/chunks/debug-C9LeNVoJ.js +501 -0
  16. package/dist/chunks/debug-C9LeNVoJ.js.map +1 -0
  17. package/dist/chunks/dsl-C5yuAn41.js +1373 -0
  18. package/dist/chunks/dsl-C5yuAn41.js.map +1 -0
  19. package/dist/chunks/hydration-TRcz5vnk.js +41 -0
  20. package/dist/chunks/hydration-TRcz5vnk.js.map +1 -0
  21. package/dist/chunks/react-runtime-O-OUrKLH.js +557 -0
  22. package/dist/chunks/react-runtime-O-OUrKLH.js.map +1 -0
  23. package/dist/chunks/runtime-engine-DvnE2g-E.js +2437 -0
  24. package/dist/chunks/runtime-engine-DvnE2g-E.js.map +1 -0
  25. package/dist/chunks/runtime-state-BTDqSYBk.js +127 -0
  26. package/dist/chunks/runtime-state-BTDqSYBk.js.map +1 -0
  27. package/dist/{merge-styles-ChW1k-ZM.js → chunks/shared-utils-DWA4LjIa.js} +55 -54
  28. package/dist/chunks/shared-utils-DWA4LjIa.js.map +1 -0
  29. package/dist/chunks/style-engine-C1ECBZxR.js +5131 -0
  30. package/dist/chunks/style-engine-C1ECBZxR.js.map +1 -0
  31. package/dist/{css-writer-BiumPvq-.js → chunks/zero-engine-B6EnYcXY.js} +3 -120
  32. package/dist/chunks/zero-engine-B6EnYcXY.js.map +1 -0
  33. package/dist/{collector-CUtAFyIb.d.ts → collector-hl5KNH7k.d.ts} +6 -4
  34. package/dist/{config-BY1e5y7V.d.ts → config-DWL1ZYue.d.ts} +20 -25
  35. package/dist/core/index.d.ts +5 -5
  36. package/dist/core/index.js +9 -6
  37. package/dist/{index-uX74k5jG.d.ts → index-D9N9GV24.d.ts} +17 -50
  38. package/dist/index.d.ts +5 -5
  39. package/dist/index.js +11 -922
  40. package/dist/{merge-styles-pf6iPs82.d.ts → merge-styles-C_oMoJVd.d.ts} +2 -2
  41. package/dist/ssr/astro-client.js +1 -14
  42. package/dist/ssr/astro-client.js.map +1 -1
  43. package/dist/ssr/astro-middleware-extract-static.js +1 -1
  44. package/dist/ssr/astro-middleware-extract.js +1 -1
  45. package/dist/ssr/astro-middleware-static.js +1 -12
  46. package/dist/ssr/astro-middleware-static.js.map +1 -1
  47. package/dist/ssr/astro-middleware.js +1 -13
  48. package/dist/ssr/astro-middleware.js.map +1 -1
  49. package/dist/ssr/astro.js +219 -1
  50. package/dist/ssr/astro.js.map +1 -0
  51. package/dist/ssr/index.d.ts +6 -6
  52. package/dist/ssr/index.js +4 -4
  53. package/dist/ssr/next-config.d.ts +1 -1
  54. package/dist/ssr/next-config.js +29 -20
  55. package/dist/ssr/next-config.js.map +1 -1
  56. package/dist/ssr/next.d.ts +1 -1
  57. package/dist/ssr/next.js +5 -37
  58. package/dist/ssr/next.js.map +1 -1
  59. package/dist/static/index.d.ts +2 -2
  60. package/dist/static/index.js +1 -19
  61. package/dist/static/index.js.map +1 -1
  62. package/dist/{index-DBjd4MAb.d.ts → types-jKZNpias.d.ts} +800 -800
  63. package/dist/zero/babel.d.ts +1 -1
  64. package/dist/zero/babel.js +25 -96
  65. package/dist/zero/babel.js.map +1 -1
  66. package/dist/zero/index.d.ts +1 -1
  67. package/dist/zero/index.js +1 -1
  68. package/dist/zero/next.d.ts +1 -1
  69. package/dist/zero/next.js +0 -31
  70. package/dist/zero/next.js.map +1 -1
  71. package/docs/debug.md +2 -5
  72. package/docs/pipeline.md +3 -0
  73. package/docs/runtime-benchmarks.md +105 -68
  74. package/docs/ssr.md +1 -1
  75. package/package.json +49 -6
  76. package/dist/astro-w8r-u4qo.js +0 -301
  77. package/dist/astro-w8r-u4qo.js.map +0 -1
  78. package/dist/async-storage-DKK-wTD4.js +0 -44
  79. package/dist/async-storage-DKK-wTD4.js.map +0 -1
  80. package/dist/collector-C7YBiY7D.js.map +0 -1
  81. package/dist/config-yXpe2jAV.js +0 -12668
  82. package/dist/config-yXpe2jAV.js.map +0 -1
  83. package/dist/context-CA8YKeMn.js +0 -24
  84. package/dist/context-CA8YKeMn.js.map +0 -1
  85. package/dist/core-DoEZAHJq.js +0 -1732
  86. package/dist/core-DoEZAHJq.js.map +0 -1
  87. package/dist/css-resources-Cyl_axbI.js.map +0 -1
  88. package/dist/css-writer-BiumPvq-.js.map +0 -1
  89. package/dist/format-global-rules-DklyaXv-.js +0 -22
  90. package/dist/format-global-rules-DklyaXv-.js.map +0 -1
  91. package/dist/format-rules-DHuG25KU.js +0 -104
  92. package/dist/format-rules-DHuG25KU.js.map +0 -1
  93. package/dist/hydrate-BvRP6QEC.js +0 -37
  94. package/dist/hydrate-BvRP6QEC.js.map +0 -1
  95. package/dist/index.js.map +0 -1
  96. package/dist/keyframes-B8uPLZwx.js +0 -535
  97. package/dist/keyframes-B8uPLZwx.js.map +0 -1
  98. package/dist/merge-styles-ChW1k-ZM.js.map +0 -1
  99. package/dist/resolve-recipes-BNmjANzT.js +0 -144
  100. package/dist/resolve-recipes-BNmjANzT.js.map +0 -1
  101. package/dist/ssr-collector-ref-COs_ioWl.js +0 -29
  102. package/dist/ssr-collector-ref-COs_ioWl.js.map +0 -1
@@ -1,2 +1,2 @@
1
- import { n as _default, r as TastyZeroConfig, t as TastyZeroBabelOptions } from "../babel-Cp_dRhuS.js";
1
+ import { n as _default, r as TastyZeroConfig, t as TastyZeroBabelOptions } from "../babel-Zs1Q03qt.js";
2
2
  export { TastyZeroBabelOptions, type TastyZeroConfig, _default as default };
@@ -1,7 +1,8 @@
1
- import { b as resetConfig, d as getGlobalStyles, i as getGlobalConfigTokens, s as getGlobalFunctions, t as configure } from "../config-yXpe2jAV.js";
2
- import { t as mergeStyles } from "../merge-styles-ChW1k-ZM.js";
3
- import { t as resolveRecipes } from "../resolve-recipes-BNmjANzT.js";
4
- import { a as extractFunctionsFromStyles, c as extractStylesForSelector, i as extractFontFaceFromStyles, l as extractStylesWithChunks, o as extractKeyframesFromStyles, r as extractCounterStyleFromStyles, s as extractPropertiesFromStyles, t as CSSWriter, u as setExtractorNamePrefix } from "../css-writer-BiumPvq-.js";
1
+ import { t as mergeStyles } from "../chunks/shared-utils-DWA4LjIa.js";
2
+ import "../chunks/css-definitions-D_it4XZH.js";
3
+ import { t as resolveRecipesWith } from "../chunks/config-engine-C3pF9EK9.js";
4
+ import { a as extractFunctionsFromStyles, c as extractStylesForSelector, i as extractFontFaceFromStyles, l as extractStylesWithChunks, o as extractKeyframesFromStyles, r as extractCounterStyleFromStyles, s as extractPropertiesFromStyles, t as CSSWriter, u as setExtractorNamePrefix } from "../chunks/zero-engine-B6EnYcXY.js";
5
+ import { n as functionsForExtraction, r as resetZeroConfig, t as configureZero } from "../chunks/build-config-CUQVwdWF.js";
5
6
  import * as fs from "fs";
6
7
  import * as path from "path";
7
8
  import { declare } from "@babel/helper-plugin-utils";
@@ -17,24 +18,6 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
17
18
  const writerCache = /* @__PURE__ */ new Map();
18
19
  //#endregion
19
20
  //#region src/zero/babel.ts
20
- /**
21
- * Babel plugin for zero-runtime tasty static site generation.
22
- *
23
- * Transforms:
24
- * - `tastyStatic(styles)` → StaticStyle object { className, styles, toString() }
25
- * - `tastyStatic(base, styles)` → StaticStyle object with merged styles
26
- * - `tastyStatic(selector, styles)` → removed entirely
27
- *
28
- * Usage:
29
- * ```javascript
30
- * // babel.config.js
31
- * module.exports = {
32
- * plugins: [
33
- * ['@tenphi/tasty/babel-plugin', { output: 'public/tasty.css' }]
34
- * ]
35
- * };
36
- * ```
37
- */
38
21
  function mtime(filePath) {
39
22
  try {
40
23
  return fs.statSync(filePath).mtimeMs;
@@ -87,19 +70,18 @@ var babel_default = declare((api, options) => {
87
70
  resolvedConfig = loaded && typeof loaded === "object" && "default" in loaded ? loaded.default : loaded;
88
71
  } else resolvedConfig = {};
89
72
  const devMode = resolvedConfig.devMode ?? false;
90
- if (cached) resetConfig();
73
+ resetZeroConfig();
91
74
  const finalConfig = {
92
75
  namePrefix: "ts",
93
76
  ...resolvedConfig
94
77
  };
95
- configure(finalConfig);
78
+ const config = configureZero(finalConfig);
96
79
  setExtractorNamePrefix(finalConfig.namePrefix ?? "ts");
97
80
  const newWriter = new CSSWriter(outputPath, { devMode });
98
81
  if (mode !== "inject") {
99
- const tokenCSS = extractCSSFromStyles(":root", getGlobalConfigTokens());
82
+ const tokenCSS = extractCSSFromStyles(":root", config.normalized.tokens);
100
83
  if (tokenCSS) newWriter.add(":root:tokens", tokenCSS);
101
- const globalStyles = getGlobalStyles();
102
- if (globalStyles) for (const [selector, styles] of Object.entries(globalStyles)) {
84
+ for (const [selector, styles] of Object.entries(config.normalized.globalStyles)) {
103
85
  const css = extractCSSFromStyles(selector, styles);
104
86
  if (css) newWriter.add(`global:${selector}`, css);
105
87
  }
@@ -108,21 +90,22 @@ var babel_default = declare((api, options) => {
108
90
  writer: newWriter,
109
91
  configKey,
110
92
  registry: {},
111
- config: finalConfig
93
+ config
112
94
  });
113
95
  }
114
96
  const entry = writerCache.get(resolvedOutputPath);
115
97
  const cssWriter = entry.writer;
116
98
  const globalRegistry = entry.registry;
117
99
  const config = entry.config;
118
- const devMode = config.devMode ?? false;
119
- setExtractorNamePrefix(config.namePrefix ?? "ts");
100
+ const sourceConfig = config.source;
101
+ const devMode = sourceConfig.devMode ?? false;
102
+ setExtractorNamePrefix(sourceConfig.namePrefix ?? "ts");
120
103
  let tokenCSS;
121
104
  let globalStylesCSS;
122
105
  if (mode === "inject") {
123
- tokenCSS = extractCSSFromStyles(":root", getGlobalConfigTokens());
124
- const gs = getGlobalStyles();
125
- if (gs) {
106
+ tokenCSS = extractCSSFromStyles(":root", config.normalized.tokens);
107
+ const gs = config.normalized.globalStyles;
108
+ if (Object.keys(gs).length > 0) {
126
109
  globalStylesCSS = /* @__PURE__ */ new Map();
127
110
  for (const [selector, styles] of Object.entries(gs)) {
128
111
  const css = extractCSSFromStyles(selector, styles);
@@ -159,9 +142,9 @@ var babel_default = declare((api, options) => {
159
142
  const args = path.node.arguments;
160
143
  if (args.length === 0) throw path.buildCodeFrameError("tastyStatic() requires at least one argument");
161
144
  const firstArg = args[0];
162
- if (t.isStringLiteral(firstArg)) handleSelectorMode(path, args, cssWriter, mode, state.sourceFile, config.keyframes, config.autoPropertyTypes, config.fontFaces, config.counterStyles, getGlobalFunctions() ?? void 0);
163
- else if (t.isObjectExpression(firstArg)) handleStylesMode(path, args, cssWriter, state, globalRegistry, mode, config.keyframes, config.autoPropertyTypes, config.fontFaces, config.counterStyles, getGlobalFunctions() ?? void 0);
164
- else if (t.isIdentifier(firstArg)) handleExtensionMode(path, args, cssWriter, state, globalRegistry, mode, config.keyframes, config.autoPropertyTypes, config.fontFaces, config.counterStyles, getGlobalFunctions() ?? void 0);
145
+ if (t.isStringLiteral(firstArg)) handleSelectorMode(path, args, cssWriter, mode, state.sourceFile, config.normalized.keyframes, sourceConfig.autoPropertyTypes, config.normalized.fontFaces, config.normalized.counterStyles, functionsForExtraction(config), config.normalized.recipes);
146
+ else if (t.isObjectExpression(firstArg)) handleStylesMode(path, args, cssWriter, state, globalRegistry, mode, config.normalized.keyframes, sourceConfig.autoPropertyTypes, config.normalized.fontFaces, config.normalized.counterStyles, functionsForExtraction(config), config.normalized.recipes);
147
+ else if (t.isIdentifier(firstArg)) handleExtensionMode(path, args, cssWriter, state, globalRegistry, mode, config.normalized.keyframes, sourceConfig.autoPropertyTypes, config.normalized.fontFaces, config.normalized.counterStyles, functionsForExtraction(config), config.normalized.recipes);
165
148
  else throw path.buildCodeFrameError("tastyStatic() first argument must be an object (styles), identifier (base StaticStyle), or string (selector)");
166
149
  },
167
150
  VariableDeclarator(path, state) {
@@ -207,35 +190,23 @@ var babel_default = declare((api, options) => {
207
190
  }
208
191
  };
209
192
  });
210
- /**
211
- * Check if an object expression looks like a StaticStyle object
212
- */
213
193
  function isStaticStyleObject(node) {
214
194
  const hasClassName = node.properties.some((p) => t.isObjectProperty(p) && t.isIdentifier(p.key, { name: "className" }));
215
195
  const hasStyles = node.properties.some((p) => t.isObjectProperty(p) && t.isIdentifier(p.key, { name: "styles" }));
216
196
  return hasClassName && hasStyles;
217
197
  }
218
- /**
219
- * Extract styles object from a StaticStyle object expression
220
- */
221
198
  function extractStylesFromStaticStyleObject(node, path) {
222
199
  for (const prop of node.properties) if (t.isObjectProperty(prop) && t.isIdentifier(prop.key, { name: "styles" }) && t.isObjectExpression(prop.value)) return evaluateObjectExpression(prop.value, path);
223
200
  return null;
224
201
  }
225
- /**
226
- * Extract className from a StaticStyle object expression
227
- */
228
202
  function extractClassNameFromStaticStyleObject(node) {
229
203
  for (const prop of node.properties) if (t.isObjectProperty(prop) && t.isIdentifier(prop.key, { name: "className" }) && t.isStringLiteral(prop.value)) return prop.value.value;
230
204
  return null;
231
205
  }
232
- /**
233
- * Handle tastyStatic(styles) - returns StaticStyle object
234
- */
235
- function handleStylesMode(path, args, cssWriter, state, globalRegistry, mode, globalKeyframes, autoPropertyTypes, globalFontFace, globalCounterStyle, globalFunction) {
206
+ function handleStylesMode(path, args, cssWriter, state, globalRegistry, mode, globalKeyframes, autoPropertyTypes, globalFontFace, globalCounterStyle, globalFunction, globalRecipes) {
236
207
  const stylesArg = args[0];
237
208
  if (!t.isObjectExpression(stylesArg)) throw path.buildCodeFrameError("tastyStatic(styles) argument must be a static object literal");
238
- const styles = resolveRecipes(evaluateObjectExpression(stylesArg, path));
209
+ const styles = resolveRecipesWith(evaluateObjectExpression(stylesArg, path), globalRecipes ?? null);
239
210
  const { keyframes, nameMap } = extractKeyframesFromStyles(styles, globalKeyframes);
240
211
  const properties = extractPropertiesFromStyles(styles, { autoPropertyTypes });
241
212
  const fontFaces = extractFontFaceFromStyles(styles, globalFontFace);
@@ -253,10 +224,7 @@ function handleStylesMode(path, args, cssWriter, state, globalRegistry, mode, gl
253
224
  }
254
225
  registerIfVariableDeclaration(path, className, styles, state, globalRegistry);
255
226
  }
256
- /**
257
- * Handle tastyStatic(base, styles) - extends base with additional styles
258
- */
259
- function handleExtensionMode(path, args, cssWriter, state, globalRegistry, mode, globalKeyframes, autoPropertyTypes, globalFontFace, globalCounterStyle, globalFunction) {
227
+ function handleExtensionMode(path, args, cssWriter, state, globalRegistry, mode, globalKeyframes, autoPropertyTypes, globalFontFace, globalCounterStyle, globalFunction, globalRecipes) {
260
228
  if (args.length < 2) throw path.buildCodeFrameError("tastyStatic(base, styles) requires two arguments");
261
229
  const baseArg = args[0];
262
230
  const stylesArg = args[1];
@@ -266,7 +234,7 @@ function handleExtensionMode(path, args, cssWriter, state, globalRegistry, mode,
266
234
  const baseEntry = state.staticStyleRegistry[baseName] || globalRegistry[baseName];
267
235
  if (!baseEntry) throw path.buildCodeFrameError(`Cannot find base StaticStyle '${baseName}'. Make sure it is defined before being extended.`);
268
236
  const overrideStyles = evaluateObjectExpression(stylesArg, path);
269
- const mergedStyles = resolveRecipes(mergeStyles(baseEntry.styles, overrideStyles));
237
+ const mergedStyles = resolveRecipesWith(mergeStyles(baseEntry.styles, overrideStyles), globalRecipes ?? null);
270
238
  const { keyframes, nameMap } = extractKeyframesFromStyles(mergedStyles, globalKeyframes);
271
239
  const properties = extractPropertiesFromStyles(mergedStyles, { autoPropertyTypes });
272
240
  const fontFaces = extractFontFaceFromStyles(mergedStyles, globalFontFace);
@@ -284,17 +252,14 @@ function handleExtensionMode(path, args, cssWriter, state, globalRegistry, mode,
284
252
  }
285
253
  registerIfVariableDeclaration(path, className, mergedStyles, state, globalRegistry);
286
254
  }
287
- /**
288
- * Handle tastyStatic(selector, styles) - removes the call entirely
289
- */
290
- function handleSelectorMode(path, args, cssWriter, mode, sourceFile, globalKeyframes, autoPropertyTypes, globalFontFace, globalCounterStyle, globalFunction) {
255
+ function handleSelectorMode(path, args, cssWriter, mode, sourceFile, globalKeyframes, autoPropertyTypes, globalFontFace, globalCounterStyle, globalFunction, globalRecipes) {
291
256
  if (args.length < 2) throw path.buildCodeFrameError("tastyStatic(selector, styles) requires two arguments");
292
257
  const selectorArg = args[0];
293
258
  const stylesArg = args[1];
294
259
  if (!t.isStringLiteral(selectorArg)) throw path.buildCodeFrameError("tastyStatic(selector, styles) first argument must be a string literal");
295
260
  if (!t.isObjectExpression(stylesArg)) throw path.buildCodeFrameError("tastyStatic(selector, styles) second argument must be a static object literal");
296
261
  const selector = selectorArg.value;
297
- const styles = resolveRecipes(evaluateObjectExpression(stylesArg, path));
262
+ const styles = resolveRecipesWith(evaluateObjectExpression(stylesArg, path), globalRecipes ?? null);
298
263
  const { keyframes, nameMap } = extractKeyframesFromStyles(styles, globalKeyframes);
299
264
  const properties = extractPropertiesFromStyles(styles, { autoPropertyTypes });
300
265
  const fontFaces = extractFontFaceFromStyles(styles, globalFontFace);
@@ -322,9 +287,6 @@ function handleSelectorMode(path, args, cssWriter, mode, sourceFile, globalKeyfr
322
287
  else path.replaceWith(t.identifier("undefined"));
323
288
  }
324
289
  }
325
- /**
326
- * Collect all extracted CSS parts into a single string (for inject mode).
327
- */
328
290
  function collectAllCSS(keyframes, properties, fontFaces, counterStyles, functions, chunks, nameMap) {
329
291
  const parts = [];
330
292
  for (const kf of keyframes) parts.push(kf.css);
@@ -335,9 +297,6 @@ function collectAllCSS(keyframes, properties, fontFaces, counterStyles, function
335
297
  for (const chunk of chunks) parts.push(nameMap.size > 0 ? replaceAnimationNamesInCSS(chunk.css, nameMap) : chunk.css);
336
298
  return parts.join("\n");
337
299
  }
338
- /**
339
- * Write all extracted CSS parts to a CSSWriter (for file mode).
340
- */
341
300
  function writeCSSToWriter(cssWriter, keyframes, properties, fontFaces, counterStyles, functions, chunks, nameMap, sourceFile) {
342
301
  for (const kf of keyframes) cssWriter.add(kf.css, kf.css, sourceFile);
343
302
  for (const prop of properties) cssWriter.add(prop.css, prop.css, sourceFile);
@@ -349,23 +308,13 @@ function writeCSSToWriter(cssWriter, keyframes, properties, fontFaces, counterSt
349
308
  cssWriter.add(chunk.className, css, sourceFile);
350
309
  }
351
310
  }
352
- /**
353
- * Extract CSS for a selector from a styles/tokens object.
354
- * Returns undefined when there are no styles or no CSS output.
355
- */
356
311
  function extractCSSFromStyles(selector, styles) {
357
312
  if (!styles || Object.keys(styles).length === 0) return void 0;
358
313
  return extractStylesForSelector(selector, styles).css || void 0;
359
314
  }
360
- /**
361
- * Create an `_$i(id, css)` call expression AST node for inject mode.
362
- */
363
315
  function createInjectCallAST(id, css) {
364
316
  return t.callExpression(t.identifier("_$i"), [t.stringLiteral(id), t.stringLiteral(css)]);
365
317
  }
366
- /**
367
- * Create a StaticStyle object AST node
368
- */
369
318
  function createStaticStyleAST(className, styles) {
370
319
  return t.objectExpression([
371
320
  t.objectProperty(t.identifier("className"), t.stringLiteral(className)),
@@ -373,9 +322,6 @@ function createStaticStyleAST(className, styles) {
373
322
  t.objectMethod("method", t.identifier("toString"), [], t.blockStatement([t.returnStatement(t.memberExpression(t.thisExpression(), t.identifier("className")))]))
374
323
  ]);
375
324
  }
376
- /**
377
- * Register a StaticStyle in the registry if it's being assigned to a variable
378
- */
379
325
  function registerIfVariableDeclaration(path, className, styles, state, globalRegistry) {
380
326
  const parent = path.parentPath;
381
327
  if (parent && t.isVariableDeclarator(parent.node)) {
@@ -393,9 +339,6 @@ function registerIfVariableDeclaration(path, className, styles, state, globalReg
393
339
  }
394
340
  }
395
341
  }
396
- /**
397
- * Convert a JavaScript value to an AST node
398
- */
399
342
  function valueToAST(value) {
400
343
  if (value === null) return t.nullLiteral();
401
344
  if (value === void 0) return t.identifier("undefined");
@@ -409,10 +352,6 @@ function valueToAST(value) {
409
352
  }
410
353
  return t.identifier("undefined");
411
354
  }
412
- /**
413
- * Evaluate an ObjectExpression to a plain JavaScript object.
414
- * Only supports static values that can be determined at build time.
415
- */
416
355
  function evaluateObjectExpression(node, path) {
417
356
  const result = {};
418
357
  for (const prop of node.properties) {
@@ -426,9 +365,6 @@ function evaluateObjectExpression(node, path) {
426
365
  }
427
366
  return result;
428
367
  }
429
- /**
430
- * Evaluate an expression to a JavaScript value.
431
- */
432
368
  function evaluateExpression(node, path) {
433
369
  if (t.isStringLiteral(node)) return node.value;
434
370
  if (t.isNumericLiteral(node)) return node.value;
@@ -451,10 +387,6 @@ function evaluateExpression(node, path) {
451
387
  }
452
388
  throw path.buildCodeFrameError(`Dynamic expressions are not supported in tastyStatic() - got ${node.type}. All values must be static literals.`);
453
389
  }
454
- /**
455
- * Replace animation names in CSS string.
456
- * Wraps the keyframes replaceAnimationNames to work on full CSS blocks.
457
- */
458
390
  function replaceAnimationNamesInCSS(css, nameMap) {
459
391
  if (nameMap.size === 0) return css;
460
392
  return css.replace(/(animation(?:-name)?)\s*:\s*([^;}]+)/gi, (match, prop, value) => {
@@ -466,9 +398,6 @@ function replaceAnimationNamesInCSS(css, nameMap) {
466
398
  return `${prop}: ${newValue}`;
467
399
  });
468
400
  }
469
- /**
470
- * Escape special regex characters.
471
- */
472
401
  function escapeRegex(str) {
473
402
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
474
403
  }
@@ -1 +1 @@
1
- {"version":3,"file":"babel.js","names":[],"sources":["../../src/zero/writer-cache.ts","../../src/zero/babel.ts"],"sourcesContent":["/**\n * Internal shared CSSWriter cache for the zero-runtime Babel plugin.\n *\n * Kept in a separate non-exported module so `clearWriterCache` is not part\n * of the public `@tenphi/tasty/babel-plugin` entry surface. The Babel plugin\n * and its tests import from here directly.\n */\n\nimport type { CSSWriter } from './css-writer';\nimport type { Styles } from '../styles/types';\nimport type { TastyZeroConfig } from './babel-types';\n\n/**\n * Registry of static styles keyed by their source identifier.\n * Used to resolve base styles when extending.\n */\nexport type StaticStyleRegistry = Record<\n string,\n {\n styles: Styles;\n className: string;\n }\n>;\n\nexport interface WriterCacheEntry {\n writer: CSSWriter;\n configKey: string;\n registry: StaticStyleRegistry;\n config: TastyZeroConfig;\n}\n\nexport const 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 * 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 getGlobalFunctions,\n getGlobalStyles,\n getGlobalConfigTokens,\n resetConfig,\n} 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 type { TastyZeroConfig } from './babel-types';\nexport type { TastyZeroConfig } from './babel-types';\nimport { writerCache, type StaticStyleRegistry } from './writer-cache';\nimport {\n extractCounterStyleFromStyles,\n extractFontFaceFromStyles,\n extractFunctionsFromStyles,\n extractKeyframesFromStyles,\n extractPropertiesFromStyles,\n extractStylesForSelector,\n extractStylesWithChunks,\n setExtractorNamePrefix,\n} from './extractor';\nimport type {\n ExtractedChunk,\n ExtractedCounterStyle,\n ExtractedFontFace,\n ExtractedFunction,\n ExtractedKeyframes,\n ExtractedProperty,\n} from './extractor';\n\nimport type { NodePath, PluginPass } from '@babel/core';\nimport type {\n CounterStyleDescriptors,\n FontFaceInput,\n FunctionDefinition,\n KeyframesSteps,\n} from '../injector/types';\n\n/**\n * Options for the `@tenphi/tasty/babel-plugin` Babel plugin.\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\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// @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 | { 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.fontFaces,\n config.counterStyles,\n getGlobalFunctions() ?? undefined,\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.fontFaces,\n config.counterStyles,\n getGlobalFunctions() ?? undefined,\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.fontFaces,\n config.counterStyles,\n getGlobalFunctions() ?? undefined,\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 globalFunction?: Record<string, FunctionDefinition>,\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 @function rules\n const functions = extractFunctionsFromStyles(styles, globalFunction);\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 functions,\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 functions,\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 globalFunction?: Record<string, FunctionDefinition>,\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 @function rules\n const functions = extractFunctionsFromStyles(mergedStyles, globalFunction);\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 functions,\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 functions,\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 globalFunction?: Record<string, FunctionDefinition>,\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 @function rules\n const functions = extractFunctionsFromStyles(styles, globalFunction);\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 for (const fn of functions) cssParts.push(fn.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 functions,\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 functions: ExtractedFunction[],\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 for (const fn of functions) parts.push(fn.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 functions: ExtractedFunction[],\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 for (const fn of functions) {\n cssWriter.add(fn.css, fn.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
+ {"version":3,"file":"babel.js","names":[],"sources":["../../src/zero/writer-cache.ts","../../src/zero/babel.ts"],"sourcesContent":["/**\n * Internal shared CSSWriter cache for the zero-runtime Babel plugin.\n *\n * Kept in a separate non-exported module so `clearWriterCache` is not part\n * of the public `@tenphi/tasty/babel-plugin` entry surface. The Babel plugin\n * and its tests import from here directly.\n */\n\nimport type { CSSWriter } from './css-writer';\nimport type { Styles } from '../styles/types';\nimport type { ResolvedZeroConfig } from './config';\n\n/**\n * Registry of static styles keyed by their source identifier.\n * Used to resolve base styles when extending.\n */\nexport type StaticStyleRegistry = Record<\n string,\n {\n styles: Styles;\n className: string;\n }\n>;\n\nexport interface WriterCacheEntry {\n writer: CSSWriter;\n configKey: string;\n registry: StaticStyleRegistry;\n config: ResolvedZeroConfig;\n}\n\nexport const 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 * 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 type { ConfigTokens, RecipeStyles, Styles } from '../styles/types';\nimport { mergeStyles } from '../utils/merge-styles';\nimport { DEFAULT_ZERO_NAME_PREFIX } from '../utils/name-prefix';\nimport { resolveRecipesWith } from '../utils/resolve-recipes-core';\n\nimport { CSSWriter } from './css-writer';\nimport type { TastyZeroConfig } from './babel-types';\nexport type { TastyZeroConfig } from './babel-types';\nimport {\n configureZero,\n functionsForExtraction,\n resetZeroConfig,\n} from './config';\nimport { writerCache, type StaticStyleRegistry } from './writer-cache';\nimport {\n extractCounterStyleFromStyles,\n extractFontFaceFromStyles,\n extractFunctionsFromStyles,\n extractKeyframesFromStyles,\n extractPropertiesFromStyles,\n extractStylesForSelector,\n extractStylesWithChunks,\n setExtractorNamePrefix,\n} from './extractor';\nimport type {\n ExtractedChunk,\n ExtractedCounterStyle,\n ExtractedFontFace,\n ExtractedFunction,\n ExtractedKeyframes,\n ExtractedProperty,\n} from './extractor';\n\nimport type { NodePath, PluginPass } from '@babel/core';\nimport type {\n CounterStyleDescriptors,\n FontFaceInput,\n FunctionDefinition,\n KeyframesSteps,\n} from '../injector/types';\n\n/**\n * Options for the `@tenphi/tasty/babel-plugin` Babel plugin.\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\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// @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 | { 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 resetZeroConfig();\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 const config = configureZero(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', config.normalized.tokens);\n if (tokenCSS) newWriter.add(':root:tokens', tokenCSS);\n\n for (const [selector, styles] of Object.entries(\n config.normalized.globalStyles,\n )) {\n const css = extractCSSFromStyles(selector, styles);\n if (css) newWriter.add(`global:${selector}`, css);\n }\n }\n\n writerCache.set(resolvedOutputPath, {\n writer: newWriter,\n configKey,\n registry: {},\n config,\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 sourceConfig = config.source;\n const devMode = sourceConfig.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(sourceConfig.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', config.normalized.tokens);\n const gs = config.normalized.globalStyles;\n if (Object.keys(gs).length > 0) {\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.normalized.keyframes,\n sourceConfig.autoPropertyTypes,\n config.normalized.fontFaces,\n config.normalized.counterStyles,\n functionsForExtraction(config),\n config.normalized.recipes,\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.normalized.keyframes,\n sourceConfig.autoPropertyTypes,\n config.normalized.fontFaces,\n config.normalized.counterStyles,\n functionsForExtraction(config),\n config.normalized.recipes,\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.normalized.keyframes,\n sourceConfig.autoPropertyTypes,\n config.normalized.fontFaces,\n config.normalized.counterStyles,\n functionsForExtraction(config),\n config.normalized.recipes,\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 globalFunction?: Record<string, FunctionDefinition>,\n globalRecipes?: Record<string, RecipeStyles>,\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 = resolveRecipesWith(rawStyles, globalRecipes ?? null);\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 @function rules\n const functions = extractFunctionsFromStyles(styles, globalFunction);\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 functions,\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 functions,\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 globalFunction?: Record<string, FunctionDefinition>,\n globalRecipes?: Record<string, RecipeStyles>,\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 = resolveRecipesWith(\n mergeStyles(baseEntry.styles, overrideStyles),\n globalRecipes ?? null,\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 @function rules\n const functions = extractFunctionsFromStyles(mergedStyles, globalFunction);\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 functions,\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 functions,\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 globalFunction?: Record<string, FunctionDefinition>,\n globalRecipes?: Record<string, RecipeStyles>,\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 = resolveRecipesWith(rawStyles, globalRecipes ?? null);\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 @function rules\n const functions = extractFunctionsFromStyles(styles, globalFunction);\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 for (const fn of functions) cssParts.push(fn.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 functions,\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 functions: ExtractedFunction[],\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 for (const fn of functions) parts.push(fn.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 functions: ExtractedFunction[],\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 for (const fn of functions) {\n cssWriter.add(fn.css, fn.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,4 +1,4 @@
1
- import { b as Styles } from "../index-DBjd4MAb.js";
1
+ import { X as Styles } from "../types-jKZNpias.js";
2
2
 
3
3
  //#region src/zero/extractor.d.ts
4
4
  interface ExtractedChunk {
@@ -1,2 +1,2 @@
1
- import { c as extractStylesForSelector, l as extractStylesWithChunks, n as createCSSWriter, t as CSSWriter } from "../css-writer-BiumPvq-.js";
1
+ import { c as extractStylesForSelector, l as extractStylesWithChunks, n as createCSSWriter, t as CSSWriter } from "../chunks/zero-engine-B6EnYcXY.js";
2
2
  export { CSSWriter, createCSSWriter, extractStylesForSelector, extractStylesWithChunks };
@@ -1,4 +1,4 @@
1
- import { r as TastyZeroConfig } from "../babel-Cp_dRhuS.js";
1
+ import { r as TastyZeroConfig } from "../babel-Zs1Q03qt.js";
2
2
 
3
3
  //#region src/zero/next.d.ts
4
4
  interface WebpackConfigContext {
package/dist/zero/next.js CHANGED
@@ -3,39 +3,8 @@ import { createJiti } from "jiti";
3
3
  import { createRequire } from "module";
4
4
  import { fileURLToPath } from "url";
5
5
  //#region src/zero/next.ts
6
- /**
7
- * Next.js configuration wrapper for tasty-zero.
8
- *
9
- * Supports both webpack and Turbopack bundlers:
10
- * - **webpack**: Injects a babel-loader rule with the tasty-zero Babel plugin
11
- * via `webpack()` config hook. Config is passed as a jiti factory function.
12
- * - **Turbopack**: Adds a `turbopack.rules` entry with babel-loader and
13
- * JSON-serializable options (`configFile` path instead of a function).
14
- * The Babel plugin loads the config internally via jiti.
15
- *
16
- * The generated CSS is injected automatically — `@tenphi/tasty/static`
17
- * imports are replaced with an import of the output CSS file at build time.
18
- * No manual CSS import in layout files is needed.
19
- *
20
- * @example
21
- * ```javascript
22
- * // next.config.js
23
- * const { withTastyZero } = require('@tenphi/tasty/zero/next');
24
- *
25
- * module.exports = withTastyZero({
26
- * output: 'public/tasty.css',
27
- * configFile: './app/tasty-zero.config.ts',
28
- * })({
29
- * // your Next.js config
30
- * });
31
- * ```
32
- */
33
6
  const __filename = fileURLToPath(import.meta.url);
34
7
  const __dirname = path.dirname(__filename);
35
- /**
36
- * Next.js configuration wrapper for tasty-zero.
37
- * Configures both webpack and Turbopack bundlers automatically.
38
- */
39
8
  function withTastyZero(options = {}) {
40
9
  const { output = "public/tasty.css", enabled = true, config: tastyConfig, configFile, configDeps = [], mode } = options;
41
10
  return (nextConfig = {}) => {