@tenphi/tasty 0.0.0-snapshot.05e04ff → 0.0.0-snapshot.06c8a41

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 (76) hide show
  1. package/dist/astro-CeYENy2x.js +301 -0
  2. package/dist/astro-CeYENy2x.js.map +1 -0
  3. package/dist/{babel-B_P8t-f0.d.ts → babel-DWCsafYw.d.ts} +2 -2
  4. package/dist/{collector-DCI2yzwx.js → collector-B3OsM252.js} +36 -13
  5. package/dist/collector-B3OsM252.js.map +1 -0
  6. package/dist/{collector-CQDeU7WS.d.ts → collector-BTVXj2hS.d.ts} +21 -3
  7. package/dist/{config-B97n_EIv.js → config-B3gPdCqd.js} +202 -393
  8. package/dist/config-B3gPdCqd.js.map +1 -0
  9. package/dist/{config-CwRr6-fG.d.ts → config-LfIDmVHx.d.ts} +93 -65
  10. package/dist/core/index.d.ts +5 -5
  11. package/dist/core/index.js +6 -6
  12. package/dist/{core-DWrUWxog.js → core-DGm0CFHP.js} +271 -184
  13. package/dist/core-DGm0CFHP.js.map +1 -0
  14. package/dist/css-resources-Cyl_axbI.js +149 -0
  15. package/dist/css-resources-Cyl_axbI.js.map +1 -0
  16. package/dist/{css-writer-Cq0fg5v8.js → css-writer-Bgowobbx.js} +3 -3
  17. package/dist/{css-writer-Cq0fg5v8.js.map → css-writer-Bgowobbx.js.map} +1 -1
  18. package/dist/{format-rules-Wb7dJOoL.js → format-rules-XRw9u7d4.js} +3 -29
  19. package/dist/format-rules-XRw9u7d4.js.map +1 -0
  20. package/dist/{hydrate-gFTLBDK9.js → hydrate-CNOmZprz.js} +2 -2
  21. package/dist/{hydrate-gFTLBDK9.js.map → hydrate-CNOmZprz.js.map} +1 -1
  22. package/dist/{index-C0W21Qcb.d.ts → index-Bm9ltvdH.d.ts} +28 -53
  23. package/dist/{index-DpykQKO8.d.ts → index-BmogEzTo.d.ts} +60 -38
  24. package/dist/index.d.ts +5 -5
  25. package/dist/index.js +41 -117
  26. package/dist/index.js.map +1 -1
  27. package/dist/{renderChunk-COXABoQz.js → keyframes-DE-OE76F.js} +248 -3
  28. package/dist/keyframes-DE-OE76F.js.map +1 -0
  29. package/dist/{merge-styles-Bpwfy1CS.d.ts → merge-styles-BcLl1u_d.d.ts} +2 -2
  30. package/dist/{merge-styles-CzVxdtav.js → merge-styles-DuoZEsm9.js} +2 -2
  31. package/dist/{merge-styles-CzVxdtav.js.map → merge-styles-DuoZEsm9.js.map} +1 -1
  32. package/dist/{resolve-recipes-BnrUEjWV.js → resolve-recipes-H9NqOQuP.js} +3 -3
  33. package/dist/{resolve-recipes-BnrUEjWV.js.map → resolve-recipes-H9NqOQuP.js.map} +1 -1
  34. package/dist/ssr/astro-client.js +1 -1
  35. package/dist/ssr/astro-middleware-extract-static.d.ts +11 -0
  36. package/dist/ssr/astro-middleware-extract-static.js +9 -0
  37. package/dist/ssr/astro-middleware-extract-static.js.map +1 -0
  38. package/dist/ssr/astro-middleware-extract.d.ts +11 -0
  39. package/dist/ssr/astro-middleware-extract.js +9 -0
  40. package/dist/ssr/astro-middleware-extract.js.map +1 -0
  41. package/dist/ssr/astro-middleware-static.d.ts +3 -1
  42. package/dist/ssr/astro-middleware-static.js +1 -1
  43. package/dist/ssr/astro-middleware.d.ts +3 -1
  44. package/dist/ssr/astro-middleware.js +1 -1
  45. package/dist/ssr/astro.d.ts +45 -3
  46. package/dist/ssr/astro.js +1 -156
  47. package/dist/ssr/index.d.ts +2 -2
  48. package/dist/ssr/index.js +3 -3
  49. package/dist/ssr/index.js.map +1 -1
  50. package/dist/ssr/next-config.d.ts +66 -0
  51. package/dist/ssr/next-config.js +115 -0
  52. package/dist/ssr/next-config.js.map +1 -0
  53. package/dist/ssr/next.d.ts +9 -2
  54. package/dist/ssr/next.js +26 -9
  55. package/dist/ssr/next.js.map +1 -1
  56. package/dist/ssr-collector-ref-COs_ioWl.js +29 -0
  57. package/dist/ssr-collector-ref-COs_ioWl.js.map +1 -0
  58. package/dist/static/index.d.ts +2 -2
  59. package/dist/static/index.js +1 -1
  60. package/dist/zero/babel.d.ts +1 -1
  61. package/dist/zero/babel.js +4 -4
  62. package/dist/zero/babel.js.map +1 -1
  63. package/dist/zero/index.d.ts +1 -1
  64. package/dist/zero/index.js +1 -1
  65. package/dist/zero/next.d.ts +1 -1
  66. package/docs/debug.md +13 -0
  67. package/docs/injector.md +21 -7
  68. package/docs/runtime-benchmarks.md +192 -75
  69. package/docs/ssr.md +179 -20
  70. package/package.json +30 -9
  71. package/dist/collector-DCI2yzwx.js.map +0 -1
  72. package/dist/config-B97n_EIv.js.map +0 -1
  73. package/dist/core-DWrUWxog.js.map +0 -1
  74. package/dist/format-rules-Wb7dJOoL.js.map +0 -1
  75. package/dist/renderChunk-COXABoQz.js.map +0 -1
  76. package/dist/ssr/astro.js.map +0 -1
@@ -1,7 +1,8 @@
1
- import { $ as hasLocalKeyframes, B as camelToKebab, Bt as hasLocalFunctions, Dt as hasLocalProperties, J as formatCounterStyleRule, Jt as getGlobalParser, K as StyleInjector, Ot as parsePropertyToken, Q as filterUsedKeyframes, Qt as parseStyle, Rt as extractLocalFunctions, St as tastyClassRegex, Tt as extractLocalProperties, Ut as registerLocalFunctionPolyfills, Vt as parseFunctionName, X as extractAnimationNamesFromStyles, Xt as normalizeColorTokenValue, Y as hasLocalCounterStyle, Z as extractLocalKeyframes, an as isDevEnv, at as hasLocalFontFace, b as markStylesGenerated, c as getGlobalInjector, cn as overrideColorAlpha, dt as PropertyTypeResolver, et as mergeKeyframes, f as getNamePrefix, it as formatFontFaceRule, jt as CHUNK_NAMES, l as getGlobalKeyframes, m as hasGlobalKeyframes, mn as normalizeDslName, n as getConfig, nt as extractLocalFontFace, q as extractLocalCounterStyle, qt as getGlobalParseFunctions, rt as fontFaceContentHash, sn as Lru, st as STYLE_HANDLER_MAP, tt as replaceAnimationNames, ut as createStyle, v as isFunctionsPolyfillEnabled, wt as hashString, y as isTestEnvironment, yt as makeClassName, zt as formatFunctionRule } from "./config-B97n_EIv.js";
2
- import { n as generateChunkCacheKey, r as categorizeStyleKeys, t as renderStylesForChunk } from "./renderChunk-COXABoQz.js";
3
- import { n as formatPropertyCSS, r as getRegisteredSSRCollector, t as formatRules } from "./format-rules-Wb7dJOoL.js";
4
- import { t as resolveRecipes } from "./resolve-recipes-BnrUEjWV.js";
1
+ import { Bt as getGlobalParseFunctions, G as StyleInjector, Gt as parseStyle, It as registerLocalFunctionPolyfills, J as hasLocalCounterStyle, K as extractLocalCounterStyle, Mt as formatFunctionRule, Nt as hasLocalFunctions, Pt as parseFunctionName, Q as hasLocalFontFace, Qt as isDevEnv, Ut as normalizeColorTokenValue, Vt as getGlobalParser, X as fontFaceContentHash, Y as extractLocalFontFace, Z as formatFontFaceRule, _ as isFunctionsPolyfillEnabled, _t as hashString, bt as hasLocalProperties, c as getGlobalInjector, en as Lru, et as STYLE_HANDLER_MAP, f as getNamePrefix, ft as makeClassName, ht as tastyClassRegex, it as PropertyTypeResolver, jt as extractLocalFunctions, l as getGlobalKeyframes, n as getConfig, ot as flushStyles, p as hasGlobalKeyframes, q as formatCounterStyleRule, rt as createStyle, sn as normalizeDslName, tn as overrideColorAlpha, v as isTestEnvironment, vt as extractLocalProperties, wt as CHUNK_NAMES, xt as parsePropertyToken, y as markStylesGenerated, z as camelToKebab } from "./config-B3gPdCqd.js";
2
+ import { a as mergeKeyframes, c as resolveKeyframesNames, d as categorizeStyleKeys, i as hasLocalKeyframes, l as renderStylesForChunk, n as extractLocalKeyframes, o as referencesAnimation, r as filterUsedKeyframes, s as replaceAnimationNames, t as extractAnimationNamesFromStyles, u as generateChunkCacheKey } from "./keyframes-DE-OE76F.js";
3
+ import { t as getRegisteredSSRCollector } from "./ssr-collector-ref-COs_ioWl.js";
4
+ import { n as formatPropertyCSS, t as formatRules } from "./format-rules-XRw9u7d4.js";
5
+ import { t as resolveRecipes } from "./resolve-recipes-H9NqOQuP.js";
5
6
  import { cache } from "react";
6
7
  //#region src/utils/function-color.ts
7
8
  const RE_FUNC_NAME = /^([a-z][a-z0-9-]*)\s*\(/i;
@@ -245,59 +246,39 @@ function getCSSTextForNode(node, options) {
245
246
  return getGlobalInjector().getCSSTextForClasses(classSet, options);
246
247
  }
247
248
  /**
248
- * The class name a cache key resolves to, and whether its CSS is described
249
- * already. Pure — safe during render.
249
+ * Take a reference on local `@keyframes` under the deterministic names the
250
+ * caller resolved, and report which entry holds each. Pair with
251
+ * `ownKeyframes()` once the rules exist to inspect.
250
252
  */
251
- function resolveChunk(cacheKey) {
252
- return getGlobalInjector().resolveChunk(cacheKey);
253
- }
254
- /** Whether this class has already been described, so its CSS need not be re-rendered. */
255
- function hasRecipe(className) {
256
- return getGlobalInjector().hasRecipe(className);
253
+ function holdKeyframes(steps, names, options) {
254
+ return getGlobalInjector().holdKeyframes(steps, names, options);
257
255
  }
258
256
  /**
259
- * Record the CSS a class name stands for without writing it to a sheet, so the
260
- * commit that mounts it can insert it — and put it back if it was collected.
257
+ * Record that a class animates these keyframes, so the reference is released
258
+ * when the last such class is collected.
261
259
  */
262
- function defineRecipe(className, recipe) {
263
- const injector = getGlobalInjector();
264
- markStylesGenerated();
265
- injector.defineRecipe(className, recipe);
260
+ function ownKeyframes(key, className, options) {
261
+ getGlobalInjector().ownKeyframes(key, className, options);
266
262
  }
267
263
  /**
268
- * Take up styles on commit: insert whatever is missing from the sheet and count
269
- * one more mounted holder. Call from `useInsertionEffect`, and pair with
270
- * `releaseStyles` in its cleanup.
271
- *
272
- * `className` may hold several space-separated chunk classes; they are acquired
273
- * together, so one component pays one effect.
274
- */
275
- function acquireStyles(className, options) {
276
- const injector = getGlobalInjector();
277
- markStylesGenerated();
278
- injector.acquire(className, options);
279
- }
280
- /**
281
- * Give up styles on unmount. At zero holders the classes become collectible,
282
- * but nothing is deleted here — see `gc()`.
283
- */
284
- function releaseStyles(className, options) {
285
- getGlobalInjector().release(className, options);
286
- }
287
- /**
288
- * Remove every injected rule that no mounted component holds and no `inject()`
289
- * handle pins. Equivalent to `gc({ force: true })`.
264
+ * Remove every injected rule that is neither in the DOM nor held by an
265
+ * outstanding `inject()` handle. Equivalent to `gc({ force: true })`.
290
266
  */
291
267
  function cleanup(root) {
292
268
  return getGlobalInjector().cleanup(root);
293
269
  }
294
270
  /**
295
- * @deprecated No longer does anything. Collection follows React commits —
296
- * styled components acquire their classes in `useInsertionEffect` and release
297
- * them on unmount — so there is no usage counter left to feed. Kept so existing
298
- * imports keep working; remove the call.
271
+ * Count a render, so that a collection pass is scheduled every
272
+ * `gc.touchInterval` of them. Used internally by computeStyles and tasty().
273
+ *
274
+ * @deprecated The class name is ignored — collection asks the DOM what is
275
+ * rendered rather than recording usage per class. The argument is kept so
276
+ * existing calls still compile.
299
277
  */
300
- function touch(_className, _options) {}
278
+ function touch(className, options) {
279
+ if (!getConfig().gc) return;
280
+ getGlobalInjector().touch(className, options);
281
+ }
301
282
  /**
302
283
  * Synchronous garbage collection of unused styles — those no element carries
303
284
  * and no `inject()` handle references. Evicts the oldest ones once they exceed
@@ -582,8 +563,10 @@ function collectInternalsRSC(rscCache) {
582
563
  function collectAncillaryRSC(rscCache, styles) {
583
564
  const parts = [];
584
565
  const usedKf = getUsedKeyframes(styles);
585
- if (usedKf) for (const [name, steps] of Object.entries(usedKf)) {
586
- const key = `__kf:${name}:${JSON.stringify(steps)}`;
566
+ const rscKeyframeNames = usedKf ? resolveKeyframesNames(usedKf) : null;
567
+ if (usedKf && rscKeyframeNames) for (const [authored, steps] of Object.entries(usedKf)) {
568
+ const name = rscKeyframeNames.get(authored);
569
+ const key = `__kf:${name}`;
587
570
  if (!rscCache.emittedKeys.has(key)) {
588
571
  rscCache.emittedKeys.add(key);
589
572
  parts.push(formatKeyframesCSS(name, steps));
@@ -643,20 +626,23 @@ function computeStylesRSC(styles, chunkMap, stableStyles) {
643
626
  const rscCache = getRSCCache();
644
627
  const cssParts = [];
645
628
  const classNames = [];
629
+ const rscUsedKf = getUsedKeyframes(styles);
630
+ const rscKeyframeNames = rscUsedKf ? resolveKeyframesNames(rscUsedKf) : null;
646
631
  const pendingCSS = flushPendingCSS(rscCache);
647
632
  if (pendingCSS) cssParts.push(pendingCSS);
648
633
  const internalsCSS = collectInternalsRSC(rscCache);
649
634
  if (internalsCSS) cssParts.push(internalsCSS);
650
635
  for (const [chunkName, chunkStyleKeys] of chunkMap) {
651
636
  if (chunkStyleKeys.length === 0) continue;
652
- const { className, isNew } = rscAllocateClassName(rscCache, generateChunkCacheKey(styles, chunkName, chunkStyleKeys, stableStyles));
637
+ const baseKey = generateChunkCacheKey(styles, chunkName, chunkStyleKeys, stableStyles);
638
+ const renderResult = renderStylesForChunk(styles, chunkName, chunkStyleKeys);
639
+ if (renderResult.rules.length === 0) continue;
640
+ const { rules, cacheKey } = applyKeyframeNames(renderResult.rules, baseKey, rscKeyframeNames);
641
+ const { className, isNew } = rscAllocateClassName(rscCache, cacheKey);
653
642
  classNames.push(className);
654
643
  if (isNew) {
655
- const renderResult = renderStylesForChunk(styles, chunkName, chunkStyleKeys);
656
- if (renderResult.rules.length > 0) {
657
- const css = formatRules(renderResult.rules, className);
658
- if (css) cssParts.push(css);
659
- }
644
+ const css = formatRules(rules, className);
645
+ if (css) cssParts.push(css);
660
646
  }
661
647
  }
662
648
  const ancillaryCSS = collectAncillaryRSC(rscCache, styles);
@@ -683,117 +669,92 @@ function getUsedKeyframes(styles) {
683
669
  /**
684
670
  * Process a chunk on the SSR path: allocate via collector, render, collect CSS.
685
671
  */
686
- function processChunkSSR(collector, styles, chunkName, styleKeys, stableStyles) {
672
+ function processChunkSSR(collector, styles, chunkName, styleKeys, stableStyles, keyframeNames) {
687
673
  if (styleKeys.length === 0) return null;
688
- const cacheKey = generateChunkCacheKey(styles, chunkName, styleKeys, stableStyles);
674
+ const baseKey = generateChunkCacheKey(styles, chunkName, styleKeys, stableStyles);
675
+ const renderResult = renderStylesForChunk(styles, chunkName, styleKeys);
676
+ if (renderResult.rules.length === 0) return null;
677
+ const { animations, rules, cacheKey } = applyKeyframeNames(renderResult.rules, baseKey, keyframeNames);
689
678
  const { className, isNewAllocation } = collector.allocateClassName(cacheKey);
690
679
  if (isNewAllocation) {
691
- const renderResult = renderStylesForChunk(styles, chunkName, styleKeys);
692
- if (renderResult.rules.length > 0) {
693
- collector.collectChunk(cacheKey, className, renderResult.rules);
694
- return {
695
- name: chunkName,
696
- styleKeys,
697
- cacheKey,
698
- renderResult,
699
- className
700
- };
701
- }
702
- return null;
703
- }
704
- return {
705
- name: chunkName,
706
- styleKeys,
707
- cacheKey,
708
- renderResult: { rules: [] },
709
- className
710
- };
711
- }
712
- /**
713
- * Process a chunk on the client: render, resolve the className, and — unless
714
- * the caller manages the class through a commit — inject it now.
715
- */
716
- function processChunkSync(styles, chunkName, styleKeys, stableStyles, root, managed) {
717
- if (styleKeys.length === 0) return null;
718
- const cacheKey = generateChunkCacheKey(styles, chunkName, styleKeys, stableStyles);
719
- if (managed) {
720
- const { name: className, described } = resolveChunk(cacheKey);
721
- if (described) return {
722
- name: chunkName,
723
- styleKeys,
724
- cacheKey,
725
- renderResult: { rules: [] },
726
- className
727
- };
728
- const renderResult = renderStylesForChunk(styles, chunkName, styleKeys, cacheKey);
729
- if (renderResult.rules.length === 0) return null;
680
+ collector.collectChunk(cacheKey, className, rules);
730
681
  return {
731
682
  name: chunkName,
732
683
  styleKeys,
733
684
  cacheKey,
734
- renderResult,
735
- className
685
+ renderResult: {
686
+ ...renderResult,
687
+ rules
688
+ },
689
+ className,
690
+ animations
736
691
  };
737
692
  }
738
- const renderResult = renderStylesForChunk(styles, chunkName, styleKeys, cacheKey);
739
- if (renderResult.rules.length === 0) return null;
740
- const { className } = inject(renderResult.rules, {
741
- cacheKey,
742
- root
743
- });
744
693
  return {
745
694
  name: chunkName,
746
695
  styleKeys,
747
696
  cacheKey,
748
- renderResult,
697
+ renderResult: { rules: [] },
749
698
  className
750
699
  };
751
700
  }
752
701
  /**
753
- * Inject keyframes synchronously and return a name replacement map.
754
- * On the client, keyframes are injected into the DOM.
755
- */
756
- function injectKeyframesSync(usedKeyframes, root) {
757
- let nameMap = null;
758
- for (const [name, steps] of Object.entries(usedKeyframes)) {
759
- const injectedName = keyframes(steps, {
760
- name,
761
- root
762
- }).toString();
763
- if (injectedName !== name) {
764
- if (!nameMap) nameMap = /* @__PURE__ */ new Map();
765
- nameMap.set(name, injectedName);
766
- }
767
- }
768
- return nameMap;
769
- }
770
- /**
771
- * Record what each freshly described chunk class stands for, so the commit that
772
- * mounts it can insert the rules — and so a later commit can put them back if
773
- * they were collected in between.
702
+ * Point a chunk's rules at the resolved keyframe names, and fold those names
703
+ * into its cache key.
704
+ *
705
+ * Both halves matter, and both have to happen before the rules are written
706
+ * anywhere: the declarations have to name the animation that will exist, and
707
+ * the key has to distinguish two components that authored the same shorthand
708
+ * over different definitions. Shared by the client and the server so they
709
+ * cannot disagree about either.
774
710
  */
775
- function recordChunkRecipes(chunks, usedKeyframes) {
776
- for (const chunk of chunks) {
777
- if (chunk.renderResult.rules.length === 0) continue;
778
- defineRecipe(chunk.className, {
779
- rules: chunk.renderResult.rules,
780
- cacheKey: chunk.cacheKey,
781
- keyframes: usedKeyframes ?? void 0
782
- });
783
- }
711
+ function applyKeyframeNames(ruleset, baseKey, keyframeNames) {
712
+ if (!keyframeNames || keyframeNames.size === 0) return {
713
+ animations: [],
714
+ rules: ruleset,
715
+ cacheKey: baseKey
716
+ };
717
+ const animations = [...keyframeNames.keys()].filter((authored) => ruleset.some((rule) => referencesAnimation(rule.declarations, authored)));
718
+ if (animations.length === 0) return {
719
+ animations,
720
+ rules: ruleset,
721
+ cacheKey: baseKey
722
+ };
723
+ return {
724
+ animations,
725
+ rules: ruleset.map((rule) => ({
726
+ ...rule,
727
+ declarations: replaceAnimationNames(rule.declarations, keyframeNames)
728
+ })),
729
+ cacheKey: `${baseKey}\u0000kf:${animations.map((authored) => `${authored}=${keyframeNames.get(authored)}`).sort().join(",")}`
730
+ };
784
731
  }
785
732
  /**
786
- * Inject chunk rules synchronously, replacing animation names if needed.
733
+ * Process a chunk on the client: render, allocate className, and inject
734
+ * CSS synchronously. The injector's cache makes this idempotent.
787
735
  */
788
- function injectChunkRulesSync(chunks, nameMap, root) {
789
- for (const chunk of chunks) if (chunk.renderResult.rules.length > 0) inject(nameMap ? chunk.renderResult.rules.map((rule) => ({
790
- ...rule,
791
- declarations: replaceAnimationNames(rule.declarations, nameMap)
792
- })) : chunk.renderResult.rules, {
793
- cacheKey: chunk.cacheKey,
736
+ function processChunkSync(styles, chunkName, styleKeys, stableStyles, root, keyframeNames) {
737
+ if (styleKeys.length === 0) return null;
738
+ const cacheKey = generateChunkCacheKey(styles, chunkName, styleKeys, stableStyles);
739
+ const renderResult = renderStylesForChunk(styles, chunkName, styleKeys, cacheKey);
740
+ if (renderResult.rules.length === 0) return null;
741
+ const { animations, rules, cacheKey: injectKey } = applyKeyframeNames(renderResult.rules, cacheKey, keyframeNames);
742
+ const { className } = inject(rules, {
743
+ cacheKey: injectKey,
794
744
  root,
795
745
  pin: false
796
746
  });
747
+ return {
748
+ name: chunkName,
749
+ styleKeys,
750
+ cacheKey: injectKey,
751
+ renderResult: {
752
+ ...renderResult,
753
+ rules
754
+ },
755
+ className,
756
+ animations
757
+ };
797
758
  }
798
759
  /**
799
760
  * Inject all ancillary rules (properties, font-faces, counter-styles) synchronously.
@@ -827,9 +788,12 @@ function injectAncillarySync(styles, root) {
827
788
  */
828
789
  function collectAncillarySSR(collector, styles, chunks) {
829
790
  const usedKf = getUsedKeyframes(styles);
830
- if (usedKf) for (const [name, steps] of Object.entries(usedKf)) {
831
- const css = formatKeyframesCSS(name, steps);
832
- collector.collectKeyframes(name, css);
791
+ if (usedKf) {
792
+ const names = resolveKeyframesNames(usedKf);
793
+ for (const [authored, steps] of Object.entries(usedKf)) {
794
+ const name = names.get(authored);
795
+ collector.collectKeyframes(name, formatKeyframesCSS(name, steps));
796
+ }
833
797
  }
834
798
  if (hasLocalProperties(styles)) {
835
799
  const localProperties = extractLocalProperties(styles);
@@ -893,24 +857,29 @@ function computeStyles(styles, options) {
893
857
  const chunks = [];
894
858
  if (collector) {
895
859
  collector.collectInternals();
860
+ const ssrKf = getUsedKeyframes(resolved);
861
+ const ssrKeyframeNames = ssrKf ? resolveKeyframesNames(ssrKf) : null;
896
862
  for (const [chunkName, chunkStyleKeys] of chunkMap) {
897
- const chunk = processChunkSSR(collector, resolved, chunkName, chunkStyleKeys, stableStyles);
863
+ const chunk = processChunkSSR(collector, resolved, chunkName, chunkStyleKeys, stableStyles, ssrKeyframeNames);
898
864
  if (chunk) chunks.push(chunk);
899
865
  }
900
866
  collectAncillarySSR(collector, resolved, chunks);
901
867
  } else if (typeof document === "undefined") return computeStylesRSC(resolved, chunkMap, stableStyles);
902
868
  else {
903
869
  const root = options?.root;
904
- const managed = options?.managed;
905
870
  injectAncillarySync(resolved, root);
906
871
  const usedKf = getUsedKeyframes(resolved);
907
- const nameMap = usedKf && !managed ? injectKeyframesSync(usedKf, root) : null;
872
+ const keyframeNames = usedKf ? resolveKeyframesNames(usedKf) : null;
873
+ const keyframeKeys = usedKf && keyframeNames ? holdKeyframes(usedKf, keyframeNames, { root }) : null;
908
874
  for (const [chunkName, chunkStyleKeys] of chunkMap) {
909
- const chunk = processChunkSync(resolved, chunkName, chunkStyleKeys, stableStyles, root, managed);
875
+ const chunk = processChunkSync(resolved, chunkName, chunkStyleKeys, stableStyles, root, keyframeNames);
910
876
  if (chunk) chunks.push(chunk);
911
877
  }
912
- if (managed) recordChunkRecipes(chunks, usedKf);
913
- else if (nameMap) injectChunkRulesSync(chunks, nameMap, root);
878
+ if (keyframeKeys) for (const chunk of chunks) for (const authored of chunk.animations ?? []) {
879
+ const key = keyframeKeys.get(authored);
880
+ if (key) ownKeyframes(key, chunk.className, { root });
881
+ }
882
+ for (const chunk of chunks) touch(chunk.className, { root });
914
883
  }
915
884
  if (chunks.length === 0) return EMPTY_RESULT;
916
885
  if (chunks.length === 1) return { className: chunks[0].className };
@@ -1190,10 +1159,41 @@ function countRules(css) {
1190
1159
  function sortTastyClasses(classes) {
1191
1160
  return Array.from(classes).sort((a, b) => a.localeCompare(b));
1192
1161
  }
1193
- function getRegistry(root = document) {
1162
+ /**
1163
+ * The root these helpers read, or `null` where there is no DOM.
1164
+ *
1165
+ * `document` used to be a default parameter value, and a default is evaluated
1166
+ * at the call site — so every read below threw a bare `ReferenceError` under
1167
+ * Node, taking out five of the eight public methods. A debug utility must not
1168
+ * be able to fail an SSR render because a call was left in, so the DOM-less
1169
+ * case reports an empty result and says why.
1170
+ */
1171
+ function defaultRoot() {
1172
+ return typeof document === "undefined" ? null : document;
1173
+ }
1174
+ let warnedNoDom = false;
1175
+ /** Say once why the numbers are empty. Silent under `{ raw: true }`. */
1176
+ function warnNoDom(raw) {
1177
+ if (raw || warnedNoDom) return;
1178
+ warnedNoDom = true;
1179
+ console.warn("[Tasty] tastyDebug reads the DOM and this environment has none, so the result is empty. During SSR, read the ServerStyleCollector instead.");
1180
+ }
1181
+ /**
1182
+ * The registry for `root`, with every queued write landed first.
1183
+ *
1184
+ * Every injector read API is a flush point, and the reads below reach past
1185
+ * those APIs straight into the registry and the sheet manager. Without this
1186
+ * they would report a batch window's contents as absent — a rule that is
1187
+ * enqueued but not yet in a sheet is missing from `globalRules`, from the
1188
+ * sheets, and from anything counting either.
1189
+ */
1190
+ function getRegistry(root = defaultRoot()) {
1191
+ if (!root) return void 0;
1192
+ flushStyles();
1194
1193
  return injector.instance._sheetManager?.getRegistry(root);
1195
1194
  }
1196
- function findDomTastyClasses(root = document) {
1195
+ function findDomTastyClasses(root = defaultRoot()) {
1196
+ if (!root) return [];
1197
1197
  const classes = /* @__PURE__ */ new Set();
1198
1198
  const elements = root.querySelectorAll?.("[class]") || [];
1199
1199
  const classRegex = tastyClassRegex(getNamePrefix());
@@ -1206,6 +1206,29 @@ function findDomTastyClasses(root = document) {
1206
1206
  return sortTastyClasses(classes);
1207
1207
  }
1208
1208
  /**
1209
+ * Everything this injector holds in `root`, in the order the engine applies it,
1210
+ * with the sources kept byte-for-byte — trimming would report a total smaller
1211
+ * than one of its own parts whenever raw CSS has edge whitespace.
1212
+ */
1213
+ function getAllCSS(root = defaultRoot()) {
1214
+ const registry = getRegistry(root);
1215
+ const sheetManager = injector.instance._sheetManager;
1216
+ if (!root || !registry || !sheetManager) return "";
1217
+ return sheetManager.getOwnedCSSInOrder(registry, root).join("\n");
1218
+ }
1219
+ /**
1220
+ * The injector's own readers fall back to `document` when `root` is omitted, so
1221
+ * they have to be reached with a real root or not at all.
1222
+ */
1223
+ function cssTextForClasses(classNames, root) {
1224
+ if (!root) return "";
1225
+ return injector.instance.getCSSTextForClasses(classNames, { root });
1226
+ }
1227
+ function getInjectorMetrics(root) {
1228
+ if (!root) return null;
1229
+ return injector.instance.getMetrics({ root });
1230
+ }
1231
+ /**
1209
1232
  * Injected classes that no element carries and nobody pinned — the exact set
1210
1233
  * `gc({ force: true })` would delete.
1211
1234
  *
@@ -1213,9 +1236,18 @@ function findDomTastyClasses(root = document) {
1213
1236
  * drifted apart once before, when this file still read "unused" off the pin
1214
1237
  * counts the render path had stopped maintaining.
1215
1238
  */
1216
- function getUnusedClasses(root = document) {
1239
+ function getUnusedClasses(root = defaultRoot()) {
1240
+ if (!root) return [];
1217
1241
  return sortTastyClasses(injector.instance.getUnusedClasses({ root }));
1218
1242
  }
1243
+ /** Every class this injector holds CSS for in `root`. */
1244
+ function getOwnedClasses(root = defaultRoot()) {
1245
+ const registry = getRegistry(root);
1246
+ if (!registry) return [];
1247
+ const owned = [];
1248
+ for (const [className, info] of registry.rules) if (info.sheetIndex >= 0) owned.push(className);
1249
+ return sortTastyClasses(owned);
1250
+ }
1219
1251
  function prettifyCSS(css) {
1220
1252
  if (!css || !css.trim()) return "";
1221
1253
  const out = [];
@@ -1276,15 +1308,15 @@ function extractChunkName(cacheKey) {
1276
1308
  }
1277
1309
  return null;
1278
1310
  }
1279
- function getChunkForClass(className, root = document) {
1311
+ function getChunkForClass(className, root = defaultRoot()) {
1280
1312
  const registry = getRegistry(root);
1281
1313
  if (!registry) return null;
1282
1314
  for (const [key, cn] of registry.cacheKeyToClassName) if (cn === className) return extractChunkName(key);
1283
1315
  return null;
1284
1316
  }
1285
- function buildChunkBreakdown(root = document) {
1317
+ function buildChunkBreakdown(root = defaultRoot()) {
1286
1318
  const registry = getRegistry(root);
1287
- if (!registry) return {
1319
+ if (!root || !registry) return {
1288
1320
  byChunk: {},
1289
1321
  totalChunkTypes: 0,
1290
1322
  totalClasses: 0
@@ -1310,15 +1342,36 @@ function buildChunkBreakdown(root = document) {
1310
1342
  totalClasses
1311
1343
  };
1312
1344
  }
1313
- function getGlobalTypeCSS(type, root = document) {
1345
+ /**
1346
+ * Every prefix `registry.globalRules` is keyed by. Anything missing here is a
1347
+ * rule the summary would hold but never count, which is how the totals stopped
1348
+ * adding up the first time.
1349
+ */
1350
+ const GLOBAL_RULE_PREFIXES = {
1351
+ global: "global:",
1352
+ property: "property:",
1353
+ fontFace: "fontface:",
1354
+ counterStyle: "counterstyle:",
1355
+ function: "function:"
1356
+ };
1357
+ function getGlobalTypeCSS(type, root = defaultRoot()) {
1314
1358
  const registry = getRegistry(root);
1315
- if (!registry) return {
1359
+ if (!root || !registry) return {
1316
1360
  css: "",
1317
1361
  ruleCount: 0,
1318
1362
  size: 0
1319
1363
  };
1320
1364
  const chunks = [];
1321
1365
  let rc = 0;
1366
+ if (type === "raw") {
1367
+ const css = injector.instance.getRawCSSText({ root });
1368
+ const sheetManager = injector.instance._sheetManager;
1369
+ return {
1370
+ css: prettifyCSS(css),
1371
+ ruleCount: sheetManager?.getRawRuleCount(root) ?? 0,
1372
+ size: css.length
1373
+ };
1374
+ }
1322
1375
  if (type === "keyframes") for (const [, entry] of registry.keyframesCache) {
1323
1376
  const info = entry.info;
1324
1377
  const sheetInfo = registry.sheets[info.sheetIndex];
@@ -1336,7 +1389,7 @@ function getGlobalTypeCSS(type, root = document) {
1336
1389
  }
1337
1390
  }
1338
1391
  else {
1339
- const prefix = type === "global" ? "global:" : type === "raw" ? "raw:" : "property:";
1392
+ const prefix = GLOBAL_RULE_PREFIXES[type];
1340
1393
  for (const [key, ri] of registry.globalRules) {
1341
1394
  if (!key.startsWith(prefix)) continue;
1342
1395
  const sheetInfo = registry.sheets[ri.sheetIndex];
@@ -1365,7 +1418,7 @@ function getGlobalTypeCSS(type, root = document) {
1365
1418
  size: raw.length
1366
1419
  };
1367
1420
  }
1368
- function getSourceCssForClasses(classNames, root = document) {
1421
+ function getSourceCssForClasses(classNames, root = defaultRoot()) {
1369
1422
  const registry = getRegistry(root);
1370
1423
  if (!registry) return null;
1371
1424
  const chunks = [];
@@ -1379,7 +1432,7 @@ function getSourceCssForClasses(classNames, root = document) {
1379
1432
  }
1380
1433
  return found ? chunks.join("\n") : null;
1381
1434
  }
1382
- function getDefs(root = document) {
1435
+ function getDefs(root = defaultRoot()) {
1383
1436
  const registry = getRegistry(root);
1384
1437
  let properties = [];
1385
1438
  if (registry?.injectedProperties) properties = Array.from(registry.injectedProperties.keys()).sort();
@@ -1409,7 +1462,11 @@ const CHUNK_ORDER = [
1409
1462
  ];
1410
1463
  const tastyDebug = {
1411
1464
  css(target, opts) {
1412
- const { root = document, prettify = true, raw = false, source = false } = opts || {};
1465
+ const { root = defaultRoot(), prettify = true, raw = false, source = false } = opts || {};
1466
+ if (!root) {
1467
+ warnNoDom(raw);
1468
+ return "";
1469
+ }
1413
1470
  let css = "";
1414
1471
  const classRegex = tastyClassRegex(getNamePrefix());
1415
1472
  if (source && typeof target === "string" && classRegex.test(target)) {
@@ -1426,7 +1483,7 @@ const tastyDebug = {
1426
1483
  if (!raw) console.warn("[Tasty] source CSS not available. Falling back to live CSSOM.");
1427
1484
  css = injector.instance.getCSSTextForClasses(target, { root });
1428
1485
  }
1429
- } else if (typeof target === "string") if (target === "all") css = injector.instance.getCSSText({ root });
1486
+ } else if (typeof target === "string") if (target === "all") css = getAllCSS(root);
1430
1487
  else if (target === "global") {
1431
1488
  css = getGlobalTypeCSS("global", root).css;
1432
1489
  return css;
@@ -1455,8 +1512,9 @@ const tastyDebug = {
1455
1512
  return result;
1456
1513
  },
1457
1514
  inspect(target, opts) {
1458
- const { root = document, raw = false } = opts || {};
1459
- const element = typeof target === "string" ? root.querySelector?.(target) : target;
1515
+ const { root = defaultRoot(), raw = false } = opts || {};
1516
+ const element = !root ? null : typeof target === "string" ? root.querySelector?.(target) : target;
1517
+ if (!root) warnNoDom(raw);
1460
1518
  if (!element) {
1461
1519
  const empty = {
1462
1520
  element: null,
@@ -1466,7 +1524,7 @@ const tastyDebug = {
1466
1524
  size: 0,
1467
1525
  rules: 0
1468
1526
  };
1469
- if (!raw) console.warn("[Tasty] debug.inspect: element not found");
1527
+ if (!raw && root) console.warn("[Tasty] debug.inspect: element not found");
1470
1528
  return empty;
1471
1529
  }
1472
1530
  const classList = element.getAttribute("class") || "";
@@ -1476,7 +1534,7 @@ const tastyDebug = {
1476
1534
  className,
1477
1535
  chunkName: getChunkForClass(className, root)
1478
1536
  }));
1479
- const css = getCSSTextForNode(element, { root });
1537
+ const css = getCSSTextForNode(element, { root: root ?? void 0 });
1480
1538
  const rules = countRules(css);
1481
1539
  const result = {
1482
1540
  element,
@@ -1499,37 +1557,60 @@ const tastyDebug = {
1499
1557
  return result;
1500
1558
  },
1501
1559
  summary(opts) {
1502
- const { root = document, raw = false } = opts || {};
1560
+ const { root = defaultRoot(), raw = false } = opts || {};
1561
+ if (!root) warnNoDom(raw);
1503
1562
  const activeClasses = findDomTastyClasses(root);
1504
1563
  const unusedClasses = getUnusedClasses(root);
1505
- const totalStyledClasses = [...activeClasses, ...unusedClasses];
1506
- const activeCSS = injector.instance.getCSSTextForClasses(activeClasses, { root });
1507
- const unusedCSS = injector.instance.getCSSTextForClasses(unusedClasses, { root });
1508
- const allCSS = injector.instance.getCSSText({ root });
1564
+ const ownedClasses = getOwnedClasses(root);
1565
+ const totalStyledClasses = sortTastyClasses(new Set([...activeClasses, ...ownedClasses]));
1566
+ const unusedSet = new Set(unusedClasses);
1567
+ const activeSet = new Set(activeClasses);
1568
+ const hotClasses = ownedClasses.filter((className) => !activeSet.has(className) && !unusedSet.has(className));
1569
+ const hotCSS = cssTextForClasses(hotClasses, root);
1570
+ const activeCSS = cssTextForClasses(activeClasses, root);
1571
+ const unusedCSS = cssTextForClasses(unusedClasses, root);
1572
+ const allCSS = getAllCSS(root);
1509
1573
  const activeRuleCount = countRules(activeCSS);
1510
1574
  const unusedRuleCount = countRules(unusedCSS);
1511
1575
  const globalData = getGlobalTypeCSS("global", root);
1512
1576
  const rawData = getGlobalTypeCSS("raw", root);
1513
1577
  const kfData = getGlobalTypeCSS("keyframes", root);
1514
1578
  const propData = getGlobalTypeCSS("property", root);
1515
- const totalRuleCount = activeRuleCount + unusedRuleCount + globalData.ruleCount + rawData.ruleCount + kfData.ruleCount + propData.ruleCount;
1516
- const metrics = injector.instance.getMetrics({ root });
1579
+ const atRuleData = [
1580
+ "fontFace",
1581
+ "counterStyle",
1582
+ "function"
1583
+ ].reduce((all, type) => {
1584
+ const data = getGlobalTypeCSS(type, root);
1585
+ return {
1586
+ css: data.css ? `${all.css}\n${data.css}`.trim() : all.css,
1587
+ ruleCount: all.ruleCount + data.ruleCount,
1588
+ size: all.size + data.size
1589
+ };
1590
+ }, {
1591
+ css: "",
1592
+ ruleCount: 0,
1593
+ size: 0
1594
+ });
1595
+ const totalRuleCount = activeRuleCount + unusedRuleCount + countRules(hotCSS) + globalData.ruleCount + atRuleData.ruleCount + rawData.ruleCount + kfData.ruleCount + propData.ruleCount;
1596
+ const metrics = getInjectorMetrics(root);
1517
1597
  const defs = getDefs(root);
1518
1598
  const chunkBreakdown = buildChunkBreakdown(root);
1519
1599
  const summary = {
1520
1600
  activeClasses,
1521
1601
  unusedClasses,
1602
+ hotClasses,
1522
1603
  totalStyledClasses,
1523
1604
  activeCSSSize: activeCSS.length,
1524
1605
  unusedCSSSize: unusedCSS.length,
1525
- globalCSSSize: globalData.size,
1606
+ globalCSSSize: globalData.size + atRuleData.size,
1526
1607
  rawCSSSize: rawData.size,
1527
1608
  keyframesCSSSize: kfData.size,
1528
1609
  propertyCSSSize: propData.size,
1529
1610
  totalCSSSize: allCSS.length,
1530
1611
  activeRuleCount,
1531
1612
  unusedRuleCount,
1532
- globalRuleCount: globalData.ruleCount,
1613
+ globalRuleCount: globalData.ruleCount + atRuleData.ruleCount,
1533
1614
  rawRuleCount: rawData.ruleCount,
1534
1615
  keyframesRuleCount: kfData.ruleCount,
1535
1616
  propertyRuleCount: propData.ruleCount,
@@ -1543,7 +1624,8 @@ const tastyDebug = {
1543
1624
  console.group("Tasty Summary");
1544
1625
  console.log(`Active: ${activeClasses.length} classes, ${activeRuleCount} rules, ${fmtSize(activeCSS.length)}`);
1545
1626
  console.log(`Unused: ${unusedClasses.length} classes, ${unusedRuleCount} rules, ${fmtSize(unusedCSS.length)}`);
1546
- console.log(`Global: ${globalData.ruleCount} rules, ${fmtSize(globalData.size)}`);
1627
+ if (hotClasses.length) console.log(`Held: ${hotClasses.length} classes, ${countRules(hotCSS)} rules, ${fmtSize(hotCSS.length)} (not rendered, not yet collectable)`);
1628
+ console.log(`Global: ${globalData.ruleCount + atRuleData.ruleCount} rules, ${fmtSize(globalData.size + atRuleData.size)}`);
1547
1629
  if (rawData.ruleCount) console.log(`Raw: ${rawData.ruleCount} rules, ${fmtSize(rawData.size)}`);
1548
1630
  if (kfData.ruleCount) console.log(`Keyframes: ${kfData.ruleCount} rules, ${fmtSize(kfData.size)}`);
1549
1631
  if (propData.ruleCount) console.log(`@property: ${propData.ruleCount} rules, ${fmtSize(propData.size)}`);
@@ -1568,7 +1650,8 @@ const tastyDebug = {
1568
1650
  return summary;
1569
1651
  },
1570
1652
  chunks(opts) {
1571
- const { root = document, raw = false } = opts || {};
1653
+ const { root = defaultRoot(), raw = false } = opts || {};
1654
+ if (!root) warnNoDom(raw);
1572
1655
  const breakdown = buildChunkBreakdown(root);
1573
1656
  if (!raw) {
1574
1657
  console.group(`Chunks (${breakdown.totalChunkTypes} types, ${breakdown.totalClasses} classes)`);
@@ -1582,15 +1665,16 @@ const tastyDebug = {
1582
1665
  return breakdown;
1583
1666
  },
1584
1667
  cache(opts) {
1585
- const { root = document, raw = false } = opts || {};
1668
+ const { root = defaultRoot(), raw = false } = opts || {};
1669
+ if (!root) warnNoDom(raw);
1586
1670
  const active = findDomTastyClasses(root);
1587
1671
  const unused = getUnusedClasses(root);
1588
- const metrics = injector.instance.getMetrics({ root });
1672
+ const metrics = getInjectorMetrics(root);
1589
1673
  const status = {
1590
1674
  classes: {
1591
1675
  active,
1592
1676
  unused,
1593
- all: [...active, ...unused]
1677
+ all: sortTastyClasses(new Set([...active, ...getOwnedClasses(root)]))
1594
1678
  },
1595
1679
  metrics
1596
1680
  };
@@ -1607,7 +1691,9 @@ const tastyDebug = {
1607
1691
  return status;
1608
1692
  },
1609
1693
  cleanup(opts) {
1610
- injector.instance.cleanup(opts?.root);
1694
+ const root = opts?.root ?? defaultRoot();
1695
+ if (!root) return;
1696
+ injector.instance.cleanup(root);
1611
1697
  },
1612
1698
  help() {
1613
1699
  console.log(`tastyDebug API:
@@ -1629,7 +1715,8 @@ Options: { raw: true } suppresses logging, { root: shadowRoot } targets Shadow D
1629
1715
  }
1630
1716
  }
1631
1717
  };
1632
- function getPageCSS(root = document) {
1718
+ function getPageCSS(root = defaultRoot()) {
1719
+ if (!root) return "";
1633
1720
  const chunks = [];
1634
1721
  try {
1635
1722
  if ("styleSheets" in root) for (const sheet of Array.from(root.styleSheets)) try {
@@ -1640,6 +1727,6 @@ function getPageCSS(root = document) {
1640
1727
  }
1641
1728
  if (typeof window !== "undefined" && isDevEnv()) tastyDebug.install();
1642
1729
  //#endregion
1643
- export { injector as A, getCSSText as C, inject as D, hasRecipe as E, resolveChunk as F, touch as I, ChunkSheetRegistry as L, keyframes as M, property as N, injectGlobal as O, releaseStyles as P, chunkSheetRegistry as R, gc as S, getRawCSSText as T, createInjector as _, color as a, fontFace as b, hasKeys as c, collectAutoInferredPropertiesRSC as d, getStyleTarget as f, counterStyle as g, cleanup as h, _modAttrs as i, isPropertyDefined as j, injectRawCSS as k, formatKeyframesCSS as l, acquireStyles as m, processTokens as n, filterBaseProps as o, pushRSCCSS as p, dotize as r, computeStyles as s, tastyDebug as t, collectAutoInferredProperties as u, defineRecipe as v, getCSSTextForNode as w, func as x, destroy as y, resolveFunctionColor as z };
1730
+ export { keyframes as A, getRawCSSText as C, injectRawCSS as D, injectGlobal as E, chunkSheetRegistry as F, resolveFunctionColor as I, property as M, touch as N, injector as O, ChunkSheetRegistry as P, getCSSTextForNode as S, inject as T, destroy as _, color as a, gc as b, hasKeys as c, collectAutoInferredPropertiesRSC as d, getStyleTarget as f, createInjector as g, counterStyle as h, _modAttrs as i, ownKeyframes as j, isPropertyDefined as k, formatKeyframesCSS as l, cleanup as m, processTokens as n, filterBaseProps as o, pushRSCCSS as p, dotize as r, computeStyles as s, tastyDebug as t, collectAutoInferredProperties as u, fontFace as v, holdKeyframes as w, getCSSText as x, func as y };
1644
1731
 
1645
- //# sourceMappingURL=core-DWrUWxog.js.map
1732
+ //# sourceMappingURL=core-DGm0CFHP.js.map