@tenphi/tasty 2.1.2 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/{collector-LuU1vZ68.d.ts → collector-BQHl-atL.d.ts} +12 -2
- package/dist/{collector-C4sagPeG.js → collector-W0bezf67.js} +24 -11
- package/dist/collector-W0bezf67.js.map +1 -0
- package/dist/{config-BovFXQil.js → config-64Uwyc2X.js} +179 -77
- package/dist/config-64Uwyc2X.js.map +1 -0
- package/dist/{config-vuCRkBWX.d.ts → config-aro6t9gs.d.ts} +43 -4
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +6 -6
- package/dist/{core-CpKZ2RrZ.js → core-PLIDTtQC.js} +18 -12
- package/dist/core-PLIDTtQC.js.map +1 -0
- package/dist/{css-writer-BYgviy4G.js → css-writer-jWRnDIy6.js} +28 -6
- package/dist/css-writer-jWRnDIy6.js.map +1 -0
- package/dist/{format-rules-BBK7s2il.js → format-rules-Dv0JpQgQ.js} +2 -2
- package/dist/{format-rules-BBK7s2il.js.map → format-rules-Dv0JpQgQ.js.map} +1 -1
- package/dist/{hydrate-DN98QICD.js → hydrate-DX8vMcau.js} +2 -2
- package/dist/{hydrate-DN98QICD.js.map → hydrate-DX8vMcau.js.map} +1 -1
- package/dist/{index-dUtwpOux.d.ts → index-Dy74C11K.d.ts} +8 -1
- package/dist/{index-ZRxZWzlj.d.ts → index-IOt-QoB7.d.ts} +32 -6
- package/dist/index.d.ts +5 -5
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/dist/{keyframes-Bzl_6mN0.js → keyframes-B-7Bm9aG.js} +3 -2
- package/dist/{keyframes-Bzl_6mN0.js.map → keyframes-B-7Bm9aG.js.map} +1 -1
- package/dist/{merge-styles-CtDJMhpJ.d.ts → merge-styles-BS-mpcci.d.ts} +2 -2
- package/dist/{merge-styles-BjdI0NVL.js → merge-styles-ucwtvIa_.js} +2 -2
- package/dist/{merge-styles-BjdI0NVL.js.map → merge-styles-ucwtvIa_.js.map} +1 -1
- package/dist/{resolve-recipes-9zJQojHT.js → resolve-recipes-prBKwyCz.js} +3 -3
- package/dist/{resolve-recipes-9zJQojHT.js.map → resolve-recipes-prBKwyCz.js.map} +1 -1
- package/dist/ssr/astro-client.js +1 -1
- package/dist/ssr/astro.d.ts +1 -12
- package/dist/ssr/astro.js +3 -3
- package/dist/ssr/astro.js.map +1 -1
- package/dist/ssr/index.d.ts +1 -1
- package/dist/ssr/index.js +3 -3
- package/dist/ssr/next.d.ts +1 -1
- package/dist/ssr/next.js +4 -4
- package/dist/ssr/next.js.map +1 -1
- package/dist/static/index.d.ts +2 -2
- package/dist/static/index.js +1 -1
- package/dist/static/index.js.map +1 -1
- package/dist/zero/babel.d.ts +1 -1
- package/dist/zero/babel.js +16 -8
- package/dist/zero/babel.js.map +1 -1
- package/dist/zero/index.d.ts +1 -1
- package/dist/zero/index.js +1 -1
- package/docs/configuration.md +44 -0
- package/docs/dsl.md +14 -13
- package/docs/ssr.md +5 -3
- package/docs/tasty-static.md +15 -0
- package/package.json +1 -1
- package/tasty.config.ts +1 -0
- package/dist/collector-C4sagPeG.js.map +0 -1
- package/dist/config-BovFXQil.js.map +0 -1
- package/dist/core-CpKZ2RrZ.js.map +0 -1
- package/dist/css-writer-BYgviy4G.js.map +0 -1
|
@@ -1374,6 +1374,93 @@ function isDevEnv() {
|
|
|
1374
1374
|
return nodeEnv !== "test" && nodeEnv !== "production";
|
|
1375
1375
|
}
|
|
1376
1376
|
//#endregion
|
|
1377
|
+
//#region src/utils/name-prefix.ts
|
|
1378
|
+
/**
|
|
1379
|
+
* Name prefix utilities for generated identifiers.
|
|
1380
|
+
*
|
|
1381
|
+
* Tasty generates three kinds of identifiers from content hashes:
|
|
1382
|
+
* - class names (used in DOM `class` attribute)
|
|
1383
|
+
* - keyframe names (used in CSS `animation`)
|
|
1384
|
+
* - counter-style names (used in CSS `list-style-type`)
|
|
1385
|
+
*
|
|
1386
|
+
* All three derive from a single configurable prefix so that an app
|
|
1387
|
+
* can namespace every identifier under one string. Discriminator letters
|
|
1388
|
+
* (`k`, `c`) keep the three kinds visually distinct in devtools — they
|
|
1389
|
+
* are not required for correctness (CSS keeps these in separate
|
|
1390
|
+
* namespaces), only for readability.
|
|
1391
|
+
*
|
|
1392
|
+
* The runtime / SSR / RSC paths must agree on the prefix; otherwise the
|
|
1393
|
+
* client-side hash for a given style will not match the server-rendered
|
|
1394
|
+
* class and hydration breaks. The zero-runtime build path uses a
|
|
1395
|
+
* different default (`'ts'`) so its classes can't collide with runtime
|
|
1396
|
+
* (`'t'`) classes when both are loaded on the same page.
|
|
1397
|
+
*/
|
|
1398
|
+
/** Default prefix used by the runtime / SSR / RSC paths. */
|
|
1399
|
+
const DEFAULT_NAME_PREFIX = "t";
|
|
1400
|
+
/** Default prefix used by the zero-runtime (`tastyStatic`) build path. */
|
|
1401
|
+
const DEFAULT_ZERO_NAME_PREFIX = "ts";
|
|
1402
|
+
/**
|
|
1403
|
+
* Allowed shape: starts with a letter or underscore, then letters/
|
|
1404
|
+
* digits/underscore/hyphen. Length capped at 32 to keep generated
|
|
1405
|
+
* names sane. Matches the CSS identifier rules for the common case
|
|
1406
|
+
* while keeping the surface conservative.
|
|
1407
|
+
*/
|
|
1408
|
+
const NAME_PREFIX_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_-]{0,31}$/;
|
|
1409
|
+
/**
|
|
1410
|
+
* Validate a `namePrefix` value.
|
|
1411
|
+
* Throws a TypeError with a descriptive message on invalid input so
|
|
1412
|
+
* misconfiguration fails loudly at `configure()` time rather than
|
|
1413
|
+
* surfacing later as broken hydration.
|
|
1414
|
+
*/
|
|
1415
|
+
function validateNamePrefix(prefix) {
|
|
1416
|
+
if (typeof prefix !== "string") throw new TypeError(`[Tasty] namePrefix must be a string, got ${typeof prefix}.`);
|
|
1417
|
+
if (!NAME_PREFIX_PATTERN.test(prefix)) throw new TypeError(`[Tasty] namePrefix "${prefix}" is invalid. It must start with a letter (a-z, A-Z) or "_", contain only letters, digits, "_" or "-", and be 1-32 characters long. Examples: "t", "ts", "myapp-", "_foo".`);
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* Build a class name: `${prefix}${hash}`.
|
|
1421
|
+
* The hash is appended verbatim — supply a separator inside the prefix
|
|
1422
|
+
* itself if you want one (e.g. `'myapp-'`).
|
|
1423
|
+
*/
|
|
1424
|
+
function makeClassName(prefix, hash) {
|
|
1425
|
+
return `${prefix}${hash}`;
|
|
1426
|
+
}
|
|
1427
|
+
/**
|
|
1428
|
+
* Build a keyframe name: `${prefix}k${suffix}`.
|
|
1429
|
+
* The `k` discriminator keeps keyframe names visually distinct from
|
|
1430
|
+
* class names sharing the same prefix. `suffix` is typically a content
|
|
1431
|
+
* hash but may be a counter for ad-hoc allocation.
|
|
1432
|
+
*/
|
|
1433
|
+
function makeKeyframeName(prefix, suffix) {
|
|
1434
|
+
return `${prefix}k${suffix}`;
|
|
1435
|
+
}
|
|
1436
|
+
/**
|
|
1437
|
+
* Build a counter-style name: `${prefix}c${suffix}`.
|
|
1438
|
+
* The `c` discriminator keeps counter-style names visually distinct
|
|
1439
|
+
* from class names sharing the same prefix.
|
|
1440
|
+
*/
|
|
1441
|
+
function makeCounterStyleName(prefix, suffix) {
|
|
1442
|
+
return `${prefix}c${suffix}`;
|
|
1443
|
+
}
|
|
1444
|
+
/** Escape a string for safe inclusion in a regex literal. */
|
|
1445
|
+
function escapeRegex(str) {
|
|
1446
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1447
|
+
}
|
|
1448
|
+
/**
|
|
1449
|
+
* Regex matching any tasty class for the given prefix.
|
|
1450
|
+
* Used by the runtime GC's DOM scan and class-allocation bookkeeping.
|
|
1451
|
+
*/
|
|
1452
|
+
function tastyClassRegex(prefix) {
|
|
1453
|
+
return new RegExp(`^${escapeRegex(prefix)}[a-z0-9]+$`);
|
|
1454
|
+
}
|
|
1455
|
+
/**
|
|
1456
|
+
* Global regex extracting tasty class names from RSC-inlined CSS.
|
|
1457
|
+
* Looks for the doubled-specificity pattern `.cls.cls` that
|
|
1458
|
+
* `formatRules()` always emits, which makes extraction reliable.
|
|
1459
|
+
*/
|
|
1460
|
+
function rscClassRegexGlobal(prefix) {
|
|
1461
|
+
return new RegExp(`\\.(${escapeRegex(prefix)}[a-z0-9]+)\\.\\1`, "g");
|
|
1462
|
+
}
|
|
1463
|
+
//#endregion
|
|
1377
1464
|
//#region src/parser/types.ts
|
|
1378
1465
|
let Bucket = /* @__PURE__ */ function(Bucket) {
|
|
1379
1466
|
Bucket[Bucket["Color"] = 0] = "Color";
|
|
@@ -1439,7 +1526,7 @@ function resolveUntilStable(value, opts, recurse, maxIterations = 10) {
|
|
|
1439
1526
|
function classify(raw, opts, recurse) {
|
|
1440
1527
|
const token = raw.trim();
|
|
1441
1528
|
if (!token) return {
|
|
1442
|
-
bucket:
|
|
1529
|
+
bucket: 2,
|
|
1443
1530
|
processed: ""
|
|
1444
1531
|
};
|
|
1445
1532
|
{
|
|
@@ -1461,31 +1548,31 @@ function classify(raw, opts, recurse) {
|
|
|
1461
1548
|
if (depth !== 0) {
|
|
1462
1549
|
console.warn("tasty: skipped invalid function token with unmatched parentheses:", token);
|
|
1463
1550
|
return {
|
|
1464
|
-
bucket:
|
|
1551
|
+
bucket: 2,
|
|
1465
1552
|
processed: ""
|
|
1466
1553
|
};
|
|
1467
1554
|
}
|
|
1468
1555
|
}
|
|
1469
1556
|
if (token.startsWith("\"") && token.endsWith("\"") || token.startsWith("'") && token.endsWith("'")) return {
|
|
1470
|
-
bucket:
|
|
1557
|
+
bucket: 1,
|
|
1471
1558
|
processed: token
|
|
1472
1559
|
};
|
|
1473
1560
|
if (token.startsWith("$$")) {
|
|
1474
1561
|
const name = token.slice(2);
|
|
1475
1562
|
if (/^[a-z_][a-z0-9-_]*$/i.test(name)) return {
|
|
1476
|
-
bucket:
|
|
1563
|
+
bucket: 1,
|
|
1477
1564
|
processed: `--${name}`
|
|
1478
1565
|
};
|
|
1479
1566
|
}
|
|
1480
1567
|
if (token.startsWith("##")) {
|
|
1481
1568
|
const name = token.slice(2);
|
|
1482
1569
|
if (/^[a-z_][a-z0-9-_]*$/i.test(name)) return {
|
|
1483
|
-
bucket:
|
|
1570
|
+
bucket: 1,
|
|
1484
1571
|
processed: `--${name}-color`
|
|
1485
1572
|
};
|
|
1486
1573
|
}
|
|
1487
1574
|
if (token === "#current") return {
|
|
1488
|
-
bucket:
|
|
1575
|
+
bucket: 0,
|
|
1489
1576
|
processed: "currentcolor"
|
|
1490
1577
|
};
|
|
1491
1578
|
const currentAlphaMatch = token.match(/^#current\.(\$[a-z_][a-z0-9-_]*|[0-9]+)$/i);
|
|
@@ -1496,7 +1583,7 @@ function classify(raw, opts, recurse) {
|
|
|
1496
1583
|
else if (rawAlpha === "0") percentage = "0%";
|
|
1497
1584
|
else percentage = `${parseFloat("." + rawAlpha) * 100}%`;
|
|
1498
1585
|
return {
|
|
1499
|
-
bucket:
|
|
1586
|
+
bucket: 0,
|
|
1500
1587
|
processed: `color-mix(in oklab, currentcolor ${percentage}, transparent)`
|
|
1501
1588
|
};
|
|
1502
1589
|
}
|
|
@@ -1569,7 +1656,7 @@ function classify(raw, opts, recurse) {
|
|
|
1569
1656
|
const constructed = `${normalizedFunc}(${hasModernAlpha || hasLegacyAlpha ? normalizeArgs(hasModernAlpha ? args.slice(0, slashIdx).trim() : args.slice(0, lastTopLevelComma).trim()) : normalizeArgs(args)} / ${alpha})`;
|
|
1570
1657
|
if (!COLOR_FUNCS.has(normalizedFunc) && opts.funcs && normalizedFunc in opts.funcs) return classify(constructed, opts, recurse);
|
|
1571
1658
|
return {
|
|
1572
|
-
bucket:
|
|
1659
|
+
bucket: 0,
|
|
1573
1660
|
processed: constructed
|
|
1574
1661
|
};
|
|
1575
1662
|
}
|
|
@@ -1580,11 +1667,11 @@ function classify(raw, opts, recurse) {
|
|
|
1580
1667
|
}
|
|
1581
1668
|
}
|
|
1582
1669
|
if (token.match(/^var\(--([a-z0-9-]+)-color\)$/)) return {
|
|
1583
|
-
bucket:
|
|
1670
|
+
bucket: 0,
|
|
1584
1671
|
processed: token
|
|
1585
1672
|
};
|
|
1586
1673
|
if (token.startsWith("url(")) return {
|
|
1587
|
-
bucket:
|
|
1674
|
+
bucket: 1,
|
|
1588
1675
|
processed: token
|
|
1589
1676
|
};
|
|
1590
1677
|
if (token[0] === "$") {
|
|
@@ -1593,7 +1680,7 @@ function classify(raw, opts, recurse) {
|
|
|
1593
1680
|
const name = identMatch[1];
|
|
1594
1681
|
const processed = `var(--${name})`;
|
|
1595
1682
|
return {
|
|
1596
|
-
bucket: name.endsWith("-color") ?
|
|
1683
|
+
bucket: name.endsWith("-color") ? 0 : 1,
|
|
1597
1684
|
processed
|
|
1598
1685
|
};
|
|
1599
1686
|
}
|
|
@@ -1607,17 +1694,17 @@ function classify(raw, opts, recurse) {
|
|
|
1607
1694
|
else if (rawAlpha === "0") alpha = "0";
|
|
1608
1695
|
else alpha = `.${rawAlpha}`;
|
|
1609
1696
|
return {
|
|
1610
|
-
bucket:
|
|
1697
|
+
bucket: 0,
|
|
1611
1698
|
processed: `${getColorSpaceFunc()}(var(--${base}-color-${getColorSpaceSuffix()}) / ${alpha})`
|
|
1612
1699
|
};
|
|
1613
1700
|
}
|
|
1614
1701
|
const name = token.slice(1);
|
|
1615
1702
|
if (RE_HEX.test(name)) return {
|
|
1616
|
-
bucket:
|
|
1703
|
+
bucket: 0,
|
|
1617
1704
|
processed: `var(--${name}-color, #${name})`
|
|
1618
1705
|
};
|
|
1619
1706
|
return {
|
|
1620
|
-
bucket:
|
|
1707
|
+
bucket: 0,
|
|
1621
1708
|
processed: `var(--${name}-color)`
|
|
1622
1709
|
};
|
|
1623
1710
|
}
|
|
@@ -1628,7 +1715,7 @@ function classify(raw, opts, recurse) {
|
|
|
1628
1715
|
if (COLOR_FUNCS.has(fname)) {
|
|
1629
1716
|
const argProcessed = recurse(inner).output.replace(/,\s+/g, ",");
|
|
1630
1717
|
return {
|
|
1631
|
-
bucket:
|
|
1718
|
+
bucket: 0,
|
|
1632
1719
|
processed: `${canonicalFuncName(fname)}(${argProcessed})`
|
|
1633
1720
|
};
|
|
1634
1721
|
}
|
|
@@ -1641,7 +1728,7 @@ function classify(raw, opts, recurse) {
|
|
|
1641
1728
|
}
|
|
1642
1729
|
const argProcessed = recurse(inner).output;
|
|
1643
1730
|
return {
|
|
1644
|
-
bucket:
|
|
1731
|
+
bucket: 1,
|
|
1645
1732
|
processed: `${canonicalFuncName(fname)}(${argProcessed})`
|
|
1646
1733
|
};
|
|
1647
1734
|
}
|
|
@@ -1649,10 +1736,9 @@ function classify(raw, opts, recurse) {
|
|
|
1649
1736
|
const colorMatch = token.slice(1, -1).match(/^#([a-z0-9-]+)\s*,\s*(.*)$/i);
|
|
1650
1737
|
if (colorMatch) {
|
|
1651
1738
|
const [, name, fallback] = colorMatch;
|
|
1652
|
-
const processedFallback = recurse(fallback).output;
|
|
1653
1739
|
return {
|
|
1654
|
-
bucket:
|
|
1655
|
-
processed: `var(--${name}-color, ${
|
|
1740
|
+
bucket: 0,
|
|
1741
|
+
processed: `var(--${name}-color, ${recurse(fallback).output})`
|
|
1656
1742
|
};
|
|
1657
1743
|
}
|
|
1658
1744
|
}
|
|
@@ -1662,18 +1748,15 @@ function classify(raw, opts, recurse) {
|
|
|
1662
1748
|
const [, name, fallback] = match;
|
|
1663
1749
|
const processedFallback = recurse(fallback).output;
|
|
1664
1750
|
return {
|
|
1665
|
-
bucket: name.endsWith("-color") ?
|
|
1751
|
+
bucket: name.endsWith("-color") ? 0 : 1,
|
|
1666
1752
|
processed: `var(--${name}, ${processedFallback})`
|
|
1667
1753
|
};
|
|
1668
1754
|
}
|
|
1669
1755
|
}
|
|
1670
|
-
if (token[0] === "(" && token[token.length - 1] === ")") {
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
processed: `calc(${innerProcessed})`
|
|
1675
|
-
};
|
|
1676
|
-
}
|
|
1756
|
+
if (token[0] === "(" && token[token.length - 1] === ")") return {
|
|
1757
|
+
bucket: 1,
|
|
1758
|
+
processed: `calc(${recurse(token.slice(1, -1)).output})`
|
|
1759
|
+
};
|
|
1677
1760
|
const um = token.match(RE_UNIT_NUM);
|
|
1678
1761
|
if (um) {
|
|
1679
1762
|
const unit = um[1];
|
|
@@ -1683,47 +1766,43 @@ function classify(raw, opts, recurse) {
|
|
|
1683
1766
|
const rawMatch = handler.match(RE_RAW_UNIT);
|
|
1684
1767
|
if (rawMatch) {
|
|
1685
1768
|
const [, baseNum, cssUnit] = rawMatch;
|
|
1686
|
-
const resolved = resolveUntilStable(`${numericPart * parseFloat(baseNum)}${cssUnit}`, opts, recurse);
|
|
1687
1769
|
return {
|
|
1688
|
-
bucket:
|
|
1689
|
-
processed:
|
|
1770
|
+
bucket: 1,
|
|
1771
|
+
processed: resolveUntilStable(`${numericPart * parseFloat(baseNum)}${cssUnit}`, opts, recurse)
|
|
1690
1772
|
};
|
|
1691
1773
|
}
|
|
1692
1774
|
const base = handler;
|
|
1693
1775
|
if (numericPart === 1) return {
|
|
1694
|
-
bucket:
|
|
1776
|
+
bucket: 1,
|
|
1695
1777
|
processed: base
|
|
1696
1778
|
};
|
|
1697
1779
|
return {
|
|
1698
|
-
bucket:
|
|
1780
|
+
bucket: 1,
|
|
1699
1781
|
processed: `calc(${numericPart} * ${base})`
|
|
1700
1782
|
};
|
|
1701
|
-
} else {
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
processed: inner
|
|
1706
|
-
};
|
|
1707
|
-
}
|
|
1783
|
+
} else return {
|
|
1784
|
+
bucket: 1,
|
|
1785
|
+
processed: handler(numericPart)
|
|
1786
|
+
};
|
|
1708
1787
|
}
|
|
1709
1788
|
if (/^[+-]?(?:\d*\.\d+|\d+)[a-z%]+$/.test(token)) return {
|
|
1710
|
-
bucket:
|
|
1789
|
+
bucket: 1,
|
|
1711
1790
|
processed: token
|
|
1712
1791
|
};
|
|
1713
1792
|
if (RE_NUMBER.test(token)) return {
|
|
1714
|
-
bucket:
|
|
1793
|
+
bucket: 1,
|
|
1715
1794
|
processed: token
|
|
1716
1795
|
};
|
|
1717
1796
|
if (VALUE_KEYWORDS.has(token)) return {
|
|
1718
|
-
bucket:
|
|
1797
|
+
bucket: 1,
|
|
1719
1798
|
processed: token
|
|
1720
1799
|
};
|
|
1721
1800
|
if (token === "transparent" || token === "currentcolor") return {
|
|
1722
|
-
bucket:
|
|
1801
|
+
bucket: 0,
|
|
1723
1802
|
processed: token
|
|
1724
1803
|
};
|
|
1725
1804
|
return {
|
|
1726
|
-
bucket:
|
|
1805
|
+
bucket: 2,
|
|
1727
1806
|
processed: token
|
|
1728
1807
|
};
|
|
1729
1808
|
}
|
|
@@ -1823,13 +1902,13 @@ var StyleParser = class {
|
|
|
1823
1902
|
return;
|
|
1824
1903
|
}
|
|
1825
1904
|
switch (bucket) {
|
|
1826
|
-
case
|
|
1905
|
+
case 0:
|
|
1827
1906
|
currentPart.colors.push(processed);
|
|
1828
1907
|
break;
|
|
1829
|
-
case
|
|
1908
|
+
case 1:
|
|
1830
1909
|
currentPart.values.push(processed);
|
|
1831
1910
|
break;
|
|
1832
|
-
case
|
|
1911
|
+
case 2:
|
|
1833
1912
|
currentPart.mods.push(processed);
|
|
1834
1913
|
break;
|
|
1835
1914
|
}
|
|
@@ -4809,18 +4888,10 @@ function formatCounterStyleRule(name, descriptors) {
|
|
|
4809
4888
|
//#endregion
|
|
4810
4889
|
//#region src/injector/injector.ts
|
|
4811
4890
|
/**
|
|
4812
|
-
* Generate a deterministic class name from a cache key using content hash.
|
|
4813
|
-
* The same cache key always produces the same class name across environments.
|
|
4814
|
-
*/
|
|
4815
|
-
function generateClassName(cacheKey) {
|
|
4816
|
-
return `t${hashString(cacheKey)}`;
|
|
4817
|
-
}
|
|
4818
|
-
const RSC_CLASS_RE = /\.(t[a-z0-9]+)\.\1/g;
|
|
4819
|
-
/**
|
|
4820
4891
|
* Extract class names from `<style data-tasty-rsc>` tags.
|
|
4821
4892
|
* The doubled-specificity pattern `.tXXX.tXXX` makes extraction reliable.
|
|
4822
4893
|
*/
|
|
4823
|
-
function extractRSCClassNames() {
|
|
4894
|
+
function extractRSCClassNames(rscClassRegex) {
|
|
4824
4895
|
if (typeof document === "undefined") return [];
|
|
4825
4896
|
const styles = document.querySelectorAll("style[data-tasty-rsc]");
|
|
4826
4897
|
if (styles.length === 0) return [];
|
|
@@ -4829,8 +4900,8 @@ function extractRSCClassNames() {
|
|
|
4829
4900
|
const text = style.textContent;
|
|
4830
4901
|
if (!text) continue;
|
|
4831
4902
|
let match;
|
|
4832
|
-
|
|
4833
|
-
while ((match =
|
|
4903
|
+
rscClassRegex.lastIndex = 0;
|
|
4904
|
+
while ((match = rscClassRegex.exec(text)) !== null) classSet.add(match[1]);
|
|
4834
4905
|
}
|
|
4835
4906
|
return Array.from(classSet);
|
|
4836
4907
|
}
|
|
@@ -4844,7 +4915,7 @@ function extractRSCClassNames() {
|
|
|
4844
4915
|
* Called inside `inject()` / `allocateClassName()` to pick up
|
|
4845
4916
|
* class names rendered on the server (including during SPA navigation).
|
|
4846
4917
|
*/
|
|
4847
|
-
function syncServerClasses(registry) {
|
|
4918
|
+
function syncServerClasses(registry, rscClassRegex) {
|
|
4848
4919
|
if (typeof window === "undefined") return;
|
|
4849
4920
|
const classes = window.__TASTY__;
|
|
4850
4921
|
if (classes && classes.length > registry.serverClassSyncIndex) {
|
|
@@ -4853,7 +4924,7 @@ function syncServerClasses(registry) {
|
|
|
4853
4924
|
}
|
|
4854
4925
|
if (!registry.rscStylesScanned) {
|
|
4855
4926
|
registry.rscStylesScanned = true;
|
|
4856
|
-
for (const cls of extractRSCClassNames()) registerHydratedClass(registry, cls);
|
|
4927
|
+
for (const cls of extractRSCClassNames(rscClassRegex)) registerHydratedClass(registry, cls);
|
|
4857
4928
|
}
|
|
4858
4929
|
}
|
|
4859
4930
|
function registerHydratedClass(registry, className) {
|
|
@@ -4865,25 +4936,40 @@ function registerHydratedClass(registry, className) {
|
|
|
4865
4936
|
});
|
|
4866
4937
|
registry.refCounts.set(className, 0);
|
|
4867
4938
|
}
|
|
4868
|
-
var StyleInjector = class
|
|
4939
|
+
var StyleInjector = class {
|
|
4869
4940
|
sheetManager;
|
|
4870
4941
|
config;
|
|
4871
4942
|
globalRuleCounter = 0;
|
|
4872
4943
|
pendingGCHandle = null;
|
|
4944
|
+
namePrefix;
|
|
4945
|
+
classRegex;
|
|
4946
|
+
rscClassRegex;
|
|
4873
4947
|
/** @internal — exposed for debug utilities only */
|
|
4874
4948
|
get _sheetManager() {
|
|
4875
4949
|
return this.sheetManager;
|
|
4876
4950
|
}
|
|
4877
4951
|
constructor(config = {}) {
|
|
4952
|
+
if (config.namePrefix !== void 0) validateNamePrefix(config.namePrefix);
|
|
4878
4953
|
this.config = config;
|
|
4879
4954
|
this.sheetManager = new SheetManager(config);
|
|
4955
|
+
this.namePrefix = config.namePrefix ?? "t";
|
|
4956
|
+
this.classRegex = tastyClassRegex(this.namePrefix);
|
|
4957
|
+
this.rscClassRegex = rscClassRegexGlobal(this.namePrefix);
|
|
4958
|
+
}
|
|
4959
|
+
/**
|
|
4960
|
+
* Generate a deterministic class name from a cache key using content hash.
|
|
4961
|
+
* The same cache key always produces the same class name across environments
|
|
4962
|
+
* with the same `namePrefix`.
|
|
4963
|
+
*/
|
|
4964
|
+
generateClassName(cacheKey) {
|
|
4965
|
+
return makeClassName(this.namePrefix, hashString(cacheKey));
|
|
4880
4966
|
}
|
|
4881
4967
|
/**
|
|
4882
4968
|
* Check if `className` was hydrated from server-rendered styles and,
|
|
4883
4969
|
* if so, wire the cacheKey mapping. Returns true on hit.
|
|
4884
4970
|
*/
|
|
4885
4971
|
tryHydratedHit(registry, cacheKey, className) {
|
|
4886
|
-
syncServerClasses(registry);
|
|
4972
|
+
syncServerClasses(registry, this.rscClassRegex);
|
|
4887
4973
|
const rule = registry.rules.get(className);
|
|
4888
4974
|
if (rule && rule.ruleIndex === -2 && rule.sheetIndex === -2) {
|
|
4889
4975
|
registry.cacheKeyToClassName.set(cacheKey, className);
|
|
@@ -4902,7 +4988,7 @@ var StyleInjector = class StyleInjector {
|
|
|
4902
4988
|
className: registry.cacheKeyToClassName.get(cacheKey),
|
|
4903
4989
|
isNewAllocation: false
|
|
4904
4990
|
};
|
|
4905
|
-
const className = generateClassName(cacheKey);
|
|
4991
|
+
const className = this.generateClassName(cacheKey);
|
|
4906
4992
|
if (this.tryHydratedHit(registry, cacheKey, className)) return {
|
|
4907
4993
|
className,
|
|
4908
4994
|
isNewAllocation: false
|
|
@@ -4954,7 +5040,7 @@ var StyleInjector = class StyleInjector {
|
|
|
4954
5040
|
};
|
|
4955
5041
|
}
|
|
4956
5042
|
} else if (cacheKey) {
|
|
4957
|
-
className = generateClassName(cacheKey);
|
|
5043
|
+
className = this.generateClassName(cacheKey);
|
|
4958
5044
|
if (this.tryHydratedHit(registry, cacheKey, className)) {
|
|
4959
5045
|
registry.refCounts.set(className, (registry.refCounts.get(className) || 0) + 1);
|
|
4960
5046
|
if (registry.metrics) registry.metrics.hits++;
|
|
@@ -4963,7 +5049,10 @@ var StyleInjector = class StyleInjector {
|
|
|
4963
5049
|
dispose: () => this.dispose(className, registry)
|
|
4964
5050
|
};
|
|
4965
5051
|
}
|
|
4966
|
-
} else
|
|
5052
|
+
} else {
|
|
5053
|
+
const parts = rules.map((r) => `${r.selector}\0${r.declarations}`);
|
|
5054
|
+
className = makeClassName(this.namePrefix, hashString(parts.join("\n")));
|
|
5055
|
+
}
|
|
4967
5056
|
const rulesToInsert = rules.map((rule) => {
|
|
4968
5057
|
let newSelector = rule.selector;
|
|
4969
5058
|
if (rule.needsClassName) {
|
|
@@ -5283,12 +5372,12 @@ var StyleInjector = class StyleInjector {
|
|
|
5283
5372
|
let actualName;
|
|
5284
5373
|
if (providedName) {
|
|
5285
5374
|
const existingContentForName = registry.keyframesNameToContent.get(providedName);
|
|
5286
|
-
if (existingContentForName && existingContentForName !== contentHash) actualName = `${providedName}
|
|
5375
|
+
if (existingContentForName && existingContentForName !== contentHash) actualName = `${providedName}-${makeKeyframeName(this.namePrefix, String(registry.keyframesCounter++))}`;
|
|
5287
5376
|
else {
|
|
5288
5377
|
actualName = providedName;
|
|
5289
5378
|
registry.keyframesNameToContent.set(providedName, contentHash);
|
|
5290
5379
|
}
|
|
5291
|
-
} else actualName =
|
|
5380
|
+
} else actualName = makeKeyframeName(this.namePrefix, String(registry.keyframesCounter++));
|
|
5292
5381
|
const result = this.sheetManager.insertKeyframes(registry, steps, actualName, root);
|
|
5293
5382
|
if (!result) return {
|
|
5294
5383
|
toString: () => "",
|
|
@@ -5337,7 +5426,6 @@ var StyleInjector = class StyleInjector {
|
|
|
5337
5426
|
}
|
|
5338
5427
|
}
|
|
5339
5428
|
}
|
|
5340
|
-
static TASTY_CLASS_RE = /^t[a-z0-9]+$/;
|
|
5341
5429
|
/**
|
|
5342
5430
|
* Record a render-time usage hit for one or more classNames.
|
|
5343
5431
|
* Handles space-separated multi-chunk classNames.
|
|
@@ -5353,7 +5441,7 @@ var StyleInjector = class StyleInjector {
|
|
|
5353
5441
|
const now = Date.now();
|
|
5354
5442
|
const parts = className.indexOf(" ") === -1 ? [className] : className.split(" ");
|
|
5355
5443
|
for (const cls of parts) {
|
|
5356
|
-
if (!
|
|
5444
|
+
if (!this.classRegex.test(cls)) continue;
|
|
5357
5445
|
if (!registry.rules.has(cls)) continue;
|
|
5358
5446
|
const entry = registry.usageMap.get(cls);
|
|
5359
5447
|
if (entry) entry.lastTouchedAt = now;
|
|
@@ -5406,7 +5494,7 @@ var StyleInjector = class StyleInjector {
|
|
|
5406
5494
|
if (registry.usageMap.size - activeCount <= capacity) return 0;
|
|
5407
5495
|
}
|
|
5408
5496
|
const liveClasses = /* @__PURE__ */ new Set();
|
|
5409
|
-
for (const el of root.querySelectorAll("[class]")) for (const token of el.classList) if (
|
|
5497
|
+
for (const el of root.querySelectorAll("[class]")) for (const token of el.classList) if (this.classRegex.test(token)) liveClasses.add(token);
|
|
5410
5498
|
let swept = 0;
|
|
5411
5499
|
if (force) for (const [className] of registry.usageMap) {
|
|
5412
5500
|
if (liveClasses.has(className)) continue;
|
|
@@ -9203,14 +9291,15 @@ function validatePattern(pattern) {
|
|
|
9203
9291
|
* processSinglePattern('>Body>Row>', 'Cell')
|
|
9204
9292
|
* // → '> [data-element="Body"] > [data-element="Row"] > [data-element="Cell"]'
|
|
9205
9293
|
*
|
|
9206
|
-
* processSinglePattern('
|
|
9207
|
-
* // → '::before' (
|
|
9294
|
+
* processSinglePattern('&::before', 'Before')
|
|
9295
|
+
* // → '::before' (& attaches pseudo directly to root, no key injection)
|
|
9208
9296
|
*
|
|
9209
9297
|
* processSinglePattern('>@:hover', 'Item')
|
|
9210
9298
|
* // → '> [data-element="Item"]:hover'
|
|
9211
9299
|
*/
|
|
9212
9300
|
function processSinglePattern(pattern, key) {
|
|
9213
|
-
const
|
|
9301
|
+
const startsWithAmpersand = pattern.startsWith("&");
|
|
9302
|
+
const normalized = (startsWithAmpersand ? pattern.slice(1) : pattern).trim();
|
|
9214
9303
|
if (!normalized) return ` [data-element="${key}"]`;
|
|
9215
9304
|
const startsWithPseudo = /^::?[a-z]/.test(normalized);
|
|
9216
9305
|
let result = transformPattern(normalized);
|
|
@@ -9221,7 +9310,7 @@ function processSinglePattern(pattern, key) {
|
|
|
9221
9310
|
return result;
|
|
9222
9311
|
}
|
|
9223
9312
|
if (shouldInjectKey(normalized, key)) result = result + ` [data-element="${key}"]`;
|
|
9224
|
-
if (!
|
|
9313
|
+
if (!startsWithAmpersand && !result.startsWith(" ")) result = " " + result;
|
|
9225
9314
|
return result;
|
|
9226
9315
|
}
|
|
9227
9316
|
/**
|
|
@@ -9803,7 +9892,8 @@ function createDefaultConfig(isTest) {
|
|
|
9803
9892
|
return {
|
|
9804
9893
|
maxRulesPerSheet: 8192,
|
|
9805
9894
|
forceTextInjection: isTest ?? false,
|
|
9806
|
-
devMode: isDevEnv()
|
|
9895
|
+
devMode: isDevEnv(),
|
|
9896
|
+
namePrefix: "t"
|
|
9807
9897
|
};
|
|
9808
9898
|
}
|
|
9809
9899
|
/**
|
|
@@ -10045,6 +10135,7 @@ function configure(config = {}) {
|
|
|
10045
10135
|
warnOnce("configure-after-styles", "[Tasty] Cannot call configure() after styles have been generated.\nConfiguration must be done before the first render. The configuration will be ignored.");
|
|
10046
10136
|
return;
|
|
10047
10137
|
}
|
|
10138
|
+
if (config.namePrefix !== void 0) validateNamePrefix(config.namePrefix);
|
|
10048
10139
|
let mergedStates = {};
|
|
10049
10140
|
let mergedUnits = {};
|
|
10050
10141
|
let mergedFuncs = {};
|
|
@@ -10196,6 +10287,17 @@ function getConfig() {
|
|
|
10196
10287
|
return currentConfig;
|
|
10197
10288
|
}
|
|
10198
10289
|
/**
|
|
10290
|
+
* Get the configured prefix used for every generated identifier
|
|
10291
|
+
* (class names, keyframe names, counter-style names).
|
|
10292
|
+
*
|
|
10293
|
+
* Falls back to the default prefix (`'t'`) when `configure()` has not
|
|
10294
|
+
* been called yet — this matches the auto-configuration behavior used
|
|
10295
|
+
* by the rest of the system.
|
|
10296
|
+
*/
|
|
10297
|
+
function getNamePrefix() {
|
|
10298
|
+
return currentConfig?.namePrefix ?? "t";
|
|
10299
|
+
}
|
|
10300
|
+
/**
|
|
10199
10301
|
* Get the global injector instance.
|
|
10200
10302
|
* Auto-configures with defaults if not already configured.
|
|
10201
10303
|
*/
|
|
@@ -10229,6 +10331,6 @@ function resetConfig() {
|
|
|
10229
10331
|
delete storage[GLOBAL_INJECTOR_KEY];
|
|
10230
10332
|
}
|
|
10231
10333
|
//#endregion
|
|
10232
|
-
export {
|
|
10334
|
+
export { parseColor as $, StyleInjector as A, strToRgb as At, styleHandlers as B, parseStateKey as C, getColorSpaceFunc as Ct, extractPredefinedStateRefs as D, getRgbValuesFromRgbaString as Dt, extractLocalPredefinedStates as E, getNamedColorHex as Et, fontFaceContentHash as F, CUSTOM_UNITS as G, warn as H, formatFontFaceRule as I, filterMods as J, DIRECTIONS as K, hasLocalFontFace as L, formatCounterStyleRule as M, hasLocalCounterStyle as N, getGlobalPredefinedStates as O, hexToRgb as Ot, extractLocalFontFace as P, normalizeColorTokenValue as Q, SheetManager as R, renderStyles as S, getColorSpaceComponents as St, createStateParserContext as T, getComponentPropertySyntax as Tt, createStyle as U, deprecationWarning as V, PropertyTypeResolver as W, getGlobalParser as X, getGlobalFuncs as Y, getGlobalPredefinedTokens as Z, markStylesGenerated as _, extractLocalProperties as _t, getGlobalCounterStyle as a, okhslPlugin as at, hasPipelineCacheEntry as b, parsePropertyToken as bt, getGlobalKeyframes as c, DEFAULT_NAME_PREFIX as ct, getNamePrefix as d, makeCounterStyleName as dt, parseStyle as et, hasGlobalKeyframes as f, makeKeyframeName as ft, isTestEnvironment as g, hashString as gt, isConfigLocked as h, isDevEnv as ht, getGlobalConfigTokens as i, okhslFunc as it, extractLocalCounterStyle as j, Lru as jt, setGlobalPredefinedStates as k, hslToRgbValues as kt, getGlobalRecipes as l, DEFAULT_ZERO_NAME_PREFIX as lt, hasStylesGenerated as m, validateNamePrefix as mt, getConfig as n, setGlobalPredefinedTokens as nt, getGlobalFontFace as o, StyleParser as ot, hasGlobalRecipes as p, tastyClassRegex as pt, customFunc as q, getEffectiveProperties as r, stringifyStyles as rt, getGlobalInjector as s, Bucket as st, configure as t, resetGlobalPredefinedTokens as tt, getGlobalStyles as u, makeClassName as ut, resetConfig as v, getEffectiveDefinition as vt, camelToKebab as w, getColorSpaceSuffix as wt, isSelector as x, colorInitialValueToComponents as xt, generateTypographyTokens as y, hasLocalProperties as yt, STYLE_HANDLER_MAP as z };
|
|
10233
10335
|
|
|
10234
|
-
//# sourceMappingURL=config-
|
|
10336
|
+
//# sourceMappingURL=config-64Uwyc2X.js.map
|