@tenphi/tasty 3.7.0 → 3.9.0

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 (103) hide show
  1. package/dist/{babel-DWCsafYw.d.ts → babel-Zs1Q03qt.d.ts} +2 -2
  2. package/dist/chunks/async-storage-CG5HnUT5.js +20 -0
  3. package/dist/chunks/async-storage-CG5HnUT5.js.map +1 -0
  4. package/dist/chunks/build-config-CUQVwdWF.js +42 -0
  5. package/dist/chunks/build-config-CUQVwdWF.js.map +1 -0
  6. package/dist/{collector-B3OsM252.js → chunks/collector-B0LTHw6Z.js} +6 -125
  7. package/dist/chunks/collector-B0LTHw6Z.js.map +1 -0
  8. package/dist/chunks/config-engine-C3pF9EK9.js +267 -0
  9. package/dist/chunks/config-engine-C3pF9EK9.js.map +1 -0
  10. package/dist/chunks/css-definitions-D_it4XZH.js +875 -0
  11. package/dist/chunks/css-definitions-D_it4XZH.js.map +1 -0
  12. package/dist/{css-resources-Cyl_axbI.js → chunks/css-resources-BN8apgxt.js} +1 -8
  13. package/dist/chunks/css-resources-BN8apgxt.js.map +1 -0
  14. package/dist/chunks/debug-C9LeNVoJ.js +501 -0
  15. package/dist/chunks/debug-C9LeNVoJ.js.map +1 -0
  16. package/dist/chunks/dsl-C5yuAn41.js +1373 -0
  17. package/dist/chunks/dsl-C5yuAn41.js.map +1 -0
  18. package/dist/chunks/hydration-TRcz5vnk.js +41 -0
  19. package/dist/chunks/hydration-TRcz5vnk.js.map +1 -0
  20. package/dist/chunks/react-runtime-O-OUrKLH.js +557 -0
  21. package/dist/chunks/react-runtime-O-OUrKLH.js.map +1 -0
  22. package/dist/chunks/runtime-engine-DvnE2g-E.js +2437 -0
  23. package/dist/chunks/runtime-engine-DvnE2g-E.js.map +1 -0
  24. package/dist/chunks/runtime-state-BTDqSYBk.js +127 -0
  25. package/dist/chunks/runtime-state-BTDqSYBk.js.map +1 -0
  26. package/dist/{merge-styles-DuoZEsm9.js → chunks/shared-utils-DWA4LjIa.js} +55 -54
  27. package/dist/chunks/shared-utils-DWA4LjIa.js.map +1 -0
  28. package/dist/chunks/style-engine-C1ECBZxR.js +5131 -0
  29. package/dist/chunks/style-engine-C1ECBZxR.js.map +1 -0
  30. package/dist/{css-writer-Bgowobbx.js → chunks/zero-engine-B6EnYcXY.js} +3 -120
  31. package/dist/chunks/zero-engine-B6EnYcXY.js.map +1 -0
  32. package/dist/{collector-BTVXj2hS.d.ts → collector-hl5KNH7k.d.ts} +6 -4
  33. package/dist/{config-LfIDmVHx.d.ts → config-DWL1ZYue.d.ts} +20 -25
  34. package/dist/core/index.d.ts +5 -5
  35. package/dist/core/index.js +9 -6
  36. package/dist/{index-Bm9ltvdH.d.ts → index-D9N9GV24.d.ts} +96 -82
  37. package/dist/index.d.ts +5 -5
  38. package/dist/index.js +11 -922
  39. package/dist/{merge-styles-BcLl1u_d.d.ts → merge-styles-C_oMoJVd.d.ts} +2 -2
  40. package/dist/ssr/astro-client.js +1 -14
  41. package/dist/ssr/astro-client.js.map +1 -1
  42. package/dist/ssr/astro-middleware-extract-static.js +1 -1
  43. package/dist/ssr/astro-middleware-extract.js +1 -1
  44. package/dist/ssr/astro-middleware-static.js +1 -12
  45. package/dist/ssr/astro-middleware-static.js.map +1 -1
  46. package/dist/ssr/astro-middleware.js +1 -13
  47. package/dist/ssr/astro-middleware.js.map +1 -1
  48. package/dist/ssr/astro.js +219 -1
  49. package/dist/ssr/astro.js.map +1 -0
  50. package/dist/ssr/index.d.ts +6 -6
  51. package/dist/ssr/index.js +4 -4
  52. package/dist/ssr/next-config.d.ts +1 -1
  53. package/dist/ssr/next-config.js +29 -20
  54. package/dist/ssr/next-config.js.map +1 -1
  55. package/dist/ssr/next.d.ts +1 -1
  56. package/dist/ssr/next.js +5 -37
  57. package/dist/ssr/next.js.map +1 -1
  58. package/dist/static/index.d.ts +2 -2
  59. package/dist/static/index.js +1 -19
  60. package/dist/static/index.js.map +1 -1
  61. package/dist/{index-BmogEzTo.d.ts → types-jKZNpias.d.ts} +845 -804
  62. package/dist/zero/babel.d.ts +1 -1
  63. package/dist/zero/babel.js +25 -96
  64. package/dist/zero/babel.js.map +1 -1
  65. package/dist/zero/index.d.ts +1 -1
  66. package/dist/zero/index.js +1 -1
  67. package/dist/zero/next.d.ts +1 -1
  68. package/dist/zero/next.js +0 -31
  69. package/dist/zero/next.js.map +1 -1
  70. package/docs/ai-agents.md +8 -3
  71. package/docs/debug.md +2 -5
  72. package/docs/methodology.md +3 -3
  73. package/docs/pipeline.md +3 -0
  74. package/docs/runtime-benchmarks.md +105 -68
  75. package/docs/styles.md +43 -11
  76. package/package.json +48 -5
  77. package/dist/astro-CeYENy2x.js +0 -301
  78. package/dist/astro-CeYENy2x.js.map +0 -1
  79. package/dist/async-storage-DKK-wTD4.js +0 -44
  80. package/dist/async-storage-DKK-wTD4.js.map +0 -1
  81. package/dist/collector-B3OsM252.js.map +0 -1
  82. package/dist/config-B3gPdCqd.js +0 -12421
  83. package/dist/config-B3gPdCqd.js.map +0 -1
  84. package/dist/context-CA8YKeMn.js +0 -24
  85. package/dist/context-CA8YKeMn.js.map +0 -1
  86. package/dist/core-DGm0CFHP.js +0 -1732
  87. package/dist/core-DGm0CFHP.js.map +0 -1
  88. package/dist/css-resources-Cyl_axbI.js.map +0 -1
  89. package/dist/css-writer-Bgowobbx.js.map +0 -1
  90. package/dist/format-global-rules-DklyaXv-.js +0 -22
  91. package/dist/format-global-rules-DklyaXv-.js.map +0 -1
  92. package/dist/format-rules-XRw9u7d4.js +0 -104
  93. package/dist/format-rules-XRw9u7d4.js.map +0 -1
  94. package/dist/hydrate-CNOmZprz.js +0 -37
  95. package/dist/hydrate-CNOmZprz.js.map +0 -1
  96. package/dist/index.js.map +0 -1
  97. package/dist/keyframes-DE-OE76F.js +0 -535
  98. package/dist/keyframes-DE-OE76F.js.map +0 -1
  99. package/dist/merge-styles-DuoZEsm9.js.map +0 -1
  100. package/dist/resolve-recipes-H9NqOQuP.js +0 -144
  101. package/dist/resolve-recipes-H9NqOQuP.js.map +0 -1
  102. package/dist/ssr-collector-ref-COs_ioWl.js +0 -29
  103. package/dist/ssr-collector-ref-COs_ioWl.js.map +0 -1
@@ -0,0 +1,2437 @@
1
+ import { f as parseStyle, j as normalizeDslName, m as resetGlobalPredefinedTokens, p as resetGlobalParseFunctions, u as normalizeColorTokenValue, w as Lru } from "./dsl-C5yuAn41.js";
2
+ import { i as warn, n as isSelector, o as isDevEnv, r as resetStyleWarnings } from "./shared-utils-DWA4LjIa.js";
3
+ import { A as validateNamePrefix, B as formatFunctionPrelude, D as makeKeyframeName, F as normalizePropertyDefinition, G as registerLocalFunctionPolyfills, I as parsePropertyToken, K as resetFunctionPolyfills, M as extractLocalProperties, N as getEffectiveDefinition, O as rscClassRegexGlobal, R as extractLocalFunctions, S as PropertyTypeResolver, T as makeClassName, U as parseFunctionName, V as formatFunctionRule, _ as extractLocalFontFace, a as formatPropertyCSS, b as formatFontFaceRule, c as filterUsedKeyframes, d as replaceAnimationNames, f as resolveKeyframesNames, h as formatCounterStyleRule, i as formatKeyframesCSS, j as hashString, k as tastyClassRegex, l as hasLocalKeyframes, m as formatCounterStyleDeclarations, o as extractAnimationNamesFromStyles, p as extractLocalCounterStyle, r as formatRules, s as extractLocalKeyframes, u as mergeKeyframes, v as fontFaceContentHash, y as formatFontFaceDeclarations, z as formatFunctionDeclarations } from "./css-definitions-D_it4XZH.js";
4
+ import { C as STYLE_HANDLER_MAP, D as resetHandlers, G as resetGlobalPolyfillsState, H as hasStylesGenerated, K as resetStylesGeneratedState, R as resetStyleChunks, S as camelToKebab, U as isFunctionsPolyfillEnabled, W as markStylesGeneratedState, a as registerBaseStyleProps, b as renderStyles, k as createStyle, n as generateChunkCacheKey, o as resetBaseStyleProps, r as categorizeStyleKeys, t as renderStylesForChunk, y as clearPipelineCache } from "./style-engine-C1ECBZxR.js";
5
+ import { n as applyStyleConfig, r as normalizeConfig, t as resolveRecipesWith } from "./config-engine-C3pF9EK9.js";
6
+ import { _ as resetConfigResources, a as getGlobalConfigTokens, c as getGlobalFunctions, d as mergeGlobalConfigTokens, f as mergeGlobalCounterStyles, g as mergeGlobalStyles, h as mergeGlobalProperties, i as getEffectiveProperties, l as getGlobalStyles, m as mergeGlobalFunctions, o as getGlobalCounterStyles, p as mergeGlobalFontFaces, s as getGlobalFontFaces, t as getRegisteredSSRCollector, v as setRuntimeConfigState } from "./runtime-state-BTDqSYBk.js";
7
+ import { cache } from "react";
8
+ //#region src/prop-handlers.ts
9
+ const GTKEY = "__tasty_prop_handlers__";
10
+ const globalStore = globalThis;
11
+ const propHandlerRegistry = globalStore[GTKEY] ?? (globalStore[GTKEY] = {
12
+ apply: null,
13
+ list: []
14
+ });
15
+ function normalize(key, definition, options) {
16
+ const source = options?.source ?? "configure()";
17
+ if (typeof definition === "function") return {
18
+ key,
19
+ triggers: [key],
20
+ fn: definition,
21
+ source
22
+ };
23
+ if (Array.isArray(definition)) {
24
+ const [first, fn] = definition;
25
+ if (typeof fn !== "function") throw new Error(`[Tasty] Invalid prop handler definition for "${key}". Tuple must have a function as the second element: [string, function] or [string[], function].`);
26
+ if (first === "*") return {
27
+ key,
28
+ triggers: null,
29
+ fn,
30
+ source
31
+ };
32
+ if (typeof first === "string") return {
33
+ key,
34
+ triggers: [first],
35
+ fn,
36
+ source
37
+ };
38
+ if (Array.isArray(first)) return {
39
+ key,
40
+ triggers: first.includes("*") ? null : first,
41
+ fn,
42
+ source
43
+ };
44
+ throw new Error(`[Tasty] Invalid prop handler definition for "${key}". First element must be a string or string array.`);
45
+ }
46
+ throw new Error(`[Tasty] Invalid prop handler definition for "${key}". Expected function, [string, function], or [string[], function].`);
47
+ }
48
+ function runOne(handler, props) {
49
+ const next = handler.fn(props);
50
+ if (next != null && typeof next === "object" && !Array.isArray(next)) return next;
51
+ if (isDevEnv()) console.warn(next == null ? `[Tasty] propHandlers["${handler.key}"] (from ${handler.source}) returned ${String(next)}. Props are treated as unchanged — did you forget to \`return props\`?` : `[Tasty] propHandlers["${handler.key}"] (from ${handler.source}) returned ${Array.isArray(next) ? "an array" : typeof next}. A prop handler must return a props object. The result was ignored.`);
52
+ return props;
53
+ }
54
+ function compose(list) {
55
+ if (list.length === 0) return null;
56
+ if (list.length === 1) {
57
+ const only = list[0];
58
+ if (only.triggers === null) return (props) => runOne(only, props);
59
+ if (only.triggers.length === 1) {
60
+ const trigger = only.triggers[0];
61
+ return (props) => trigger in props ? runOne(only, props) : props;
62
+ }
63
+ }
64
+ return (props) => {
65
+ for (const handler of list) {
66
+ const triggers = handler.triggers;
67
+ if (triggers !== null) {
68
+ let triggered = false;
69
+ for (const trigger of triggers) if (trigger in props) {
70
+ triggered = true;
71
+ break;
72
+ }
73
+ if (!triggered) continue;
74
+ }
75
+ props = runOne(handler, props);
76
+ }
77
+ return props;
78
+ };
79
+ }
80
+ function registerPropHandler(key, definition, options) {
81
+ const normalized = normalize(key, definition, options);
82
+ const { list } = propHandlerRegistry;
83
+ const existing = list.findIndex((handler) => handler.key === key);
84
+ if (existing === -1) list.push(normalized);
85
+ else list[existing] = normalized;
86
+ propHandlerRegistry.apply = compose(list);
87
+ }
88
+ function resetPropHandlers() {
89
+ if (propHandlerRegistry.list.length === 0) return;
90
+ propHandlerRegistry.list.length = 0;
91
+ propHandlerRegistry.apply = null;
92
+ }
93
+ //#endregion
94
+ //#region src/injector/batch.ts
95
+ let queue = [];
96
+ let head = 0;
97
+ let microtaskScheduled = false;
98
+ let flushing = false;
99
+ let windowOpen = false;
100
+ let everOpened = false;
101
+ let warnedNoProvider = false;
102
+ function enqueueStyleWrite(run) {
103
+ if (flushing) {
104
+ run();
105
+ return {
106
+ run,
107
+ cancelled: false,
108
+ done: true
109
+ };
110
+ }
111
+ const entry = {
112
+ run,
113
+ cancelled: false,
114
+ done: false
115
+ };
116
+ queue.push(entry);
117
+ scheduleMicrotaskFlush();
118
+ return entry;
119
+ }
120
+ function hasPendingStyleWrites() {
121
+ return head < queue.length;
122
+ }
123
+ function openBatchWindow() {
124
+ if (typeof document === "undefined") return;
125
+ windowOpen = true;
126
+ everOpened = true;
127
+ }
128
+ function closeBatchWindow() {
129
+ windowOpen = false;
130
+ flushStyles();
131
+ }
132
+ function isBatchWindowOpen() {
133
+ return windowOpen;
134
+ }
135
+ function scheduleMicrotaskFlush() {
136
+ if (microtaskScheduled || flushing) return;
137
+ microtaskScheduled = true;
138
+ queueMicrotask(() => {
139
+ microtaskScheduled = false;
140
+ windowOpen = false;
141
+ flushStyles();
142
+ });
143
+ }
144
+ function flushStyles() {
145
+ if (head >= queue.length) return;
146
+ if (flushing) return;
147
+ flushing = true;
148
+ try {
149
+ while (head < queue.length) {
150
+ const entry = queue[head++];
151
+ if (entry.cancelled) {
152
+ entry.done = true;
153
+ continue;
154
+ }
155
+ entry.run();
156
+ entry.done = true;
157
+ }
158
+ } finally {
159
+ queue = [];
160
+ head = 0;
161
+ flushing = false;
162
+ }
163
+ }
164
+ function warnBatchProviderMissing() {
165
+ if (everOpened || warnedNoProvider || !isDevEnv()) return;
166
+ warnedNoProvider = true;
167
+ warn("[Tasty] batchInjection needs <TastyBatchProvider> mounted to batch.");
168
+ }
169
+ function resetStyleBatch() {
170
+ queue = [];
171
+ head = 0;
172
+ microtaskScheduled = false;
173
+ flushing = false;
174
+ windowOpen = false;
175
+ everOpened = false;
176
+ warnedNoProvider = false;
177
+ }
178
+ //#endregion
179
+ //#region src/injector/sheet-manager.ts
180
+ const supportsConstructableSheets = typeof CSSStyleSheet !== "undefined" && (() => {
181
+ try {
182
+ new CSSStyleSheet();
183
+ return true;
184
+ } catch {
185
+ return false;
186
+ }
187
+ })();
188
+ function wrapAtRules(css, atRules) {
189
+ return atRules?.reduce((wrapped, atRule) => `${atRule} { ${wrapped} }`, css) ?? css;
190
+ }
191
+ function splitSelectorsSafely(selectorList) {
192
+ const parts = [];
193
+ let buffer = "";
194
+ let squareDepth = 0;
195
+ let parenDepth = 0;
196
+ let quote = "";
197
+ for (let i = 0; i < selectorList.length; i++) {
198
+ const char = selectorList[i];
199
+ if (quote) {
200
+ if (char === quote && selectorList[i - 1] !== "\\") quote = "";
201
+ buffer += char;
202
+ continue;
203
+ }
204
+ if (char === "\"" || char === "'") {
205
+ quote = char;
206
+ buffer += char;
207
+ continue;
208
+ }
209
+ if (char === "[") squareDepth++;
210
+ else if (char === "]") squareDepth = Math.max(0, squareDepth - 1);
211
+ else if (char === "(") parenDepth++;
212
+ else if (char === ")") parenDepth = Math.max(0, parenDepth - 1);
213
+ if (char === "," && squareDepth === 0 && parenDepth === 0) {
214
+ const part = buffer.trim();
215
+ if (part) parts.push(part);
216
+ buffer = "";
217
+ } else buffer += char;
218
+ }
219
+ const tail = buffer.trim();
220
+ if (tail) parts.push(tail);
221
+ return parts;
222
+ }
223
+ function rulesToCSS(sheet) {
224
+ return Array.from(sheet.cssRules, (rule) => rule.cssText).join("\n");
225
+ }
226
+ function rawBlocksToCSS(blocks) {
227
+ return [...blocks.values()].sort((a, b) => a.startOffset - b.startOffset).map((block) => block.css).join("\n");
228
+ }
229
+ var SheetManager = class {
230
+ rootRegistries = /* @__PURE__ */ new WeakMap();
231
+ activeRoots = /* @__PURE__ */ new Set();
232
+ config;
233
+ rawStyleElements = /* @__PURE__ */ new WeakMap();
234
+ rawConstructableSheets = /* @__PURE__ */ new WeakMap();
235
+ rawCSSBlocks = /* @__PURE__ */ new WeakMap();
236
+ rawCSSCounter = 0;
237
+ constructor(config) {
238
+ this.config = config;
239
+ }
240
+ getCSSSheet(sheetInfo) {
241
+ if (sheetInfo.constructableSheet) return sheetInfo.constructableSheet;
242
+ return sheetInfo.sheet?.sheet ?? null;
243
+ }
244
+ trackTextRule(sheet, ruleIndex, ruleText) {
245
+ if (!sheet.textMode) return;
246
+ const rules = sheet.textRules ??= [];
247
+ while (rules.length < ruleIndex) rules.push("");
248
+ rules[ruleIndex] = ruleText;
249
+ }
250
+ deleteTextRules(sheet, indices) {
251
+ const rules = sheet.textRules;
252
+ if (!rules) return [];
253
+ const removed = [...new Set(indices)].filter((idx) => idx >= 0 && idx < rules.length).sort((a, b) => b - a);
254
+ for (const idx of removed) rules.splice(idx, 1);
255
+ if (removed.length > 0 && sheet.sheet) sheet.sheet.textContent = rules.length ? "\n" + rules.join("\n") : "";
256
+ return removed;
257
+ }
258
+ detectInjectionMode(root) {
259
+ if (root instanceof ShadowRoot && supportsConstructableSheets && !this.config.forceTextInjection) return "adopted";
260
+ return "style-element";
261
+ }
262
+ getRegistry(root) {
263
+ let registry = this.rootRegistries.get(root);
264
+ if (!registry) {
265
+ const metrics = this.config.devMode ? {
266
+ hits: 0,
267
+ misses: 0,
268
+ bulkCleanups: 0,
269
+ totalInsertions: 0,
270
+ totalUnused: 0,
271
+ stylesCleanedUp: 0,
272
+ cleanupHistory: [],
273
+ startTime: Date.now()
274
+ } : void 0;
275
+ registry = {
276
+ sheets: [],
277
+ pinCounts: /* @__PURE__ */ new Map(),
278
+ rules: /* @__PURE__ */ new Map(),
279
+ cacheKeyToClassName: /* @__PURE__ */ new Map(),
280
+ ruleTextSet: /* @__PURE__ */ new Set(),
281
+ metrics,
282
+ keyframesCache: /* @__PURE__ */ new Map(),
283
+ keyframesNameToContent: /* @__PURE__ */ new Map(),
284
+ keyframesCounter: 0,
285
+ injectedProperties: /* @__PURE__ */ new Map(),
286
+ injectedFontFaces: /* @__PURE__ */ new Set(),
287
+ injectedCounterStyles: /* @__PURE__ */ new Map(),
288
+ injectedFunctions: /* @__PURE__ */ new Map(),
289
+ globalRules: /* @__PURE__ */ new Map(),
290
+ propertyTypeResolver: new PropertyTypeResolver(),
291
+ unusedSince: /* @__PURE__ */ new Map(),
292
+ localKeyframes: /* @__PURE__ */ new Map(),
293
+ touchCount: 0,
294
+ serverClassSyncIndex: 0,
295
+ rscStylesScanned: false,
296
+ injectionMode: this.detectInjectionMode(root)
297
+ };
298
+ this.rootRegistries.set(root, registry);
299
+ this.activeRoots.add(root);
300
+ }
301
+ return registry;
302
+ }
303
+ getActiveRoots() {
304
+ return this.activeRoots;
305
+ }
306
+ hasActiveRoots() {
307
+ return this.activeRoots.size > 0;
308
+ }
309
+ pruneDisconnectedRoots() {
310
+ for (const root of this.activeRoots) if (root !== document && !root.host?.isConnected) this.cleanup(root);
311
+ }
312
+ createSheet(registry, root) {
313
+ if (registry.injectionMode === "adopted") {
314
+ const constructableSheet = new CSSStyleSheet();
315
+ root.adoptedStyleSheets = [...root.adoptedStyleSheets, constructableSheet];
316
+ const sheetInfo = {
317
+ sheet: null,
318
+ constructableSheet,
319
+ ruleCount: 0,
320
+ holes: []
321
+ };
322
+ registry.sheets.push(sheetInfo);
323
+ return sheetInfo;
324
+ }
325
+ const sheet = this.createStyleElement(root);
326
+ const textMode = this.config.forceTextInjection === true || sheet.sheet == null;
327
+ const sheetInfo = {
328
+ sheet,
329
+ ruleCount: 0,
330
+ holes: [],
331
+ textMode,
332
+ ...textMode ? { textRules: [] } : {}
333
+ };
334
+ registry.sheets.push(sheetInfo);
335
+ return sheetInfo;
336
+ }
337
+ createStyleElement(root, attribute = "data-tasty") {
338
+ const style = root.createElement?.("style") || document.createElement("style");
339
+ if (this.config.nonce) style.nonce = this.config.nonce;
340
+ style.setAttribute(attribute, "");
341
+ ("head" in root && root.head ? root.head : root).appendChild(style);
342
+ if (attribute === "data-tasty" && !style.isConnected && !this.config.forceTextInjection) console.error("[Tasty] SheetManager: style element failed to connect to the DOM.", {
343
+ parentNode: style.parentNode?.nodeName,
344
+ isConnected: style.isConnected
345
+ });
346
+ return style;
347
+ }
348
+ appendTextRule(sheet, ruleIndex, ruleText) {
349
+ this.trackTextRule(sheet, ruleIndex, ruleText);
350
+ const style = sheet.sheet;
351
+ style.textContent = (style.textContent || "") + "\n" + ruleText;
352
+ }
353
+ insertRule(registry, flattenedRules, className, root) {
354
+ let targetSheet = this.findAvailableSheet(registry);
355
+ if (!targetSheet) targetSheet = this.createSheet(registry, root);
356
+ const sheetIndex = registry.sheets.indexOf(targetSheet);
357
+ try {
358
+ const groupedRules = /* @__PURE__ */ new Map();
359
+ for (const rule of flattenedRules) {
360
+ const key = `${rule.atRules?.join("|") ?? ""}||${rule.selector}||${rule.startingStyle ? "1" : "0"}`;
361
+ const existing = groupedRules.get(key);
362
+ if (existing) existing.declarations = existing.declarations ? `${existing.declarations} ${rule.declarations}` : rule.declarations;
363
+ else groupedRules.set(key, {
364
+ selector: rule.selector,
365
+ atRules: rule.atRules,
366
+ startingStyle: rule.startingStyle,
367
+ declarations: rule.declarations
368
+ });
369
+ }
370
+ const insertedRuleTexts = [];
371
+ const insertedIndices = [];
372
+ let currentRuleIndex = this.findAvailableRuleIndex(targetSheet);
373
+ let firstInsertedIndex = null;
374
+ let lastInsertedIndex = null;
375
+ const recordInsertion = (index) => {
376
+ targetSheet.ruleCount++;
377
+ insertedIndices.push(index);
378
+ if (firstInsertedIndex == null) firstInsertedIndex = index;
379
+ lastInsertedIndex = index;
380
+ currentRuleIndex = index + 1;
381
+ };
382
+ for (const rule of groupedRules.values()) {
383
+ const declarations = rule.declarations;
384
+ const innerContent = rule.startingStyle ? `@starting-style { ${declarations} }` : declarations;
385
+ const fullRule = wrapAtRules(`${rule.selector} { ${innerContent} }`, rule.atRules);
386
+ const styleElement = targetSheet.sheet;
387
+ const styleSheet = this.getCSSSheet(targetSheet);
388
+ if (!targetSheet.textMode && styleSheet) {
389
+ const maxIndex = styleSheet.cssRules.length;
390
+ const atomicRuleIndex = this.findAvailableRuleIndex(targetSheet);
391
+ const safeIndex = Math.min(Math.max(0, atomicRuleIndex), maxIndex);
392
+ try {
393
+ styleSheet.insertRule(fullRule, safeIndex);
394
+ recordInsertion(safeIndex);
395
+ } catch (e) {
396
+ const selectors = splitSelectorsSafely(rule.selector);
397
+ if (selectors.length > 1) for (const sel of selectors) {
398
+ const singleRule = wrapAtRules(`${sel} { ${declarations} }`, rule.atRules);
399
+ try {
400
+ const maxIdx = styleSheet.cssRules.length;
401
+ const atomicIdx = this.findAvailableRuleIndex(targetSheet);
402
+ const idx = Math.min(Math.max(0, atomicIdx), maxIdx);
403
+ styleSheet.insertRule(singleRule, idx);
404
+ recordInsertion(idx);
405
+ } catch (singleErr) {
406
+ console.warn("[Tasty] Browser rejected CSS rule:", singleRule, singleErr);
407
+ }
408
+ }
409
+ else if (!(fullRule.startsWith("@property ") && !this.engineSupportsAtProperty(registry, styleSheet))) console.warn("[Tasty] Browser rejected CSS rule:", fullRule, e);
410
+ }
411
+ } else if (styleElement) {
412
+ const atomicRuleIndex = this.findAvailableRuleIndex(targetSheet);
413
+ this.appendTextRule(targetSheet, atomicRuleIndex, fullRule);
414
+ recordInsertion(atomicRuleIndex);
415
+ }
416
+ if (styleElement && !styleElement.parentNode && !this.config.forceTextInjection) console.error("[Tasty] SheetManager: style element is not attached to the DOM; rules will not apply.", {
417
+ className,
418
+ ruleIndex: currentRuleIndex
419
+ });
420
+ if (this.config.devMode) {
421
+ insertedRuleTexts.push(fullRule);
422
+ try {
423
+ registry.ruleTextSet.add(fullRule);
424
+ } catch {}
425
+ }
426
+ }
427
+ if (insertedIndices.length === 0) return null;
428
+ return {
429
+ className,
430
+ ruleIndex: firstInsertedIndex ?? 0,
431
+ sheetIndex,
432
+ cssText: this.config.devMode ? insertedRuleTexts : void 0,
433
+ endRuleIndex: lastInsertedIndex ?? firstInsertedIndex ?? 0,
434
+ indices: insertedIndices
435
+ };
436
+ } catch (error) {
437
+ console.warn("[Tasty] Failed to insert CSS rules:", error, {
438
+ flattenedRules,
439
+ className
440
+ });
441
+ return null;
442
+ }
443
+ }
444
+ insertGlobalRule(registry, flattenedRules, globalKey, root) {
445
+ const ruleInfo = this.insertRule(registry, flattenedRules, globalKey, root);
446
+ if (ruleInfo) registry.globalRules.set(globalKey, ruleInfo);
447
+ return ruleInfo;
448
+ }
449
+ deleteGlobalRule(registry, globalKey) {
450
+ const ruleInfo = registry.globalRules.get(globalKey);
451
+ if (!ruleInfo) return;
452
+ this.deleteRule(registry, ruleInfo);
453
+ registry.globalRules.delete(globalKey);
454
+ }
455
+ adjustIndicesAfterDeletion(registry, sheetIndex, startIdx, endIdx, deleteCount, deletedRuleInfo, deletedIndices) {
456
+ try {
457
+ const sortedDeleted = deletedIndices && deletedIndices.length > 0 ? [...deletedIndices].sort((a, b) => a - b) : null;
458
+ const countDeletedBefore = (sorted, idx) => {
459
+ let shift = 0;
460
+ for (const delIdx of sorted) if (delIdx < idx) shift++;
461
+ else break;
462
+ return shift;
463
+ };
464
+ const adjustRuleInfo = (info) => {
465
+ if (info === deletedRuleInfo) return;
466
+ if (info.sheetIndex !== sheetIndex) return;
467
+ if (!info.indices || info.indices.length === 0) return;
468
+ if (sortedDeleted) info.indices = info.indices.map((idx) => {
469
+ return idx - countDeletedBefore(sortedDeleted, idx);
470
+ });
471
+ else info.indices = info.indices.map((idx) => idx > endIdx ? Math.max(0, idx - deleteCount) : idx);
472
+ if (info.indices.length > 0) {
473
+ info.ruleIndex = Math.min(...info.indices);
474
+ info.endRuleIndex = Math.max(...info.indices);
475
+ }
476
+ };
477
+ for (const info of registry.rules.values()) adjustRuleInfo(info);
478
+ for (const info of registry.globalRules.values()) adjustRuleInfo(info);
479
+ for (const entry of registry.keyframesCache.values()) {
480
+ const ki = entry.info;
481
+ if (ki.sheetIndex !== sheetIndex) continue;
482
+ if (sortedDeleted) {
483
+ const shift = countDeletedBefore(sortedDeleted, ki.ruleIndex);
484
+ if (shift > 0) ki.ruleIndex = Math.max(0, ki.ruleIndex - shift);
485
+ } else if (ki.ruleIndex > endIdx) ki.ruleIndex = Math.max(0, ki.ruleIndex - deleteCount);
486
+ }
487
+ } catch {}
488
+ }
489
+ deleteRule(registry, ruleInfo) {
490
+ const sheet = registry.sheets[ruleInfo.sheetIndex];
491
+ if (!sheet) return;
492
+ try {
493
+ const texts = this.config.devMode && Array.isArray(ruleInfo.cssText) ? ruleInfo.cssText.slice() : [];
494
+ const styleSheet = this.getCSSSheet(sheet);
495
+ const indices = ruleInfo.indices;
496
+ if (sheet.textMode) {
497
+ let targetIndices;
498
+ if (indices?.length) targetIndices = indices;
499
+ else {
500
+ const startIdx = Math.max(0, ruleInfo.ruleIndex);
501
+ const endIdx = Math.min((sheet.textRules?.length ?? 0) - 1, Number.isFinite(ruleInfo.endRuleIndex) ? ruleInfo.endRuleIndex : startIdx);
502
+ targetIndices = [];
503
+ for (let idx = startIdx; idx <= endIdx; idx++) targetIndices.push(idx);
504
+ }
505
+ const deletedIndices = this.deleteTextRules(sheet, targetIndices);
506
+ if (deletedIndices.length > 0) {
507
+ sheet.ruleCount = Math.max(0, sheet.ruleCount - deletedIndices.length);
508
+ this.adjustIndicesAfterDeletion(registry, ruleInfo.sheetIndex, Math.min(...deletedIndices), Math.max(...deletedIndices), deletedIndices.length, ruleInfo, deletedIndices);
509
+ }
510
+ } else if (styleSheet) {
511
+ const rules = styleSheet.cssRules;
512
+ if (indices?.length) {
513
+ const sortedIndices = [...indices].sort((a, b) => b - a);
514
+ const deletedIndices = [];
515
+ for (const idx of sortedIndices) if (idx >= 0 && idx < styleSheet.cssRules.length) try {
516
+ styleSheet.deleteRule(idx);
517
+ deletedIndices.push(idx);
518
+ } catch (e) {
519
+ console.warn(`[Tasty] Failed to delete rule at index ${idx}:`, e);
520
+ }
521
+ sheet.ruleCount = Math.max(0, sheet.ruleCount - deletedIndices.length);
522
+ if (deletedIndices.length > 0) this.adjustIndicesAfterDeletion(registry, ruleInfo.sheetIndex, Math.min(...deletedIndices), Math.max(...deletedIndices), deletedIndices.length, ruleInfo, deletedIndices);
523
+ } else {
524
+ const startIdx = Math.max(0, ruleInfo.ruleIndex);
525
+ const endIdx = Math.min(rules.length - 1, Number.isFinite(ruleInfo.endRuleIndex) ? ruleInfo.endRuleIndex : startIdx);
526
+ if (Number.isFinite(startIdx) && endIdx >= startIdx) {
527
+ const deleteCount = endIdx - startIdx + 1;
528
+ for (let idx = endIdx; idx >= startIdx; idx--) {
529
+ if (idx < 0 || idx >= styleSheet.cssRules.length) continue;
530
+ styleSheet.deleteRule(idx);
531
+ }
532
+ sheet.ruleCount = Math.max(0, sheet.ruleCount - deleteCount);
533
+ this.adjustIndicesAfterDeletion(registry, ruleInfo.sheetIndex, startIdx, endIdx, deleteCount, ruleInfo);
534
+ }
535
+ }
536
+ }
537
+ if (this.config.devMode && texts.length) try {
538
+ for (const text of texts) registry.ruleTextSet.delete(text);
539
+ } catch {}
540
+ } catch (error) {
541
+ console.warn("[Tasty] Failed to delete CSS rule:", error);
542
+ }
543
+ }
544
+ findAvailableSheet(registry) {
545
+ const maxRules = this.config.maxRulesPerSheet;
546
+ if (!maxRules) return registry.sheets[registry.sheets.length - 1] || null;
547
+ for (const sheet of registry.sheets) if (sheet.ruleCount < maxRules) return sheet;
548
+ return null;
549
+ }
550
+ findAvailableRuleIndex(sheet) {
551
+ return sheet.ruleCount;
552
+ }
553
+ engineSupportsAtProperty(registry, styleSheet) {
554
+ if (registry.atPropertySupported !== void 0) return registry.atPropertySupported;
555
+ const probeRule = "@property --__tasty_probe__ { syntax: \"*\"; inherits: true; }";
556
+ try {
557
+ const probeIdx = styleSheet.cssRules.length;
558
+ styleSheet.insertRule(probeRule, probeIdx);
559
+ try {
560
+ styleSheet.deleteRule(probeIdx);
561
+ } catch {}
562
+ registry.atPropertySupported = true;
563
+ } catch {
564
+ registry.atPropertySupported = false;
565
+ }
566
+ return registry.atPropertySupported;
567
+ }
568
+ deleteClasses(registry, classNames) {
569
+ const cleanupStartTime = Date.now();
570
+ const selected = Array.from(classNames).map((className) => {
571
+ const ruleInfo = registry.rules.get(className);
572
+ return ruleInfo ? {
573
+ className,
574
+ ruleInfo
575
+ } : null;
576
+ }).filter((entry) => entry != null);
577
+ if (selected.length === 0) return 0;
578
+ const deleted = /* @__PURE__ */ new Set();
579
+ let totalCssSize = 0;
580
+ let totalRulesDeleted = 0;
581
+ const rulesBySheet = /* @__PURE__ */ new Map();
582
+ for (const { className, ruleInfo } of selected) {
583
+ const sheetIndex = ruleInfo.sheetIndex;
584
+ if (this.config.devMode && Array.isArray(ruleInfo.cssText)) {
585
+ const cssSize = ruleInfo.cssText.reduce((total, css) => total + css.length, 0);
586
+ totalCssSize += cssSize;
587
+ totalRulesDeleted += ruleInfo.cssText.length;
588
+ }
589
+ const rules = rulesBySheet.get(sheetIndex);
590
+ if (rules) rules.push({
591
+ className,
592
+ ruleInfo
593
+ });
594
+ else rulesBySheet.set(sheetIndex, [{
595
+ className,
596
+ ruleInfo
597
+ }]);
598
+ }
599
+ for (const rulesInSheet of rulesBySheet.values()) {
600
+ rulesInSheet.sort((a, b) => b.ruleInfo.ruleIndex - a.ruleInfo.ruleIndex);
601
+ for (const { className, ruleInfo } of rulesInSheet) {
602
+ if ((registry.pinCounts.get(className) ?? 0) > 0) continue;
603
+ if (registry.rules.get(className) !== ruleInfo) continue;
604
+ const sheetInfo = registry.sheets[ruleInfo.sheetIndex];
605
+ if (!sheetInfo || !sheetInfo.sheet && !sheetInfo.constructableSheet) continue;
606
+ const styleSheet = this.getCSSSheet(sheetInfo);
607
+ if (!sheetInfo.textMode && !styleSheet) continue;
608
+ const maxRuleIndex = (sheetInfo.textMode ? sheetInfo.textRules?.length ?? 0 : styleSheet?.cssRules.length ?? 0) - 1;
609
+ const startIdx = ruleInfo.ruleIndex;
610
+ const endIdx = ruleInfo.endRuleIndex ?? ruleInfo.ruleIndex;
611
+ if (startIdx < 0 || endIdx > maxRuleIndex || startIdx > endIdx) continue;
612
+ this.deleteRule(registry, ruleInfo);
613
+ registry.rules.delete(className);
614
+ registry.pinCounts.delete(className);
615
+ registry.unusedSince.delete(className);
616
+ for (const [key, entry] of registry.localKeyframes) {
617
+ if (!entry.owners.delete(className)) continue;
618
+ if (entry.owners.size === 0) {
619
+ entry.dispose();
620
+ registry.localKeyframes.delete(key);
621
+ }
622
+ }
623
+ deleted.add(className);
624
+ }
625
+ }
626
+ if (deleted.size > 0) {
627
+ for (const [key, mappedClassName] of registry.cacheKeyToClassName) if (deleted.has(mappedClassName)) registry.cacheKeyToClassName.delete(key);
628
+ }
629
+ if (registry.metrics) {
630
+ registry.metrics.bulkCleanups++;
631
+ registry.metrics.stylesCleanedUp += deleted.size;
632
+ registry.metrics.cleanupHistory.push({
633
+ timestamp: cleanupStartTime,
634
+ classesDeleted: deleted.size,
635
+ cssSize: totalCssSize,
636
+ rulesDeleted: totalRulesDeleted
637
+ });
638
+ }
639
+ return deleted.size;
640
+ }
641
+ getTotalRuleCount(registry) {
642
+ return registry.sheets.reduce((total, sheet) => total + sheet.ruleCount - sheet.holes.length, 0);
643
+ }
644
+ readSheetCSS(sheetInfo) {
645
+ try {
646
+ if (sheetInfo.sheet?.textContent) return sheetInfo.sheet.textContent;
647
+ const sheet = this.getCSSSheet(sheetInfo);
648
+ if (sheet) return rulesToCSS(sheet);
649
+ } catch (error) {
650
+ console.warn("[Tasty] Failed to read CSS from sheet:", error);
651
+ }
652
+ return null;
653
+ }
654
+ getCSSText(registry) {
655
+ const cssChunks = [];
656
+ for (const sheetInfo of registry.sheets) {
657
+ const css = this.readSheetCSS(sheetInfo);
658
+ if (css !== null) cssChunks.push(css);
659
+ }
660
+ return cssChunks.join("\n");
661
+ }
662
+ getMetrics(registry) {
663
+ if (!registry.metrics) return null;
664
+ return {
665
+ ...registry.metrics,
666
+ unusedHits: 0
667
+ };
668
+ }
669
+ resetMetrics(registry) {
670
+ if (registry.metrics) registry.metrics = {
671
+ hits: 0,
672
+ misses: 0,
673
+ bulkCleanups: 0,
674
+ totalInsertions: 0,
675
+ totalUnused: 0,
676
+ stylesCleanedUp: 0,
677
+ cleanupHistory: [],
678
+ startTime: Date.now()
679
+ };
680
+ }
681
+ stepsToCSS(steps) {
682
+ const rules = [];
683
+ const allDeclarations = [];
684
+ for (const [key, value] of Object.entries(steps)) {
685
+ if (typeof value === "string") {
686
+ rules.push(`${key} { ${value.trim()} }`);
687
+ allDeclarations.push(value.trim());
688
+ continue;
689
+ }
690
+ const styleMap = value || {};
691
+ const styleNames = Object.keys(styleMap).sort();
692
+ const handlerQueue = [];
693
+ const seenHandlers = /* @__PURE__ */ new Set();
694
+ styleNames.forEach((styleName) => {
695
+ let handlers = STYLE_HANDLER_MAP[styleName];
696
+ if (!handlers) handlers = STYLE_HANDLER_MAP[styleName] = [createStyle(styleName)];
697
+ handlers.forEach((handler) => {
698
+ if (!seenHandlers.has(handler)) {
699
+ seenHandlers.add(handler);
700
+ handlerQueue.push(handler);
701
+ }
702
+ });
703
+ });
704
+ const declarationPairs = [];
705
+ handlerQueue.forEach((handler) => {
706
+ const result = handler(handler.__lookupStyles.reduce((acc, name) => {
707
+ const v = styleMap[name];
708
+ if (v !== void 0) acc[name] = v;
709
+ return acc;
710
+ }, {}));
711
+ if (!result) return;
712
+ (Array.isArray(result) ? result : [result]).forEach((cssMap) => {
713
+ if (!cssMap || typeof cssMap !== "object") return;
714
+ const { $: _$, ...props } = cssMap;
715
+ Object.entries(props).forEach(([prop, val]) => {
716
+ if (val == null || val === "") return;
717
+ if (Array.isArray(val)) val.forEach((v) => {
718
+ if (v != null && v !== "") declarationPairs.push({
719
+ prop,
720
+ value: String(v)
721
+ });
722
+ });
723
+ else declarationPairs.push({
724
+ prop,
725
+ value: String(val)
726
+ });
727
+ });
728
+ });
729
+ });
730
+ const declarations = declarationPairs.map((d) => `${d.prop}: ${d.value}`).join("; ");
731
+ rules.push(`${key} { ${declarations.trim()} }`);
732
+ allDeclarations.push(declarations);
733
+ }
734
+ return {
735
+ css: rules.join(" "),
736
+ declarations: allDeclarations.join("; ")
737
+ };
738
+ }
739
+ insertKeyframes(registry, steps, name, root) {
740
+ let targetSheet = this.findAvailableSheet(registry);
741
+ if (!targetSheet) targetSheet = this.createSheet(registry, root);
742
+ const ruleIndex = this.findAvailableRuleIndex(targetSheet);
743
+ const sheetIndex = registry.sheets.indexOf(targetSheet);
744
+ try {
745
+ const { css: cssSteps, declarations } = this.stepsToCSS(steps);
746
+ const fullRule = `@keyframes ${name} { ${cssSteps} }`;
747
+ const styleSheet = this.getCSSSheet(targetSheet);
748
+ if (!targetSheet.textMode && styleSheet) {
749
+ const safeIndex = Math.min(Math.max(0, ruleIndex), styleSheet.cssRules.length);
750
+ styleSheet.insertRule(fullRule, safeIndex);
751
+ } else if (targetSheet.sheet) this.appendTextRule(targetSheet, ruleIndex, fullRule);
752
+ targetSheet.ruleCount++;
753
+ return {
754
+ info: {
755
+ name,
756
+ ruleIndex,
757
+ sheetIndex,
758
+ cssText: this.config.devMode ? fullRule : void 0
759
+ },
760
+ declarations
761
+ };
762
+ } catch (error) {
763
+ console.warn("[Tasty] Failed to insert keyframes:", error);
764
+ return null;
765
+ }
766
+ }
767
+ deleteKeyframes(registry, info) {
768
+ const sheet = registry.sheets[info.sheetIndex];
769
+ if (!sheet) return;
770
+ try {
771
+ const styleSheet = this.getCSSSheet(sheet);
772
+ if (sheet.textMode) {
773
+ if (!this.deleteTextRules(sheet, [info.ruleIndex]).length) return;
774
+ } else {
775
+ if (!styleSheet || info.ruleIndex < 0 || info.ruleIndex >= styleSheet.cssRules.length) return;
776
+ styleSheet.deleteRule(info.ruleIndex);
777
+ }
778
+ sheet.ruleCount = Math.max(0, sheet.ruleCount - 1);
779
+ this.adjustIndicesAfterDeletion(registry, info.sheetIndex, info.ruleIndex, info.ruleIndex, 1, null, [info.ruleIndex]);
780
+ } catch (error) {
781
+ console.warn("[Tasty] Failed to delete keyframes:", error);
782
+ }
783
+ }
784
+ cleanup(root) {
785
+ const registry = this.rootRegistries.get(root);
786
+ if (!registry) return;
787
+ if (registry.injectionMode === "adopted") {
788
+ const shadowRoot = root;
789
+ const ownedSheets = /* @__PURE__ */ new Set();
790
+ for (const sheetInfo of registry.sheets) if (sheetInfo.constructableSheet) ownedSheets.add(sheetInfo.constructableSheet);
791
+ const rawSheet = this.rawConstructableSheets.get(shadowRoot);
792
+ if (rawSheet) {
793
+ ownedSheets.add(rawSheet);
794
+ this.rawConstructableSheets.delete(shadowRoot);
795
+ }
796
+ if (ownedSheets.size > 0) shadowRoot.adoptedStyleSheets = shadowRoot.adoptedStyleSheets.filter((s) => !ownedSheets.has(s));
797
+ } else {
798
+ for (const sheet of registry.sheets) try {
799
+ const styleElement = sheet.sheet;
800
+ if (styleElement?.parentNode) styleElement.parentNode.removeChild(styleElement);
801
+ } catch (error) {
802
+ console.warn("[Tasty] Failed to cleanup sheet:", error);
803
+ }
804
+ const rawStyleElement = this.rawStyleElements.get(root);
805
+ if (rawStyleElement?.parentNode) rawStyleElement.parentNode.removeChild(rawStyleElement);
806
+ this.rawStyleElements.delete(root);
807
+ }
808
+ this.rootRegistries.delete(root);
809
+ this.activeRoots.delete(root);
810
+ this.rawCSSBlocks.delete(root);
811
+ }
812
+ isAdoptedMode(root) {
813
+ const registry = this.rootRegistries.get(root);
814
+ if (registry) return registry.injectionMode === "adopted";
815
+ return this.detectInjectionMode(root) === "adopted";
816
+ }
817
+ getOrCreateRawAdoptedSheet(root) {
818
+ let sheet = this.rawConstructableSheets.get(root);
819
+ if (!sheet) {
820
+ sheet = new CSSStyleSheet();
821
+ root.adoptedStyleSheets = [sheet, ...root.adoptedStyleSheets];
822
+ this.rawConstructableSheets.set(root, sheet);
823
+ if (!this.rawCSSBlocks.has(root)) this.rawCSSBlocks.set(root, /* @__PURE__ */ new Map());
824
+ }
825
+ return sheet;
826
+ }
827
+ getOrCreateRawStyleElement(root) {
828
+ let styleElement = this.rawStyleElements.get(root);
829
+ if (!styleElement) {
830
+ styleElement = this.createStyleElement(root, "data-tasty-raw");
831
+ this.rawStyleElements.set(root, styleElement);
832
+ this.rawCSSBlocks.set(root, /* @__PURE__ */ new Map());
833
+ }
834
+ return styleElement;
835
+ }
836
+ injectRawCSS(css, root) {
837
+ if (!css.trim()) return { dispose: () => {} };
838
+ const id = `raw_${this.rawCSSCounter++}`;
839
+ if (this.isAdoptedMode(root)) {
840
+ this.getOrCreateRawAdoptedSheet(root);
841
+ const blocksMap = this.rawCSSBlocks.get(root);
842
+ const info = {
843
+ id,
844
+ css,
845
+ startOffset: 0,
846
+ endOffset: css.length
847
+ };
848
+ blocksMap.set(id, info);
849
+ this.rebuildRawAdoptedSheet(root);
850
+ } else {
851
+ const styleElement = this.getOrCreateRawStyleElement(root);
852
+ const blocksMap = this.rawCSSBlocks.get(root);
853
+ const currentContent = styleElement.textContent || "";
854
+ const cssWithNewline = (currentContent ? "\n" : "") + css;
855
+ styleElement.textContent = currentContent + cssWithNewline;
856
+ blocksMap.set(id, {
857
+ id,
858
+ css,
859
+ startOffset: currentContent.length,
860
+ endOffset: currentContent.length + cssWithNewline.length
861
+ });
862
+ }
863
+ return { dispose: () => {
864
+ this.disposeRawCSS(id, root);
865
+ } };
866
+ }
867
+ rebuildRawAdoptedSheet(root) {
868
+ const sheet = this.rawConstructableSheets.get(root);
869
+ const blocksMap = this.rawCSSBlocks.get(root);
870
+ if (!sheet || !blocksMap) return;
871
+ sheet.replaceSync(rawBlocksToCSS(blocksMap));
872
+ }
873
+ disposeRawCSS(id, root) {
874
+ const blocksMap = this.rawCSSBlocks.get(root);
875
+ if (!blocksMap?.delete(id)) return;
876
+ if (this.isAdoptedMode(root)) {
877
+ this.rebuildRawAdoptedSheet(root);
878
+ return;
879
+ }
880
+ const styleElement = this.rawStyleElements.get(root);
881
+ if (!styleElement) return;
882
+ const remainingBlocks = Array.from(blocksMap.values());
883
+ if (remainingBlocks.length === 0) styleElement.textContent = "";
884
+ else {
885
+ remainingBlocks.sort((a, b) => a.startOffset - b.startOffset);
886
+ styleElement.textContent = remainingBlocks.map((block) => block.css).join("\n");
887
+ let offset = 0;
888
+ for (const block of remainingBlocks) {
889
+ block.startOffset = offset;
890
+ block.endOffset = offset + block.css.length;
891
+ offset = block.endOffset + 1;
892
+ }
893
+ }
894
+ }
895
+ getOwnedCSSInOrder(registry, root) {
896
+ const raw = this.getRawCSSText(root);
897
+ const rawElement = this.isAdoptedMode(root) ? null : this.rawStyleElements.get(root);
898
+ let rawIndex = raw && !rawElement ? 0 : -1;
899
+ const chunks = [];
900
+ for (const sheetInfo of registry.sheets) {
901
+ const css = this.readSheetCSS(sheetInfo);
902
+ if (css === null) continue;
903
+ if (rawIndex < 0 && rawElement && sheetInfo.sheet && rawElement.compareDocumentPosition(sheetInfo.sheet) & Node.DOCUMENT_POSITION_FOLLOWING) rawIndex = chunks.length;
904
+ chunks.push(css);
905
+ }
906
+ if (!raw) return chunks;
907
+ chunks.splice(rawIndex < 0 ? chunks.length : rawIndex, 0, raw);
908
+ return chunks;
909
+ }
910
+ getRawRuleCount(root) {
911
+ const sheet = this.isAdoptedMode(root) ? this.rawConstructableSheets.get(root) : this.rawStyleElements.get(root)?.sheet;
912
+ try {
913
+ return sheet?.cssRules.length ?? 0;
914
+ } catch {
915
+ return 0;
916
+ }
917
+ }
918
+ getRawCSSText(root) {
919
+ if (this.isAdoptedMode(root)) {
920
+ const blocksMap = this.rawCSSBlocks.get(root);
921
+ if (!blocksMap || blocksMap.size === 0) return "";
922
+ return rawBlocksToCSS(blocksMap);
923
+ }
924
+ return this.rawStyleElements.get(root)?.textContent || "";
925
+ }
926
+ };
927
+ //#endregion
928
+ //#region src/injector/injector.ts
929
+ const DEFAULT_GC_GRACE = 1e4;
930
+ const noop = () => {};
931
+ const EMPTY_KEYFRAMES_INFO = {
932
+ name: "",
933
+ ruleIndex: -3,
934
+ sheetIndex: -3
935
+ };
936
+ function extractRSCClassNames(rscClassRegex) {
937
+ if (typeof document === "undefined") return [];
938
+ const styles = document.querySelectorAll("style[data-tasty-rsc]");
939
+ if (styles.length === 0) return [];
940
+ const classSet = /* @__PURE__ */ new Set();
941
+ for (const style of styles) {
942
+ const text = style.textContent;
943
+ if (!text) continue;
944
+ let match;
945
+ rscClassRegex.lastIndex = 0;
946
+ while ((match = rscClassRegex.exec(text)) !== null) classSet.add(match[1]);
947
+ }
948
+ return Array.from(classSet);
949
+ }
950
+ function syncServerClasses(registry, rscClassRegex) {
951
+ if (typeof window === "undefined") return;
952
+ const classes = window.__TASTY__;
953
+ if (classes && classes.length > registry.serverClassSyncIndex) {
954
+ for (let i = registry.serverClassSyncIndex; i < classes.length; i++) registerHydratedClass(registry, classes[i]);
955
+ registry.serverClassSyncIndex = classes.length;
956
+ }
957
+ if (!registry.rscStylesScanned) {
958
+ registry.rscStylesScanned = true;
959
+ for (const cls of extractRSCClassNames(rscClassRegex)) registerHydratedClass(registry, cls);
960
+ }
961
+ }
962
+ function registerHydratedClass(registry, className) {
963
+ if (registry.rules.has(className)) return;
964
+ registry.rules.set(className, {
965
+ className,
966
+ ruleIndex: -2,
967
+ sheetIndex: -2
968
+ });
969
+ registry.pinCounts.set(className, 0);
970
+ }
971
+ var StyleInjector = class {
972
+ sheetManager;
973
+ config;
974
+ globalRuleCounter = 0;
975
+ cancelPendingGC = null;
976
+ namePrefix;
977
+ classRegex;
978
+ rscClassRegex;
979
+ get _sheetManager() {
980
+ return this.sheetManager;
981
+ }
982
+ inferProperties(registry, rules, root) {
983
+ if (this.config.autoPropertyTypes === false) return;
984
+ const resolver = registry.propertyTypeResolver;
985
+ const defined = registry.injectedProperties;
986
+ for (const rule of rules) {
987
+ if (!rule.declarations) continue;
988
+ resolver.scanDeclarations(rule.declarations, (name) => defined.has(name), (name, syntax, initialValue) => {
989
+ this.property(name, {
990
+ syntax,
991
+ inherits: true,
992
+ initialValue,
993
+ root
994
+ });
995
+ });
996
+ }
997
+ }
998
+ get batching() {
999
+ const mode = this.config.batchInjection;
1000
+ if (!mode || typeof document === "undefined") return false;
1001
+ if (mode === "always") return true;
1002
+ if (isBatchWindowOpen()) return true;
1003
+ warnBatchProviderMissing();
1004
+ return false;
1005
+ }
1006
+ writeSheet(task) {
1007
+ if (this.batching) return enqueueStyleWrite(task);
1008
+ task();
1009
+ return null;
1010
+ }
1011
+ writeGlobalRule(registry, rules, key, root, onApplied) {
1012
+ if (this.batching) {
1013
+ onApplied?.();
1014
+ enqueueStyleWrite(() => {
1015
+ this.sheetManager.insertGlobalRule(registry, rules, key, root);
1016
+ });
1017
+ return;
1018
+ }
1019
+ if (this.sheetManager.insertGlobalRule(registry, rules, key, root)) onApplied?.();
1020
+ }
1021
+ constructor(config = {}) {
1022
+ if (config.namePrefix !== void 0) validateNamePrefix(config.namePrefix);
1023
+ this.config = config;
1024
+ this.sheetManager = new SheetManager(config);
1025
+ this.namePrefix = config.namePrefix ?? "t";
1026
+ this.classRegex = tastyClassRegex(this.namePrefix);
1027
+ this.rscClassRegex = rscClassRegexGlobal(this.namePrefix);
1028
+ }
1029
+ generateClassName(cacheKey) {
1030
+ return makeClassName(this.namePrefix, hashString(cacheKey));
1031
+ }
1032
+ tryHydratedHit(registry, cacheKey, className) {
1033
+ syncServerClasses(registry, this.rscClassRegex);
1034
+ const rule = registry.rules.get(className);
1035
+ if (rule && rule.ruleIndex === -2 && rule.sheetIndex === -2) {
1036
+ registry.cacheKeyToClassName.set(cacheKey, className);
1037
+ return true;
1038
+ }
1039
+ return false;
1040
+ }
1041
+ allocateClassName(cacheKey, options) {
1042
+ const root = options?.root || document;
1043
+ const registry = this.sheetManager.getRegistry(root);
1044
+ if (registry.cacheKeyToClassName.has(cacheKey)) return {
1045
+ className: registry.cacheKeyToClassName.get(cacheKey),
1046
+ isNewAllocation: false
1047
+ };
1048
+ const className = this.generateClassName(cacheKey);
1049
+ if (this.tryHydratedHit(registry, cacheKey, className)) return {
1050
+ className,
1051
+ isNewAllocation: false
1052
+ };
1053
+ if (registry.rules.get(className)) {
1054
+ if (isDevEnv()) console.warn(`[Tasty] Hash collision: cache keys produce the same class "${className}". Styles may be incorrect.`);
1055
+ registry.cacheKeyToClassName.set(cacheKey, className);
1056
+ return {
1057
+ className,
1058
+ isNewAllocation: false
1059
+ };
1060
+ }
1061
+ const placeholderRuleInfo = {
1062
+ className,
1063
+ ruleIndex: -1,
1064
+ sheetIndex: -1
1065
+ };
1066
+ registry.rules.set(className, placeholderRuleInfo);
1067
+ registry.cacheKeyToClassName.set(cacheKey, className);
1068
+ return {
1069
+ className,
1070
+ isNewAllocation: true
1071
+ };
1072
+ }
1073
+ inject(rules, options) {
1074
+ const root = options?.root || document;
1075
+ const registry = this.sheetManager.getRegistry(root);
1076
+ const pin = options?.pin ?? true;
1077
+ if (rules.length === 0) return {
1078
+ className: "",
1079
+ dispose: () => {}
1080
+ };
1081
+ const cacheKey = options?.cacheKey;
1082
+ let className;
1083
+ if (cacheKey && registry.cacheKeyToClassName.has(cacheKey)) {
1084
+ className = registry.cacheKeyToClassName.get(cacheKey);
1085
+ const existingRuleInfo = registry.rules.get(className);
1086
+ if (existingRuleInfo.ruleIndex === -3) {
1087
+ registry.unusedSince.delete(className);
1088
+ if (pin) registry.pinCounts.set(className, (registry.pinCounts.get(className) || 0) + 1);
1089
+ if (registry.metrics) registry.metrics.hits++;
1090
+ return {
1091
+ className,
1092
+ dispose: pin ? () => this.unpin(className, registry) : noop
1093
+ };
1094
+ }
1095
+ if (!(existingRuleInfo.ruleIndex === -1 && existingRuleInfo.sheetIndex === -1)) {
1096
+ registry.unusedSince.delete(className);
1097
+ if (pin) {
1098
+ const pins = registry.pinCounts.get(className) || 0;
1099
+ registry.pinCounts.set(className, pins + 1);
1100
+ }
1101
+ if (registry.metrics) registry.metrics.hits++;
1102
+ return {
1103
+ className,
1104
+ dispose: pin ? () => this.unpin(className, registry) : noop
1105
+ };
1106
+ }
1107
+ } else if (cacheKey) {
1108
+ className = this.generateClassName(cacheKey);
1109
+ if (this.tryHydratedHit(registry, cacheKey, className)) {
1110
+ if (pin) registry.pinCounts.set(className, (registry.pinCounts.get(className) || 0) + 1);
1111
+ if (registry.metrics) registry.metrics.hits++;
1112
+ return {
1113
+ className,
1114
+ dispose: pin ? () => this.unpin(className, registry) : noop
1115
+ };
1116
+ }
1117
+ } else {
1118
+ const parts = rules.map((r) => `${r.selector}\0${r.declarations}`);
1119
+ className = makeClassName(this.namePrefix, hashString(parts.join("\n")));
1120
+ }
1121
+ const rulesToInsert = rules.map((rule) => {
1122
+ let newSelector = rule.selector;
1123
+ if (rule.needsClassName) {
1124
+ const selectorParts = newSelector ? newSelector.split("|||") : [""];
1125
+ const classPrefix = `.${className}.${className}`;
1126
+ newSelector = selectorParts.map((part) => {
1127
+ const classSelector = part ? `${classPrefix}${part}` : classPrefix;
1128
+ if (rule.rootPrefix) return `${rule.rootPrefix} ${classSelector}`;
1129
+ return classSelector;
1130
+ }).join(", ");
1131
+ }
1132
+ return {
1133
+ ...rule,
1134
+ selector: newSelector,
1135
+ needsClassName: void 0,
1136
+ rootPrefix: void 0
1137
+ };
1138
+ });
1139
+ const applySheetWrite = () => {
1140
+ this.inferProperties(registry, rulesToInsert, root);
1141
+ const ruleInfo = this.sheetManager.insertRule(registry, rulesToInsert, className, root);
1142
+ if (!ruleInfo) {
1143
+ if (registry.metrics) registry.metrics.misses++;
1144
+ return null;
1145
+ }
1146
+ registry.rules.set(className, ruleInfo);
1147
+ if (cacheKey) registry.cacheKeyToClassName.set(cacheKey, className);
1148
+ if (registry.metrics) {
1149
+ registry.metrics.totalInsertions++;
1150
+ registry.metrics.misses++;
1151
+ }
1152
+ return ruleInfo;
1153
+ };
1154
+ if (this.batching) {
1155
+ registry.rules.set(className, {
1156
+ className,
1157
+ ruleIndex: -3,
1158
+ sheetIndex: -3
1159
+ });
1160
+ if (cacheKey) registry.cacheKeyToClassName.set(cacheKey, className);
1161
+ if (pin) registry.pinCounts.set(className, 1);
1162
+ registry.unusedSince.set(className, Date.now());
1163
+ const queued = enqueueStyleWrite(() => {
1164
+ if (applySheetWrite()) return;
1165
+ registry.rules.set(className, {
1166
+ className,
1167
+ ruleIndex: -1,
1168
+ sheetIndex: -1
1169
+ });
1170
+ });
1171
+ return {
1172
+ className,
1173
+ dispose: pin ? () => {
1174
+ if (!queued.done && registry.pinCounts.get(className) === 1 && registry.rules.get(className)?.ruleIndex === -3) {
1175
+ queued.cancelled = true;
1176
+ registry.rules.delete(className);
1177
+ if (cacheKey) registry.cacheKeyToClassName.delete(cacheKey);
1178
+ registry.pinCounts.set(className, 0);
1179
+ return;
1180
+ }
1181
+ this.unpin(className, registry);
1182
+ } : noop
1183
+ };
1184
+ }
1185
+ if (!applySheetWrite()) return {
1186
+ className,
1187
+ dispose: () => {}
1188
+ };
1189
+ if (pin) registry.pinCounts.set(className, 1);
1190
+ registry.unusedSince.set(className, Date.now());
1191
+ return {
1192
+ className,
1193
+ dispose: pin ? () => this.unpin(className, registry) : noop
1194
+ };
1195
+ }
1196
+ injectGlobal(rules, options) {
1197
+ const root = options?.root || document;
1198
+ const registry = this.sheetManager.getRegistry(root);
1199
+ if (!rules || rules.length === 0) return { dispose: () => {} };
1200
+ const key = `global:${this.globalRuleCounter++}`;
1201
+ const applyWrite = () => {
1202
+ this.inferProperties(registry, rules, root);
1203
+ const inserted = this.sheetManager.insertGlobalRule(registry, rules, key, root);
1204
+ if (registry.metrics) registry.metrics.totalInsertions++;
1205
+ return inserted;
1206
+ };
1207
+ if (this.batching) {
1208
+ let info = null;
1209
+ const queued = enqueueStyleWrite(() => {
1210
+ info = applyWrite();
1211
+ });
1212
+ return { dispose: () => {
1213
+ if (!queued.done) {
1214
+ queued.cancelled = true;
1215
+ return;
1216
+ }
1217
+ if (info) this.sheetManager.deleteGlobalRule(registry, key);
1218
+ } };
1219
+ }
1220
+ const info = applyWrite();
1221
+ return { dispose: () => {
1222
+ if (info) this.sheetManager.deleteGlobalRule(registry, key);
1223
+ } };
1224
+ }
1225
+ injectRawCSS(css, options) {
1226
+ const root = options?.root || document;
1227
+ if (!this.batching) return this.sheetManager.injectRawCSS(css, root);
1228
+ let result = null;
1229
+ const queued = enqueueStyleWrite(() => {
1230
+ result = this.sheetManager.injectRawCSS(css, root);
1231
+ });
1232
+ return { dispose: () => {
1233
+ if (!queued.done) {
1234
+ queued.cancelled = true;
1235
+ return;
1236
+ }
1237
+ result?.dispose();
1238
+ } };
1239
+ }
1240
+ getRawCSSText(options) {
1241
+ flushStyles();
1242
+ const root = options?.root || document;
1243
+ return this.sheetManager.getRawCSSText(root);
1244
+ }
1245
+ holdKeyframes(steps, names, options) {
1246
+ const root = options?.root || document;
1247
+ const registry = this.sheetManager.getRegistry(root);
1248
+ const keys = /* @__PURE__ */ new Map();
1249
+ for (const [authored, definition] of Object.entries(steps)) {
1250
+ const resolved = names.get(authored) ?? authored;
1251
+ let entry = registry.localKeyframes.get(resolved);
1252
+ if (!entry) {
1253
+ const injected = this.keyframes(definition, {
1254
+ name: resolved,
1255
+ root,
1256
+ distinctByName: true
1257
+ });
1258
+ entry = {
1259
+ name: injected.toString(),
1260
+ dispose: injected.dispose,
1261
+ owners: /* @__PURE__ */ new Set()
1262
+ };
1263
+ registry.localKeyframes.set(resolved, entry);
1264
+ }
1265
+ keys.set(authored, resolved);
1266
+ }
1267
+ return keys;
1268
+ }
1269
+ ownKeyframes(key, className, options) {
1270
+ this.sheetManager.getRegistry(options?.root || document).localKeyframes.get(key)?.owners.add(className);
1271
+ }
1272
+ trackRef(cacheKey, options) {
1273
+ const root = options?.root || document;
1274
+ const registry = this.sheetManager.getRegistry(root);
1275
+ if (!registry.cacheKeyToClassName.has(cacheKey)) return null;
1276
+ const className = registry.cacheKeyToClassName.get(cacheKey);
1277
+ const pins = registry.pinCounts.get(className) || 0;
1278
+ registry.pinCounts.set(className, pins + 1);
1279
+ if (registry.metrics) registry.metrics.hits++;
1280
+ return {
1281
+ className,
1282
+ dispose: () => this.unpin(className, registry)
1283
+ };
1284
+ }
1285
+ unpin(className, registry) {
1286
+ const pins = registry.pinCounts.get(className);
1287
+ if (pins == null || pins <= 0) return;
1288
+ const remaining = pins - 1;
1289
+ registry.pinCounts.set(className, remaining);
1290
+ if (remaining === 0 && registry.metrics) registry.metrics.totalUnused++;
1291
+ }
1292
+ cleanup(root) {
1293
+ this.gc({
1294
+ root,
1295
+ force: true
1296
+ });
1297
+ }
1298
+ getCSSText(options) {
1299
+ flushStyles();
1300
+ const root = options?.root || document;
1301
+ const registry = this.sheetManager.getRegistry(root);
1302
+ return this.sheetManager.getCSSText(registry);
1303
+ }
1304
+ getCSSTextForClasses(classNames, options) {
1305
+ flushStyles();
1306
+ const root = options?.root || document;
1307
+ const registry = this.sheetManager.getRegistry(root);
1308
+ const cssChunks = [];
1309
+ for (const cls of classNames) {
1310
+ const info = registry.rules.get(cls);
1311
+ if (info) {
1312
+ const sheet = registry.sheets[info.sheetIndex];
1313
+ const styleSheet = sheet ? this.sheetManager.getCSSSheet(sheet) : null;
1314
+ if (styleSheet) {
1315
+ const start = Math.max(0, info.ruleIndex);
1316
+ const end = Math.min(styleSheet.cssRules.length - 1, info.endRuleIndex ?? info.ruleIndex);
1317
+ if (start >= 0 && end >= start && start < styleSheet.cssRules.length) for (let i = start; i <= end; i++) {
1318
+ const rule = styleSheet.cssRules[i];
1319
+ if (rule) cssChunks.push(rule.cssText);
1320
+ }
1321
+ } else if (info.cssText && info.cssText.length) cssChunks.push(...info.cssText);
1322
+ }
1323
+ }
1324
+ return cssChunks.join("\n");
1325
+ }
1326
+ getMetrics(options) {
1327
+ flushStyles();
1328
+ const root = options?.root || document;
1329
+ const registry = this.sheetManager.getRegistry(root);
1330
+ const metrics = this.sheetManager.getMetrics(registry);
1331
+ if (metrics && typeof document !== "undefined") metrics.unusedHits = this.collectUnused(registry, root).length;
1332
+ return metrics;
1333
+ }
1334
+ resetMetrics(options) {
1335
+ const root = options?.root || document;
1336
+ const registry = this.sheetManager.getRegistry(root);
1337
+ this.sheetManager.resetMetrics(registry);
1338
+ }
1339
+ property(name, options) {
1340
+ const root = options?.root || document;
1341
+ const registry = this.sheetManager.getRegistry(root);
1342
+ const effectiveResult = getEffectiveDefinition(name, {
1343
+ syntax: options?.syntax,
1344
+ inherits: options?.inherits,
1345
+ initialValue: options?.initialValue
1346
+ });
1347
+ if (!effectiveResult.isValid) {
1348
+ if (isDevEnv()) console.warn(`[Tasty] property(): ${effectiveResult.error}. Got: "${name}"`);
1349
+ return;
1350
+ }
1351
+ const cssName = effectiveResult.cssName;
1352
+ const definition = effectiveResult.definition;
1353
+ this.insertPropertyRule(registry, root, cssName, definition, name);
1354
+ }
1355
+ insertPropertyRule(registry, root, cssName, definition, cacheKey) {
1356
+ if (registry.injectedProperties.has(cssName)) return;
1357
+ const parts = [];
1358
+ if (definition.syntax != null) {
1359
+ let syntax = String(definition.syntax).trim();
1360
+ if (!/^['"]/u.test(syntax)) syntax = `"${syntax}"`;
1361
+ parts.push(`syntax: ${syntax};`);
1362
+ }
1363
+ const inherits = definition.inherits ?? true;
1364
+ parts.push(`inherits: ${inherits ? "true" : "false"};`);
1365
+ if (definition.initialValue != null) {
1366
+ let initialValueStr;
1367
+ if (typeof definition.initialValue === "number") initialValueStr = String(definition.initialValue);
1368
+ else initialValueStr = parseStyle(definition.initialValue).output;
1369
+ parts.push(`initial-value: ${initialValueStr};`);
1370
+ }
1371
+ const declarations = parts.join(" ").trim();
1372
+ const rule = {
1373
+ selector: `@property ${cssName}`,
1374
+ declarations
1375
+ };
1376
+ registry.injectedProperties.set(cssName, normalizePropertyDefinition(definition));
1377
+ this.writeGlobalRule(registry, [rule], `property:${cacheKey}`, root);
1378
+ }
1379
+ isPropertyDefined(name, options) {
1380
+ flushStyles();
1381
+ const root = options?.root || document;
1382
+ const registry = this.sheetManager.getRegistry(root);
1383
+ const effectiveResult = getEffectiveDefinition(name, {});
1384
+ if (!effectiveResult.isValid) return false;
1385
+ return registry.injectedProperties.has(effectiveResult.cssName);
1386
+ }
1387
+ fontFace(family, descriptors, options) {
1388
+ const root = options?.root || document;
1389
+ const registry = this.sheetManager.getRegistry(root);
1390
+ const hash = fontFaceContentHash(family, descriptors);
1391
+ if (registry.injectedFontFaces.has(hash)) return;
1392
+ const rule = {
1393
+ selector: "@font-face",
1394
+ declarations: formatFontFaceDeclarations(family, descriptors)
1395
+ };
1396
+ this.writeGlobalRule(registry, [rule], `fontface:${hash}`, root, () => {
1397
+ registry.injectedFontFaces.add(hash);
1398
+ });
1399
+ }
1400
+ counterStyle(name, descriptors, options) {
1401
+ const root = options?.root || document;
1402
+ const registry = this.sheetManager.getRegistry(root);
1403
+ const isWeak = options?.weak === true;
1404
+ const existingIsStrong = registry.injectedCounterStyles.get(name);
1405
+ if (existingIsStrong !== void 0) {
1406
+ if (isWeak || existingIsStrong === true) return;
1407
+ this.writeSheet(() => {
1408
+ this.sheetManager.deleteGlobalRule(registry, `counterstyle:${name}`);
1409
+ });
1410
+ }
1411
+ const rule = {
1412
+ selector: `@counter-style ${name}`,
1413
+ declarations: formatCounterStyleDeclarations(descriptors)
1414
+ };
1415
+ this.writeGlobalRule(registry, [rule], `counterstyle:${name}`, root, () => {
1416
+ registry.injectedCounterStyles.set(name, !isWeak);
1417
+ });
1418
+ }
1419
+ func(name, definition, options) {
1420
+ const root = options?.root || document;
1421
+ const registry = this.sheetManager.getRegistry(root);
1422
+ const isWeak = options?.weak === true;
1423
+ const cssName = parseFunctionName(name);
1424
+ const existingIsStrong = registry.injectedFunctions.get(cssName);
1425
+ if (existingIsStrong !== void 0) {
1426
+ if (isWeak || existingIsStrong === true) return;
1427
+ this.writeSheet(() => {
1428
+ this.sheetManager.deleteGlobalRule(registry, `function:${cssName}`);
1429
+ });
1430
+ }
1431
+ const rule = {
1432
+ selector: formatFunctionPrelude(name, definition.args, definition.returns),
1433
+ declarations: formatFunctionDeclarations(definition)
1434
+ };
1435
+ this.writeGlobalRule(registry, [rule], `function:${cssName}`, root, () => {
1436
+ registry.injectedFunctions.set(cssName, !isWeak);
1437
+ });
1438
+ }
1439
+ keyframes(steps, nameOrOptions) {
1440
+ const isStringName = typeof nameOrOptions === "string";
1441
+ const providedName = isStringName ? nameOrOptions : nameOrOptions?.name;
1442
+ const distinctByName = isStringName ? false : nameOrOptions?.distinctByName ?? false;
1443
+ const root = isStringName ? document : nameOrOptions?.root || document;
1444
+ const registry = this.sheetManager.getRegistry(root);
1445
+ if (Object.keys(steps).length === 0) return {
1446
+ toString: () => "",
1447
+ dispose: () => {}
1448
+ };
1449
+ const contentHash = distinctByName && providedName ? `${providedName}\u0000${JSON.stringify(steps)}` : JSON.stringify(steps);
1450
+ const existing = registry.keyframesCache.get(contentHash);
1451
+ if (existing) {
1452
+ existing.refCount++;
1453
+ return {
1454
+ toString: () => existing.name,
1455
+ dispose: () => this.disposeKeyframes(contentHash, registry)
1456
+ };
1457
+ }
1458
+ let actualName;
1459
+ if (providedName) {
1460
+ const existingContentForName = registry.keyframesNameToContent.get(providedName);
1461
+ if (existingContentForName && existingContentForName !== contentHash) actualName = `${providedName}-${makeKeyframeName(this.namePrefix, String(registry.keyframesCounter++))}`;
1462
+ else {
1463
+ actualName = providedName;
1464
+ registry.keyframesNameToContent.set(providedName, contentHash);
1465
+ }
1466
+ } else actualName = makeKeyframeName(this.namePrefix, String(registry.keyframesCounter++));
1467
+ const applyWrite = () => {
1468
+ const result = this.sheetManager.insertKeyframes(registry, steps, actualName, root);
1469
+ if (!result) return false;
1470
+ const { info, declarations } = result;
1471
+ if (this.config.autoPropertyTypes !== false && declarations) registry.propertyTypeResolver.scanDeclarations(declarations, (name) => registry.injectedProperties.has(name), (name, syntax, initialValue) => {
1472
+ this.property(name, {
1473
+ syntax,
1474
+ inherits: true,
1475
+ initialValue,
1476
+ root
1477
+ });
1478
+ });
1479
+ const entry = registry.keyframesCache.get(contentHash);
1480
+ if (entry) {
1481
+ entry.info = info;
1482
+ entry.pending = void 0;
1483
+ } else registry.keyframesCache.set(contentHash, {
1484
+ name: actualName,
1485
+ refCount: 1,
1486
+ info
1487
+ });
1488
+ if (registry.metrics) {
1489
+ registry.metrics.totalInsertions++;
1490
+ registry.metrics.misses++;
1491
+ }
1492
+ return true;
1493
+ };
1494
+ if (this.batching) {
1495
+ const entry = {
1496
+ name: actualName,
1497
+ refCount: 1,
1498
+ info: EMPTY_KEYFRAMES_INFO
1499
+ };
1500
+ registry.keyframesCache.set(contentHash, entry);
1501
+ entry.pending = enqueueStyleWrite(() => {
1502
+ if (applyWrite()) return;
1503
+ if (registry.keyframesCache.get(contentHash) === entry) registry.keyframesCache.delete(contentHash);
1504
+ });
1505
+ return {
1506
+ toString: () => actualName,
1507
+ dispose: () => this.disposeKeyframes(contentHash, registry)
1508
+ };
1509
+ }
1510
+ if (!applyWrite()) return {
1511
+ toString: () => "",
1512
+ dispose: () => {}
1513
+ };
1514
+ return {
1515
+ toString: () => actualName,
1516
+ dispose: () => this.disposeKeyframes(contentHash, registry)
1517
+ };
1518
+ }
1519
+ disposeKeyframes(contentHash, registry) {
1520
+ const entry = registry.keyframesCache.get(contentHash);
1521
+ if (!entry) return;
1522
+ entry.refCount--;
1523
+ if (entry.refCount <= 0) {
1524
+ if (entry.pending && !entry.pending.done) entry.pending.cancelled = true;
1525
+ else this.sheetManager.deleteKeyframes(registry, entry.info);
1526
+ registry.keyframesCache.delete(contentHash);
1527
+ for (const [name, hash] of registry.keyframesNameToContent.entries()) if (hash === contentHash) {
1528
+ registry.keyframesNameToContent.delete(name);
1529
+ break;
1530
+ }
1531
+ if (registry.metrics) {
1532
+ registry.metrics.totalUnused++;
1533
+ registry.metrics.stylesCleanedUp++;
1534
+ }
1535
+ }
1536
+ }
1537
+ touch(_className, options) {
1538
+ if (typeof document === "undefined") return;
1539
+ if (!this.config.gc) return;
1540
+ const registry = this.sheetManager.getRegistry(options?.root || document);
1541
+ if (++registry.touchCount >= (this.config.gc.touchInterval ?? 1e3)) {
1542
+ registry.touchCount = 0;
1543
+ this.scheduleGC();
1544
+ }
1545
+ }
1546
+ scheduleGC() {
1547
+ if (this.cancelPendingGC) return;
1548
+ const runGC = () => {
1549
+ this.cancelPendingGC = null;
1550
+ this.sheetManager.pruneDisconnectedRoots();
1551
+ for (const root of this.sheetManager.getActiveRoots()) this.gc({ root });
1552
+ };
1553
+ if (typeof requestIdleCallback !== "undefined") {
1554
+ const handle = requestIdleCallback(() => runGC());
1555
+ this.cancelPendingGC = () => cancelIdleCallback(handle);
1556
+ }
1557
+ }
1558
+ collectUnused(registry, root) {
1559
+ const now = Date.now();
1560
+ const grace = this.config.gc?.grace ?? DEFAULT_GC_GRACE;
1561
+ const liveClasses = /* @__PURE__ */ new Set();
1562
+ for (const el of root.querySelectorAll("[class]")) for (const token of el.classList) if (this.classRegex.test(token)) liveClasses.add(token);
1563
+ const unused = [];
1564
+ for (const [className, ruleInfo] of registry.rules) {
1565
+ if (ruleInfo.sheetIndex < 0) continue;
1566
+ if (liveClasses.has(className)) {
1567
+ registry.unusedSince.delete(className);
1568
+ continue;
1569
+ }
1570
+ if ((registry.pinCounts.get(className) ?? 0) > 0) continue;
1571
+ let since = registry.unusedSince.get(className);
1572
+ if (since === void 0) {
1573
+ since = now;
1574
+ registry.unusedSince.set(className, now);
1575
+ }
1576
+ if (now - since < grace) continue;
1577
+ unused.push(className);
1578
+ }
1579
+ unused.sort((a, b) => (registry.unusedSince.get(b) ?? 0) - (registry.unusedSince.get(a) ?? 0));
1580
+ return unused;
1581
+ }
1582
+ getUnusedClasses(options) {
1583
+ flushStyles();
1584
+ if (typeof document === "undefined") return [];
1585
+ const root = options?.root || document;
1586
+ const registry = this.sheetManager.getRegistry(root);
1587
+ return this.collectUnused(registry, root);
1588
+ }
1589
+ gc(options) {
1590
+ flushStyles();
1591
+ if (typeof document === "undefined") return 0;
1592
+ this.cancelPendingGC?.();
1593
+ this.cancelPendingGC = null;
1594
+ const root = options?.root || document;
1595
+ const force = options?.force;
1596
+ const registry = this.sheetManager.getRegistry(root);
1597
+ const capacity = this.config.gc?.capacity ?? 1e3;
1598
+ if (!force && registry.rules.size <= capacity) return 0;
1599
+ const unused = this.collectUnused(registry, root);
1600
+ let doomed;
1601
+ if (force) doomed = unused;
1602
+ else if (unused.length > capacity) doomed = unused.slice(capacity);
1603
+ else return 0;
1604
+ if (doomed.length === 0) return 0;
1605
+ return this.sheetManager.deleteClasses(registry, doomed);
1606
+ }
1607
+ destroy(root) {
1608
+ flushStyles();
1609
+ const targetRoot = root || document;
1610
+ this.sheetManager.cleanup(targetRoot);
1611
+ if (this.cancelPendingGC && !this.sheetManager.hasActiveRoots()) {
1612
+ this.cancelPendingGC();
1613
+ this.cancelPendingGC = null;
1614
+ }
1615
+ }
1616
+ };
1617
+ //#endregion
1618
+ //#region src/config.ts
1619
+ const emittedWarnings = /* @__PURE__ */ new Set();
1620
+ const devMode = isDevEnv();
1621
+ function warnOnce(key, message) {
1622
+ if (devMode && !emittedWarnings.has(key)) {
1623
+ emittedWarnings.add(key);
1624
+ console.warn(message);
1625
+ }
1626
+ }
1627
+ let currentConfig = null;
1628
+ let globalKeyframes = null;
1629
+ let globalRecipes = null;
1630
+ const GLOBAL_INJECTOR_KEY = "__TASTY_GLOBAL_INJECTOR__";
1631
+ function isTestEnvironment() {
1632
+ if (typeof global !== "undefined") {
1633
+ const g = global;
1634
+ if (g.vi || g.jest || g.expect || g.describe || g.it) return true;
1635
+ }
1636
+ if (typeof window !== "undefined") {
1637
+ const ua = window.navigator?.userAgent;
1638
+ if (ua?.includes("jsdom") || ua?.includes("HappyDOM")) return true;
1639
+ }
1640
+ if (typeof globalThis !== "undefined") {
1641
+ const gt = globalThis;
1642
+ if (gt.vitest || gt.mocha) return true;
1643
+ }
1644
+ return false;
1645
+ }
1646
+ function createDefaultConfig(isTest) {
1647
+ return {
1648
+ maxRulesPerSheet: 8192,
1649
+ forceTextInjection: isTest ?? false,
1650
+ devMode: isDevEnv(),
1651
+ namePrefix: "t"
1652
+ };
1653
+ }
1654
+ function markStylesGenerated() {
1655
+ if (!markStylesGeneratedState()) return;
1656
+ if (typeof document !== "undefined" && document.querySelector("[data-tasty-ssr]")) {
1657
+ warnOnce("ssr-globals-skip", "[Tasty] SSR styles detected — skipping client-side global CSS injection to avoid duplicates.");
1658
+ return;
1659
+ }
1660
+ const injector = getGlobalInjector();
1661
+ const globalFontFaces = getGlobalFontFaces();
1662
+ const globalCounterStyles = getGlobalCounterStyles();
1663
+ const globalFunctions = getGlobalFunctions();
1664
+ const globalTokens = getGlobalConfigTokens();
1665
+ const configuredGlobalStyles = getGlobalStyles();
1666
+ for (const [token, definition] of Object.entries(getEffectiveProperties())) injector.property(token, definition);
1667
+ if (globalFontFaces && Object.keys(globalFontFaces).length > 0) for (const [family, input] of Object.entries(globalFontFaces)) {
1668
+ const descriptors = Array.isArray(input) ? input : [input];
1669
+ for (const desc of descriptors) injector.fontFace(family, desc);
1670
+ }
1671
+ if (globalCounterStyles && Object.keys(globalCounterStyles).length > 0) for (const [name, descriptors] of Object.entries(globalCounterStyles)) injector.counterStyle(name, descriptors, { weak: true });
1672
+ if (globalFunctions && Object.keys(globalFunctions).length > 0) for (const [name, definition] of Object.entries(globalFunctions)) injector.func(name, definition, { weak: true });
1673
+ if (globalTokens && Object.keys(globalTokens).length > 0) {
1674
+ const tokenRules = renderStyles(globalTokens, ":root");
1675
+ if (tokenRules.length > 0) injector.injectGlobal(tokenRules);
1676
+ }
1677
+ if (configuredGlobalStyles) {
1678
+ for (const [selector, styles] of Object.entries(configuredGlobalStyles)) if (Object.keys(styles).length > 0) {
1679
+ const rules = renderStyles(styles, selector);
1680
+ if (rules.length > 0) injector.injectGlobal(rules);
1681
+ }
1682
+ }
1683
+ }
1684
+ let _hasGlobalKeyframes = false;
1685
+ function hasGlobalKeyframes() {
1686
+ return _hasGlobalKeyframes;
1687
+ }
1688
+ function getGlobalKeyframes() {
1689
+ return globalKeyframes;
1690
+ }
1691
+ function setGlobalKeyframes(keyframes) {
1692
+ if (hasStylesGenerated()) {
1693
+ warnOnce("keyframes-after-styles", "[Tasty] Cannot update keyframes after styles have been generated.\nThe new keyframes will be ignored.");
1694
+ return;
1695
+ }
1696
+ globalKeyframes = {
1697
+ ...globalKeyframes ?? {},
1698
+ ...keyframes
1699
+ };
1700
+ _hasGlobalKeyframes = Object.keys(globalKeyframes).length > 0;
1701
+ }
1702
+ function setGlobalProperties(properties) {
1703
+ if (hasStylesGenerated()) {
1704
+ warnOnce("properties-after-styles", "[Tasty] Cannot update properties after styles have been generated.\nThe new properties will be ignored.");
1705
+ return;
1706
+ }
1707
+ mergeGlobalProperties(properties);
1708
+ }
1709
+ function setGlobalFontFace(fontFace) {
1710
+ if (hasStylesGenerated()) {
1711
+ warnOnce("fontface-after-styles", "[Tasty] Cannot update fontFaces after styles have been generated.\nThe new font faces will be ignored.");
1712
+ return;
1713
+ }
1714
+ mergeGlobalFontFaces(fontFace);
1715
+ }
1716
+ function setGlobalCounterStyle(counterStyle) {
1717
+ if (hasStylesGenerated()) {
1718
+ warnOnce("counterstyle-after-styles", "[Tasty] Cannot update counterStyles after styles have been generated.\nThe new counter styles will be ignored.");
1719
+ return;
1720
+ }
1721
+ mergeGlobalCounterStyles(counterStyle);
1722
+ }
1723
+ function setGlobalFunction(functions) {
1724
+ if (hasStylesGenerated()) {
1725
+ warnOnce("function-after-styles", "[Tasty] Cannot update functions after styles have been generated.\nThe new functions will be ignored.");
1726
+ return;
1727
+ }
1728
+ mergeGlobalFunctions(functions);
1729
+ }
1730
+ function hasGlobalRecipes() {
1731
+ return globalRecipes !== null && Object.keys(globalRecipes).length > 0;
1732
+ }
1733
+ function getGlobalRecipes() {
1734
+ return globalRecipes;
1735
+ }
1736
+ function setGlobalRecipes(recipes) {
1737
+ if (hasStylesGenerated()) {
1738
+ warnOnce("recipes-after-styles", "[Tasty] Cannot update recipes after styles have been generated.\nThe new recipes will be ignored.");
1739
+ return;
1740
+ }
1741
+ if (devMode) for (const [name, recipeStyles] of Object.entries(recipes)) {
1742
+ if (name === "none") warnOnce("recipe-reserved-none", "[Tasty] Recipe name \"none\" is reserved. It is used as a keyword meaning \"no base recipes\" (e.g. recipe: 'none / post-recipe'). Choose a different name for your recipe.");
1743
+ for (const key of Object.keys(recipeStyles)) {
1744
+ if (isSelector(key)) warnOnce(`recipe-selector-${name}-${key}`, `[Tasty] Recipe "${name}" contains sub-element key "${key}". Recipes must be flat styles without sub-element keys. Remove the sub-element key from the recipe definition.`);
1745
+ if (key === "recipe") warnOnce(`recipe-recursive-${name}`, `[Tasty] Recipe "${name}" contains a "recipe" key. Recipes cannot reference other recipes. Use space-separated names for composition: recipe: 'base elevated'.`);
1746
+ }
1747
+ }
1748
+ globalRecipes = {
1749
+ ...globalRecipes ?? {},
1750
+ ...recipes
1751
+ };
1752
+ }
1753
+ function setGlobalConfigTokens(styles) {
1754
+ if (hasStylesGenerated()) {
1755
+ warnOnce("tokens-after-styles", "[Tasty] Cannot update tokens after styles have been generated.\nThe new tokens will be ignored.");
1756
+ return;
1757
+ }
1758
+ mergeGlobalConfigTokens(styles);
1759
+ }
1760
+ function setGlobalStyles(styles) {
1761
+ if (hasStylesGenerated()) {
1762
+ warnOnce("globalStyles-after-styles", "[Tasty] Cannot update globalStyles after styles have been generated.\nThe new global styles will be ignored.");
1763
+ return;
1764
+ }
1765
+ mergeGlobalStyles(styles);
1766
+ }
1767
+ function isConfigLocked() {
1768
+ return hasStylesGenerated();
1769
+ }
1770
+ function configure(config = {}) {
1771
+ if (hasStylesGenerated()) {
1772
+ warnOnce("configure-after-styles", "[Tasty] Cannot call configure() after styles have been generated.\nConfiguration must be done before the first render. The configuration will be ignored.");
1773
+ return;
1774
+ }
1775
+ if (config.namePrefix !== void 0) validateNamePrefix(config.namePrefix);
1776
+ const normalized = normalizeConfig(config);
1777
+ const { propHandlers: mergedPropHandlers, propHandlerSources, baseStyleProps: mergedBaseStyleProps, properties: mergedProperties, keyframes: mergedKeyframes, fontFaces: mergedFontFaces, counterStyles: mergedCounterStyles, tokens: mergedConfigTokens, recipes: mergedRecipes, globalStyles: mergedGlobalStyles } = normalized;
1778
+ const functionDefs = applyStyleConfig(config, normalized, warnOnce);
1779
+ if (!isFunctionsPolyfillEnabled() && Object.keys(functionDefs).length > 0) setGlobalFunction(functionDefs);
1780
+ if (Object.keys(mergedKeyframes).length > 0) setGlobalKeyframes(mergedKeyframes);
1781
+ if (Object.keys(mergedProperties).length > 0) setGlobalProperties(mergedProperties);
1782
+ if (Object.keys(mergedFontFaces).length > 0) setGlobalFontFace(mergedFontFaces);
1783
+ if (Object.keys(mergedCounterStyles).length > 0) setGlobalCounterStyle(mergedCounterStyles);
1784
+ if (Object.keys(mergedPropHandlers).length > 0) for (const [name, definition] of Object.entries(mergedPropHandlers)) registerPropHandler(name, definition, { source: propHandlerSources.get(name) });
1785
+ if (mergedBaseStyleProps.length > 0) registerBaseStyleProps(mergedBaseStyleProps);
1786
+ if (Object.keys(mergedConfigTokens).length > 0) setGlobalConfigTokens(mergedConfigTokens);
1787
+ if (Object.keys(mergedRecipes).length > 0) setGlobalRecipes(mergedRecipes);
1788
+ if (Object.keys(mergedGlobalStyles).length > 0) setGlobalStyles(mergedGlobalStyles);
1789
+ const { states: _states, parserCacheSize: _parserCacheSize, units: _units, functions: _functions, polyfills: _polyfills, plugins: _plugins, keyframes: _keyframes, properties: _properties, fontFaces: _fontFaces, counterStyles: _counterStyles, handlers: _handlers, propHandlers: _propHandlers, baseStyleProps: _baseStyleProps, tokens: _tokens, replaceTokens: _replaceTokens, recipes: _recipes, colorSpace: _colorSpace, presets: _presets, globalStyles: _globalStyles, ...injectorConfig } = config;
1790
+ const fullConfig = {
1791
+ ...createDefaultConfig(),
1792
+ ...currentConfig,
1793
+ ...injectorConfig
1794
+ };
1795
+ currentConfig = fullConfig;
1796
+ setRuntimeConfigState(fullConfig);
1797
+ const storage = typeof window !== "undefined" ? window : globalThis;
1798
+ storage[GLOBAL_INJECTOR_KEY] = new StyleInjector(fullConfig);
1799
+ }
1800
+ function getConfig() {
1801
+ if (currentConfig) return currentConfig;
1802
+ const defaultConfig = createDefaultConfig(isTestEnvironment());
1803
+ currentConfig = defaultConfig;
1804
+ setRuntimeConfigState(defaultConfig);
1805
+ return defaultConfig;
1806
+ }
1807
+ function getNamePrefix() {
1808
+ return currentConfig?.namePrefix ?? "t";
1809
+ }
1810
+ function getGlobalInjector() {
1811
+ const storage = typeof window !== "undefined" ? window : globalThis;
1812
+ if (!storage[GLOBAL_INJECTOR_KEY]) configure();
1813
+ return storage[GLOBAL_INJECTOR_KEY];
1814
+ }
1815
+ function resetConfig() {
1816
+ resetStylesGeneratedState();
1817
+ currentConfig = null;
1818
+ globalKeyframes = null;
1819
+ _hasGlobalKeyframes = false;
1820
+ resetGlobalPolyfillsState();
1821
+ globalRecipes = null;
1822
+ resetConfigResources();
1823
+ resetGlobalPredefinedTokens();
1824
+ resetGlobalParseFunctions();
1825
+ resetFunctionPolyfills();
1826
+ resetHandlers();
1827
+ resetStyleChunks();
1828
+ resetPropHandlers();
1829
+ resetBaseStyleProps();
1830
+ clearPipelineCache();
1831
+ emittedWarnings.clear();
1832
+ resetStyleWarnings();
1833
+ const storage = typeof window !== "undefined" ? window : globalThis;
1834
+ delete storage[GLOBAL_INJECTOR_KEY];
1835
+ }
1836
+ //#endregion
1837
+ //#region src/injector/chunk-sheet-registry.ts
1838
+ var ChunkSheetRegistry = class {
1839
+ sheets = /* @__PURE__ */ new Map();
1840
+ sheetToHash = /* @__PURE__ */ new WeakMap();
1841
+ acquire(cssText) {
1842
+ const hash = hashString(cssText);
1843
+ const existing = this.sheets.get(hash);
1844
+ if (existing) {
1845
+ existing.refCount++;
1846
+ return existing.sheet;
1847
+ }
1848
+ const sheet = new CSSStyleSheet();
1849
+ sheet.replaceSync(cssText);
1850
+ const entry = {
1851
+ sheet,
1852
+ cssText,
1853
+ refCount: 1
1854
+ };
1855
+ this.sheets.set(hash, entry);
1856
+ this.sheetToHash.set(sheet, hash);
1857
+ return sheet;
1858
+ }
1859
+ release(sheet) {
1860
+ const hash = this.sheetToHash.get(sheet);
1861
+ if (!hash) return;
1862
+ const entry = this.sheets.get(hash);
1863
+ if (!entry) return;
1864
+ entry.refCount--;
1865
+ if (entry.refCount <= 0) {
1866
+ this.sheets.delete(hash);
1867
+ this.sheetToHash.delete(sheet);
1868
+ }
1869
+ }
1870
+ acquireAll(cssTexts) {
1871
+ return cssTexts.map((text) => this.acquire(text));
1872
+ }
1873
+ releaseAll(sheets) {
1874
+ for (const sheet of sheets) this.release(sheet);
1875
+ }
1876
+ get size() {
1877
+ return this.sheets.size;
1878
+ }
1879
+ };
1880
+ const chunkSheetRegistry = new ChunkSheetRegistry();
1881
+ //#endregion
1882
+ //#region src/injector/index.ts
1883
+ function inject(rules, options) {
1884
+ const injector = getGlobalInjector();
1885
+ markStylesGenerated();
1886
+ return injector.inject(rules, options);
1887
+ }
1888
+ function injectGlobal(rules, options) {
1889
+ return getGlobalInjector().injectGlobal(rules, options);
1890
+ }
1891
+ function injectRawCSS(css, options) {
1892
+ return getGlobalInjector().injectRawCSS(css, options);
1893
+ }
1894
+ function getRawCSSText(options) {
1895
+ return getGlobalInjector().getRawCSSText(options);
1896
+ }
1897
+ function keyframes(steps, nameOrOptions) {
1898
+ return getGlobalInjector().keyframes(steps, nameOrOptions);
1899
+ }
1900
+ function property(name, options) {
1901
+ return getGlobalInjector().property(name, options);
1902
+ }
1903
+ function isPropertyDefined(name, options) {
1904
+ return getGlobalInjector().isPropertyDefined(name, options);
1905
+ }
1906
+ function fontFace(family, descriptors, options) {
1907
+ return getGlobalInjector().fontFace(family, descriptors, options);
1908
+ }
1909
+ function counterStyle(name, descriptors, options) {
1910
+ return getGlobalInjector().counterStyle(name, descriptors, options);
1911
+ }
1912
+ function func(name, definition, options) {
1913
+ return getGlobalInjector().func(name, definition, options);
1914
+ }
1915
+ function getCSSText(options) {
1916
+ return getGlobalInjector().getCSSText(options);
1917
+ }
1918
+ function getCSSTextForNode(node, options) {
1919
+ const classRegex = tastyClassRegex(getNamePrefix());
1920
+ const classSet = /* @__PURE__ */ new Set();
1921
+ const readClasses = (el) => {
1922
+ const cls = el.getAttribute("class");
1923
+ if (!cls) return;
1924
+ for (const token of cls.split(/\s+/)) if (classRegex.test(token)) classSet.add(token);
1925
+ };
1926
+ if (node.getAttribute) readClasses(node);
1927
+ const elements = node.querySelectorAll ? node.querySelectorAll("[class]") : [];
1928
+ if (elements) elements.forEach(readClasses);
1929
+ return getGlobalInjector().getCSSTextForClasses(classSet, options);
1930
+ }
1931
+ function holdKeyframes(steps, names, options) {
1932
+ return getGlobalInjector().holdKeyframes(steps, names, options);
1933
+ }
1934
+ function ownKeyframes(key, className, options) {
1935
+ getGlobalInjector().ownKeyframes(key, className, options);
1936
+ }
1937
+ function cleanup(root) {
1938
+ return getGlobalInjector().cleanup(root);
1939
+ }
1940
+ function touch(className, options) {
1941
+ if (!getConfig().gc) return;
1942
+ getGlobalInjector().touch(className, options);
1943
+ }
1944
+ function gc(options) {
1945
+ return getGlobalInjector().gc(options);
1946
+ }
1947
+ const injector = { get instance() {
1948
+ return getGlobalInjector();
1949
+ } };
1950
+ function destroy(root) {
1951
+ return getGlobalInjector().destroy(root);
1952
+ }
1953
+ function createInjector(config = {}) {
1954
+ return new StyleInjector({
1955
+ ...getConfig(),
1956
+ forceTextInjection: config.forceTextInjection ?? isTestEnvironment(),
1957
+ ...config
1958
+ });
1959
+ }
1960
+ //#endregion
1961
+ //#region src/rsc-cache.ts
1962
+ const getRSCCache = cache(() => ({
1963
+ cacheKeyToClassName: /* @__PURE__ */ new Map(),
1964
+ emittedKeys: /* @__PURE__ */ new Set(),
1965
+ internalsEmitted: false,
1966
+ pendingCSS: [],
1967
+ keyToIndex: /* @__PURE__ */ new Map(),
1968
+ generatedNames: /* @__PURE__ */ new Map()
1969
+ }));
1970
+ function rscAllocateClassName(rscCache, cacheKey) {
1971
+ const existing = rscCache.cacheKeyToClassName.get(cacheKey);
1972
+ if (existing) return {
1973
+ className: existing,
1974
+ isNew: false
1975
+ };
1976
+ const className = makeClassName(getNamePrefix(), hashString(cacheKey));
1977
+ rscCache.cacheKeyToClassName.set(cacheKey, className);
1978
+ return {
1979
+ className,
1980
+ isNew: true
1981
+ };
1982
+ }
1983
+ function flushPendingCSS(rscCache) {
1984
+ if (rscCache.pendingCSS.length === 0) return "";
1985
+ const css = rscCache.pendingCSS.join("\n");
1986
+ rscCache.pendingCSS.length = 0;
1987
+ rscCache.keyToIndex.clear();
1988
+ return css;
1989
+ }
1990
+ function pushRSCCSS(rscCache, key, css, replace) {
1991
+ if (replace) {
1992
+ const pendingIndex = rscCache.keyToIndex.get(key);
1993
+ if (pendingIndex !== void 0) {
1994
+ rscCache.pendingCSS[pendingIndex] = css;
1995
+ return true;
1996
+ }
1997
+ } else if (rscCache.emittedKeys.has(key)) return false;
1998
+ rscCache.emittedKeys.add(key);
1999
+ rscCache.keyToIndex.set(key, rscCache.pendingCSS.length);
2000
+ rscCache.pendingCSS.push(css);
2001
+ return true;
2002
+ }
2003
+ function getStyleTarget() {
2004
+ const collector = getRegisteredSSRCollector();
2005
+ if (collector) return {
2006
+ mode: "ssr",
2007
+ collector
2008
+ };
2009
+ if (typeof document === "undefined") return {
2010
+ mode: "rsc",
2011
+ cache: getRSCCache()
2012
+ };
2013
+ return { mode: "client" };
2014
+ }
2015
+ //#endregion
2016
+ //#region src/ssr/collect-auto-properties.ts
2017
+ function scanAndEmitAutoProperties(rules, styles, emit) {
2018
+ const registered = /* @__PURE__ */ new Set();
2019
+ if (styles) {
2020
+ const localProps = styles["@property"];
2021
+ if (localProps && typeof localProps === "object") for (const token of Object.keys(localProps)) {
2022
+ const parsed = parsePropertyToken(token);
2023
+ if (parsed.isValid) registered.add(parsed.cssName);
2024
+ }
2025
+ }
2026
+ const resolver = new PropertyTypeResolver();
2027
+ for (const rule of rules) {
2028
+ if (!rule.declarations) continue;
2029
+ resolver.scanDeclarations(rule.declarations, (name) => registered.has(name), (name, syntax, initialValue) => {
2030
+ registered.add(name);
2031
+ const css = formatPropertyCSS(name, {
2032
+ syntax,
2033
+ inherits: true,
2034
+ initialValue
2035
+ });
2036
+ if (css) emit(name, css);
2037
+ });
2038
+ }
2039
+ }
2040
+ function collectAutoInferredProperties(rules, collector, styles) {
2041
+ scanAndEmitAutoProperties(rules, styles, (name, css) => {
2042
+ collector.collectProperty(`__auto:${name}`, css);
2043
+ });
2044
+ }
2045
+ function collectAutoInferredPropertiesRSC(rules, rscCache, styles) {
2046
+ scanAndEmitAutoProperties(rules, styles, (name, css) => {
2047
+ pushRSCCSS(rscCache, `__auto:${name}`, css);
2048
+ });
2049
+ }
2050
+ //#endregion
2051
+ //#region src/utils/has-keys.ts
2052
+ function hasKeys(obj) {
2053
+ for (const _ in obj) return true;
2054
+ return false;
2055
+ }
2056
+ //#endregion
2057
+ //#region src/utils/resolve-recipes.ts
2058
+ function resolveRecipes(styles) {
2059
+ return resolveRecipesWith(styles, getGlobalRecipes());
2060
+ }
2061
+ //#endregion
2062
+ //#region src/compute-styles.ts
2063
+ const EMPTY_RESULT = { className: "" };
2064
+ function collectAncillaryRSC(rscCache, styles, usedKf, keyframeNames) {
2065
+ const parts = [];
2066
+ if (usedKf && keyframeNames) for (const [authored, steps] of Object.entries(usedKf)) {
2067
+ const name = keyframeNames.get(authored);
2068
+ const key = `__kf:${name}`;
2069
+ if (!rscCache.emittedKeys.has(key)) {
2070
+ rscCache.emittedKeys.add(key);
2071
+ parts.push(formatKeyframesCSS(name, steps));
2072
+ }
2073
+ }
2074
+ const localProperties = extractLocalProperties(styles);
2075
+ if (localProperties) for (const [token, definition] of Object.entries(localProperties)) {
2076
+ const key = `__prop:${token}`;
2077
+ if (!rscCache.emittedKeys.has(key)) {
2078
+ rscCache.emittedKeys.add(key);
2079
+ const css = formatPropertyCSS(token, definition);
2080
+ if (css) parts.push(css);
2081
+ }
2082
+ }
2083
+ const localFontFace = extractLocalFontFace(styles);
2084
+ if (localFontFace) for (const [family, input] of Object.entries(localFontFace)) {
2085
+ const descriptors = Array.isArray(input) ? input : [input];
2086
+ for (const desc of descriptors) {
2087
+ const key = `__ff:${fontFaceContentHash(family, desc)}`;
2088
+ if (!rscCache.emittedKeys.has(key)) {
2089
+ rscCache.emittedKeys.add(key);
2090
+ parts.push(formatFontFaceRule(family, desc));
2091
+ }
2092
+ }
2093
+ }
2094
+ const localCounterStyle = extractLocalCounterStyle(styles);
2095
+ if (localCounterStyle) for (const [name, descriptors] of Object.entries(localCounterStyle)) {
2096
+ const key = `__cs:${name}:${JSON.stringify(descriptors)}`;
2097
+ if (!rscCache.emittedKeys.has(key)) {
2098
+ rscCache.emittedKeys.add(key);
2099
+ parts.push(formatCounterStyleRule(name, descriptors));
2100
+ }
2101
+ }
2102
+ if (!isFunctionsPolyfillEnabled()) {
2103
+ const localFunctions = extractLocalFunctions(styles);
2104
+ if (localFunctions) for (const [name, definition] of Object.entries(localFunctions)) {
2105
+ const key = `__func:${parseFunctionName(name)}`;
2106
+ if (!rscCache.emittedKeys.has(key)) {
2107
+ rscCache.emittedKeys.add(key);
2108
+ parts.push(formatFunctionRule(name, definition));
2109
+ }
2110
+ }
2111
+ }
2112
+ return parts.join("\n");
2113
+ }
2114
+ function computeStylesRSC(styles, chunkMap, stableStyles) {
2115
+ const rscCache = getRSCCache();
2116
+ const cssParts = [];
2117
+ const classNames = [];
2118
+ const rscUsedKf = getUsedKeyframes(styles);
2119
+ const rscKeyframeNames = rscUsedKf ? resolveKeyframesNames(rscUsedKf) : null;
2120
+ const pendingCSS = flushPendingCSS(rscCache);
2121
+ if (pendingCSS) cssParts.push(pendingCSS);
2122
+ rscCache.internalsEmitted = true;
2123
+ for (const [chunkName, chunkStyleKeys] of chunkMap) {
2124
+ if (chunkStyleKeys.length === 0) continue;
2125
+ const baseKey = generateChunkCacheKey(styles, chunkName, chunkStyleKeys, stableStyles);
2126
+ const renderResult = renderStylesForChunk(styles, chunkName, chunkStyleKeys);
2127
+ if (renderResult.rules.length === 0) continue;
2128
+ const { rules, cacheKey } = applyKeyframeNames(renderResult.rules, baseKey, rscKeyframeNames);
2129
+ const { className, isNew } = rscAllocateClassName(rscCache, cacheKey);
2130
+ classNames.push(className);
2131
+ if (isNew) {
2132
+ const css = formatRules(rules, className);
2133
+ if (css) cssParts.push(css);
2134
+ }
2135
+ }
2136
+ const ancillaryCSS = collectAncillaryRSC(rscCache, styles, rscUsedKf, rscKeyframeNames);
2137
+ if (ancillaryCSS) cssParts.push(ancillaryCSS);
2138
+ if (classNames.length === 0) return EMPTY_RESULT;
2139
+ const css = cssParts.join("\n");
2140
+ return {
2141
+ className: classNames.join(" "),
2142
+ css: css || void 0
2143
+ };
2144
+ }
2145
+ function getUsedKeyframes(styles) {
2146
+ const hasLocal = hasLocalKeyframes(styles);
2147
+ const hasGlobal = hasGlobalKeyframes();
2148
+ if (!hasLocal && !hasGlobal) return null;
2149
+ const usedNames = extractAnimationNamesFromStyles(styles);
2150
+ if (usedNames.size === 0) return null;
2151
+ return filterUsedKeyframes(mergeKeyframes(hasLocal ? extractLocalKeyframes(styles) : null, hasGlobal ? getGlobalKeyframes() : null), usedNames);
2152
+ }
2153
+ function processChunkSSR(collector, styles, chunkName, styleKeys, stableStyles, keyframeNames) {
2154
+ if (styleKeys.length === 0) return null;
2155
+ const baseKey = generateChunkCacheKey(styles, chunkName, styleKeys, stableStyles);
2156
+ const renderResult = renderStylesForChunk(styles, chunkName, styleKeys);
2157
+ if (renderResult.rules.length === 0) return null;
2158
+ const { rules, cacheKey } = applyKeyframeNames(renderResult.rules, baseKey, keyframeNames);
2159
+ const { className, isNewAllocation } = collector.allocateClassName(cacheKey);
2160
+ if (isNewAllocation) {
2161
+ collector.collectChunk(cacheKey, className, rules);
2162
+ return {
2163
+ className,
2164
+ rules
2165
+ };
2166
+ }
2167
+ return {
2168
+ className,
2169
+ rules: []
2170
+ };
2171
+ }
2172
+ function applyKeyframeNames(ruleset, baseKey, keyframeNames) {
2173
+ if (!keyframeNames || keyframeNames.size === 0) return {
2174
+ animations: [],
2175
+ rules: ruleset,
2176
+ cacheKey: baseKey
2177
+ };
2178
+ const usedNames = /* @__PURE__ */ new Set();
2179
+ let rules;
2180
+ for (let i = 0; i < ruleset.length; i++) {
2181
+ const rule = ruleset[i];
2182
+ const declarations = replaceAnimationNames(rule.declarations, keyframeNames, usedNames);
2183
+ if (declarations !== rule.declarations) {
2184
+ rules ??= ruleset.slice();
2185
+ rules[i] = {
2186
+ ...rule,
2187
+ declarations
2188
+ };
2189
+ }
2190
+ }
2191
+ const animations = [...keyframeNames.keys()].filter((authored) => usedNames.has(authored));
2192
+ if (animations.length === 0) return {
2193
+ animations,
2194
+ rules: ruleset,
2195
+ cacheKey: baseKey
2196
+ };
2197
+ const cacheKey = `${baseKey}\u0000kf:${animations.map((authored) => `${authored}=${keyframeNames.get(authored)}`).sort().join(",")}`;
2198
+ return {
2199
+ animations,
2200
+ rules: rules ?? ruleset,
2201
+ cacheKey
2202
+ };
2203
+ }
2204
+ function processChunkSync(styles, chunkName, styleKeys, stableStyles, root, keyframeNames) {
2205
+ if (styleKeys.length === 0) return null;
2206
+ const cacheKey = generateChunkCacheKey(styles, chunkName, styleKeys, stableStyles);
2207
+ const renderResult = renderStylesForChunk(styles, chunkName, styleKeys, cacheKey);
2208
+ if (renderResult.rules.length === 0) return null;
2209
+ const { animations, rules, cacheKey: injectKey } = applyKeyframeNames(renderResult.rules, cacheKey, keyframeNames);
2210
+ const { className } = inject(rules, {
2211
+ cacheKey: injectKey,
2212
+ root,
2213
+ pin: false
2214
+ });
2215
+ return {
2216
+ className,
2217
+ animations
2218
+ };
2219
+ }
2220
+ function injectAncillarySync(styles, root) {
2221
+ const localProperties = extractLocalProperties(styles);
2222
+ if (localProperties) for (const [token, definition] of Object.entries(localProperties)) property(token, {
2223
+ ...definition,
2224
+ root
2225
+ });
2226
+ const localFontFace = extractLocalFontFace(styles);
2227
+ if (localFontFace) for (const [family, input] of Object.entries(localFontFace)) {
2228
+ const descriptors = Array.isArray(input) ? input : [input];
2229
+ for (const desc of descriptors) fontFace(family, desc, { root });
2230
+ }
2231
+ const localCounterStyle = extractLocalCounterStyle(styles);
2232
+ if (localCounterStyle) for (const [name, descriptors] of Object.entries(localCounterStyle)) counterStyle(name, descriptors, { root });
2233
+ if (!isFunctionsPolyfillEnabled()) {
2234
+ const localFunctions = extractLocalFunctions(styles);
2235
+ if (localFunctions) for (const [name, definition] of Object.entries(localFunctions)) func(name, definition, { root });
2236
+ }
2237
+ }
2238
+ function collectAncillarySSR(collector, styles, chunks, usedKf, keyframeNames) {
2239
+ if (usedKf && keyframeNames) for (const [authored, steps] of Object.entries(usedKf)) {
2240
+ const name = keyframeNames.get(authored);
2241
+ collector.collectKeyframes(name, formatKeyframesCSS(name, steps));
2242
+ }
2243
+ const localProperties = extractLocalProperties(styles);
2244
+ if (localProperties) for (const [token, definition] of Object.entries(localProperties)) {
2245
+ const css = formatPropertyCSS(token, definition);
2246
+ if (css) collector.collectProperty(token, css);
2247
+ }
2248
+ const localFontFace = extractLocalFontFace(styles);
2249
+ if (localFontFace) for (const [family, input] of Object.entries(localFontFace)) {
2250
+ const descriptors = Array.isArray(input) ? input : [input];
2251
+ for (const desc of descriptors) {
2252
+ const hash = fontFaceContentHash(family, desc);
2253
+ const css = formatFontFaceRule(family, desc);
2254
+ collector.collectFontFace(hash, css);
2255
+ }
2256
+ }
2257
+ const localCounterStyle = extractLocalCounterStyle(styles);
2258
+ if (localCounterStyle) for (const [name, descriptors] of Object.entries(localCounterStyle)) {
2259
+ const css = formatCounterStyleRule(name, descriptors);
2260
+ collector.collectCounterStyle(name, css);
2261
+ }
2262
+ if (!isFunctionsPolyfillEnabled()) {
2263
+ const localFunctions = extractLocalFunctions(styles);
2264
+ if (localFunctions) for (const [name, definition] of Object.entries(localFunctions)) {
2265
+ const css = formatFunctionRule(name, definition);
2266
+ collector.collectFunction(parseFunctionName(name), css);
2267
+ }
2268
+ }
2269
+ if (getConfig().autoPropertyTypes !== false) {
2270
+ const allRules = chunks.flatMap((chunk) => chunk.rules ?? []);
2271
+ if (allRules.length > 0) collectAutoInferredProperties(allRules, collector, styles);
2272
+ }
2273
+ }
2274
+ function computeStyles(styles, options) {
2275
+ if (!styles || !hasKeys(styles)) return EMPTY_RESULT;
2276
+ const resolved = resolveRecipes(styles);
2277
+ const stableStyles = options?.stableStyles === true && resolved === styles;
2278
+ if (isFunctionsPolyfillEnabled()) registerLocalFunctionPolyfills(resolved);
2279
+ const chunkMap = categorizeStyleKeys(resolved);
2280
+ const collector = options?.ssrCollector !== void 0 ? options.ssrCollector : getRegisteredSSRCollector();
2281
+ const chunks = [];
2282
+ if (collector) {
2283
+ collector.collectInternals();
2284
+ const ssrKf = getUsedKeyframes(resolved);
2285
+ const ssrKeyframeNames = ssrKf ? resolveKeyframesNames(ssrKf) : null;
2286
+ for (const [chunkName, chunkStyleKeys] of chunkMap) {
2287
+ const chunk = processChunkSSR(collector, resolved, chunkName, chunkStyleKeys, stableStyles, ssrKeyframeNames);
2288
+ if (chunk) chunks.push(chunk);
2289
+ }
2290
+ collectAncillarySSR(collector, resolved, chunks, ssrKf, ssrKeyframeNames);
2291
+ } else if (typeof document === "undefined") return computeStylesRSC(resolved, chunkMap, stableStyles);
2292
+ else {
2293
+ const root = options?.root;
2294
+ injectAncillarySync(resolved, root);
2295
+ const usedKf = getUsedKeyframes(resolved);
2296
+ const keyframeNames = usedKf ? resolveKeyframesNames(usedKf) : null;
2297
+ const keyframeKeys = usedKf && keyframeNames ? holdKeyframes(usedKf, keyframeNames, { root }) : null;
2298
+ for (const [chunkName, chunkStyleKeys] of chunkMap) {
2299
+ const chunk = processChunkSync(resolved, chunkName, chunkStyleKeys, stableStyles, root, keyframeNames);
2300
+ if (chunk) chunks.push(chunk);
2301
+ }
2302
+ if (keyframeKeys) for (const chunk of chunks) for (const authored of chunk.animations ?? []) {
2303
+ const key = keyframeKeys.get(authored);
2304
+ if (key) ownKeyframes(key, chunk.className, { root });
2305
+ }
2306
+ for (const chunk of chunks) touch(chunk.className, { root });
2307
+ }
2308
+ if (chunks.length === 0) return EMPTY_RESULT;
2309
+ if (chunks.length === 1) return { className: chunks[0].className };
2310
+ return { className: chunks.map((c) => c.className).join(" ") };
2311
+ }
2312
+ //#endregion
2313
+ //#region src/utils/filter-base-props.ts
2314
+ const BasePropNames = new Set([
2315
+ "role",
2316
+ "as",
2317
+ "element",
2318
+ "css",
2319
+ "qa",
2320
+ "mods",
2321
+ "qaVal",
2322
+ "hidden",
2323
+ "isHidden",
2324
+ "disabled",
2325
+ "isDisabled",
2326
+ "children",
2327
+ "style",
2328
+ "className",
2329
+ "href",
2330
+ "target",
2331
+ "tabIndex"
2332
+ ]);
2333
+ const eventRe = /^on[A-Z].+$/;
2334
+ const ignoredEventProps = new Set([
2335
+ "onPress",
2336
+ "onHoverStart",
2337
+ "onHoverEnd",
2338
+ "onPressStart",
2339
+ "onPressEnd"
2340
+ ]);
2341
+ function filterBaseProps(props, opts = {}) {
2342
+ const { propNames, eventProps } = opts;
2343
+ const filteredProps = {};
2344
+ for (const prop of Object.keys(props)) if (prop === "id" || BasePropNames.has(prop) || prop.startsWith("aria-") || eventProps && eventRe.test(prop) && !ignoredEventProps.has(prop) || propNames?.has(prop) || prop.startsWith("data-")) filteredProps[prop] = props[prop];
2345
+ return filteredProps;
2346
+ }
2347
+ //#endregion
2348
+ //#region src/utils/mod-attrs.ts
2349
+ const cache$1 = new Lru();
2350
+ function modAttrs(map) {
2351
+ if (!map) return null;
2352
+ const cacheKey = JSON.stringify(map);
2353
+ const cached = cache$1.get(cacheKey);
2354
+ if (cached) return cached;
2355
+ const attrs = {};
2356
+ for (const key of Object.keys(map)) {
2357
+ const value = map[key];
2358
+ if (value == null || value === false) continue;
2359
+ const attrName = `data-${camelToKebab(key)}`;
2360
+ if (value === true) attrs[attrName] = "";
2361
+ else if (typeof value === "string") attrs[attrName] = value;
2362
+ else if (typeof value === "number") attrs[attrName] = String(value);
2363
+ else console.warn(`[Tasty] Invalid mod value for "${key}". Expected boolean, string, or number, got ${typeof value}`);
2364
+ }
2365
+ cache$1.set(cacheKey, attrs);
2366
+ return attrs;
2367
+ }
2368
+ //#endregion
2369
+ //#region src/utils/process-tokens.ts
2370
+ function isValidTokenValue(value) {
2371
+ if (value === void 0 || value === null || value === false) return false;
2372
+ if (typeof value === "object") {
2373
+ console.warn("[Tasty] Object values are not allowed in tokens prop. Tokens do not support state-based styling. Use a primitive value instead.");
2374
+ return false;
2375
+ }
2376
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
2377
+ }
2378
+ function processTokenValue(value) {
2379
+ if (typeof value === "number") {
2380
+ if (value === 0) return "0";
2381
+ return parseStyle(String(value)).output;
2382
+ }
2383
+ return parseStyle(value).output;
2384
+ }
2385
+ function resolveTokenEntry(key, value) {
2386
+ const name = `--${normalizeDslName(key.slice(1))}`;
2387
+ if (key[0] === "$") return [name, processTokenValue(value === true ? "" : value)];
2388
+ const colorValue = normalizeColorTokenValue(value);
2389
+ if (colorValue === null) return null;
2390
+ return [`${name}-color`, processTokenValue(colorValue)];
2391
+ }
2392
+ function processTokens(tokens) {
2393
+ if (!tokens) return;
2394
+ const keys = Object.keys(tokens);
2395
+ if (keys.length === 0) return;
2396
+ let result;
2397
+ for (const key of keys) {
2398
+ const value = tokens[key];
2399
+ if (!isValidTokenValue(value)) continue;
2400
+ if (key[0] !== "$" && key[0] !== "#") continue;
2401
+ const entry = resolveTokenEntry(key, value);
2402
+ if (!entry) continue;
2403
+ if (!result) result = {};
2404
+ result[entry[0]] = entry[1];
2405
+ }
2406
+ return result;
2407
+ }
2408
+ //#endregion
2409
+ //#region src/utils/client-state.ts
2410
+ function createClientState(create) {
2411
+ const byInjector = /* @__PURE__ */ new WeakMap();
2412
+ return (root) => {
2413
+ const injector = getGlobalInjector();
2414
+ let byRoot = byInjector.get(injector);
2415
+ if (!byRoot) {
2416
+ byRoot = /* @__PURE__ */ new WeakMap();
2417
+ byInjector.set(injector, byRoot);
2418
+ }
2419
+ let state = byRoot.get(root);
2420
+ if (!state) {
2421
+ state = create();
2422
+ byRoot.set(root, state);
2423
+ }
2424
+ return state;
2425
+ };
2426
+ }
2427
+ //#endregion
2428
+ //#region src/utils/deps-equal.ts
2429
+ function depsEqual(a, b) {
2430
+ if (a.length !== b.length) return false;
2431
+ for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return false;
2432
+ return true;
2433
+ }
2434
+ //#endregion
2435
+ export { propHandlerRegistry as $, ownKeyframes as A, getNamePrefix as B, holdKeyframes as C, injector as D, injectRawCSS as E, configure as F, resetConfig as G, hasGlobalRecipes as H, getConfig as I, closeBatchWindow as J, StyleInjector as K, getGlobalInjector as L, touch as M, ChunkSheetRegistry as N, isPropertyDefined as O, chunkSheetRegistry as P, resetStyleBatch as Q, getGlobalKeyframes as R, getRawCSSText as S, injectGlobal as T, isConfigLocked as U, hasGlobalKeyframes as V, isTestEnvironment as W, hasPendingStyleWrites as X, flushStyles as Y, openBatchWindow as Z, fontFace as _, filterBaseProps as a, getCSSText as b, hasKeys as c, getStyleTarget as d, pushRSCCSS as f, destroy as g, createInjector as h, modAttrs as i, property as j, keyframes as k, collectAutoInferredProperties as l, counterStyle as m, createClientState as n, computeStyles as o, cleanup as p, SheetManager as q, processTokens as r, resolveRecipes as s, depsEqual as t, collectAutoInferredPropertiesRSC as u, func as v, inject as w, getCSSTextForNode as x, gc as y, getGlobalRecipes as z };
2436
+
2437
+ //# sourceMappingURL=runtime-engine-DvnE2g-E.js.map