@tenphi/tasty 0.0.0-snapshot.61865f6 → 0.0.0-snapshot.6b4c7b6
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.
- package/README.md +2 -2
- package/dist/debug.js +1 -1
- package/dist/debug.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/pipeline/index.js +47 -43
- package/dist/pipeline/index.js.map +1 -1
- package/dist/pipeline/materialize.js +37 -81
- package/dist/pipeline/materialize.js.map +1 -1
- package/dist/pipeline/parseStateKey.js +10 -0
- package/dist/pipeline/parseStateKey.js.map +1 -1
- package/dist/pipeline/simplify.js +43 -58
- package/dist/pipeline/simplify.js.map +1 -1
- package/dist/pipeline/warnings.js +18 -0
- package/dist/pipeline/warnings.js.map +1 -0
- package/dist/styles/align.d.ts +1 -1
- package/dist/styles/align.js.map +1 -1
- package/dist/styles/border.d.ts +1 -1
- package/dist/styles/border.js.map +1 -1
- package/dist/styles/color.d.ts +2 -2
- package/dist/styles/color.js.map +1 -1
- package/dist/styles/createStyle.js +1 -1
- package/dist/styles/createStyle.js.map +1 -1
- package/dist/styles/fade.d.ts +1 -1
- package/dist/styles/fade.js.map +1 -1
- package/dist/styles/fill.d.ts +14 -16
- package/dist/styles/fill.js.map +1 -1
- package/dist/styles/flow.d.ts +3 -3
- package/dist/styles/flow.js.map +1 -1
- package/dist/styles/justify.d.ts +1 -1
- package/dist/styles/justify.js.map +1 -1
- package/dist/styles/predefined.js.map +1 -1
- package/dist/styles/radius.d.ts +1 -1
- package/dist/styles/radius.js.map +1 -1
- package/dist/styles/scrollbar.d.ts +1 -1
- package/dist/styles/scrollbar.js +19 -12
- package/dist/styles/scrollbar.js.map +1 -1
- package/dist/styles/shadow.d.ts +2 -2
- package/dist/styles/shadow.js.map +1 -1
- package/dist/styles/styledScrollbar.d.ts +1 -1
- package/dist/styles/styledScrollbar.js.map +1 -1
- package/dist/styles/transition.d.ts +1 -1
- package/dist/styles/transition.js.map +1 -1
- package/dist/tasty.d.ts +8 -8
- package/dist/types.d.ts +2 -2
- package/dist/utils/colors.d.ts +1 -1
- package/dist/utils/colors.js.map +1 -1
- package/dist/utils/css-types.d.ts +1 -1
- package/dist/utils/dotize.d.ts +1 -1
- package/dist/utils/mod-attrs.js.map +1 -1
- package/dist/utils/string.js.map +1 -1
- package/dist/utils/styles.d.ts +7 -12
- package/dist/utils/styles.js +13 -8
- package/dist/utils/styles.js.map +1 -1
- package/package.json +48 -2
package/README.md
CHANGED
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
Most CSS-in-JS libraries
|
|
20
|
+
Most CSS-in-JS libraries emit rules that compete through cascade and specificity. Tasty emits **mutually exclusive CSS selectors** — for any component state combination, exactly one selector matches each property at a time. No cascade conflicts, no specificity wars, no `!important` escapes. Components compose and extend without breaking each other.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
That guarantee unlocks a concise, CSS-like DSL where design tokens, custom units, responsive states, container queries, sub-element styling, and theming all compose without surprises — one coherent system that scales from a single component to an enterprise design system.
|
|
23
23
|
|
|
24
24
|
## Why Tasty
|
|
25
25
|
|
package/dist/debug.js
CHANGED
|
@@ -665,7 +665,7 @@ const tastyDebug = {
|
|
|
665
665
|
const ruleCount = (css.match(/\{/g) || []).length;
|
|
666
666
|
console.group(`🎨 ${displayTitle} (${ruleCount} rules, ${lines} lines, ${sizeStr})`);
|
|
667
667
|
const subElementMatches = css.match(/\[data-element="([^"]+)"\]/g) || [];
|
|
668
|
-
const subElements = [...new Set(subElementMatches.map((match) => match.match(/\[data-element="([^"]+)"\]/)?.[1]).filter(
|
|
668
|
+
const subElements = [...new Set(subElementMatches.map((match) => match.match(/\[data-element="([^"]+)"\]/)?.[1]).filter((v) => !!v))];
|
|
669
669
|
if (subElements.length > 0) {
|
|
670
670
|
console.log(`🧩 Sub-elements found: ${subElements.join(", ")}`);
|
|
671
671
|
subElements.forEach((element) => {
|
package/dist/debug.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug.js","names":[],"sources":["../src/debug.ts"],"sourcesContent":["/* eslint-disable no-console */\n/**\n * Debug utilities for inspecting tasty-generated CSS at runtime\n */\n\nimport { CHUNK_NAMES } from './chunks/definitions';\nimport { getCssTextForNode, injector } from './injector';\nimport type { CleanupStats } from './injector/types';\nimport { isDevEnv } from './utils/is-dev-env';\n\ndeclare global {\n interface Window {\n tastyDebug?: typeof tastyDebug;\n }\n}\n\n// Type definitions for the new API\ntype CSSTarget =\n | 'all' // tasty CSS + tasty global CSS + raw CSS\n | 'global' // only tasty global CSS\n | 'active' // tasty CSS for classes currently in DOM\n | 'unused' // tasty CSS with refCount = 0 (still in cache but not actively used)\n | 'page' // ALL CSS on the page across stylesheets (not only tasty)\n | string // 't123' tasty class or a CSS selector\n | string[] // array of tasty classes like ['t1', 't2']\n | Element; // a DOM element\n\ninterface CssOptions {\n root?: Document | ShadowRoot;\n prettify?: boolean; // default: true\n log?: boolean; // default: false\n}\n\ninterface ChunkInfo {\n className: string;\n chunkName: string | null;\n}\n\ninterface InspectResult {\n element?: Element | null;\n classes: string[]; // tasty classes found on the element\n chunks: ChunkInfo[]; // chunk information per class (with chunking enabled)\n css: string; // full, prettified CSS affecting the element\n size: number; // characters in css\n rules: number; // number of rule blocks\n}\n\ninterface CacheMetrics {\n hits: number;\n misses: number;\n bulkCleanups: number;\n totalInsertions: number;\n totalUnused: number;\n stylesCleanedUp: number;\n cleanupHistory: {\n timestamp: number;\n classesDeleted: number;\n cssSize: number;\n rulesDeleted: number;\n }[];\n startTime: number;\n\n // Calculated metrics\n unusedHits?: number; // calculated as current unused count\n}\n\ninterface CacheStatus {\n classes: {\n active: string[]; // classes with refCount > 0 and present in DOM\n unused: string[]; // classes with refCount = 0 but still in cache\n all: string[]; // union of both\n };\n metrics: CacheMetrics | null;\n}\n\ninterface Definitions {\n properties: string[]; // defined via @property\n keyframes: { name: string; refCount: number }[];\n}\n\ninterface SummaryOptions {\n root?: Document | ShadowRoot;\n log?: boolean;\n includePageCSS?:\n | false // do not include page-level CSS stats (default)\n | true // include sizes/counts only\n | 'all'; // include stats and return full page CSS string\n}\n\ninterface Summary {\n // Classes\n activeClasses: string[];\n unusedClasses: string[];\n totalStyledClasses: string[];\n\n // Tasty CSS sizes\n activeCSSSize: number;\n unusedCSSSize: number;\n globalCSSSize: number; // injectGlobal() CSS\n rawCSSSize: number; // injectRawCSS() / useRawCSS() CSS\n keyframesCSSSize: number; // @keyframes CSS\n propertyCSSSize: number; // @property CSS\n totalCSSSize: number; // all tasty CSS (active + unused + global + raw + keyframes + property)\n\n // Tasty CSS payloads\n activeCSS: string;\n unusedCSS: string;\n globalCSS: string; // injectGlobal() CSS\n rawCSS: string; // injectRawCSS() / useRawCSS() CSS\n keyframesCSS: string; // @keyframes CSS\n propertyCSS: string; // @property CSS\n allCSS: string; // all tasty CSS combined\n\n // Rule counts\n globalRuleCount: number;\n rawRuleCount: number;\n keyframesRuleCount: number;\n propertyRuleCount: number;\n\n // Page-level CSS (across all stylesheets, not only tasty) — shown when includePageCSS != false\n page?: {\n css?: string; // present only when includePageCSS === 'all'\n cssSize: number; // total characters\n ruleCount: number; // approximate rule count\n stylesheetCount: number; // stylesheets scanned (CORS-safe)\n skippedStylesheets: number; // stylesheets skipped due to cross-origin/CORS\n };\n\n // Metrics & definitions\n metrics: CacheMetrics | null;\n definedProperties: string[];\n definedKeyframes: { name: string; refCount: number }[];\n propertyCount: number;\n keyframeCount: number;\n\n // Cleanup summary\n cleanupSummary: {\n enabled: boolean;\n totalCleanups: number;\n totalClassesDeleted: number;\n totalCssDeleted: number;\n totalRulesDeleted: number;\n averageClassesPerCleanup: number;\n averageCssPerCleanup: number;\n averageRulesPerCleanup: number;\n lastCleanup?: {\n timestamp: number;\n date: string;\n classesDeleted: number;\n cssSize: number;\n rulesDeleted: number;\n };\n };\n\n // Chunk breakdown (style chunking optimization)\n chunkBreakdown: {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n };\n}\n\n/**\n * Pretty-print CSS with proper indentation and formatting\n */\nfunction prettifyCSS(css: string): string {\n if (!css || css.trim() === '') {\n return '';\n }\n\n // First, normalize whitespace but preserve structure\n let formatted = css.replace(/\\s+/g, ' ').trim();\n\n // Add newlines after opening braces\n formatted = formatted.replace(/\\s*\\{\\s*/g, ' {\\n');\n\n // Add newlines after semicolons (but not inside strings or functions)\n formatted = formatted.replace(/;(?![^\"']*[\"'][^\"']*$)(?![^()]*\\))/g, ';\\n');\n\n // Add newlines before closing braces\n formatted = formatted.replace(/\\s*\\}\\s*/g, '\\n}\\n');\n\n // Handle comma-separated selectors (only outside of property values)\n // This regex looks for commas that are:\n // 1. Not inside quotes\n // 2. Not inside parentheses (CSS functions)\n // 3. Not followed by a colon (not in a property value)\n formatted = formatted.replace(\n /,(?![^\"']*[\"'][^\"']*$)(?![^()]*\\))(?=.*:.*\\{|.*\\{)/g,\n ',\\n',\n );\n\n // Process line by line for proper indentation\n const lines = formatted.split('\\n');\n let indentLevel = 0;\n const indentSize = 2;\n\n const formattedLines = lines.map((line) => {\n const trimmed = line.trim();\n if (!trimmed) return '';\n\n // Handle closing braces - decrease indent first\n if (trimmed === '}') {\n indentLevel = Math.max(0, indentLevel - 1);\n return ' '.repeat(indentLevel * indentSize) + trimmed;\n }\n\n // Current line with proper indentation\n const indent = ' '.repeat(indentLevel * indentSize);\n const result = indent + trimmed;\n\n // Handle opening braces - increase indent for next line\n if (trimmed.endsWith('{')) {\n indentLevel++;\n }\n\n return result;\n });\n\n // Clean up the result and ensure proper spacing\n let result = formattedLines\n .filter((line) => line.trim()) // Remove empty lines\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n') // Max 2 consecutive newlines\n .trim();\n\n // Final cleanup: ensure single spaces in function calls\n result = result.replace(/,\\s+/g, ', ');\n\n return result;\n}\n\n// Helper functions\nfunction findAllTastyClasses(root: Document | ShadowRoot = document): string[] {\n const classes = new Set<string>();\n const elements = (root as Document).querySelectorAll?.('[class]') || [];\n\n elements.forEach((element) => {\n const classList = element.getAttribute('class');\n if (classList) {\n const tastyClasses = classList\n .split(/\\s+/)\n .filter((cls) => /^t\\d+$/.test(cls));\n tastyClasses.forEach((cls) => classes.add(cls));\n }\n });\n\n return Array.from(classes).sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n}\n\nfunction findAllStyledClasses(\n root: Document | ShadowRoot = document,\n): string[] {\n // Extract tasty classes from all CSS text by parsing selectors\n const allCSS = injector.instance.getCssText({ root });\n const classes = new Set<string>();\n\n // Simple regex to find .t{number} class selectors\n const classRegex = /\\.t(\\d+)/g;\n let match;\n while ((match = classRegex.exec(allCSS)) !== null) {\n classes.add(`t${match[1]}`);\n }\n\n return Array.from(classes).sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n}\n\nfunction extractCSSRules(\n css: string,\n): { selector: string; declarations: string }[] {\n const rules: { selector: string; declarations: string }[] = [];\n\n // Remove comments\n const cleanCSS = css.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n\n let i = 0;\n while (i < cleanCSS.length) {\n // Skip whitespace\n while (i < cleanCSS.length && /\\s/.test(cleanCSS[i])) {\n i++;\n }\n if (i >= cleanCSS.length) break;\n\n // Find selector start\n const selectorStart = i;\n let braceDepth = 0;\n let inString = false;\n let stringChar = '';\n\n // Find opening brace\n while (i < cleanCSS.length) {\n const char = cleanCSS[i];\n if (inString) {\n if (char === stringChar && cleanCSS[i - 1] !== '\\\\') {\n inString = false;\n }\n } else {\n if (char === '\"' || char === \"'\") {\n inString = true;\n stringChar = char;\n } else if (char === '{') {\n braceDepth++;\n if (braceDepth === 1) break;\n }\n }\n i++;\n }\n\n if (i >= cleanCSS.length) break;\n const selector = cleanCSS.substring(selectorStart, i).trim();\n i++; // Skip opening brace\n\n // Find matching closing brace\n const contentStart = i;\n braceDepth = 1;\n inString = false;\n\n while (i < cleanCSS.length && braceDepth > 0) {\n const char = cleanCSS[i];\n if (inString) {\n if (char === stringChar && cleanCSS[i - 1] !== '\\\\') {\n inString = false;\n }\n } else {\n if (char === '\"' || char === \"'\") {\n inString = true;\n stringChar = char;\n } else if (char === '{') {\n braceDepth++;\n } else if (char === '}') {\n braceDepth--;\n }\n }\n i++;\n }\n\n const content = cleanCSS.substring(contentStart, i - 1).trim();\n if (content && selector) {\n rules.push({ selector, declarations: content });\n }\n }\n\n return rules;\n}\n\nfunction getGlobalCSS(root: Document | ShadowRoot = document): string {\n const allCSS = injector.instance.getCssText({ root });\n const rules = extractCSSRules(allCSS);\n\n const globalRules = rules.filter((rule) => {\n const selectors = rule.selector.split(',').map((s) => s.trim());\n return !selectors.every((selector) => {\n const cleanSelector = selector.replace(/[.#:\\s>+~[\\]()]/g, ' ');\n const parts = cleanSelector.split(/\\s+/).filter(Boolean);\n return parts.length > 0 && parts.every((part) => /^t\\d+$/.test(part));\n });\n });\n\n const globalCSS = globalRules\n .map((rule) => `${rule.selector} { ${rule.declarations} }`)\n .join('\\n');\n return prettifyCSS(globalCSS);\n}\n\nfunction getPageCSS(options?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n}): string {\n const root = options?.root || document;\n const includeCrossOrigin = options?.includeCrossOrigin ?? false;\n\n const cssChunks: string[] = [];\n\n try {\n if ('styleSheets' in root) {\n const styleSheets = Array.from((root as Document).styleSheets);\n\n for (const sheet of styleSheets) {\n try {\n if (sheet.cssRules) {\n const rules = Array.from(sheet.cssRules);\n cssChunks.push(rules.map((rule) => rule.cssText).join('\\n'));\n }\n } catch {\n // Cross-origin sheet or other access error\n if (includeCrossOrigin) {\n cssChunks.push(\n `/* Cross-origin stylesheet: ${sheet.href || 'inline'} */`,\n );\n }\n }\n }\n }\n } catch {\n // Fallback error handling\n }\n\n return cssChunks.join('\\n');\n}\n\nfunction getPageStats(options?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n}): {\n cssSize: number;\n ruleCount: number;\n stylesheetCount: number;\n skippedStylesheets: number;\n} {\n const root = options?.root || document;\n\n const _includeCrossOrigin = options?.includeCrossOrigin ?? false;\n\n let cssSize = 0;\n let ruleCount = 0;\n let stylesheetCount = 0;\n let skippedStylesheets = 0;\n\n try {\n if ('styleSheets' in root) {\n const styleSheets = Array.from((root as Document).styleSheets);\n stylesheetCount = styleSheets.length;\n\n for (const sheet of styleSheets) {\n try {\n if (sheet.cssRules) {\n const rules = Array.from(sheet.cssRules);\n ruleCount += rules.length;\n cssSize += rules.reduce(\n (sum, rule) => sum + rule.cssText.length,\n 0,\n );\n }\n } catch {\n skippedStylesheets++;\n }\n }\n }\n } catch {\n // Fallback error handling\n }\n\n return { cssSize, ruleCount, stylesheetCount, skippedStylesheets };\n}\n\n// ============================================================================\n// Chunk-aware helpers (for style chunking optimization)\n// ============================================================================\n\n/**\n * Extract chunk name from a cache key.\n *\n * Cache keys have the format: \"chunkName\\0key:value\\0key:value...\"\n * or \"[states:...]\\0chunkName\\0...\" for predefined states.\n *\n * @param cacheKey - The cache key to parse\n * @returns The chunk name, or null if not found\n */\nfunction extractChunkNameFromCacheKey(cacheKey: string): string | null {\n // Cache keys are separated by \\0 (null character)\n const parts = cacheKey.split('\\0');\n\n for (const part of parts) {\n // Skip predefined states prefix\n if (part.startsWith('[states:')) continue;\n // First non-states part that doesn't contain : is the chunk name\n if (!part.includes(':') && part.length > 0) {\n return part;\n }\n }\n return null;\n}\n\n/**\n * Get chunk info for a className by reverse-looking up its cache key.\n *\n * @param className - The tasty class name (e.g., \"t0\", \"t123\")\n * @param root - The document or shadow root to search in\n * @returns Object with chunk name and cache key, or nulls if not found\n */\nfunction getChunkForClassName(\n className: string,\n root: Document | ShadowRoot = document,\n): { chunkName: string | null; cacheKey: string | null } {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (!registry) {\n return { chunkName: null, cacheKey: null };\n }\n\n // Reverse lookup: find the cache key for this className\n for (const [cacheKey, cn] of registry.cacheKeyToClassName) {\n if (cn === className) {\n return {\n chunkName: extractChunkNameFromCacheKey(cacheKey),\n cacheKey,\n };\n }\n }\n return { chunkName: null, cacheKey: null };\n}\n\n/**\n * Get chunk breakdown statistics for all styles.\n *\n * @param root - The document or shadow root to search in\n * @returns Object with breakdown by chunk type and totals\n */\nfunction getChunkBreakdown(root: Document | ShadowRoot = document): {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n} {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n\n if (!registry) {\n return {\n byChunk: {},\n totalChunkTypes: 0,\n };\n }\n\n const byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n > = {};\n\n // Group classes by chunk\n for (const [cacheKey, className] of registry.cacheKeyToClassName) {\n const chunkName = extractChunkNameFromCacheKey(cacheKey) || 'unknown';\n\n if (!byChunk[chunkName]) {\n byChunk[chunkName] = { classes: [], cssSize: 0, ruleCount: 0 };\n }\n\n byChunk[chunkName].classes.push(className);\n\n // Get CSS for this class\n const css = injector.instance.getCssTextForClasses([className], { root });\n byChunk[chunkName].cssSize += css.length;\n byChunk[chunkName].ruleCount += (css.match(/\\{[^}]*\\}/g) || []).length;\n }\n\n // Sort classes within each chunk for consistency\n for (const entry of Object.values(byChunk)) {\n entry.classes.sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n }\n\n return {\n byChunk,\n totalChunkTypes: Object.keys(byChunk).length,\n };\n}\n\n/**\n * Concise tastyDebug API for inspecting styles at runtime\n */\nexport const tastyDebug = {\n // 1) One function to get CSS from anywhere\n css(target: CSSTarget, opts?: CssOptions): string {\n const { root = document, prettify = true, log = false } = opts || {};\n let css = '';\n\n if (typeof target === 'string') {\n if (target === 'all') {\n css = injector.instance.getCssText({ root });\n } else if (target === 'global') {\n css = getGlobalCSS(root);\n } else if (target === 'active') {\n const activeClasses = findAllTastyClasses(root);\n css = injector.instance.getCssTextForClasses(activeClasses, { root });\n } else if (target === 'unused') {\n // Get unused classes (refCount = 0) from the registry\n const registry = injector.instance._sheetManager?.getRegistry(root);\n const unusedClasses: string[] = registry\n ? Array.from(\n registry.refCounts.entries() as IterableIterator<\n [string, number]\n >,\n )\n .filter(([, refCount]: [string, number]) => refCount === 0)\n .map(([className]: [string, number]) => className)\n : [];\n css = injector.instance.getCssTextForClasses(unusedClasses, { root });\n } else if (target === 'page') {\n css = getPageCSS({ root, includeCrossOrigin: true });\n } else if (/^t\\d+$/.test(target)) {\n // Single tasty class\n css = injector.instance.getCssTextForClasses([target], { root });\n } else {\n // CSS selector - find element and get its CSS\n const element = (root as Document).querySelector?.(target);\n if (element) {\n css = getCssTextForNode(element, { root });\n }\n }\n } else if (Array.isArray(target)) {\n // Array of tasty classes\n css = injector.instance.getCssTextForClasses(target, { root });\n } else if (target instanceof Element) {\n // DOM element\n css = getCssTextForNode(target, { root });\n }\n\n const result = prettify ? prettifyCSS(css) : css;\n\n if (log) {\n console.group(\n `🎨 CSS for ${Array.isArray(target) ? `[${target.join(', ')}]` : target}`,\n );\n console.log(result || '(empty)');\n console.groupEnd();\n }\n\n return result;\n },\n\n // 2) Element-level inspection\n inspect(\n target: string | Element,\n opts?: { root?: Document | ShadowRoot },\n ): InspectResult {\n const { root = document } = opts || {};\n const element =\n typeof target === 'string'\n ? (root as Document).querySelector?.(target)\n : target;\n\n if (!element) {\n return {\n element: null,\n classes: [],\n chunks: [],\n css: '',\n size: 0,\n rules: 0,\n };\n }\n\n const classList = element.getAttribute('class') || '';\n const tastyClasses = classList\n .split(/\\s+/)\n .filter((cls) => /^t\\d+$/.test(cls));\n\n // Get chunk info for each tasty class\n const chunks: ChunkInfo[] = tastyClasses.map((className) => ({\n className,\n chunkName: getChunkForClassName(className, root).chunkName,\n }));\n\n const css = getCssTextForNode(element, { root });\n const prettifiedCSS = prettifyCSS(css);\n const ruleCount = (css.match(/\\{[^}]*\\}/g) || []).length;\n\n return {\n element,\n classes: tastyClasses,\n chunks,\n css: prettifiedCSS,\n size: css.length,\n rules: ruleCount,\n };\n },\n\n // 3) Cache + metrics at a glance\n cache(opts?: {\n root?: Document | ShadowRoot;\n includeHistory?: boolean;\n }): CacheStatus {\n const { root = document } = opts || {};\n const activeClasses = findAllTastyClasses(root);\n\n const _allClasses = findAllStyledClasses(root);\n // Get unused classes (refCount = 0) from the registry\n const registry = injector.instance._sheetManager?.getRegistry(root);\n const unusedClasses: string[] = registry\n ? Array.from(\n registry.refCounts.entries() as IterableIterator<[string, number]>,\n )\n .filter(([, refCount]: [string, number]) => refCount === 0)\n .map(([className]: [string, number]) => className)\n : [];\n\n return {\n classes: {\n active: activeClasses,\n unused: unusedClasses,\n all: [...activeClasses, ...unusedClasses],\n },\n metrics: injector.instance.getMetrics({ root }),\n };\n },\n\n // 4) Cleanup + metrics utilities\n cleanup(opts?: { root?: Document | ShadowRoot }): void {\n const { root } = opts || {};\n injector.instance.cleanup(root);\n },\n\n metrics(opts?: { root?: Document | ShadowRoot }): CacheMetrics | null {\n const { root } = opts || {};\n return injector.instance.getMetrics({ root });\n },\n\n resetMetrics(opts?: { root?: Document | ShadowRoot }): void {\n const { root } = opts || {};\n injector.instance.resetMetrics({ root });\n },\n\n // 5) Chunk breakdown (style chunking optimization)\n /**\n * Get breakdown of styles by chunk type.\n *\n * With style chunking enabled, styles are split into logical chunks\n * (appearance, font, dimension, container, etc.) for better caching\n * and CSS reuse.\n *\n * @param opts - Options including root document/shadow root\n * @returns Breakdown by chunk type with class counts and CSS sizes\n */\n chunks(opts?: { root?: Document | ShadowRoot; log?: boolean }): {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n totalClasses: number;\n } {\n const { root = document, log = false } = opts || {};\n const breakdown = getChunkBreakdown(root);\n\n const totalClasses = Object.values(breakdown.byChunk).reduce(\n (sum, entry) => sum + entry.classes.length,\n 0,\n );\n\n if (log) {\n console.group('🧩 Style Chunk Breakdown');\n\n // Define display order matching CHUNK_NAMES\n const displayOrder = [\n CHUNK_NAMES.COMBINED, // non-chunked styles (e.g., @starting-style)\n CHUNK_NAMES.APPEARANCE,\n CHUNK_NAMES.FONT,\n CHUNK_NAMES.DIMENSION,\n CHUNK_NAMES.DISPLAY,\n CHUNK_NAMES.LAYOUT,\n CHUNK_NAMES.POSITION,\n CHUNK_NAMES.MISC,\n CHUNK_NAMES.SUBCOMPONENTS,\n ];\n\n // Show chunks in order\n for (const chunkName of displayOrder) {\n const data = breakdown.byChunk[chunkName];\n if (data) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n\n // Show any unknown chunks\n for (const [chunkName, data] of Object.entries(breakdown.byChunk)) {\n if (\n !displayOrder.includes(chunkName as (typeof displayOrder)[number])\n ) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n\n console.log(\n `📊 Total: ${totalClasses} classes across ${breakdown.totalChunkTypes} chunk types`,\n );\n console.groupEnd();\n }\n\n return {\n ...breakdown,\n totalClasses,\n };\n },\n\n // 6) Get CSS for specific global types\n getGlobalTypeCSS(\n type: 'global' | 'raw' | 'keyframes' | 'property',\n opts?: { root?: Document | ShadowRoot },\n ): { css: string; ruleCount: number; size: number } {\n const { root = document } = opts || {};\n const registry = injector.instance._sheetManager?.getRegistry(root);\n\n if (!registry) {\n return { css: '', ruleCount: 0, size: 0 };\n }\n\n const cssChunks: string[] = [];\n let ruleCount = 0;\n\n if (type === 'keyframes') {\n // Handle keyframes separately - they're stored in keyframesCache\n for (const [, entry] of registry.keyframesCache) {\n const info = entry.info;\n const sheet = registry.sheets[info.sheetIndex];\n const styleSheet = sheet?.sheet?.sheet;\n\n if (styleSheet && info.ruleIndex < styleSheet.cssRules.length) {\n const rule = styleSheet.cssRules[info.ruleIndex] as\n | CSSRule\n | undefined;\n if (rule) {\n cssChunks.push(rule.cssText);\n ruleCount++;\n }\n } else if (info.cssText) {\n cssChunks.push(info.cssText);\n ruleCount++;\n }\n }\n } else {\n // Handle other global types stored in globalRules\n const prefix =\n type === 'global' ? 'global:' : type === 'raw' ? 'raw:' : 'property:';\n\n for (const [key, ruleInfo] of registry.globalRules) {\n if (key.startsWith(prefix)) {\n const sheet = registry.sheets[ruleInfo.sheetIndex];\n const styleSheet = sheet?.sheet?.sheet;\n if (styleSheet) {\n const start = Math.max(0, ruleInfo.ruleIndex);\n const end = Math.min(\n styleSheet.cssRules.length - 1,\n (ruleInfo.endRuleIndex as number) ?? ruleInfo.ruleIndex,\n );\n\n if (\n start >= 0 &&\n end >= start &&\n start < styleSheet.cssRules.length\n ) {\n for (let i = start; i <= end; i++) {\n const rule = styleSheet.cssRules[i] as CSSRule | undefined;\n if (rule) {\n cssChunks.push(rule.cssText);\n ruleCount++;\n }\n }\n }\n } else if (ruleInfo.cssText && ruleInfo.cssText.length) {\n // Fallback in environments without CSSOM access\n cssChunks.push(...ruleInfo.cssText);\n ruleCount += ruleInfo.cssText.length;\n }\n }\n }\n }\n\n const rawCSS = cssChunks.join('\\n');\n\n return {\n css: prettifyCSS(rawCSS),\n ruleCount,\n size: rawCSS.length, // Use raw CSS size for consistent calculations\n };\n },\n\n // 6) Defined @property and keyframes\n defs(opts?: { root?: Document | ShadowRoot }): Definitions {\n const { root = document } = opts || {};\n\n // Get properties from injector if available, otherwise scan CSS\n let properties: string[] = [];\n try {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (registry?.injectedProperties) {\n properties = Array.from(\n (registry.injectedProperties as Map<string, string>).keys(),\n ).sort();\n }\n } catch {\n // Fallback: scan CSS for @property rules\n const allCSS = injector.instance.getCssText({ root });\n const propRegex = /@property\\s+(--[a-z0-9-]+)/gi;\n const propSet = new Set<string>();\n let match;\n while ((match = propRegex.exec(allCSS)) !== null) {\n propSet.add(match[1]);\n }\n properties = Array.from(propSet).sort();\n }\n\n // Get keyframes\n let keyframes: { name: string; refCount: number }[] = [];\n try {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (registry) {\n for (const entry of registry.keyframesCache.values()) {\n keyframes.push({\n name: entry.name,\n refCount: entry.refCount,\n });\n }\n keyframes.sort((a, b) => a.name.localeCompare(b.name));\n }\n } catch {\n // Fallback: scan CSS for @keyframes rules\n const allCSS = injector.instance.getCssText({ root });\n const keyframesRegex = /@keyframes\\s+([a-zA-Z0-9_-]+)/gi;\n const keyframesSet = new Set<string>();\n let match;\n while ((match = keyframesRegex.exec(allCSS)) !== null) {\n keyframesSet.add(match[1]);\n }\n keyframes = Array.from(keyframesSet)\n .sort()\n .map((name) => ({ name, refCount: 1 }));\n }\n\n return { properties, keyframes };\n },\n\n // 7) One-shot overview\n summary(opts?: SummaryOptions): Summary {\n const { root = document, log = false, includePageCSS = false } = opts || {};\n const cacheStatus = this.cache({ root });\n const definitions = this.defs({ root });\n const metrics = this.metrics({ root });\n\n const activeCSS = this.css('active', { root, prettify: false });\n const unusedCSS = this.css('unused', { root, prettify: false });\n const allCSS = this.css('all', { root, prettify: false });\n\n // Calculate global CSS by subtracting class-based CSS from total\n const classCSSSize = activeCSS.length + unusedCSS.length;\n const totalGlobalCSSSize = allCSS.length - classCSSSize;\n\n // Get CSS for each global type separately for display purposes\n const globalData = this.getGlobalTypeCSS('global', { root });\n const rawData = this.getGlobalTypeCSS('raw', { root });\n const keyframesData = this.getGlobalTypeCSS('keyframes', { root });\n const propertyData = this.getGlobalTypeCSS('property', { root });\n\n // Use the calculated sizes to avoid double-counting\n const globalTypesTotalSize =\n globalData.size + rawData.size + keyframesData.size + propertyData.size;\n\n // Build cleanup summary from metrics\n const cleanupSummary = {\n enabled: !!metrics,\n totalCleanups: metrics?.cleanupHistory?.length || 0,\n totalClassesDeleted:\n metrics?.cleanupHistory?.reduce(\n (sum, c) => sum + c.classesDeleted,\n 0,\n ) || 0,\n totalCssDeleted:\n metrics?.cleanupHistory?.reduce((sum, c) => sum + c.cssSize, 0) || 0,\n totalRulesDeleted:\n metrics?.cleanupHistory?.reduce((sum, c) => sum + c.rulesDeleted, 0) ||\n 0,\n averageClassesPerCleanup: 0,\n averageCssPerCleanup: 0,\n averageRulesPerCleanup: 0,\n lastCleanup: undefined as (CleanupStats & { date: string }) | undefined,\n };\n\n if (cleanupSummary.totalCleanups > 0) {\n cleanupSummary.averageClassesPerCleanup =\n cleanupSummary.totalClassesDeleted / cleanupSummary.totalCleanups;\n cleanupSummary.averageCssPerCleanup =\n cleanupSummary.totalCssDeleted / cleanupSummary.totalCleanups;\n cleanupSummary.averageRulesPerCleanup =\n cleanupSummary.totalRulesDeleted / cleanupSummary.totalCleanups;\n\n const lastCleanup =\n metrics?.cleanupHistory?.[metrics.cleanupHistory.length - 1];\n if (lastCleanup) {\n cleanupSummary.lastCleanup = {\n ...lastCleanup,\n date: new Date(lastCleanup.timestamp).toISOString(),\n };\n }\n }\n\n let page: Summary['page'] | undefined;\n if (includePageCSS) {\n const pageStats = getPageStats({ root, includeCrossOrigin: true });\n page = {\n ...pageStats,\n css:\n includePageCSS === 'all'\n ? getPageCSS({ root, includeCrossOrigin: true })\n : undefined,\n };\n }\n\n // If individual extraction matches total, use individual sizes\n // Otherwise, proportionally scale the individual sizes to match the total\n const useIndividualSizes =\n Math.abs(globalTypesTotalSize - totalGlobalCSSSize) < 100;\n\n let adjustedGlobalSizes;\n if (useIndividualSizes) {\n adjustedGlobalSizes = {\n globalCSSSize: globalData.size,\n rawCSSSize: rawData.size,\n keyframesCSSSize: keyframesData.size,\n propertyCSSSize: propertyData.size,\n };\n } else {\n // Scale proportionally to match the actual total\n const scaleFactor = totalGlobalCSSSize / globalTypesTotalSize;\n adjustedGlobalSizes = {\n globalCSSSize: Math.round(globalData.size * scaleFactor),\n rawCSSSize: Math.round(rawData.size * scaleFactor),\n keyframesCSSSize: Math.round(keyframesData.size * scaleFactor),\n propertyCSSSize: Math.round(propertyData.size * scaleFactor),\n };\n }\n\n // Get chunk breakdown\n const chunkBreakdown = getChunkBreakdown(root);\n\n const summary: Summary = {\n activeClasses: cacheStatus.classes.active,\n unusedClasses: cacheStatus.classes.unused,\n totalStyledClasses: cacheStatus.classes.all,\n activeCSSSize: activeCSS.length,\n unusedCSSSize: unusedCSS.length,\n ...adjustedGlobalSizes,\n totalCSSSize: allCSS.length,\n activeCSS: prettifyCSS(activeCSS),\n unusedCSS: prettifyCSS(unusedCSS),\n globalCSS: globalData.css,\n rawCSS: rawData.css,\n keyframesCSS: keyframesData.css,\n propertyCSS: propertyData.css,\n allCSS: prettifyCSS(allCSS),\n globalRuleCount: globalData.ruleCount,\n rawRuleCount: rawData.ruleCount,\n keyframesRuleCount: keyframesData.ruleCount,\n propertyRuleCount: propertyData.ruleCount,\n page,\n metrics,\n definedProperties: definitions.properties,\n definedKeyframes: definitions.keyframes,\n propertyCount: definitions.properties.length,\n keyframeCount: definitions.keyframes.length,\n cleanupSummary,\n chunkBreakdown,\n };\n\n if (log) {\n console.group('🎨 Comprehensive Tasty Debug Summary');\n console.log(`📊 Style Cache Status:`);\n console.log(\n ` • Active classes (in DOM): ${summary.activeClasses.length}`,\n );\n console.log(\n ` • Unused classes (refCount = 0): ${summary.unusedClasses.length}`,\n );\n console.log(\n ` • Total styled classes: ${summary.totalStyledClasses.length}`,\n );\n console.log(`💾 CSS Size:`);\n console.log(` • Active CSS: ${summary.activeCSSSize} characters`);\n console.log(` • Unused CSS: ${summary.unusedCSSSize} characters`);\n console.log(\n ` • Global CSS (injectGlobal): ${summary.globalCSSSize} characters (${summary.globalRuleCount} rules)`,\n );\n console.log(\n ` • Raw CSS (injectRawCSS/useRawCSS): ${summary.rawCSSSize} characters (${summary.rawRuleCount} rules)`,\n );\n console.log(\n ` • Keyframes CSS: ${summary.keyframesCSSSize} characters (${summary.keyframesRuleCount} rules)`,\n );\n console.log(\n ` • Property CSS: ${summary.propertyCSSSize} characters (${summary.propertyRuleCount} rules)`,\n );\n\n // Show breakdown calculation\n const calculatedTotal =\n summary.activeCSSSize +\n summary.unusedCSSSize +\n summary.globalCSSSize +\n summary.rawCSSSize +\n summary.keyframesCSSSize +\n summary.propertyCSSSize;\n console.log(` • Calculated Total: ${calculatedTotal} characters`);\n console.log(` • Actual Total: ${summary.totalCSSSize} characters`);\n\n const difference = Math.abs(calculatedTotal - summary.totalCSSSize);\n if (difference > 100) {\n console.warn(\n ` ⚠️ Size mismatch: ${difference} characters difference`,\n );\n\n // Debug: show what might be missing\n console.group('🔍 Debugging size mismatch:');\n console.log(\n `Active + Unused = ${summary.activeCSSSize + summary.unusedCSSSize}`,\n );\n console.log(\n `All Global Types = ${summary.globalCSSSize + summary.rawCSSSize + summary.keyframesCSSSize + summary.propertyCSSSize}`,\n );\n console.log(\n `Class-based vs Total difference = ${summary.totalCSSSize - (summary.activeCSSSize + summary.unusedCSSSize)}`,\n );\n\n // Show scaling information\n console.log(`Raw global extraction total: ${globalTypesTotalSize}`);\n console.log(`Calculated global size: ${totalGlobalCSSSize}`);\n console.log(`Used individual sizes: ${useIndividualSizes}`);\n if (!useIndividualSizes) {\n console.log(\n `Scale factor applied: ${(totalGlobalCSSSize / globalTypesTotalSize).toFixed(3)}`,\n );\n }\n console.groupEnd();\n }\n\n if (page) {\n console.log(`📄 Page CSS:`);\n console.log(` • Total page CSS: ${page.cssSize} characters`);\n console.log(` • Total page rules: ${page.ruleCount}`);\n console.log(\n ` • Stylesheets: ${page.stylesheetCount} (${page.skippedStylesheets} skipped)`,\n );\n }\n\n console.log('🏷️ Properties & Keyframes:');\n console.log(` • Defined @property: ${summary.propertyCount}`);\n console.log(` • Defined @keyframes: ${summary.keyframeCount}`);\n\n if (metrics) {\n console.log(`⚡ Performance Metrics:`);\n console.log(` • Cache hits: ${metrics.hits}`);\n console.log(` • Cache misses: ${metrics.misses}`);\n console.log(` • Cached style reuses: ${metrics.unusedHits}`);\n const hitRate =\n metrics.hits + metrics.misses > 0\n ? (\n ((metrics.hits + (metrics.unusedHits || 0)) /\n (metrics.hits + metrics.misses)) *\n 100\n ).toFixed(1)\n : '0';\n console.log(` • Overall cache hit rate: ${hitRate}%`);\n }\n\n // Show chunk breakdown\n if (summary.chunkBreakdown.totalChunkTypes > 0) {\n console.log('🧩 Style Chunk Breakdown:');\n const displayOrder = [\n CHUNK_NAMES.COMBINED, // non-chunked styles (e.g., @starting-style)\n CHUNK_NAMES.APPEARANCE,\n CHUNK_NAMES.FONT,\n CHUNK_NAMES.DIMENSION,\n CHUNK_NAMES.DISPLAY,\n CHUNK_NAMES.LAYOUT,\n CHUNK_NAMES.POSITION,\n CHUNK_NAMES.MISC,\n CHUNK_NAMES.SUBCOMPONENTS,\n ];\n for (const chunkName of displayOrder) {\n const data = summary.chunkBreakdown.byChunk[chunkName];\n if (data) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n }\n\n console.log('🔍 Details:');\n console.log(' • Active classes:', summary.activeClasses);\n console.log(' • Unused classes:', summary.unusedClasses);\n console.groupEnd();\n }\n\n return summary;\n },\n\n // 8) Page-level CSS helpers\n pageCSS(opts?: {\n root?: Document | ShadowRoot;\n prettify?: boolean;\n log?: boolean;\n includeCrossOrigin?: boolean;\n }): string {\n const {\n root = document,\n prettify = true,\n log = false,\n includeCrossOrigin = true,\n } = opts || {};\n const css = getPageCSS({ root, includeCrossOrigin });\n const result = prettify ? prettifyCSS(css) : css;\n\n if (log) {\n console.group('📄 Page CSS (All Stylesheets)');\n console.log(result || '(empty)');\n console.groupEnd();\n }\n\n return result;\n },\n\n pageStats(opts?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n }): {\n cssSize: number;\n ruleCount: number;\n stylesheetCount: number;\n skippedStylesheets: number;\n } {\n const { root = document, includeCrossOrigin = true } = opts || {};\n return getPageStats({ root, includeCrossOrigin });\n },\n\n // 9) Install globally\n install(): void {\n if (typeof window !== 'undefined' && window.tastyDebug !== tastyDebug) {\n window.tastyDebug = tastyDebug;\n console.log(\n '🎨 tastyDebug installed on window. Run tastyDebug.help() for quick start guide.',\n );\n }\n },\n\n // 10) Beautiful console logging with collapsible CSS\n log(target: CSSTarget, opts?: CssOptions & { title?: string }): void {\n const { title, ...cssOpts } = opts || {};\n const css = tastyDebug.css(target, cssOpts);\n\n if (!css.trim()) {\n console.warn(`🎨 No CSS found for target: ${String(target)}`);\n return;\n }\n\n const targetStr = Array.isArray(target)\n ? target.join(', ')\n : String(target);\n const displayTitle = title || `CSS for \"${targetStr}\"`;\n\n // Get some stats about the CSS\n const lines = css.split('\\n').length;\n const size = new Blob([css]).size;\n const sizeStr = size > 1024 ? `${(size / 1024).toFixed(1)}KB` : `${size}B`;\n\n // Count CSS rules (blocks with opening braces)\n const ruleCount = (css.match(/\\{/g) || []).length;\n\n console.group(\n `🎨 ${displayTitle} (${ruleCount} rules, ${lines} lines, ${sizeStr})`,\n );\n\n // Detect sub-elements in CSS\n const subElementMatches = css.match(/\\[data-element=\"([^\"]+)\"\\]/g) || [];\n const subElements = [\n ...new Set(\n subElementMatches\n .map((match) => match.match(/\\[data-element=\"([^\"]+)\"\\]/)?.[1])\n .filter(Boolean),\n ),\n ];\n\n if (subElements.length > 0) {\n console.log(`🧩 Sub-elements found: ${subElements.join(', ')}`);\n\n // Show stats and CSS for each sub-element\n subElements.forEach((element) => {\n const _elementSelector = `[data-element=\"${element}\"]`;\n const elementRegex = new RegExp(\n `[^}]*\\\\[data-element=\"${element.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\"\\\\][^{]*\\\\{[^}]*\\\\}`,\n 'gm',\n );\n const elementCSS = (css.match(elementRegex) || []).join('\\n');\n\n if (elementCSS) {\n const elementRules = (elementCSS.match(/\\{/g) || []).length;\n const elementLines = elementCSS.split('\\n').length;\n const elementSize = new Blob([elementCSS]).size;\n const elementSizeStr =\n elementSize > 1024\n ? `${(elementSize / 1024).toFixed(1)}KB`\n : `${elementSize}B`;\n\n console.groupCollapsed(\n `🧩 ${element} (${elementRules} rules, ${elementLines} lines, ${elementSizeStr})`,\n );\n console.log(\n `%c${elementCSS}`,\n 'color: #666; font-family: monospace; font-size: 12px; white-space: pre;',\n );\n console.groupEnd();\n }\n });\n }\n\n // Full CSS in collapsible group (hidden by default)\n console.groupCollapsed('📄 Full CSS (click to expand)');\n console.log(\n `%c${css}`,\n 'color: #666; font-family: monospace; font-size: 12px; white-space: pre;',\n );\n console.groupEnd();\n\n console.groupEnd();\n },\n\n // 12) Show help and usage examples\n help(): void {\n console.group('🎨 tastyDebug - Quick Start Guide');\n console.log('💡 Essential commands:');\n console.log(\n ' • tastyDebug.summary({ log: true }) - comprehensive overview',\n );\n console.log(' • tastyDebug.chunks({ log: true }) - style chunk breakdown');\n console.log(' • tastyDebug.log(\"active\") - beautiful CSS display');\n console.log(' • tastyDebug.css(\"active\") - get active CSS');\n console.log(\n ' • tastyDebug.inspect(\".my-element\") - element inspection with chunk info',\n );\n console.log(' • tastyDebug.cache() - cache status');\n console.log(' • tastyDebug.defs() - defined properties & keyframes');\n console.log(' • tastyDebug.pageCSS({ log: true }) - all page CSS');\n console.log('');\n console.log('📖 Common targets for css()/log():');\n console.log(' • \"all\" - all tasty CSS + global CSS');\n console.log(' • \"active\" - CSS for classes in DOM');\n console.log(' • \"unused\" - CSS for classes with refCount = 0');\n console.log(' • \"global\" - only global CSS (injectGlobal)');\n console.log(' • \"page\" - ALL page CSS (including non-tasty)');\n console.log(' • \"t123\" - specific tasty class');\n console.log(' • [\".my-selector\"] - CSS selector');\n console.log('');\n console.log('🔧 Available options:');\n console.log(' • { log: true } - auto-log results to console');\n console.log(' • { title: \"Custom\" } - custom title for log()');\n console.log(' • { root: shadowRoot } - target Shadow DOM');\n console.log(' • { prettify: false } - skip CSS formatting');\n console.log('');\n console.log('🧩 Style Chunking:');\n console.log(\n ' Elements have multiple classes (one per chunk: appearance, font, dimension, etc.)',\n );\n console.log(\n ' • tastyDebug.chunks({ log: true }) - breakdown by chunk type',\n );\n console.log(\n ' • tastyDebug.inspect() - shows which chunk each class belongs to',\n );\n console.log(\n ' Chunk types: combined (non-chunked), appearance, font, dimension, container, scrollbar, position, misc, subcomponents',\n );\n console.groupEnd();\n },\n};\n\n/**\n * Auto-install in development\n */\nif (typeof window !== 'undefined' && isDevEnv()) {\n tastyDebug.install();\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"debug.js","names":[],"sources":["../src/debug.ts"],"sourcesContent":["/* eslint-disable no-console */\n/**\n * Debug utilities for inspecting tasty-generated CSS at runtime\n */\n\nimport { CHUNK_NAMES } from './chunks/definitions';\nimport { getCssTextForNode, injector } from './injector';\nimport type { CleanupStats } from './injector/types';\nimport { isDevEnv } from './utils/is-dev-env';\n\ndeclare global {\n interface Window {\n tastyDebug?: typeof tastyDebug;\n }\n}\n\n// Type definitions for the new API\ntype CSSTarget =\n | 'all' // tasty CSS + tasty global CSS + raw CSS\n | 'global' // only tasty global CSS\n | 'active' // tasty CSS for classes currently in DOM\n | 'unused' // tasty CSS with refCount = 0 (still in cache but not actively used)\n | 'page' // ALL CSS on the page across stylesheets (not only tasty)\n | string // 't123' tasty class or a CSS selector\n | string[] // array of tasty classes like ['t1', 't2']\n | Element; // a DOM element\n\ninterface CssOptions {\n root?: Document | ShadowRoot;\n prettify?: boolean; // default: true\n log?: boolean; // default: false\n}\n\ninterface ChunkInfo {\n className: string;\n chunkName: string | null;\n}\n\ninterface InspectResult {\n element?: Element | null;\n classes: string[]; // tasty classes found on the element\n chunks: ChunkInfo[]; // chunk information per class (with chunking enabled)\n css: string; // full, prettified CSS affecting the element\n size: number; // characters in css\n rules: number; // number of rule blocks\n}\n\ninterface CacheMetrics {\n hits: number;\n misses: number;\n bulkCleanups: number;\n totalInsertions: number;\n totalUnused: number;\n stylesCleanedUp: number;\n cleanupHistory: {\n timestamp: number;\n classesDeleted: number;\n cssSize: number;\n rulesDeleted: number;\n }[];\n startTime: number;\n\n // Calculated metrics\n unusedHits?: number; // calculated as current unused count\n}\n\ninterface CacheStatus {\n classes: {\n active: string[]; // classes with refCount > 0 and present in DOM\n unused: string[]; // classes with refCount = 0 but still in cache\n all: string[]; // union of both\n };\n metrics: CacheMetrics | null;\n}\n\ninterface Definitions {\n properties: string[]; // defined via @property\n keyframes: { name: string; refCount: number }[];\n}\n\ninterface SummaryOptions {\n root?: Document | ShadowRoot;\n log?: boolean;\n includePageCSS?:\n | false // do not include page-level CSS stats (default)\n | true // include sizes/counts only\n | 'all'; // include stats and return full page CSS string\n}\n\ninterface Summary {\n // Classes\n activeClasses: string[];\n unusedClasses: string[];\n totalStyledClasses: string[];\n\n // Tasty CSS sizes\n activeCSSSize: number;\n unusedCSSSize: number;\n globalCSSSize: number; // injectGlobal() CSS\n rawCSSSize: number; // injectRawCSS() / useRawCSS() CSS\n keyframesCSSSize: number; // @keyframes CSS\n propertyCSSSize: number; // @property CSS\n totalCSSSize: number; // all tasty CSS (active + unused + global + raw + keyframes + property)\n\n // Tasty CSS payloads\n activeCSS: string;\n unusedCSS: string;\n globalCSS: string; // injectGlobal() CSS\n rawCSS: string; // injectRawCSS() / useRawCSS() CSS\n keyframesCSS: string; // @keyframes CSS\n propertyCSS: string; // @property CSS\n allCSS: string; // all tasty CSS combined\n\n // Rule counts\n globalRuleCount: number;\n rawRuleCount: number;\n keyframesRuleCount: number;\n propertyRuleCount: number;\n\n // Page-level CSS (across all stylesheets, not only tasty) — shown when includePageCSS != false\n page?: {\n css?: string; // present only when includePageCSS === 'all'\n cssSize: number; // total characters\n ruleCount: number; // approximate rule count\n stylesheetCount: number; // stylesheets scanned (CORS-safe)\n skippedStylesheets: number; // stylesheets skipped due to cross-origin/CORS\n };\n\n // Metrics & definitions\n metrics: CacheMetrics | null;\n definedProperties: string[];\n definedKeyframes: { name: string; refCount: number }[];\n propertyCount: number;\n keyframeCount: number;\n\n // Cleanup summary\n cleanupSummary: {\n enabled: boolean;\n totalCleanups: number;\n totalClassesDeleted: number;\n totalCssDeleted: number;\n totalRulesDeleted: number;\n averageClassesPerCleanup: number;\n averageCssPerCleanup: number;\n averageRulesPerCleanup: number;\n lastCleanup?: {\n timestamp: number;\n date: string;\n classesDeleted: number;\n cssSize: number;\n rulesDeleted: number;\n };\n };\n\n // Chunk breakdown (style chunking optimization)\n chunkBreakdown: {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n };\n}\n\n/**\n * Pretty-print CSS with proper indentation and formatting\n */\nfunction prettifyCSS(css: string): string {\n if (!css || css.trim() === '') {\n return '';\n }\n\n // First, normalize whitespace but preserve structure\n let formatted = css.replace(/\\s+/g, ' ').trim();\n\n // Add newlines after opening braces\n formatted = formatted.replace(/\\s*\\{\\s*/g, ' {\\n');\n\n // Add newlines after semicolons (but not inside strings or functions)\n formatted = formatted.replace(/;(?![^\"']*[\"'][^\"']*$)(?![^()]*\\))/g, ';\\n');\n\n // Add newlines before closing braces\n formatted = formatted.replace(/\\s*\\}\\s*/g, '\\n}\\n');\n\n // Handle comma-separated selectors (only outside of property values)\n // This regex looks for commas that are:\n // 1. Not inside quotes\n // 2. Not inside parentheses (CSS functions)\n // 3. Not followed by a colon (not in a property value)\n formatted = formatted.replace(\n /,(?![^\"']*[\"'][^\"']*$)(?![^()]*\\))(?=.*:.*\\{|.*\\{)/g,\n ',\\n',\n );\n\n // Process line by line for proper indentation\n const lines = formatted.split('\\n');\n let indentLevel = 0;\n const indentSize = 2;\n\n const formattedLines = lines.map((line) => {\n const trimmed = line.trim();\n if (!trimmed) return '';\n\n // Handle closing braces - decrease indent first\n if (trimmed === '}') {\n indentLevel = Math.max(0, indentLevel - 1);\n return ' '.repeat(indentLevel * indentSize) + trimmed;\n }\n\n // Current line with proper indentation\n const indent = ' '.repeat(indentLevel * indentSize);\n const result = indent + trimmed;\n\n // Handle opening braces - increase indent for next line\n if (trimmed.endsWith('{')) {\n indentLevel++;\n }\n\n return result;\n });\n\n // Clean up the result and ensure proper spacing\n let result = formattedLines\n .filter((line) => line.trim()) // Remove empty lines\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n') // Max 2 consecutive newlines\n .trim();\n\n // Final cleanup: ensure single spaces in function calls\n result = result.replace(/,\\s+/g, ', ');\n\n return result;\n}\n\n// Helper functions\nfunction findAllTastyClasses(root: Document | ShadowRoot = document): string[] {\n const classes = new Set<string>();\n const elements = (root as Document).querySelectorAll?.('[class]') || [];\n\n elements.forEach((element) => {\n const classList = element.getAttribute('class');\n if (classList) {\n const tastyClasses = classList\n .split(/\\s+/)\n .filter((cls) => /^t\\d+$/.test(cls));\n tastyClasses.forEach((cls) => classes.add(cls));\n }\n });\n\n return Array.from(classes).sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n}\n\nfunction findAllStyledClasses(\n root: Document | ShadowRoot = document,\n): string[] {\n // Extract tasty classes from all CSS text by parsing selectors\n const allCSS = injector.instance.getCssText({ root });\n const classes = new Set<string>();\n\n // Simple regex to find .t{number} class selectors\n const classRegex = /\\.t(\\d+)/g;\n let match;\n while ((match = classRegex.exec(allCSS)) !== null) {\n classes.add(`t${match[1]}`);\n }\n\n return Array.from(classes).sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n}\n\nfunction extractCSSRules(\n css: string,\n): { selector: string; declarations: string }[] {\n const rules: { selector: string; declarations: string }[] = [];\n\n // Remove comments\n const cleanCSS = css.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n\n let i = 0;\n while (i < cleanCSS.length) {\n // Skip whitespace\n while (i < cleanCSS.length && /\\s/.test(cleanCSS[i])) {\n i++;\n }\n if (i >= cleanCSS.length) break;\n\n // Find selector start\n const selectorStart = i;\n let braceDepth = 0;\n let inString = false;\n let stringChar = '';\n\n // Find opening brace\n while (i < cleanCSS.length) {\n const char = cleanCSS[i];\n if (inString) {\n if (char === stringChar && cleanCSS[i - 1] !== '\\\\') {\n inString = false;\n }\n } else {\n if (char === '\"' || char === \"'\") {\n inString = true;\n stringChar = char;\n } else if (char === '{') {\n braceDepth++;\n if (braceDepth === 1) break;\n }\n }\n i++;\n }\n\n if (i >= cleanCSS.length) break;\n const selector = cleanCSS.substring(selectorStart, i).trim();\n i++; // Skip opening brace\n\n // Find matching closing brace\n const contentStart = i;\n braceDepth = 1;\n inString = false;\n\n while (i < cleanCSS.length && braceDepth > 0) {\n const char = cleanCSS[i];\n if (inString) {\n if (char === stringChar && cleanCSS[i - 1] !== '\\\\') {\n inString = false;\n }\n } else {\n if (char === '\"' || char === \"'\") {\n inString = true;\n stringChar = char;\n } else if (char === '{') {\n braceDepth++;\n } else if (char === '}') {\n braceDepth--;\n }\n }\n i++;\n }\n\n const content = cleanCSS.substring(contentStart, i - 1).trim();\n if (content && selector) {\n rules.push({ selector, declarations: content });\n }\n }\n\n return rules;\n}\n\nfunction getGlobalCSS(root: Document | ShadowRoot = document): string {\n const allCSS = injector.instance.getCssText({ root });\n const rules = extractCSSRules(allCSS);\n\n const globalRules = rules.filter((rule) => {\n const selectors = rule.selector.split(',').map((s) => s.trim());\n return !selectors.every((selector) => {\n const cleanSelector = selector.replace(/[.#:\\s>+~[\\]()]/g, ' ');\n const parts = cleanSelector.split(/\\s+/).filter(Boolean);\n return parts.length > 0 && parts.every((part) => /^t\\d+$/.test(part));\n });\n });\n\n const globalCSS = globalRules\n .map((rule) => `${rule.selector} { ${rule.declarations} }`)\n .join('\\n');\n return prettifyCSS(globalCSS);\n}\n\nfunction getPageCSS(options?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n}): string {\n const root = options?.root || document;\n const includeCrossOrigin = options?.includeCrossOrigin ?? false;\n\n const cssChunks: string[] = [];\n\n try {\n if ('styleSheets' in root) {\n const styleSheets = Array.from((root as Document).styleSheets);\n\n for (const sheet of styleSheets) {\n try {\n if (sheet.cssRules) {\n const rules = Array.from(sheet.cssRules);\n cssChunks.push(rules.map((rule) => rule.cssText).join('\\n'));\n }\n } catch {\n // Cross-origin sheet or other access error\n if (includeCrossOrigin) {\n cssChunks.push(\n `/* Cross-origin stylesheet: ${sheet.href || 'inline'} */`,\n );\n }\n }\n }\n }\n } catch {\n // Fallback error handling\n }\n\n return cssChunks.join('\\n');\n}\n\nfunction getPageStats(options?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n}): {\n cssSize: number;\n ruleCount: number;\n stylesheetCount: number;\n skippedStylesheets: number;\n} {\n const root = options?.root || document;\n\n const _includeCrossOrigin = options?.includeCrossOrigin ?? false;\n\n let cssSize = 0;\n let ruleCount = 0;\n let stylesheetCount = 0;\n let skippedStylesheets = 0;\n\n try {\n if ('styleSheets' in root) {\n const styleSheets = Array.from((root as Document).styleSheets);\n stylesheetCount = styleSheets.length;\n\n for (const sheet of styleSheets) {\n try {\n if (sheet.cssRules) {\n const rules = Array.from(sheet.cssRules);\n ruleCount += rules.length;\n cssSize += rules.reduce(\n (sum, rule) => sum + rule.cssText.length,\n 0,\n );\n }\n } catch {\n skippedStylesheets++;\n }\n }\n }\n } catch {\n // Fallback error handling\n }\n\n return { cssSize, ruleCount, stylesheetCount, skippedStylesheets };\n}\n\n// ============================================================================\n// Chunk-aware helpers (for style chunking optimization)\n// ============================================================================\n\n/**\n * Extract chunk name from a cache key.\n *\n * Cache keys have the format: \"chunkName\\0key:value\\0key:value...\"\n * or \"[states:...]\\0chunkName\\0...\" for predefined states.\n *\n * @param cacheKey - The cache key to parse\n * @returns The chunk name, or null if not found\n */\nfunction extractChunkNameFromCacheKey(cacheKey: string): string | null {\n // Cache keys are separated by \\0 (null character)\n const parts = cacheKey.split('\\0');\n\n for (const part of parts) {\n // Skip predefined states prefix\n if (part.startsWith('[states:')) continue;\n // First non-states part that doesn't contain : is the chunk name\n if (!part.includes(':') && part.length > 0) {\n return part;\n }\n }\n return null;\n}\n\n/**\n * Get chunk info for a className by reverse-looking up its cache key.\n *\n * @param className - The tasty class name (e.g., \"t0\", \"t123\")\n * @param root - The document or shadow root to search in\n * @returns Object with chunk name and cache key, or nulls if not found\n */\nfunction getChunkForClassName(\n className: string,\n root: Document | ShadowRoot = document,\n): { chunkName: string | null; cacheKey: string | null } {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (!registry) {\n return { chunkName: null, cacheKey: null };\n }\n\n // Reverse lookup: find the cache key for this className\n for (const [cacheKey, cn] of registry.cacheKeyToClassName) {\n if (cn === className) {\n return {\n chunkName: extractChunkNameFromCacheKey(cacheKey),\n cacheKey,\n };\n }\n }\n return { chunkName: null, cacheKey: null };\n}\n\n/**\n * Get chunk breakdown statistics for all styles.\n *\n * @param root - The document or shadow root to search in\n * @returns Object with breakdown by chunk type and totals\n */\nfunction getChunkBreakdown(root: Document | ShadowRoot = document): {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n} {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n\n if (!registry) {\n return {\n byChunk: {},\n totalChunkTypes: 0,\n };\n }\n\n const byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n > = {};\n\n // Group classes by chunk\n for (const [cacheKey, className] of registry.cacheKeyToClassName) {\n const chunkName = extractChunkNameFromCacheKey(cacheKey) || 'unknown';\n\n if (!byChunk[chunkName]) {\n byChunk[chunkName] = { classes: [], cssSize: 0, ruleCount: 0 };\n }\n\n byChunk[chunkName].classes.push(className);\n\n // Get CSS for this class\n const css = injector.instance.getCssTextForClasses([className], { root });\n byChunk[chunkName].cssSize += css.length;\n byChunk[chunkName].ruleCount += (css.match(/\\{[^}]*\\}/g) || []).length;\n }\n\n // Sort classes within each chunk for consistency\n for (const entry of Object.values(byChunk)) {\n entry.classes.sort((a, b) => {\n const aNum = parseInt(a.slice(1));\n const bNum = parseInt(b.slice(1));\n return aNum - bNum;\n });\n }\n\n return {\n byChunk,\n totalChunkTypes: Object.keys(byChunk).length,\n };\n}\n\n/**\n * Concise tastyDebug API for inspecting styles at runtime\n */\nexport const tastyDebug = {\n // 1) One function to get CSS from anywhere\n css(target: CSSTarget, opts?: CssOptions): string {\n const { root = document, prettify = true, log = false } = opts || {};\n let css = '';\n\n if (typeof target === 'string') {\n if (target === 'all') {\n css = injector.instance.getCssText({ root });\n } else if (target === 'global') {\n css = getGlobalCSS(root);\n } else if (target === 'active') {\n const activeClasses = findAllTastyClasses(root);\n css = injector.instance.getCssTextForClasses(activeClasses, { root });\n } else if (target === 'unused') {\n // Get unused classes (refCount = 0) from the registry\n const registry = injector.instance._sheetManager?.getRegistry(root);\n const unusedClasses: string[] = registry\n ? Array.from(\n registry.refCounts.entries() as IterableIterator<\n [string, number]\n >,\n )\n .filter(([, refCount]: [string, number]) => refCount === 0)\n .map(([className]: [string, number]) => className)\n : [];\n css = injector.instance.getCssTextForClasses(unusedClasses, { root });\n } else if (target === 'page') {\n css = getPageCSS({ root, includeCrossOrigin: true });\n } else if (/^t\\d+$/.test(target)) {\n // Single tasty class\n css = injector.instance.getCssTextForClasses([target], { root });\n } else {\n // CSS selector - find element and get its CSS\n const element = (root as Document).querySelector?.(target);\n if (element) {\n css = getCssTextForNode(element, { root });\n }\n }\n } else if (Array.isArray(target)) {\n // Array of tasty classes\n css = injector.instance.getCssTextForClasses(target, { root });\n } else if (target instanceof Element) {\n // DOM element\n css = getCssTextForNode(target, { root });\n }\n\n const result = prettify ? prettifyCSS(css) : css;\n\n if (log) {\n console.group(\n `🎨 CSS for ${Array.isArray(target) ? `[${target.join(', ')}]` : target}`,\n );\n console.log(result || '(empty)');\n console.groupEnd();\n }\n\n return result;\n },\n\n // 2) Element-level inspection\n inspect(\n target: string | Element,\n opts?: { root?: Document | ShadowRoot },\n ): InspectResult {\n const { root = document } = opts || {};\n const element =\n typeof target === 'string'\n ? (root as Document).querySelector?.(target)\n : target;\n\n if (!element) {\n return {\n element: null,\n classes: [],\n chunks: [],\n css: '',\n size: 0,\n rules: 0,\n };\n }\n\n const classList = element.getAttribute('class') || '';\n const tastyClasses = classList\n .split(/\\s+/)\n .filter((cls) => /^t\\d+$/.test(cls));\n\n // Get chunk info for each tasty class\n const chunks: ChunkInfo[] = tastyClasses.map((className) => ({\n className,\n chunkName: getChunkForClassName(className, root).chunkName,\n }));\n\n const css = getCssTextForNode(element, { root });\n const prettifiedCSS = prettifyCSS(css);\n const ruleCount = (css.match(/\\{[^}]*\\}/g) || []).length;\n\n return {\n element,\n classes: tastyClasses,\n chunks,\n css: prettifiedCSS,\n size: css.length,\n rules: ruleCount,\n };\n },\n\n // 3) Cache + metrics at a glance\n cache(opts?: {\n root?: Document | ShadowRoot;\n includeHistory?: boolean;\n }): CacheStatus {\n const { root = document } = opts || {};\n const activeClasses = findAllTastyClasses(root);\n\n const _allClasses = findAllStyledClasses(root);\n // Get unused classes (refCount = 0) from the registry\n const registry = injector.instance._sheetManager?.getRegistry(root);\n const unusedClasses: string[] = registry\n ? Array.from(\n registry.refCounts.entries() as IterableIterator<[string, number]>,\n )\n .filter(([, refCount]: [string, number]) => refCount === 0)\n .map(([className]: [string, number]) => className)\n : [];\n\n return {\n classes: {\n active: activeClasses,\n unused: unusedClasses,\n all: [...activeClasses, ...unusedClasses],\n },\n metrics: injector.instance.getMetrics({ root }),\n };\n },\n\n // 4) Cleanup + metrics utilities\n cleanup(opts?: { root?: Document | ShadowRoot }): void {\n const { root } = opts || {};\n injector.instance.cleanup(root);\n },\n\n metrics(opts?: { root?: Document | ShadowRoot }): CacheMetrics | null {\n const { root } = opts || {};\n return injector.instance.getMetrics({ root });\n },\n\n resetMetrics(opts?: { root?: Document | ShadowRoot }): void {\n const { root } = opts || {};\n injector.instance.resetMetrics({ root });\n },\n\n // 5) Chunk breakdown (style chunking optimization)\n /**\n * Get breakdown of styles by chunk type.\n *\n * With style chunking enabled, styles are split into logical chunks\n * (appearance, font, dimension, container, etc.) for better caching\n * and CSS reuse.\n *\n * @param opts - Options including root document/shadow root\n * @returns Breakdown by chunk type with class counts and CSS sizes\n */\n chunks(opts?: { root?: Document | ShadowRoot; log?: boolean }): {\n byChunk: Record<\n string,\n { classes: string[]; cssSize: number; ruleCount: number }\n >;\n totalChunkTypes: number;\n totalClasses: number;\n } {\n const { root = document, log = false } = opts || {};\n const breakdown = getChunkBreakdown(root);\n\n const totalClasses = Object.values(breakdown.byChunk).reduce(\n (sum, entry) => sum + entry.classes.length,\n 0,\n );\n\n if (log) {\n console.group('🧩 Style Chunk Breakdown');\n\n // Define display order matching CHUNK_NAMES\n const displayOrder = [\n CHUNK_NAMES.COMBINED, // non-chunked styles (e.g., @starting-style)\n CHUNK_NAMES.APPEARANCE,\n CHUNK_NAMES.FONT,\n CHUNK_NAMES.DIMENSION,\n CHUNK_NAMES.DISPLAY,\n CHUNK_NAMES.LAYOUT,\n CHUNK_NAMES.POSITION,\n CHUNK_NAMES.MISC,\n CHUNK_NAMES.SUBCOMPONENTS,\n ];\n\n // Show chunks in order\n for (const chunkName of displayOrder) {\n const data = breakdown.byChunk[chunkName];\n if (data) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n\n // Show any unknown chunks\n for (const [chunkName, data] of Object.entries(breakdown.byChunk)) {\n if (\n !displayOrder.includes(chunkName as (typeof displayOrder)[number])\n ) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n\n console.log(\n `📊 Total: ${totalClasses} classes across ${breakdown.totalChunkTypes} chunk types`,\n );\n console.groupEnd();\n }\n\n return {\n ...breakdown,\n totalClasses,\n };\n },\n\n // 6) Get CSS for specific global types\n getGlobalTypeCSS(\n type: 'global' | 'raw' | 'keyframes' | 'property',\n opts?: { root?: Document | ShadowRoot },\n ): { css: string; ruleCount: number; size: number } {\n const { root = document } = opts || {};\n const registry = injector.instance._sheetManager?.getRegistry(root);\n\n if (!registry) {\n return { css: '', ruleCount: 0, size: 0 };\n }\n\n const cssChunks: string[] = [];\n let ruleCount = 0;\n\n if (type === 'keyframes') {\n // Handle keyframes separately - they're stored in keyframesCache\n for (const [, entry] of registry.keyframesCache) {\n const info = entry.info;\n const sheet = registry.sheets[info.sheetIndex];\n const styleSheet = sheet?.sheet?.sheet;\n\n if (styleSheet && info.ruleIndex < styleSheet.cssRules.length) {\n const rule = styleSheet.cssRules[info.ruleIndex] as\n | CSSRule\n | undefined;\n if (rule) {\n cssChunks.push(rule.cssText);\n ruleCount++;\n }\n } else if (info.cssText) {\n cssChunks.push(info.cssText);\n ruleCount++;\n }\n }\n } else {\n // Handle other global types stored in globalRules\n const prefix =\n type === 'global' ? 'global:' : type === 'raw' ? 'raw:' : 'property:';\n\n for (const [key, ruleInfo] of registry.globalRules) {\n if (key.startsWith(prefix)) {\n const sheet = registry.sheets[ruleInfo.sheetIndex];\n const styleSheet = sheet?.sheet?.sheet;\n if (styleSheet) {\n const start = Math.max(0, ruleInfo.ruleIndex);\n const end = Math.min(\n styleSheet.cssRules.length - 1,\n (ruleInfo.endRuleIndex as number) ?? ruleInfo.ruleIndex,\n );\n\n if (\n start >= 0 &&\n end >= start &&\n start < styleSheet.cssRules.length\n ) {\n for (let i = start; i <= end; i++) {\n const rule = styleSheet.cssRules[i] as CSSRule | undefined;\n if (rule) {\n cssChunks.push(rule.cssText);\n ruleCount++;\n }\n }\n }\n } else if (ruleInfo.cssText && ruleInfo.cssText.length) {\n // Fallback in environments without CSSOM access\n cssChunks.push(...ruleInfo.cssText);\n ruleCount += ruleInfo.cssText.length;\n }\n }\n }\n }\n\n const rawCSS = cssChunks.join('\\n');\n\n return {\n css: prettifyCSS(rawCSS),\n ruleCount,\n size: rawCSS.length, // Use raw CSS size for consistent calculations\n };\n },\n\n // 6) Defined @property and keyframes\n defs(opts?: { root?: Document | ShadowRoot }): Definitions {\n const { root = document } = opts || {};\n\n // Get properties from injector if available, otherwise scan CSS\n let properties: string[] = [];\n try {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (registry?.injectedProperties) {\n properties = Array.from(\n (registry.injectedProperties as Map<string, string>).keys(),\n ).sort();\n }\n } catch {\n // Fallback: scan CSS for @property rules\n const allCSS = injector.instance.getCssText({ root });\n const propRegex = /@property\\s+(--[a-z0-9-]+)/gi;\n const propSet = new Set<string>();\n let match;\n while ((match = propRegex.exec(allCSS)) !== null) {\n propSet.add(match[1]);\n }\n properties = Array.from(propSet).sort();\n }\n\n // Get keyframes\n let keyframes: { name: string; refCount: number }[] = [];\n try {\n const registry = injector.instance._sheetManager?.getRegistry(root);\n if (registry) {\n for (const entry of registry.keyframesCache.values()) {\n keyframes.push({\n name: entry.name,\n refCount: entry.refCount,\n });\n }\n keyframes.sort((a, b) => a.name.localeCompare(b.name));\n }\n } catch {\n // Fallback: scan CSS for @keyframes rules\n const allCSS = injector.instance.getCssText({ root });\n const keyframesRegex = /@keyframes\\s+([a-zA-Z0-9_-]+)/gi;\n const keyframesSet = new Set<string>();\n let match;\n while ((match = keyframesRegex.exec(allCSS)) !== null) {\n keyframesSet.add(match[1]);\n }\n keyframes = Array.from(keyframesSet)\n .sort()\n .map((name) => ({ name, refCount: 1 }));\n }\n\n return { properties, keyframes };\n },\n\n // 7) One-shot overview\n summary(opts?: SummaryOptions): Summary {\n const { root = document, log = false, includePageCSS = false } = opts || {};\n const cacheStatus = this.cache({ root });\n const definitions = this.defs({ root });\n const metrics = this.metrics({ root });\n\n const activeCSS = this.css('active', { root, prettify: false });\n const unusedCSS = this.css('unused', { root, prettify: false });\n const allCSS = this.css('all', { root, prettify: false });\n\n // Calculate global CSS by subtracting class-based CSS from total\n const classCSSSize = activeCSS.length + unusedCSS.length;\n const totalGlobalCSSSize = allCSS.length - classCSSSize;\n\n // Get CSS for each global type separately for display purposes\n const globalData = this.getGlobalTypeCSS('global', { root });\n const rawData = this.getGlobalTypeCSS('raw', { root });\n const keyframesData = this.getGlobalTypeCSS('keyframes', { root });\n const propertyData = this.getGlobalTypeCSS('property', { root });\n\n // Use the calculated sizes to avoid double-counting\n const globalTypesTotalSize =\n globalData.size + rawData.size + keyframesData.size + propertyData.size;\n\n // Build cleanup summary from metrics\n const cleanupSummary = {\n enabled: !!metrics,\n totalCleanups: metrics?.cleanupHistory?.length || 0,\n totalClassesDeleted:\n metrics?.cleanupHistory?.reduce(\n (sum, c) => sum + c.classesDeleted,\n 0,\n ) || 0,\n totalCssDeleted:\n metrics?.cleanupHistory?.reduce((sum, c) => sum + c.cssSize, 0) || 0,\n totalRulesDeleted:\n metrics?.cleanupHistory?.reduce((sum, c) => sum + c.rulesDeleted, 0) ||\n 0,\n averageClassesPerCleanup: 0,\n averageCssPerCleanup: 0,\n averageRulesPerCleanup: 0,\n lastCleanup: undefined as (CleanupStats & { date: string }) | undefined,\n };\n\n if (cleanupSummary.totalCleanups > 0) {\n cleanupSummary.averageClassesPerCleanup =\n cleanupSummary.totalClassesDeleted / cleanupSummary.totalCleanups;\n cleanupSummary.averageCssPerCleanup =\n cleanupSummary.totalCssDeleted / cleanupSummary.totalCleanups;\n cleanupSummary.averageRulesPerCleanup =\n cleanupSummary.totalRulesDeleted / cleanupSummary.totalCleanups;\n\n const lastCleanup =\n metrics?.cleanupHistory?.[metrics.cleanupHistory.length - 1];\n if (lastCleanup) {\n cleanupSummary.lastCleanup = {\n ...lastCleanup,\n date: new Date(lastCleanup.timestamp).toISOString(),\n };\n }\n }\n\n let page: Summary['page'] | undefined;\n if (includePageCSS) {\n const pageStats = getPageStats({ root, includeCrossOrigin: true });\n page = {\n ...pageStats,\n css:\n includePageCSS === 'all'\n ? getPageCSS({ root, includeCrossOrigin: true })\n : undefined,\n };\n }\n\n // If individual extraction matches total, use individual sizes\n // Otherwise, proportionally scale the individual sizes to match the total\n const useIndividualSizes =\n Math.abs(globalTypesTotalSize - totalGlobalCSSSize) < 100;\n\n let adjustedGlobalSizes;\n if (useIndividualSizes) {\n adjustedGlobalSizes = {\n globalCSSSize: globalData.size,\n rawCSSSize: rawData.size,\n keyframesCSSSize: keyframesData.size,\n propertyCSSSize: propertyData.size,\n };\n } else {\n // Scale proportionally to match the actual total\n const scaleFactor = totalGlobalCSSSize / globalTypesTotalSize;\n adjustedGlobalSizes = {\n globalCSSSize: Math.round(globalData.size * scaleFactor),\n rawCSSSize: Math.round(rawData.size * scaleFactor),\n keyframesCSSSize: Math.round(keyframesData.size * scaleFactor),\n propertyCSSSize: Math.round(propertyData.size * scaleFactor),\n };\n }\n\n // Get chunk breakdown\n const chunkBreakdown = getChunkBreakdown(root);\n\n const summary: Summary = {\n activeClasses: cacheStatus.classes.active,\n unusedClasses: cacheStatus.classes.unused,\n totalStyledClasses: cacheStatus.classes.all,\n activeCSSSize: activeCSS.length,\n unusedCSSSize: unusedCSS.length,\n ...adjustedGlobalSizes,\n totalCSSSize: allCSS.length,\n activeCSS: prettifyCSS(activeCSS),\n unusedCSS: prettifyCSS(unusedCSS),\n globalCSS: globalData.css,\n rawCSS: rawData.css,\n keyframesCSS: keyframesData.css,\n propertyCSS: propertyData.css,\n allCSS: prettifyCSS(allCSS),\n globalRuleCount: globalData.ruleCount,\n rawRuleCount: rawData.ruleCount,\n keyframesRuleCount: keyframesData.ruleCount,\n propertyRuleCount: propertyData.ruleCount,\n page,\n metrics,\n definedProperties: definitions.properties,\n definedKeyframes: definitions.keyframes,\n propertyCount: definitions.properties.length,\n keyframeCount: definitions.keyframes.length,\n cleanupSummary,\n chunkBreakdown,\n };\n\n if (log) {\n console.group('🎨 Comprehensive Tasty Debug Summary');\n console.log(`📊 Style Cache Status:`);\n console.log(\n ` • Active classes (in DOM): ${summary.activeClasses.length}`,\n );\n console.log(\n ` • Unused classes (refCount = 0): ${summary.unusedClasses.length}`,\n );\n console.log(\n ` • Total styled classes: ${summary.totalStyledClasses.length}`,\n );\n console.log(`💾 CSS Size:`);\n console.log(` • Active CSS: ${summary.activeCSSSize} characters`);\n console.log(` • Unused CSS: ${summary.unusedCSSSize} characters`);\n console.log(\n ` • Global CSS (injectGlobal): ${summary.globalCSSSize} characters (${summary.globalRuleCount} rules)`,\n );\n console.log(\n ` • Raw CSS (injectRawCSS/useRawCSS): ${summary.rawCSSSize} characters (${summary.rawRuleCount} rules)`,\n );\n console.log(\n ` • Keyframes CSS: ${summary.keyframesCSSSize} characters (${summary.keyframesRuleCount} rules)`,\n );\n console.log(\n ` • Property CSS: ${summary.propertyCSSSize} characters (${summary.propertyRuleCount} rules)`,\n );\n\n // Show breakdown calculation\n const calculatedTotal =\n summary.activeCSSSize +\n summary.unusedCSSSize +\n summary.globalCSSSize +\n summary.rawCSSSize +\n summary.keyframesCSSSize +\n summary.propertyCSSSize;\n console.log(` • Calculated Total: ${calculatedTotal} characters`);\n console.log(` • Actual Total: ${summary.totalCSSSize} characters`);\n\n const difference = Math.abs(calculatedTotal - summary.totalCSSSize);\n if (difference > 100) {\n console.warn(\n ` ⚠️ Size mismatch: ${difference} characters difference`,\n );\n\n // Debug: show what might be missing\n console.group('🔍 Debugging size mismatch:');\n console.log(\n `Active + Unused = ${summary.activeCSSSize + summary.unusedCSSSize}`,\n );\n console.log(\n `All Global Types = ${summary.globalCSSSize + summary.rawCSSSize + summary.keyframesCSSSize + summary.propertyCSSSize}`,\n );\n console.log(\n `Class-based vs Total difference = ${summary.totalCSSSize - (summary.activeCSSSize + summary.unusedCSSSize)}`,\n );\n\n // Show scaling information\n console.log(`Raw global extraction total: ${globalTypesTotalSize}`);\n console.log(`Calculated global size: ${totalGlobalCSSSize}`);\n console.log(`Used individual sizes: ${useIndividualSizes}`);\n if (!useIndividualSizes) {\n console.log(\n `Scale factor applied: ${(totalGlobalCSSSize / globalTypesTotalSize).toFixed(3)}`,\n );\n }\n console.groupEnd();\n }\n\n if (page) {\n console.log(`📄 Page CSS:`);\n console.log(` • Total page CSS: ${page.cssSize} characters`);\n console.log(` • Total page rules: ${page.ruleCount}`);\n console.log(\n ` • Stylesheets: ${page.stylesheetCount} (${page.skippedStylesheets} skipped)`,\n );\n }\n\n console.log('🏷️ Properties & Keyframes:');\n console.log(` • Defined @property: ${summary.propertyCount}`);\n console.log(` • Defined @keyframes: ${summary.keyframeCount}`);\n\n if (metrics) {\n console.log(`⚡ Performance Metrics:`);\n console.log(` • Cache hits: ${metrics.hits}`);\n console.log(` • Cache misses: ${metrics.misses}`);\n console.log(` • Cached style reuses: ${metrics.unusedHits}`);\n const hitRate =\n metrics.hits + metrics.misses > 0\n ? (\n ((metrics.hits + (metrics.unusedHits || 0)) /\n (metrics.hits + metrics.misses)) *\n 100\n ).toFixed(1)\n : '0';\n console.log(` • Overall cache hit rate: ${hitRate}%`);\n }\n\n // Show chunk breakdown\n if (summary.chunkBreakdown.totalChunkTypes > 0) {\n console.log('🧩 Style Chunk Breakdown:');\n const displayOrder = [\n CHUNK_NAMES.COMBINED, // non-chunked styles (e.g., @starting-style)\n CHUNK_NAMES.APPEARANCE,\n CHUNK_NAMES.FONT,\n CHUNK_NAMES.DIMENSION,\n CHUNK_NAMES.DISPLAY,\n CHUNK_NAMES.LAYOUT,\n CHUNK_NAMES.POSITION,\n CHUNK_NAMES.MISC,\n CHUNK_NAMES.SUBCOMPONENTS,\n ];\n for (const chunkName of displayOrder) {\n const data = summary.chunkBreakdown.byChunk[chunkName];\n if (data) {\n const sizeStr =\n data.cssSize > 1024\n ? `${(data.cssSize / 1024).toFixed(1)}KB`\n : `${data.cssSize}B`;\n console.log(\n ` • ${chunkName}: ${data.classes.length} classes, ${sizeStr}, ${data.ruleCount} rules`,\n );\n }\n }\n }\n\n console.log('🔍 Details:');\n console.log(' • Active classes:', summary.activeClasses);\n console.log(' • Unused classes:', summary.unusedClasses);\n console.groupEnd();\n }\n\n return summary;\n },\n\n // 8) Page-level CSS helpers\n pageCSS(opts?: {\n root?: Document | ShadowRoot;\n prettify?: boolean;\n log?: boolean;\n includeCrossOrigin?: boolean;\n }): string {\n const {\n root = document,\n prettify = true,\n log = false,\n includeCrossOrigin = true,\n } = opts || {};\n const css = getPageCSS({ root, includeCrossOrigin });\n const result = prettify ? prettifyCSS(css) : css;\n\n if (log) {\n console.group('📄 Page CSS (All Stylesheets)');\n console.log(result || '(empty)');\n console.groupEnd();\n }\n\n return result;\n },\n\n pageStats(opts?: {\n root?: Document | ShadowRoot;\n includeCrossOrigin?: boolean;\n }): {\n cssSize: number;\n ruleCount: number;\n stylesheetCount: number;\n skippedStylesheets: number;\n } {\n const { root = document, includeCrossOrigin = true } = opts || {};\n return getPageStats({ root, includeCrossOrigin });\n },\n\n // 9) Install globally\n install(): void {\n if (typeof window !== 'undefined' && window.tastyDebug !== tastyDebug) {\n window.tastyDebug = tastyDebug;\n console.log(\n '🎨 tastyDebug installed on window. Run tastyDebug.help() for quick start guide.',\n );\n }\n },\n\n // 10) Beautiful console logging with collapsible CSS\n log(target: CSSTarget, opts?: CssOptions & { title?: string }): void {\n const { title, ...cssOpts } = opts || {};\n const css = tastyDebug.css(target, cssOpts);\n\n if (!css.trim()) {\n console.warn(`🎨 No CSS found for target: ${String(target)}`);\n return;\n }\n\n const targetStr = Array.isArray(target)\n ? target.join(', ')\n : String(target);\n const displayTitle = title || `CSS for \"${targetStr}\"`;\n\n // Get some stats about the CSS\n const lines = css.split('\\n').length;\n const size = new Blob([css]).size;\n const sizeStr = size > 1024 ? `${(size / 1024).toFixed(1)}KB` : `${size}B`;\n\n // Count CSS rules (blocks with opening braces)\n const ruleCount = (css.match(/\\{/g) || []).length;\n\n console.group(\n `🎨 ${displayTitle} (${ruleCount} rules, ${lines} lines, ${sizeStr})`,\n );\n\n // Detect sub-elements in CSS\n const subElementMatches = css.match(/\\[data-element=\"([^\"]+)\"\\]/g) || [];\n const subElements = [\n ...new Set(\n subElementMatches\n .map((match) => match.match(/\\[data-element=\"([^\"]+)\"\\]/)?.[1])\n .filter((v): v is string => !!v),\n ),\n ];\n\n if (subElements.length > 0) {\n console.log(`🧩 Sub-elements found: ${subElements.join(', ')}`);\n\n // Show stats and CSS for each sub-element\n subElements.forEach((element) => {\n const _elementSelector = `[data-element=\"${element}\"]`;\n const elementRegex = new RegExp(\n `[^}]*\\\\[data-element=\"${element.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\"\\\\][^{]*\\\\{[^}]*\\\\}`,\n 'gm',\n );\n const elementCSS = (css.match(elementRegex) || []).join('\\n');\n\n if (elementCSS) {\n const elementRules = (elementCSS.match(/\\{/g) || []).length;\n const elementLines = elementCSS.split('\\n').length;\n const elementSize = new Blob([elementCSS]).size;\n const elementSizeStr =\n elementSize > 1024\n ? `${(elementSize / 1024).toFixed(1)}KB`\n : `${elementSize}B`;\n\n console.groupCollapsed(\n `🧩 ${element} (${elementRules} rules, ${elementLines} lines, ${elementSizeStr})`,\n );\n console.log(\n `%c${elementCSS}`,\n 'color: #666; font-family: monospace; font-size: 12px; white-space: pre;',\n );\n console.groupEnd();\n }\n });\n }\n\n // Full CSS in collapsible group (hidden by default)\n console.groupCollapsed('📄 Full CSS (click to expand)');\n console.log(\n `%c${css}`,\n 'color: #666; font-family: monospace; font-size: 12px; white-space: pre;',\n );\n console.groupEnd();\n\n console.groupEnd();\n },\n\n // 12) Show help and usage examples\n help(): void {\n console.group('🎨 tastyDebug - Quick Start Guide');\n console.log('💡 Essential commands:');\n console.log(\n ' • tastyDebug.summary({ log: true }) - comprehensive overview',\n );\n console.log(' • tastyDebug.chunks({ log: true }) - style chunk breakdown');\n console.log(' • tastyDebug.log(\"active\") - beautiful CSS display');\n console.log(' • tastyDebug.css(\"active\") - get active CSS');\n console.log(\n ' • tastyDebug.inspect(\".my-element\") - element inspection with chunk info',\n );\n console.log(' • tastyDebug.cache() - cache status');\n console.log(' • tastyDebug.defs() - defined properties & keyframes');\n console.log(' • tastyDebug.pageCSS({ log: true }) - all page CSS');\n console.log('');\n console.log('📖 Common targets for css()/log():');\n console.log(' • \"all\" - all tasty CSS + global CSS');\n console.log(' • \"active\" - CSS for classes in DOM');\n console.log(' • \"unused\" - CSS for classes with refCount = 0');\n console.log(' • \"global\" - only global CSS (injectGlobal)');\n console.log(' • \"page\" - ALL page CSS (including non-tasty)');\n console.log(' • \"t123\" - specific tasty class');\n console.log(' • [\".my-selector\"] - CSS selector');\n console.log('');\n console.log('🔧 Available options:');\n console.log(' • { log: true } - auto-log results to console');\n console.log(' • { title: \"Custom\" } - custom title for log()');\n console.log(' • { root: shadowRoot } - target Shadow DOM');\n console.log(' • { prettify: false } - skip CSS formatting');\n console.log('');\n console.log('🧩 Style Chunking:');\n console.log(\n ' Elements have multiple classes (one per chunk: appearance, font, dimension, etc.)',\n );\n console.log(\n ' • tastyDebug.chunks({ log: true }) - breakdown by chunk type',\n );\n console.log(\n ' • tastyDebug.inspect() - shows which chunk each class belongs to',\n );\n console.log(\n ' Chunk types: combined (non-chunked), appearance, font, dimension, container, scrollbar, position, misc, subcomponents',\n );\n console.groupEnd();\n },\n};\n\n/**\n * Auto-install in development\n */\nif (typeof window !== 'undefined' && isDevEnv()) {\n tastyDebug.install();\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -37,4 +37,12 @@ import { TypographyPreset } from "./tokens/typography.js";
|
|
|
37
37
|
import { generateTypographyTokens } from "./utils/typography.js";
|
|
38
38
|
import { tastyDebug } from "./debug.js";
|
|
39
39
|
import "./core/index.js";
|
|
40
|
-
|
|
40
|
+
import { CSSProperties as CSSProperties$1 } from "react";
|
|
41
|
+
|
|
42
|
+
//#region src/index.d.ts
|
|
43
|
+
declare module './utils/css-types' {
|
|
44
|
+
interface CSSProperties extends CSSProperties$1 {}
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { type AllBaseProps, type AllBasePropsWithMods, AtRuleContext, BASE_STYLES, BLOCK_INNER_STYLES, BLOCK_OUTER_STYLES, BLOCK_STYLES, type BaseProps, type BasePropsWithoutChildren, BaseStyleProps, BlockInnerStyleProps, BlockOuterStyleProps, BlockStyleProps, Bucket, CHUNK_NAMES, COLOR_STYLES, COMPUTE_FUNC_MAP, CONTAINER_STYLES, CSSMap, CSSProperties, CUSTOM_UNITS, CacheMetrics, ChunkInfo, ChunkName, ColorStyleProps, ComputeModel, ConditionNode, ContainerStyleProps, DIMENSION_STYLES, DIRECTIONS, DimensionStyleProps, DisposeFunction, Element, type ElementsDefinition, FLOW_STYLES, FlowStyleProps, GlobalStyledProps, INNER_STYLES, InjectResult, InnerStyleProps, KeyframesCacheEntry, KeyframesInfo, KeyframesResult, KeyframesSteps, ModValue, Mods, NoType, NotSelector, OUTER_STYLES, OuterStyleProps, POSITION_STYLES, ParseStateKeyOptions, ParsedAdvancedState, ParsedColor, ParserOptions, PositionStyleProps, ProcessedStyle, PropertyDefinition, PropertyOptions, Props, RawCSSResult, RawStyleHandler, RecipeStyles, RenderResult, RootRegistry, RuleInfo, STATE_OPERATORS, STATE_OPERATOR_LIST, STYLE_TO_CHUNK, Selector, SheetInfo, SheetManager, ShortGridStyles, StateParserContext, StyleDetails, StyleDetailsPart, StyleHandler, StyleHandlerDefinition, StyleHandlerResult, StyleInjector, StyleInjectorConfig, StyleMap, StyleParser, StylePropValue, StyleResult, StyleRule, StyleStateData, StyleStateDataList, StyleStateDataListMap, StyleStateMap, StyleValue, StyleValueStateMap, Styles, StylesInterface, StylesWithoutSelectors, type SubElementDefinition, type SubElementProps, SuffixForSelector, TEXT_STYLES, TagName, TastyConfig, type TastyElementOptions, type TastyElementProps, TastyExtensionConfig, TastyNamedColors, TastyPlugin, TastyPluginFactory, TastyPresetNames, type TastyProps, TastyThemeNames, TextStyleProps, TokenValue, Tokens, TypographyPreset, UnitHandler, type UsePropertyOptions, type UseStylesOptions, type UseStylesResult, type VariantMap, type WithVariant, allocateClassName, buildAtRuleContext, categorizeStyleKeys, cleanup, color, computeState, configure, createInjector, createStateParserContext, customFunc, deprecationWarning, destroy, dotize, extendStyles, extractStyles, filterBaseProps, filterMods, generateTypographyTokens, getConfig, getCssText, getCssTextForNode, getDisplayName, getGlobalFuncs, getGlobalKeyframes, getGlobalParser, getGlobalPredefinedStates, getGlobalPredefinedTokens, getGlobalRecipes, getIsTestEnvironment, getModSelector, getRawCSSText, getRgbValuesFromRgbaString, hasGlobalKeyframes, hasGlobalRecipes, hasStylesGenerated, hexToRgb, hslToRgbValues, inject, injectGlobal, injectRawCSS, injector, isAdvancedStateToken, isConfigLocked, isPropertyDefined, isSelector, isTestEnvironment, keyframes, mergeStyles, _modAttrs as modAttrs, normalizeColorTokenValue, okhslFunc, okhslPlugin, parseColor, parseStateKey, parseStateNotation, parseStyle, processTokens, property, renderStyles, resetConfig, resetGlobalPredefinedTokens, resolveRecipes, setGlobalPredefinedStates, setGlobalPredefinedTokens, strToRgb, stringifyStyles, stringifyTokens, styleHandlers, styleStateMapToStyleStateDataList, tasty, tastyDebug, useGlobalStyles, useKeyframes, useProperty, useRawCSS, useStyles, warn };
|
|
48
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/pipeline/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { and, falseCondition, not, or, trueCondition } from "./conditions.js";
|
|
|
7
7
|
import { simplifyCondition } from "./simplify.js";
|
|
8
8
|
import { buildExclusiveConditions, expandExclusiveOrs, expandOrConditions, isValueMapping, parseStyleEntries } from "./exclusive.js";
|
|
9
9
|
import { buildAtRulesFromVariant, conditionToCSS, modifierToCSS, parentGroupsToCSS, pseudoToCSS, rootConditionsToCSS, selectorConditionToCSS } from "./materialize.js";
|
|
10
|
+
import { emitWarning } from "./warnings.js";
|
|
10
11
|
import { parseStateKey } from "./parseStateKey.js";
|
|
11
12
|
|
|
12
13
|
//#region src/pipeline/index.ts
|
|
@@ -26,6 +27,7 @@ import { parseStateKey } from "./parseStateKey.js";
|
|
|
26
27
|
* 7. MATERIALIZE CSS - Convert conditions to CSS selectors + at-rules
|
|
27
28
|
*/
|
|
28
29
|
const pipelineCache = new Lru(5e3);
|
|
30
|
+
const transformPatternCache = new Lru(1e3);
|
|
29
31
|
/**
|
|
30
32
|
* Clear the pipeline cache (for testing)
|
|
31
33
|
*/
|
|
@@ -147,7 +149,7 @@ function getAllSelectors(key, styles) {
|
|
|
147
149
|
if (affix !== void 0) {
|
|
148
150
|
const result = processAffix(String(affix), key);
|
|
149
151
|
if (!result.valid) {
|
|
150
|
-
|
|
152
|
+
emitWarning("INVALID_SELECTOR_AFFIX", result.reason);
|
|
151
153
|
return null;
|
|
152
154
|
}
|
|
153
155
|
return result.selectors;
|
|
@@ -351,8 +353,23 @@ function processSinglePattern(pattern, key) {
|
|
|
351
353
|
* // → 'button.primary:hover'
|
|
352
354
|
*/
|
|
353
355
|
function transformPattern(pattern) {
|
|
354
|
-
|
|
356
|
+
const cached = transformPatternCache.get(pattern);
|
|
357
|
+
if (cached !== void 0) return cached;
|
|
358
|
+
const result = transformPatternInner(pattern);
|
|
359
|
+
transformPatternCache.set(pattern, result);
|
|
360
|
+
return result;
|
|
361
|
+
}
|
|
362
|
+
function transformPatternInner(pattern) {
|
|
363
|
+
const parts = [];
|
|
355
364
|
let i = 0;
|
|
365
|
+
const lastChar = () => {
|
|
366
|
+
if (parts.length === 0) return "";
|
|
367
|
+
const last = parts[parts.length - 1];
|
|
368
|
+
return last[last.length - 1] || "";
|
|
369
|
+
};
|
|
370
|
+
const ensureSpace = () => {
|
|
371
|
+
if (parts.length > 0 && lastChar() !== " ") parts.push(" ");
|
|
372
|
+
};
|
|
356
373
|
while (i < pattern.length) {
|
|
357
374
|
const char = pattern[i];
|
|
358
375
|
if (/\s/.test(char)) {
|
|
@@ -360,79 +377,66 @@ function transformPattern(pattern) {
|
|
|
360
377
|
continue;
|
|
361
378
|
}
|
|
362
379
|
if (/[>+~]/.test(char)) {
|
|
363
|
-
|
|
364
|
-
|
|
380
|
+
ensureSpace();
|
|
381
|
+
parts.push(char);
|
|
365
382
|
i++;
|
|
366
383
|
continue;
|
|
367
384
|
}
|
|
368
385
|
if (/[A-Z]/.test(char)) {
|
|
369
|
-
|
|
370
|
-
while (i < pattern.length && /[a-zA-Z0-9]/.test(pattern[i]))
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
374
|
-
if (result && !result.endsWith(" ")) result += " ";
|
|
375
|
-
result += `[data-element="${name}"]`;
|
|
386
|
+
const nameStart = i;
|
|
387
|
+
while (i < pattern.length && /[a-zA-Z0-9]/.test(pattern[i])) i++;
|
|
388
|
+
ensureSpace();
|
|
389
|
+
parts.push(`[data-element="${pattern.slice(nameStart, i)}"]`);
|
|
376
390
|
continue;
|
|
377
391
|
}
|
|
378
392
|
if (char === "@") {
|
|
379
|
-
|
|
380
|
-
|
|
393
|
+
ensureSpace();
|
|
394
|
+
parts.push("@");
|
|
381
395
|
i++;
|
|
382
396
|
continue;
|
|
383
397
|
}
|
|
384
398
|
if (char === ":") {
|
|
385
|
-
|
|
386
|
-
while (i < pattern.length && !/[\s>+~,@]/.test(pattern[i]) && !/[A-Z]/.test(pattern[i]))
|
|
387
|
-
|
|
388
|
-
i++;
|
|
389
|
-
}
|
|
390
|
-
result += pseudo;
|
|
399
|
+
const pseudoStart = i;
|
|
400
|
+
while (i < pattern.length && !/[\s>+~,@]/.test(pattern[i]) && !/[A-Z]/.test(pattern[i])) i++;
|
|
401
|
+
parts.push(pattern.slice(pseudoStart, i));
|
|
391
402
|
continue;
|
|
392
403
|
}
|
|
393
404
|
if (/[a-z]/.test(char)) {
|
|
394
|
-
|
|
395
|
-
while (i < pattern.length && /[a-z0-9-]/.test(pattern[i]))
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
if (result && !result.endsWith(" ")) result += " ";
|
|
400
|
-
result += tag;
|
|
405
|
+
const tagStart = i;
|
|
406
|
+
while (i < pattern.length && /[a-z0-9-]/.test(pattern[i])) i++;
|
|
407
|
+
ensureSpace();
|
|
408
|
+
parts.push(pattern.slice(tagStart, i));
|
|
401
409
|
continue;
|
|
402
410
|
}
|
|
403
411
|
if (char === ".") {
|
|
404
|
-
const
|
|
405
|
-
const attachToLast =
|
|
406
|
-
if (
|
|
407
|
-
|
|
412
|
+
const lc = lastChar();
|
|
413
|
+
const attachToLast = lc === "]" || lc === "@" || /[a-zA-Z0-9-]/.test(lc);
|
|
414
|
+
if (parts.length > 0 && !attachToLast && lc !== " ") parts.push(" ");
|
|
415
|
+
const clsStart = i;
|
|
408
416
|
i++;
|
|
409
|
-
while (i < pattern.length && /[a-zA-Z0-9_-]/.test(pattern[i]))
|
|
410
|
-
|
|
411
|
-
i++;
|
|
412
|
-
}
|
|
413
|
-
result += cls;
|
|
417
|
+
while (i < pattern.length && /[a-zA-Z0-9_-]/.test(pattern[i])) i++;
|
|
418
|
+
parts.push(pattern.slice(clsStart, i));
|
|
414
419
|
continue;
|
|
415
420
|
}
|
|
416
421
|
if (char === "[") {
|
|
417
|
-
const
|
|
418
|
-
const attachToLast =
|
|
419
|
-
if (
|
|
420
|
-
|
|
422
|
+
const lc = lastChar();
|
|
423
|
+
const attachToLast = lc === "]" || lc === "@" || /[a-zA-Z0-9-]/.test(lc);
|
|
424
|
+
if (parts.length > 0 && !attachToLast && lc !== " ") parts.push(" ");
|
|
425
|
+
const attrStart = i;
|
|
421
426
|
let depth = 0;
|
|
422
427
|
while (i < pattern.length) {
|
|
423
|
-
attr += pattern[i];
|
|
424
428
|
if (pattern[i] === "[") depth++;
|
|
425
429
|
if (pattern[i] === "]") depth--;
|
|
426
430
|
i++;
|
|
427
431
|
if (depth === 0) break;
|
|
428
432
|
}
|
|
429
|
-
|
|
433
|
+
parts.push(pattern.slice(attrStart, i));
|
|
430
434
|
continue;
|
|
431
435
|
}
|
|
432
|
-
|
|
436
|
+
parts.push(char);
|
|
433
437
|
i++;
|
|
434
438
|
}
|
|
435
|
-
return
|
|
439
|
+
return parts.join("");
|
|
436
440
|
}
|
|
437
441
|
/**
|
|
438
442
|
* Determine if the sub-element key should be auto-injected based on pattern ending.
|