windrunner 1.1.2 → 1.1.3

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/dist/index.js CHANGED
@@ -20,9 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  var index_exports = {};
21
21
  __export(index_exports, {
22
22
  compileClass: () => compileClass,
23
+ compileCriticalCss: () => compileCriticalCss,
23
24
  createWindrunner: () => createWindrunner,
24
25
  defineResponsiveUtilities: () => defineResponsiveUtilities,
25
26
  defineUtilities: () => defineUtilities,
27
+ extractClassNames: () => extractClassNames,
26
28
  parseClass: () => parseClass,
27
29
  plugin: () => plugin,
28
30
  windrunner: () => windrunner
@@ -1385,29 +1387,70 @@ var config_default = configOptions;
1385
1387
  function isFunction(fn) {
1386
1388
  return fn && {}.toString.call(fn) === "[object Function]";
1387
1389
  }
1390
+ var configCache = /* @__PURE__ */ new WeakMap();
1391
+ var defaultContextCache = null;
1392
+ function createLazyTheme(userTheme = {}, userThemeExtend = {}) {
1393
+ const resolved = /* @__PURE__ */ new Map();
1394
+ const defaultTheme = config_default.theme;
1395
+ return new Proxy({}, {
1396
+ get(_, key) {
1397
+ if (resolved.has(key)) {
1398
+ return resolved.get(key);
1399
+ }
1400
+ let value = Object.prototype.hasOwnProperty.call(userTheme, key) ? userTheme[key] : defaultTheme[key];
1401
+ if (isFunction(value)) {
1402
+ value = value({
1403
+ theme: (keyRef) => {
1404
+ if (resolved.has(keyRef)) return resolved.get(keyRef);
1405
+ return createLazyTheme(userTheme, userThemeExtend)[keyRef];
1406
+ }
1407
+ });
1408
+ }
1409
+ if (userThemeExtend[key]) {
1410
+ value = Object.assign({}, value, userThemeExtend[key]);
1411
+ }
1412
+ resolved.set(key, value);
1413
+ return value;
1414
+ },
1415
+ has(_, key) {
1416
+ return key in defaultTheme || key in userTheme;
1417
+ },
1418
+ ownKeys(_) {
1419
+ return [.../* @__PURE__ */ new Set([...Object.keys(defaultTheme), ...Object.keys(userTheme)])];
1420
+ },
1421
+ getOwnPropertyDescriptor(_, key) {
1422
+ if (key in defaultTheme || key in userTheme) {
1423
+ return {
1424
+ enumerable: true,
1425
+ configurable: true
1426
+ };
1427
+ }
1428
+ }
1429
+ });
1430
+ }
1388
1431
  function getConfigOptions(options = {}, pluginKeys = []) {
1432
+ if (!options || typeof options === "object" && Object.keys(options).length === 0) {
1433
+ if (!defaultContextCache) {
1434
+ defaultContextCache = {
1435
+ ...config_default,
1436
+ theme: createLazyTheme({}, {})
1437
+ };
1438
+ }
1439
+ return defaultContextCache;
1440
+ }
1441
+ if (configCache.has(options)) {
1442
+ return configCache.get(options);
1443
+ }
1389
1444
  const { theme: theme2 = {} } = options;
1390
1445
  const { extend: themeExtend = {} } = theme2;
1391
- const newTheme = {};
1392
- const themeKeys = Object.keys(config_default.theme);
1393
- themeKeys.forEach((key) => {
1394
- newTheme[key] = Object.prototype.hasOwnProperty.call(theme2, key) ? theme2[key] : config_default.theme[key];
1395
- });
1396
- themeKeys.forEach((key) => {
1397
- if (isFunction(newTheme[key])) {
1398
- newTheme[key] = newTheme[key]({
1399
- theme: (keyRef) => newTheme[keyRef]
1400
- });
1401
- }
1402
- if (themeExtend[key]) {
1403
- newTheme[key] = Object.assign({}, newTheme[key], themeExtend[key]);
1404
- }
1405
- });
1406
- return {
1446
+ const lazyTheme = createLazyTheme(theme2, themeExtend);
1447
+ const config = {
1407
1448
  ...config_default,
1408
1449
  ...options,
1409
- theme: newTheme
1450
+ theme: lazyTheme
1410
1451
  };
1452
+ configCache.set(options, config);
1453
+ return config;
1411
1454
  }
1412
1455
 
1413
1456
  // src/constants.js
@@ -1491,112 +1534,93 @@ function escapeCssIdentifier(value) {
1491
1534
  }
1492
1535
  function appendImportant(declaration, isImportant) {
1493
1536
  if (!isImportant) return declaration;
1494
- const entries = declaration.split(";").map((item) => item.trim()).filter(Boolean).map((item) => item.includes("!important") ? item : `${item} !important`);
1495
- return `${entries.join("; ")};`;
1537
+ return declaration.replace(/([^;{}]+);/g, (match, decl) => {
1538
+ const trimmed = decl.trim();
1539
+ if (!trimmed || trimmed.includes("!important")) return match;
1540
+ return `${trimmed} !important;`;
1541
+ });
1496
1542
  }
1497
1543
  function splitByVariantDelimiter(token) {
1498
1544
  const parts = [];
1499
- let current = "";
1545
+ let start = 0;
1500
1546
  let bracketDepth = 0;
1501
1547
  for (let i = 0; i < token.length; i += 1) {
1502
1548
  const char = token[i];
1503
- if (char === "[") bracketDepth += 1;
1504
- if (char === "]") bracketDepth = Math.max(0, bracketDepth - 1);
1505
- if (char === ":" && bracketDepth === 0) {
1506
- parts.push(current);
1507
- current = "";
1508
- } else {
1509
- current += char;
1549
+ if (char === "[") {
1550
+ bracketDepth += 1;
1551
+ } else if (char === "]") {
1552
+ bracketDepth = Math.max(0, bracketDepth - 1);
1553
+ } else if (char === ":" && bracketDepth === 0) {
1554
+ parts.push(token.slice(start, i));
1555
+ start = i + 1;
1510
1556
  }
1511
1557
  }
1512
- if (current) parts.push(current);
1558
+ parts.push(token.slice(start));
1513
1559
  return parts;
1514
1560
  }
1515
1561
 
1516
1562
  // src/maps/layout.maps.js
1563
+ function createSimpleMap(prop, values, keyMap = {}) {
1564
+ const map = {};
1565
+ values.forEach((value) => {
1566
+ const key = keyMap[value] || value;
1567
+ map[key] = `${prop}: ${value};`;
1568
+ });
1569
+ return map;
1570
+ }
1517
1571
  var DISPLAY_MAP = {
1518
- block: "display: block;",
1519
- inline: "display: inline;",
1520
- "inline-block": "display: inline-block;",
1521
- flex: "display: flex;",
1522
- "inline-flex": "display: inline-flex;",
1523
- grid: "display: grid;",
1524
- "inline-grid": "display: inline-grid;",
1525
- hidden: "display: none;",
1526
- contents: "display: contents;",
1527
- "flow-root": "display: flow-root;",
1528
- "list-item": "display: list-item;",
1529
- table: "display: table;",
1530
- "inline-table": "display: inline-table;",
1531
- "table-caption": "display: table-caption;",
1532
- "table-cell": "display: table-cell;",
1533
- "table-column": "display: table-column;",
1534
- "table-column-group": "display: table-column-group;",
1535
- "table-footer-group": "display: table-footer-group;",
1536
- "table-header-group": "display: table-header-group;",
1537
- "table-row-group": "display: table-row-group;",
1538
- "table-row": "display: table-row;"
1539
- };
1540
- var POSITION_MAP = {
1541
- static: "position: static;",
1542
- fixed: "position: fixed;",
1543
- absolute: "position: absolute;",
1544
- relative: "position: relative;",
1545
- sticky: "position: sticky;"
1572
+ ...createSimpleMap("display", [
1573
+ "block",
1574
+ "inline",
1575
+ "inline-block",
1576
+ "flex",
1577
+ "inline-flex",
1578
+ "grid",
1579
+ "inline-grid",
1580
+ "contents",
1581
+ "flow-root",
1582
+ "list-item",
1583
+ "table",
1584
+ "inline-table",
1585
+ "table-caption",
1586
+ "table-cell",
1587
+ "table-column",
1588
+ "table-column-group",
1589
+ "table-footer-group",
1590
+ "table-header-group",
1591
+ "table-row-group",
1592
+ "table-row"
1593
+ ]),
1594
+ hidden: "display: none;"
1595
+ // Special case
1546
1596
  };
1597
+ var POSITION_MAP = createSimpleMap("position", [
1598
+ "static",
1599
+ "fixed",
1600
+ "absolute",
1601
+ "relative",
1602
+ "sticky"
1603
+ ]);
1547
1604
  var VISIBILITY_MAP = {
1548
- visible: "visibility: visible;",
1549
- invisible: "visibility: hidden;",
1550
- collapse: "visibility: collapse;"
1551
- };
1552
- var OVERFLOW_MAP = {
1553
- auto: "overflow: auto;",
1554
- hidden: "overflow: hidden;",
1555
- clip: "overflow: clip;",
1556
- visible: "overflow: visible;",
1557
- scroll: "overflow: scroll;"
1558
- };
1559
- var OVERFLOW_X_MAP = {
1560
- auto: "overflow-x: auto;",
1561
- hidden: "overflow-x: hidden;",
1562
- clip: "overflow-x: clip;",
1563
- visible: "overflow-x: visible;",
1564
- scroll: "overflow-x: scroll;"
1565
- };
1566
- var OVERFLOW_Y_MAP = {
1567
- auto: "overflow-y: auto;",
1568
- hidden: "overflow-y: hidden;",
1569
- clip: "overflow-y: clip;",
1570
- visible: "overflow-y: visible;",
1571
- scroll: "overflow-y: scroll;"
1572
- };
1573
- var OVERSCROLL_MAP = {
1574
- auto: "overscroll-behavior: auto;",
1575
- contain: "overscroll-behavior: contain;",
1576
- none: "overscroll-behavior: none;"
1577
- };
1578
- var OVERSCROLL_X_MAP = {
1579
- auto: "overscroll-behavior-x: auto;",
1580
- contain: "overscroll-behavior-x: contain;",
1581
- none: "overscroll-behavior-x: none;"
1582
- };
1583
- var OVERSCROLL_Y_MAP = {
1584
- auto: "overscroll-behavior-y: auto;",
1585
- contain: "overscroll-behavior-y: contain;",
1586
- none: "overscroll-behavior-y: none;"
1605
+ ...createSimpleMap("visibility", ["visible", "collapse"]),
1606
+ invisible: "visibility: hidden;"
1607
+ // Key differs from value
1587
1608
  };
1609
+ var OVERFLOW_VALUES = ["auto", "hidden", "clip", "visible", "scroll"];
1610
+ var OVERFLOW_MAP = createSimpleMap("overflow", OVERFLOW_VALUES);
1611
+ var OVERFLOW_X_MAP = createSimpleMap("overflow-x", OVERFLOW_VALUES);
1612
+ var OVERFLOW_Y_MAP = createSimpleMap("overflow-y", OVERFLOW_VALUES);
1613
+ var OVERSCROLL_VALUES = ["auto", "contain", "none"];
1614
+ var OVERSCROLL_MAP = createSimpleMap("overscroll-behavior", OVERSCROLL_VALUES);
1615
+ var OVERSCROLL_X_MAP = createSimpleMap("overscroll-behavior-x", OVERSCROLL_VALUES);
1616
+ var OVERSCROLL_Y_MAP = createSimpleMap("overscroll-behavior-y", OVERSCROLL_VALUES);
1588
1617
  var FLOAT_MAP = {
1589
- left: "float: left;",
1590
- right: "float: right;",
1591
- none: "float: none;",
1618
+ ...createSimpleMap("float", ["left", "right", "none"]),
1592
1619
  start: "float: inline-start;",
1593
1620
  end: "float: inline-end;"
1594
1621
  };
1595
1622
  var CLEAR_MAP = {
1596
- left: "clear: left;",
1597
- right: "clear: right;",
1598
- both: "clear: both;",
1599
- none: "clear: none;",
1623
+ ...createSimpleMap("clear", ["left", "right", "both", "none"]),
1600
1624
  start: "clear: inline-start;",
1601
1625
  end: "clear: inline-end;"
1602
1626
  };
@@ -1604,13 +1628,13 @@ var ISOLATION_MAP = {
1604
1628
  isolate: "isolation: isolate;",
1605
1629
  "isolation-auto": "isolation: auto;"
1606
1630
  };
1607
- var OBJECT_FIT_MAP = {
1608
- contain: "object-fit: contain;",
1609
- cover: "object-fit: cover;",
1610
- fill: "object-fit: fill;",
1611
- none: "object-fit: none;",
1612
- "scale-down": "object-fit: scale-down;"
1613
- };
1631
+ var OBJECT_FIT_MAP = createSimpleMap("object-fit", [
1632
+ "contain",
1633
+ "cover",
1634
+ "fill",
1635
+ "none",
1636
+ "scale-down"
1637
+ ]);
1614
1638
  var TRANSFORM_STYLE_MAP = {
1615
1639
  "transform-style-flat": "transform-style: flat;",
1616
1640
  "transform-style-3d": "transform-style: preserve-3d;",
@@ -1628,81 +1652,64 @@ var BOX_SIZING_MAP = {
1628
1652
  border: "box-sizing: border-box;",
1629
1653
  content: "box-sizing: content-box;"
1630
1654
  };
1655
+ var BREAK_AFTER_BEFORE_VALUES = [
1656
+ "auto",
1657
+ "avoid",
1658
+ "avoid-page",
1659
+ "avoid-column",
1660
+ "page",
1661
+ "left",
1662
+ "right",
1663
+ "recto",
1664
+ "verso"
1665
+ ];
1631
1666
  var BREAK_AFTER_MAP = {
1632
- auto: "break-after: auto;",
1633
- avoid: "break-after: avoid;",
1634
- "avoid-page": "break-after: avoid-page;",
1635
- "avoid-column": "break-after: avoid-column;",
1636
- page: "break-after: page;",
1637
- all: "break-after: all;",
1638
- left: "break-after: left;",
1639
- right: "break-after: right;",
1640
- recto: "break-after: recto;",
1641
- verso: "break-after: verso;"
1642
- };
1643
- var BREAK_BEFORE_MAP = {
1644
- auto: "break-before: auto;",
1645
- avoid: "break-before: avoid;",
1646
- "avoid-page": "break-before: avoid-page;",
1647
- "avoid-column": "break-before: avoid-column;",
1648
- page: "break-before: page;",
1649
- left: "break-before: left;",
1650
- right: "break-before: right;",
1651
- recto: "break-before: recto;",
1652
- verso: "break-before: verso;"
1653
- };
1654
- var BREAK_INSIDE_MAP = {
1655
- auto: "break-inside: auto;",
1656
- avoid: "break-inside: avoid;",
1657
- "avoid-page": "break-inside: avoid-page;",
1658
- "avoid-column": "break-inside: avoid-column;"
1659
- };
1660
- var BOX_DECORATION_BREAK_MAP = {
1661
- slice: "box-decoration-break: slice;",
1662
- clone: "box-decoration-break: clone;"
1663
- };
1664
- var HYPHENS_MAP = {
1665
- none: "hyphens: none;",
1666
- manual: "hyphens: manual;",
1667
- auto: "hyphens: auto;"
1668
- };
1669
- var COLOR_SCHEME_MAP = {
1670
- light: "color-scheme: light;",
1671
- dark: "color-scheme: dark;",
1672
- normal: "color-scheme: normal;"
1673
- };
1674
- var SCROLLBAR_COLOR_MAP = {
1675
- auto: "scrollbar-color: auto;",
1676
- transparent: "scrollbar-color: transparent;",
1677
- current: "scrollbar-color: currentColor;"
1678
- };
1679
- var SCROLLBAR_WIDTH_MAP = {
1680
- auto: "scrollbar-width: auto;",
1681
- thin: "scrollbar-width: thin;",
1682
- none: "scrollbar-width: none;"
1667
+ ...createSimpleMap("break-after", BREAK_AFTER_BEFORE_VALUES),
1668
+ all: "break-after: all;"
1683
1669
  };
1670
+ var BREAK_BEFORE_MAP = createSimpleMap("break-before", BREAK_AFTER_BEFORE_VALUES);
1671
+ var BREAK_INSIDE_MAP = createSimpleMap("break-inside", [
1672
+ "auto",
1673
+ "avoid",
1674
+ "avoid-page",
1675
+ "avoid-column"
1676
+ ]);
1677
+ var BOX_DECORATION_BREAK_MAP = createSimpleMap("box-decoration-break", [
1678
+ "slice",
1679
+ "clone"
1680
+ ]);
1681
+ var HYPHENS_MAP = createSimpleMap("hyphens", ["none", "manual", "auto"]);
1682
+ var COLOR_SCHEME_MAP = createSimpleMap("color-scheme", [
1683
+ "light",
1684
+ "dark",
1685
+ "normal"
1686
+ ]);
1687
+ var SCROLLBAR_COLOR_MAP = createSimpleMap("scrollbar-color", [
1688
+ "auto",
1689
+ "transparent",
1690
+ "current"
1691
+ ]);
1692
+ var SCROLLBAR_WIDTH_MAP = createSimpleMap("scrollbar-width", [
1693
+ "auto",
1694
+ "thin",
1695
+ "none"
1696
+ ]);
1684
1697
  var SCROLLBAR_GUTTER_MAP = {
1685
1698
  auto: "scrollbar-gutter: auto;",
1686
1699
  stable: "scrollbar-gutter: stable;",
1687
1700
  "stable-both-edges": "scrollbar-gutter: stable both-edges;",
1688
1701
  "both-edges": "scrollbar-gutter: both-edges;"
1689
1702
  };
1690
- var TABLE_LAYOUT_MAP = {
1691
- auto: "table-layout: auto;",
1692
- fixed: "table-layout: fixed;"
1693
- };
1694
- var CAPTION_SIDE_MAP = {
1695
- top: "caption-side: top;",
1696
- bottom: "caption-side: bottom;"
1697
- };
1698
- var BORDER_COLLAPSE_MAP = {
1699
- collapse: "border-collapse: collapse;",
1700
- separate: "border-collapse: separate;"
1701
- };
1702
- var SCROLL_BEHAVIOR_MAP = {
1703
- auto: "scroll-behavior: auto;",
1704
- smooth: "scroll-behavior: smooth;"
1705
- };
1703
+ var TABLE_LAYOUT_MAP = createSimpleMap("table-layout", ["auto", "fixed"]);
1704
+ var CAPTION_SIDE_MAP = createSimpleMap("caption-side", ["top", "bottom"]);
1705
+ var BORDER_COLLAPSE_MAP = createSimpleMap("border-collapse", [
1706
+ "collapse",
1707
+ "separate"
1708
+ ]);
1709
+ var SCROLL_BEHAVIOR_MAP = createSimpleMap("scroll-behavior", [
1710
+ "auto",
1711
+ "smooth"
1712
+ ]);
1706
1713
  var SIDE_PROPS = {
1707
1714
  "": [""],
1708
1715
  t: ["-top"],
@@ -1733,71 +1740,69 @@ var ROUNDED_PROPS = {
1733
1740
  };
1734
1741
 
1735
1742
  // src/maps/interactivity.maps.js
1736
- var CURSOR_MAP = {
1737
- auto: "cursor: auto;",
1738
- default: "cursor: default;",
1739
- pointer: "cursor: pointer;",
1740
- wait: "cursor: wait;",
1741
- text: "cursor: text;",
1742
- move: "cursor: move;",
1743
- help: "cursor: help;",
1744
- "not-allowed": "cursor: not-allowed;",
1745
- none: "cursor: none;",
1746
- "context-menu": "cursor: context-menu;",
1747
- progress: "cursor: progress;",
1748
- cell: "cursor: cell;",
1749
- crosshair: "cursor: crosshair;",
1750
- "vertical-text": "cursor: vertical-text;",
1751
- alias: "cursor: alias;",
1752
- copy: "cursor: copy;",
1753
- "no-drop": "cursor: no-drop;",
1754
- grab: "cursor: grab;",
1755
- grabbing: "cursor: grabbing;",
1756
- "all-scroll": "cursor: all-scroll;",
1757
- "zoom-in": "cursor: zoom-in;",
1758
- "zoom-out": "cursor: zoom-out;"
1759
- };
1760
- var POINTER_EVENTS_MAP = {
1761
- none: "pointer-events: none;",
1762
- auto: "pointer-events: auto;"
1763
- };
1764
- var USER_SELECT_MAP = {
1765
- none: "user-select: none;",
1766
- text: "user-select: text;",
1767
- all: "user-select: all;",
1768
- auto: "user-select: auto;"
1769
- };
1770
- var APPEARANCE_MAP = {
1771
- none: "appearance: none;",
1772
- auto: "appearance: auto;"
1773
- };
1774
- var TOUCH_ACTION_MAP = {
1775
- auto: "touch-action: auto;",
1776
- none: "touch-action: none;",
1777
- "pan-x": "touch-action: pan-x;",
1778
- "pan-left": "touch-action: pan-left;",
1779
- "pan-right": "touch-action: pan-right;",
1780
- "pan-y": "touch-action: pan-y;",
1781
- "pan-up": "touch-action: pan-up;",
1782
- "pan-down": "touch-action: pan-down;",
1783
- "pinch-zoom": "touch-action: pinch-zoom;",
1784
- manipulation: "touch-action: manipulation;"
1785
- };
1743
+ function createSimpleMap2(prop, values) {
1744
+ const map = {};
1745
+ values.forEach((value) => {
1746
+ map[value] = `${prop}: ${value};`;
1747
+ });
1748
+ return map;
1749
+ }
1750
+ var CURSOR_MAP = createSimpleMap2("cursor", [
1751
+ "auto",
1752
+ "default",
1753
+ "pointer",
1754
+ "wait",
1755
+ "text",
1756
+ "move",
1757
+ "help",
1758
+ "not-allowed",
1759
+ "none",
1760
+ "context-menu",
1761
+ "progress",
1762
+ "cell",
1763
+ "crosshair",
1764
+ "vertical-text",
1765
+ "alias",
1766
+ "copy",
1767
+ "no-drop",
1768
+ "grab",
1769
+ "grabbing",
1770
+ "all-scroll",
1771
+ "zoom-in",
1772
+ "zoom-out"
1773
+ ]);
1774
+ var POINTER_EVENTS_MAP = createSimpleMap2("pointer-events", ["none", "auto"]);
1775
+ var USER_SELECT_MAP = createSimpleMap2("user-select", [
1776
+ "none",
1777
+ "text",
1778
+ "all",
1779
+ "auto"
1780
+ ]);
1781
+ var APPEARANCE_MAP = createSimpleMap2("appearance", ["none", "auto"]);
1782
+ var TOUCH_ACTION_MAP = createSimpleMap2("touch-action", [
1783
+ "auto",
1784
+ "none",
1785
+ "pan-x",
1786
+ "pan-left",
1787
+ "pan-right",
1788
+ "pan-y",
1789
+ "pan-up",
1790
+ "pan-down",
1791
+ "pinch-zoom",
1792
+ "manipulation"
1793
+ ]);
1786
1794
  var OUTLINE_STYLE_MAP = {
1787
1795
  none: "outline: 2px solid transparent; outline-offset: 2px;",
1788
- solid: "outline-style: solid;",
1789
- dashed: "outline-style: dashed;",
1790
- dotted: "outline-style: dotted;",
1791
- double: "outline-style: double;"
1792
- };
1793
- var BORDER_STYLE_MAP = {
1794
- solid: "border-style: solid;",
1795
- dashed: "border-style: dashed;",
1796
- dotted: "border-style: dotted;",
1797
- double: "border-style: double;",
1798
- hidden: "border-style: hidden;",
1799
- none: "border-style: none;"
1796
+ ...createSimpleMap2("outline-style", ["solid", "dashed", "dotted", "double"])
1800
1797
  };
1798
+ var BORDER_STYLE_MAP = createSimpleMap2("border-style", [
1799
+ "solid",
1800
+ "dashed",
1801
+ "dotted",
1802
+ "double",
1803
+ "hidden",
1804
+ "none"
1805
+ ]);
1801
1806
  var TRANSITION_PROPERTY_MAP = {
1802
1807
  none: "none",
1803
1808
  all: "all",
@@ -3250,7 +3255,8 @@ function buildDivideDeclaration(baseToken, theme2) {
3250
3255
  // src/plugins.js
3251
3256
  var PluginRegistry = class {
3252
3257
  constructor() {
3253
- this.utilities = /* @__PURE__ */ new Map();
3258
+ this.exactUtilities = /* @__PURE__ */ new Map();
3259
+ this.regexUtilities = [];
3254
3260
  this.variants = /* @__PURE__ */ new Map();
3255
3261
  }
3256
3262
  /**
@@ -3259,7 +3265,11 @@ var PluginRegistry = class {
3259
3265
  * @param {Function|string} handler - Function that returns CSS or CSS string
3260
3266
  */
3261
3267
  addUtility(pattern, handler) {
3262
- this.utilities.set(pattern, handler);
3268
+ if (pattern instanceof RegExp) {
3269
+ this.regexUtilities.push([pattern, handler]);
3270
+ } else {
3271
+ this.exactUtilities.set(pattern, handler);
3272
+ }
3263
3273
  }
3264
3274
  /**
3265
3275
  * Register multiple utilities at once
@@ -3289,18 +3299,22 @@ var PluginRegistry = class {
3289
3299
  }
3290
3300
  /**
3291
3301
  * Check if a token matches any custom utility pattern
3302
+ * Optimized: O(1) fast path for exact matches, O(n) only for regex patterns
3292
3303
  * @param {string} token - The base token to match
3293
3304
  * @returns {Object|null} - { handler, match } or null
3294
3305
  */
3295
3306
  matchUtility(token) {
3296
- for (const [pattern, handler] of this.utilities) {
3297
- if (pattern instanceof RegExp) {
3298
- const match = pattern.exec(token);
3299
- if (match) {
3300
- return { handler, match };
3301
- }
3302
- } else if (pattern === token) {
3303
- return { handler, match: [token] };
3307
+ if (this.exactUtilities.has(token)) {
3308
+ return {
3309
+ handler: this.exactUtilities.get(token),
3310
+ match: [token]
3311
+ };
3312
+ }
3313
+ for (let i = 0; i < this.regexUtilities.length; i += 1) {
3314
+ const [pattern, handler] = this.regexUtilities[i];
3315
+ const match = pattern.exec(token);
3316
+ if (match) {
3317
+ return { handler, match };
3304
3318
  }
3305
3319
  }
3306
3320
  return null;
@@ -3317,7 +3331,10 @@ var PluginRegistry = class {
3317
3331
  * Get all registered utility patterns (for debugging)
3318
3332
  */
3319
3333
  getUtilities() {
3320
- return Array.from(this.utilities.keys());
3334
+ return [
3335
+ ...Array.from(this.exactUtilities.keys()),
3336
+ ...this.regexUtilities.map(([pattern]) => pattern)
3337
+ ];
3321
3338
  }
3322
3339
  /**
3323
3340
  * Get all registered variant names (for debugging)
@@ -3329,7 +3346,8 @@ var PluginRegistry = class {
3329
3346
  * Clear all registered plugins
3330
3347
  */
3331
3348
  clear() {
3332
- this.utilities.clear();
3349
+ this.exactUtilities.clear();
3350
+ this.regexUtilities = [];
3333
3351
  this.variants.clear();
3334
3352
  }
3335
3353
  };
@@ -3534,8 +3552,26 @@ function extractPrefix(token) {
3534
3552
  }
3535
3553
  return prefix;
3536
3554
  }
3555
+ var UNKNOWN_PREFIX_CACHE = /* @__PURE__ */ new Set();
3556
+ var MAX_UNKNOWN_CACHE_SIZE = 500;
3537
3557
  function checkAllBuilders(baseToken, theme2) {
3538
- return buildLayoutDeclaration(baseToken, theme2) || buildPositionInsetDeclaration(baseToken, theme2) || buildSpacingDeclaration(baseToken, theme2) || buildSpaceBetweenDeclaration(baseToken, theme2) || buildGapDeclaration(baseToken, theme2) || buildDimensionDeclaration(baseToken, theme2) || buildFlexGridDeclaration(baseToken, theme2) || buildBorderDeclaration(baseToken, theme2) || buildBorderRadiusDeclaration(baseToken, theme2) || buildBorderSpacingDeclaration(baseToken, theme2) || buildDivideDeclaration(baseToken, theme2) || buildOpacityDeclaration(baseToken, theme2) || buildShadowDeclaration(baseToken, theme2) || buildInsetShadowDeclaration(baseToken, theme2) || buildInsetRingDeclaration(baseToken, theme2) || buildRingDeclaration(baseToken, theme2) || buildRingOffsetDeclaration(baseToken, theme2) || buildTextShadowDeclaration(baseToken, theme2) || buildTransitionDeclaration(baseToken) || buildTransformDeclaration(baseToken, theme2) || buildFilterDeclaration(baseToken, theme2) || buildBackgroundDeclaration(baseToken, theme2) || buildGradientDeclaration(baseToken, theme2) || buildColorDeclaration(baseToken, theme2) || buildTypographyDeclaration(baseToken, theme2) || buildBlendingDeclaration(baseToken) || buildInteractivityDeclaration(baseToken, theme2) || buildAnimationDeclaration(baseToken) || buildMaskDeclaration(baseToken) || buildContainerQueryDeclaration(baseToken) || buildScrollSnapDeclaration(baseToken) || buildAccessibilityDeclaration(baseToken) || buildZoomDeclaration(baseToken, theme2) || buildForcedColorDeclaration(baseToken);
3558
+ const prefix = extractPrefix(baseToken);
3559
+ if (UNKNOWN_PREFIX_CACHE.has(prefix)) {
3560
+ return void 0;
3561
+ }
3562
+ const result = buildLayoutDeclaration(baseToken, theme2) || buildPositionInsetDeclaration(baseToken, theme2) || buildSpacingDeclaration(baseToken, theme2) || buildSpaceBetweenDeclaration(baseToken, theme2) || buildGapDeclaration(baseToken, theme2) || buildDimensionDeclaration(baseToken, theme2) || buildFlexGridDeclaration(baseToken, theme2) || buildBorderDeclaration(baseToken, theme2) || buildBorderRadiusDeclaration(baseToken, theme2) || buildBorderSpacingDeclaration(baseToken, theme2) || buildDivideDeclaration(baseToken, theme2) || buildOpacityDeclaration(baseToken, theme2) || buildShadowDeclaration(baseToken, theme2) || buildInsetShadowDeclaration(baseToken, theme2) || buildInsetRingDeclaration(baseToken, theme2) || buildRingDeclaration(baseToken, theme2) || buildRingOffsetDeclaration(baseToken, theme2) || buildTextShadowDeclaration(baseToken, theme2) || buildTransitionDeclaration(baseToken) || buildTransformDeclaration(baseToken, theme2) || buildFilterDeclaration(baseToken, theme2) || buildBackgroundDeclaration(baseToken, theme2) || buildGradientDeclaration(baseToken, theme2) || buildColorDeclaration(baseToken, theme2) || buildTypographyDeclaration(baseToken, theme2) || buildBlendingDeclaration(baseToken) || buildInteractivityDeclaration(baseToken, theme2) || buildAnimationDeclaration(baseToken) || buildMaskDeclaration(baseToken) || buildContainerQueryDeclaration(baseToken) || buildScrollSnapDeclaration(baseToken) || buildAccessibilityDeclaration(baseToken) || buildZoomDeclaration(baseToken, theme2) || buildForcedColorDeclaration(baseToken);
3563
+ if (!result && prefix) {
3564
+ if (UNKNOWN_PREFIX_CACHE.size >= MAX_UNKNOWN_CACHE_SIZE) {
3565
+ const toRemove = Math.floor(MAX_UNKNOWN_CACHE_SIZE / 2);
3566
+ const iterator = UNKNOWN_PREFIX_CACHE.values();
3567
+ for (let i = 0; i < toRemove; i += 1) {
3568
+ const value = iterator.next().value;
3569
+ if (value) UNKNOWN_PREFIX_CACHE.delete(value);
3570
+ }
3571
+ }
3572
+ UNKNOWN_PREFIX_CACHE.add(prefix);
3573
+ }
3574
+ return result;
3539
3575
  }
3540
3576
  function compileBaseToken(baseToken, theme2, pluginRegistry) {
3541
3577
  if (pluginRegistry) {
@@ -3779,6 +3815,30 @@ function compileRuntimeClassNameWithContext(className, context) {
3779
3815
  function compileClass(className, options = {}) {
3780
3816
  return compileRuntimeClassNameWithContext(className, resolveRuntimeContext(options));
3781
3817
  }
3818
+ function compileCriticalCss(classNames, options = {}) {
3819
+ const classList = typeof classNames === "string" ? classNames.split(/\s+/).filter(Boolean) : Array.isArray(classNames) ? classNames.flatMap(
3820
+ (str) => typeof str === "string" ? str.split(/\s+/).filter(Boolean) : []
3821
+ ) : [];
3822
+ const context = resolveRuntimeContext(options);
3823
+ const cssRules = /* @__PURE__ */ new Set();
3824
+ classList.forEach((className) => {
3825
+ const css = compileRuntimeClassNameWithContext(className, context);
3826
+ if (css) {
3827
+ cssRules.add(css);
3828
+ }
3829
+ });
3830
+ return Array.from(cssRules).join("\n");
3831
+ }
3832
+ function extractClassNames(html) {
3833
+ const classSet = /* @__PURE__ */ new Set();
3834
+ const classRegex = /class(?:Name)?=["']([^"']+)["']/g;
3835
+ let match;
3836
+ while ((match = classRegex.exec(html)) !== null) {
3837
+ const classes = match[1].split(/\s+/).filter(Boolean);
3838
+ classes.forEach((cls) => classSet.add(cls));
3839
+ }
3840
+ return Array.from(classSet);
3841
+ }
3782
3842
 
3783
3843
  // src/preflight.js
3784
3844
  var preflight = `
@@ -3926,7 +3986,16 @@ function createWindrunner(options = {}) {
3926
3986
  const cssRule = compileWithCache(className);
3927
3987
  if (!cssRule) {
3928
3988
  ensureCompatStyle();
3929
- if (onError) onError(className);
3989
+ if (onError) {
3990
+ const parsed = parseClass(className, context.screens, context.containers);
3991
+ const errorContext = {
3992
+ reason: parsed ? "unknown-utility" : "parse-error",
3993
+ baseToken: parsed ? parsed.baseToken : className,
3994
+ variants: parsed ? parsed.variants : void 0,
3995
+ details: parsed ? `Could not compile utility "${parsed.baseToken}"${parsed.variants.length ? ` with variants: ${parsed.variants.join(", ")}` : ""}` : `Failed to parse class name "${className}"`
3996
+ };
3997
+ onError(className, errorContext);
3998
+ }
3930
3999
  } else {
3931
4000
  insertRule(cssRule);
3932
4001
  if (onCompile) onCompile(className, cssRule);
@@ -3950,9 +4019,39 @@ function createWindrunner(options = {}) {
3950
4019
  };
3951
4020
  const scan = (root = document) => {
3952
4021
  if (typeof document !== "object" || !root) return;
3953
- if (root.nodeType === 1) processElementTree(root);
4022
+ const startTime = typeof performance !== "undefined" ? performance.now() : Date.now();
4023
+ const scannedElements = /* @__PURE__ */ new Set();
4024
+ const foundClasses = /* @__PURE__ */ new Set();
4025
+ const initialRuleCount = insertedRules.size;
4026
+ if (root.nodeType === 1) {
4027
+ processElementTree(root);
4028
+ if (root.classList) {
4029
+ scannedElements.add(root);
4030
+ root.classList.forEach((cls) => foundClasses.add(cls));
4031
+ }
4032
+ }
3954
4033
  const elements = root.querySelectorAll ? root.querySelectorAll("[class]") : [];
3955
- elements.forEach((element) => processElement(element));
4034
+ elements.forEach((element) => {
4035
+ processElement(element);
4036
+ scannedElements.add(element);
4037
+ if (element.classList) {
4038
+ element.classList.forEach((cls) => foundClasses.add(cls));
4039
+ }
4040
+ });
4041
+ if (typeof options.onScanComplete === "function") {
4042
+ const endTime = typeof performance !== "undefined" ? performance.now() : Date.now();
4043
+ const stats = {
4044
+ elementCount: scannedElements.size,
4045
+ classCount: foundClasses.size,
4046
+ ruleCount: insertedRules.size - initialRuleCount,
4047
+ duration: endTime - startTime
4048
+ };
4049
+ if (typeof requestAnimationFrame === "function") {
4050
+ requestAnimationFrame(() => options.onScanComplete(stats));
4051
+ } else {
4052
+ setTimeout(() => options.onScanComplete(stats), 0);
4053
+ }
4054
+ }
3956
4055
  };
3957
4056
  const flushQueue = () => {
3958
4057
  scheduled = false;
@@ -3985,12 +4084,18 @@ function createWindrunner(options = {}) {
3985
4084
  });
3986
4085
  scheduleFlush();
3987
4086
  });
3988
- observer.observe(root, {
3989
- childList: true,
3990
- subtree: true,
3991
- attributes: true,
3992
- attributeFilter: ["class"]
3993
- });
4087
+ const observerConfig = options.observerOptions || {};
4088
+ const finalConfig = {
4089
+ childList: observerConfig.childList !== false,
4090
+ // default: true
4091
+ subtree: observerConfig.subtree !== false,
4092
+ // default: true
4093
+ attributes: observerConfig.attributes !== false,
4094
+ // default: true
4095
+ attributeFilter: observerConfig.attributeFilter || ["class"]
4096
+ // default: ["class"]
4097
+ };
4098
+ observer.observe(root, finalConfig);
3994
4099
  };
3995
4100
  const disconnect = () => {
3996
4101
  pendingElements.clear();
@@ -4068,10 +4173,13 @@ function windrunner(options = {}) {
4068
4173
  // Annotate the CommonJS export names for ESM import in node:
4069
4174
  0 && (module.exports = {
4070
4175
  compileClass,
4176
+ compileCriticalCss,
4071
4177
  createWindrunner,
4072
4178
  defineResponsiveUtilities,
4073
4179
  defineUtilities,
4180
+ extractClassNames,
4074
4181
  parseClass,
4075
4182
  plugin,
4076
4183
  windrunner
4077
4184
  });
4185
+ //# sourceMappingURL=index.js.map