kss-modern 1.3.0-beta.1 → 1.3.0-beta.2
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 +1 -1
- package/dist/node/lib/index.d.mts +1 -1
- package/dist/node/lib/index.d.ts +1 -1
- package/dist/node/lib/index.mjs +232 -98
- package/dist/styleguide-assets/.vite/manifest.json +29 -13
- package/dist/styleguide-assets/a11y-report-BgeWSrYe.js +186 -0
- package/dist/styleguide-assets/{clipboard-BUvXbiCa.js → clipboard-CHYspHPs.js} +1 -1
- package/dist/styleguide-assets/{fullpage-B5QPff3p.js → fullpage-D-fU_bAa.js} +14 -20
- package/dist/styleguide-assets/{html-validator-BxGmbFa-.js → html-validator-DJGwslsw.js} +68 -100
- package/dist/styleguide-assets/{icons-C6KKEuT_.js → icons-Cip2t08v.js} +1 -1
- package/dist/styleguide-assets/kss-modern-BJ971T05.css +3 -0
- package/dist/styleguide-assets/{preview-D2-sk3lE.js → preview-DEipbLLB.js} +8 -7
- package/dist/styleguide-assets/section-previews-D-Mr2eVX.js +49 -0
- package/dist/styleguide-assets/{utils-DrMb1LbR.js → utils-DtB-AzJa.js} +3 -3
- package/package.json +1 -1
- package/dist/styleguide-assets/kss-modern-CTiCJXSr.css +0 -3
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ A modern, KSS-compatible styleguide generator. Parses KSS comment blocks from CS
|
|
|
9
9
|
- Pug template support via worker thread pool
|
|
10
10
|
- Color palette and icon gallery documentation
|
|
11
11
|
- Figma embed integration with light/dark theme sync
|
|
12
|
-
- Accessibility auditing (axe-core) and HTML validation
|
|
12
|
+
- Accessibility auditing (axe-core) and HTML validation, per component or page-wide via `window.kssAudit()` for CI and AI agents
|
|
13
13
|
- Markdown descriptions with custom components (alerts, accordions)
|
|
14
14
|
- Dark mode with three-way toggle (System/Light/Dark)
|
|
15
15
|
- Global search, keyboard navigation, and "Open in Editor" links
|
package/dist/node/lib/index.d.ts
CHANGED
package/dist/node/lib/index.mjs
CHANGED
|
@@ -217,6 +217,9 @@ function escape(str) {
|
|
|
217
217
|
return String(str).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
218
218
|
}
|
|
219
219
|
const when = (condition, content) => condition ? content() : "";
|
|
220
|
+
function attrs(obj) {
|
|
221
|
+
return Object.entries(obj).filter(([, value]) => value !== null && value !== void 0 && value !== false).map(([key, value]) => value === true ? key : `${key}="${value}"`).join(" ");
|
|
222
|
+
}
|
|
220
223
|
|
|
221
224
|
const alertRenderer = (bodyContent, props) => {
|
|
222
225
|
const type = props.type || "info";
|
|
@@ -1247,6 +1250,66 @@ async function compilePugMarkupIncremental(mode, contentDir, repository, ids) {
|
|
|
1247
1250
|
return compileIds(mode, contentDir, repository, wanted);
|
|
1248
1251
|
}
|
|
1249
1252
|
|
|
1253
|
+
function createRebuildQueue(handlers) {
|
|
1254
|
+
let isRunning = false;
|
|
1255
|
+
let isStructuralPending = false;
|
|
1256
|
+
const pendingMarkupFiles = /* @__PURE__ */ new Set();
|
|
1257
|
+
let idleResolvers = [];
|
|
1258
|
+
const hasPendingWork = () => isStructuralPending || pendingMarkupFiles.size > 0;
|
|
1259
|
+
const releaseIdleWaiters = () => {
|
|
1260
|
+
const resolvers = idleResolvers;
|
|
1261
|
+
idleResolvers = [];
|
|
1262
|
+
resolvers.forEach((resolve) => resolve());
|
|
1263
|
+
};
|
|
1264
|
+
const runNext = async () => {
|
|
1265
|
+
if (isStructuralPending) {
|
|
1266
|
+
isStructuralPending = false;
|
|
1267
|
+
pendingMarkupFiles.clear();
|
|
1268
|
+
await handlers.onStructural();
|
|
1269
|
+
return;
|
|
1270
|
+
}
|
|
1271
|
+
const changedFiles = [...pendingMarkupFiles];
|
|
1272
|
+
pendingMarkupFiles.clear();
|
|
1273
|
+
await handlers.onMarkup(changedFiles);
|
|
1274
|
+
};
|
|
1275
|
+
const drain = async () => {
|
|
1276
|
+
if (isRunning)
|
|
1277
|
+
return;
|
|
1278
|
+
isRunning = true;
|
|
1279
|
+
try {
|
|
1280
|
+
while (hasPendingWork()) {
|
|
1281
|
+
try {
|
|
1282
|
+
await runNext();
|
|
1283
|
+
} catch (error) {
|
|
1284
|
+
handlers.onError?.(error);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
} finally {
|
|
1288
|
+
isRunning = false;
|
|
1289
|
+
releaseIdleWaiters();
|
|
1290
|
+
}
|
|
1291
|
+
};
|
|
1292
|
+
return {
|
|
1293
|
+
requestStructural: () => {
|
|
1294
|
+
isStructuralPending = true;
|
|
1295
|
+
void drain();
|
|
1296
|
+
},
|
|
1297
|
+
requestMarkup: (changedFiles) => {
|
|
1298
|
+
for (const file of changedFiles) {
|
|
1299
|
+
pendingMarkupFiles.add(file);
|
|
1300
|
+
}
|
|
1301
|
+
void drain();
|
|
1302
|
+
},
|
|
1303
|
+
whenIdle: () => {
|
|
1304
|
+
if (!isRunning && !hasPendingWork())
|
|
1305
|
+
return Promise.resolve();
|
|
1306
|
+
return new Promise((resolve) => {
|
|
1307
|
+
idleResolvers.push(resolve);
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
};
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1250
1313
|
const TRANSIENT_FS_ERROR_CODES = /* @__PURE__ */ new Set(["ENOENT", "EBUSY", "EPERM", "EACCES"]);
|
|
1251
1314
|
function isTransientFsError(error) {
|
|
1252
1315
|
if (typeof error !== "object" || error === null)
|
|
@@ -1291,7 +1354,7 @@ async function generateFullPageFile(data) {
|
|
|
1291
1354
|
<meta name="theme-color" media="(prefers-color-scheme: light)" content="${data.theme.light}">
|
|
1292
1355
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="${data.theme.dark}">
|
|
1293
1356
|
` : `<meta name="theme-color" content="${data.theme}">`}
|
|
1294
|
-
<script type="module" src="/styleguide-assets/fullpage-
|
|
1357
|
+
<script type="module" src="/styleguide-assets/fullpage-D-fU_bAa.js"><\/script>
|
|
1295
1358
|
${computedStyleTags}
|
|
1296
1359
|
</head>
|
|
1297
1360
|
<body${data.page.bodyclass ? ` class="${data.page.bodyclass}"` : ""}>
|
|
@@ -1303,6 +1366,9 @@ async function generateFullPageFile(data) {
|
|
|
1303
1366
|
await logicalWriteFile(data.filePath, content);
|
|
1304
1367
|
}
|
|
1305
1368
|
|
|
1369
|
+
function getSectionTitleLine(section) {
|
|
1370
|
+
return section.source.css.line + 1;
|
|
1371
|
+
}
|
|
1306
1372
|
function getHasSectionExternalFullpage(section) {
|
|
1307
1373
|
return section.markup.length > 0 && (section.icons === void 0 || section.icons.length === 0) && (section.colors === void 0 || section.colors.length === 0);
|
|
1308
1374
|
}
|
|
@@ -1578,10 +1644,17 @@ function getMainContentSectionWrapper(section, html) {
|
|
|
1578
1644
|
}
|
|
1579
1645
|
return `<p class="mt-2${section.sectionLevel === "second" ? " text-xl" : ""}">${section.description}</p>`;
|
|
1580
1646
|
};
|
|
1647
|
+
const sourceAttributes = attrs({
|
|
1648
|
+
"data-section-reference": sanitizeSpecialCharacters(section.id),
|
|
1649
|
+
"data-source-file": sanitizeSpecialCharacters(section.source.css.file),
|
|
1650
|
+
"data-source-line": getSectionTitleLine(section),
|
|
1651
|
+
"data-markup-file": section.source.markup?.file ? sanitizeSpecialCharacters(section.source.markup.file) : void 0
|
|
1652
|
+
});
|
|
1581
1653
|
return `
|
|
1582
|
-
<section
|
|
1583
|
-
id="section-${sectionSanitizeId(section.id)}"
|
|
1654
|
+
<section
|
|
1655
|
+
id="section-${sectionSanitizeId(section.id)}"
|
|
1584
1656
|
class="styleguide-section border-b px-4 py-10 border-b-styleguide-border scroll-mt-[50px] md:px-10"
|
|
1657
|
+
${sourceAttributes}
|
|
1585
1658
|
>
|
|
1586
1659
|
<div class="flex items-center justify-between gap-6">
|
|
1587
1660
|
<a class="relative group" href="#section-${sectionSanitizeId(section.id)}">
|
|
@@ -1618,7 +1691,7 @@ function getMainContentRegular(section, config) {
|
|
|
1618
1691
|
if (config.mode === "development" && config.launchInEditor) {
|
|
1619
1692
|
const computedRootPath = config.launchInEditor && typeof config.launchInEditor === "object" && "rootDir" in config.launchInEditor ? config.launchInEditor.rootDir : process.cwd();
|
|
1620
1693
|
const cssFilePath = ensureStartingSlash(path.join(computedRootPath, section.source.css.file));
|
|
1621
|
-
const cssLineNumber = section
|
|
1694
|
+
const cssLineNumber = getSectionTitleLine(section);
|
|
1622
1695
|
openInEditorPaths.css = {
|
|
1623
1696
|
vscode: `vscode://file//${cssFilePath}:${cssLineNumber}`,
|
|
1624
1697
|
phpstorm: `phpstorm://open?file=${cssFilePath}&line=${cssLineNumber}`
|
|
@@ -1640,7 +1713,7 @@ function getMainContentRegular(section, config) {
|
|
|
1640
1713
|
};
|
|
1641
1714
|
const renderOpenInEditorLink = (editorType, contentType, link) => `
|
|
1642
1715
|
<a
|
|
1643
|
-
class="hidden editor-${editorType}-only @md:inline-flex items-center group/${editorType} gap-1.5 p-4 desktop-device-only cursor-pointer active:scale-90 transition hover:text-styleguide-highlight duration-200"
|
|
1716
|
+
class="pointer-events-auto hidden editor-${editorType}-only @md:inline-flex items-center group/${editorType} gap-1.5 p-4 desktop-device-only cursor-pointer active:scale-90 transition hover:text-styleguide-highlight duration-200"
|
|
1644
1717
|
href="${link}"
|
|
1645
1718
|
>
|
|
1646
1719
|
<span class="hidden @2xl:inline-block">Open ${contentType}</span>
|
|
@@ -1673,47 +1746,59 @@ function getMainContentRegular(section, config) {
|
|
|
1673
1746
|
</div>
|
|
1674
1747
|
|
|
1675
1748
|
<!-- Code -->
|
|
1676
|
-
<
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1749
|
+
<div class="relative @container">
|
|
1750
|
+
<details class="group">
|
|
1751
|
+
<summary class="flex cursor-pointer items-center rounded-b-2xl px-6 text-sm font-light bg-styleguide-bg">
|
|
1752
|
+
<span class="flex gap-2 items-center py-4 select-none">
|
|
1753
|
+
<svg class="h-4 w-4 group-open:rotate-90 transition-transform" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor">
|
|
1754
|
+
<path fill-rule="evenodd" d="M6.22 4.22a.75.75 0 0 1 1.06 0l3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06L8.94 8 6.22 5.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
|
|
1755
|
+
</svg>
|
|
1756
|
+
|
|
1757
|
+
<span class="group-open:hidden">Show code</span>
|
|
1758
|
+
<span class="group-open:block hidden">Hide code</span>
|
|
1759
|
+
</span>
|
|
1760
|
+
</summary>
|
|
1761
|
+
|
|
1762
|
+
<div class="border-t p-6 text-sm bg-styleguide-bg-highlight border-styleguide-border">
|
|
1763
|
+
<div
|
|
1764
|
+
id="code-fullpage-${sectionSanitizeId(section.id)}"
|
|
1765
|
+
class="overflow-x-auto w-full code-highlight"
|
|
1766
|
+
data-source-code="${encodeURIComponent(sourceCode)}"
|
|
1767
|
+
data-source-lang="html"
|
|
1768
|
+
></div>
|
|
1769
|
+
</div>
|
|
1770
|
+
</details>
|
|
1682
1771
|
|
|
1683
|
-
|
|
1684
|
-
<span class="group-open:block hidden">Hide code</span>
|
|
1685
|
-
</span>
|
|
1686
|
-
|
|
1687
|
-
<span class="flex items-center">
|
|
1772
|
+
<span class="pointer-events-none absolute top-0 right-0 flex items-center pr-6 text-sm font-light">
|
|
1688
1773
|
${section.figma ? `<a
|
|
1689
|
-
class="inline-flex items-center group/figma gap-1.5 p-4 desktop-device-only cursor-pointer active:scale-90 transition hover:text-styleguide-highlight duration-200"
|
|
1774
|
+
class="pointer-events-auto inline-flex items-center group/figma gap-1.5 p-4 desktop-device-only cursor-pointer active:scale-90 transition hover:text-styleguide-highlight duration-200"
|
|
1690
1775
|
href="${computeFigmaExternalLink(section.figma)}"
|
|
1691
1776
|
target="_blank"
|
|
1692
1777
|
>
|
|
1693
1778
|
<span class="hidden @2xl:inline-block">Open in</span>
|
|
1694
1779
|
<span class="sr-only">Figma</span>
|
|
1695
|
-
<img
|
|
1780
|
+
<img
|
|
1696
1781
|
src="styleguide-assets/icons/figma.svg"
|
|
1697
|
-
width="600"
|
|
1698
|
-
height="600"
|
|
1699
|
-
class="size-4 saturate-0 group-hover/figma:saturate-100 transition"
|
|
1700
|
-
alt="Figma Logo"
|
|
1701
|
-
aria-hidden="true"
|
|
1782
|
+
width="600"
|
|
1783
|
+
height="600"
|
|
1784
|
+
class="size-4 saturate-0 group-hover/figma:saturate-100 transition"
|
|
1785
|
+
alt="Figma Logo"
|
|
1786
|
+
aria-hidden="true"
|
|
1702
1787
|
>
|
|
1703
1788
|
</a>` : ""}
|
|
1704
|
-
|
|
1789
|
+
|
|
1705
1790
|
${openInEditorPaths.html ? `
|
|
1706
1791
|
${renderOpenInEditorLink("phpstorm", openInEditorPaths.html.phpstorm.includes(".pug") ? "Pug" : "HTML", openInEditorPaths.html.phpstorm)}
|
|
1707
1792
|
${renderOpenInEditorLink("vscode", openInEditorPaths.html.phpstorm.includes(".pug") ? "Pug" : "HTML", openInEditorPaths.html.vscode)}
|
|
1708
1793
|
` : ""}
|
|
1709
|
-
|
|
1794
|
+
|
|
1710
1795
|
${openInEditorPaths.css ? `
|
|
1711
1796
|
${renderOpenInEditorLink("phpstorm", "CSS", openInEditorPaths.css.phpstorm)}
|
|
1712
1797
|
${renderOpenInEditorLink("vscode", "CSS", openInEditorPaths.css.vscode)}
|
|
1713
1798
|
` : ""}
|
|
1714
1799
|
|
|
1715
1800
|
<button
|
|
1716
|
-
class="inline-flex items-center gap-1.5 p-4 cursor-pointer active:scale-90 transition hover:text-styleguide-highlight duration-200"
|
|
1801
|
+
class="pointer-events-auto inline-flex items-center gap-1.5 p-4 cursor-pointer active:scale-90 transition hover:text-styleguide-highlight duration-200"
|
|
1717
1802
|
type="button"
|
|
1718
1803
|
data-clipboard-value="${encodeURIComponent(sourceCode)}"
|
|
1719
1804
|
data-clipboard-uri-encoded="true"
|
|
@@ -1728,7 +1813,7 @@ function getMainContentRegular(section, config) {
|
|
|
1728
1813
|
</button>
|
|
1729
1814
|
|
|
1730
1815
|
<button
|
|
1731
|
-
class="inline-flex items-center gap-1.5 p-4 cursor-pointer active:scale-90 transition hover:text-styleguide-highlight duration-200"
|
|
1816
|
+
class="pointer-events-auto inline-flex items-center gap-1.5 p-4 cursor-pointer active:scale-90 transition hover:text-styleguide-highlight duration-200"
|
|
1732
1817
|
type="button"
|
|
1733
1818
|
data-code-audit-iframe="preview-fullpage-${sectionSanitizeId(section.id)}"
|
|
1734
1819
|
aria-controls="code-audit-dialog"
|
|
@@ -1737,10 +1822,10 @@ function getMainContentRegular(section, config) {
|
|
|
1737
1822
|
<svg class="h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 122.88 122.88" aria-hidden="true"><title>accessibility</title><path fill="currentcolor" d="M61.44,0A61.46,61.46,0,1,1,18,18,61.21,61.21,0,0,1,61.44,0Zm-.39,74.18L52.1,98.91a4.94,4.94,0,0,1-2.58,2.83A5,5,0,0,1,42.7,95.5l6.24-17.28a26.3,26.3,0,0,0,1.17-4,40.64,40.64,0,0,0,.54-4.18c.24-2.53.41-5.27.54-7.9s.22-5.18.29-7.29c.09-2.63-.62-2.8-2.73-3.3l-.44-.1-18-3.39A5,5,0,0,1,27.08,46a5,5,0,0,1,5.05-7.74l19.34,3.63c.77.07,1.52.16,2.31.25a57.64,57.64,0,0,0,7.18.53A81.13,81.13,0,0,0,69.9,42c.9-.1,1.75-.21,2.6-.29l18.25-3.42A5,5,0,0,1,94.5,39a5,5,0,0,1,1.3,7,5,5,0,0,1-3.21,2.09L75.15,51.37c-.58.13-1.1.22-1.56.29-1.82.31-2.72.47-2.61,3.06.08,1.89.31,4.15.61,6.51.35,2.77.81,5.71,1.29,8.4.31,1.77.6,3.19,1,4.55s.79,2.75,1.39,4.42l6.11,16.9a5,5,0,0,1-6.82,6.24,4.94,4.94,0,0,1-2.58-2.83L63,74.23,62,72.4l-1,1.78Zm.39-53.52a8.83,8.83,0,1,1-6.24,2.59,8.79,8.79,0,0,1,6.24-2.59Zm36.35,4.43a51.42,51.42,0,1,0,15,36.35,51.27,51.27,0,0,0-15-36.35Z"/></svg>
|
|
1738
1823
|
<span class="hidden md:inline-block">Audit</span>
|
|
1739
1824
|
</button>
|
|
1740
|
-
|
|
1825
|
+
|
|
1741
1826
|
${getHasSectionExternalFullpage(section) ? `
|
|
1742
1827
|
<a
|
|
1743
|
-
class="hidden [.styleguide-section--large_&]:inline-block -mr-2 px-2 py-4 group/externallink hover:text-styleguide-highlight focus:text-styleguide-highlight"
|
|
1828
|
+
class="pointer-events-auto hidden [.styleguide-section--large_&]:inline-block -mr-2 px-2 py-4 group/externallink hover:text-styleguide-highlight focus:text-styleguide-highlight"
|
|
1744
1829
|
href="/${section.fullpageFileName}"
|
|
1745
1830
|
target="_blank"
|
|
1746
1831
|
title="Open ${section.header} in fullpage"
|
|
@@ -1752,17 +1837,7 @@ function getMainContentRegular(section, config) {
|
|
|
1752
1837
|
</a>
|
|
1753
1838
|
` : ""}
|
|
1754
1839
|
</span>
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
<div class="border-t p-6 text-sm bg-styleguide-bg-highlight border-styleguide-border">
|
|
1758
|
-
<div
|
|
1759
|
-
id="code-fullpage-${sectionSanitizeId(section.id)}"
|
|
1760
|
-
class="overflow-x-auto w-full code-highlight"
|
|
1761
|
-
data-source-code="${encodeURIComponent(sourceCode)}"
|
|
1762
|
-
data-source-lang="html"
|
|
1763
|
-
></div>
|
|
1764
|
-
</div>
|
|
1765
|
-
</details>
|
|
1840
|
+
</div>
|
|
1766
1841
|
</div>
|
|
1767
1842
|
|
|
1768
1843
|
${section.modifiers?.length > 0 ? `
|
|
@@ -2098,7 +2173,7 @@ async function generatePreviewFile(data) {
|
|
|
2098
2173
|
<meta name="theme-color" media="(prefers-color-scheme: light)" content="${data.theme.light}">
|
|
2099
2174
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="${data.theme.dark}">
|
|
2100
2175
|
` : `<meta name="theme-color" content="${data.theme}">`}
|
|
2101
|
-
<link rel="stylesheet" type="text/css" href="/styleguide-assets/kss-modern-
|
|
2176
|
+
<link rel="stylesheet" type="text/css" href="/styleguide-assets/kss-modern-BJ971T05.css">
|
|
2102
2177
|
<script>
|
|
2103
2178
|
//#region client/lib/iframe-resize.ts
|
|
2104
2179
|
var e = [
|
|
@@ -2261,7 +2336,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
2261
2336
|
//#endregion
|
|
2262
2337
|
;
|
|
2263
2338
|
<\/script>
|
|
2264
|
-
<script type="module" src="/styleguide-assets/preview-
|
|
2339
|
+
<script type="module" src="/styleguide-assets/preview-DEipbLLB.js"><\/script>
|
|
2265
2340
|
<link rel="preload" href="/styleguide-assets/fonts/geist-mono-latin-400-normal.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
2266
2341
|
<link rel="preload" href="/styleguide-assets/fonts/geist-mono-latin-600-normal.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
2267
2342
|
<link rel="preload" href="/styleguide-assets/fonts/geist-mono-latin-300-normal.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
@@ -2316,6 +2391,26 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
2316
2391
|
await logicalWriteFile(data.filePath, content);
|
|
2317
2392
|
}
|
|
2318
2393
|
|
|
2394
|
+
function batchDebounce(fn, windowMs) {
|
|
2395
|
+
let timer;
|
|
2396
|
+
let buffer = [];
|
|
2397
|
+
return (item) => {
|
|
2398
|
+
buffer.push(item);
|
|
2399
|
+
if (timer !== void 0) {
|
|
2400
|
+
clearTimeout(timer);
|
|
2401
|
+
}
|
|
2402
|
+
timer = setTimeout(() => {
|
|
2403
|
+
const batch = buffer;
|
|
2404
|
+
buffer = [];
|
|
2405
|
+
timer = void 0;
|
|
2406
|
+
fn(batch);
|
|
2407
|
+
}, windowMs);
|
|
2408
|
+
};
|
|
2409
|
+
}
|
|
2410
|
+
|
|
2411
|
+
const BATCH_SETTLE_MS = 300;
|
|
2412
|
+
const POLLING_INTERVAL_MS = 300;
|
|
2413
|
+
const USE_POLLING = process.env.FORCE_POLLING === "1" || existsSync("/.dockerenv") || existsSync("/run/.containerenv") || process.env.container !== void 0;
|
|
2319
2414
|
const VALID_CSS_FILE_TYPES = [".css", ".scss", ".sass", ".less"];
|
|
2320
2415
|
const MARKUP_FILE_TYPES = [".pug", ".html"];
|
|
2321
2416
|
function isCssFile(filePath) {
|
|
@@ -2346,11 +2441,33 @@ function tryReadFileSync(filePath) {
|
|
|
2346
2441
|
throw error;
|
|
2347
2442
|
}
|
|
2348
2443
|
}
|
|
2444
|
+
function planRebuilds(changes) {
|
|
2445
|
+
const structural = changes.some((change) => change.category === "structural");
|
|
2446
|
+
if (structural) {
|
|
2447
|
+
return { structural: true, markupFiles: [] };
|
|
2448
|
+
}
|
|
2449
|
+
const markupFiles = [...new Set(
|
|
2450
|
+
changes.filter((change) => change.category === "markup").map((change) => change.path)
|
|
2451
|
+
)];
|
|
2452
|
+
return { structural: false, markupFiles };
|
|
2453
|
+
}
|
|
2349
2454
|
function watchStyleguideForChanges(watchPath, handlers) {
|
|
2350
2455
|
if (typeof handlers.onStructuralChange !== "function" || typeof handlers.onMarkupChange !== "function") {
|
|
2351
2456
|
throw new TypeError("styleguide watch requires onStructuralChange and onMarkupChange callbacks");
|
|
2352
2457
|
}
|
|
2353
2458
|
const regexFileContents = /* @__PURE__ */ new Map();
|
|
2459
|
+
const dispatch = batchDebounce((changes) => {
|
|
2460
|
+
const { structural, markupFiles } = planRebuilds(changes);
|
|
2461
|
+
if (structural) {
|
|
2462
|
+
handlers.onStructuralChange();
|
|
2463
|
+
return;
|
|
2464
|
+
}
|
|
2465
|
+
if (markupFiles.length > 0) {
|
|
2466
|
+
handlers.onMarkupChange(markupFiles);
|
|
2467
|
+
}
|
|
2468
|
+
}, BATCH_SETTLE_MS);
|
|
2469
|
+
const requestStructural = () => dispatch({ category: "structural" });
|
|
2470
|
+
const requestMarkup = (filePath) => dispatch({ category: "markup", path: path.resolve(filePath) });
|
|
2354
2471
|
const handleCssAdd = (filePath) => {
|
|
2355
2472
|
const contents = tryReadFileSync(filePath);
|
|
2356
2473
|
if (contents === void 0)
|
|
@@ -2360,7 +2477,7 @@ function watchStyleguideForChanges(watchPath, handlers) {
|
|
|
2360
2477
|
return;
|
|
2361
2478
|
}
|
|
2362
2479
|
regexFileContents.set(filePath, currentFileMatches);
|
|
2363
|
-
|
|
2480
|
+
requestStructural();
|
|
2364
2481
|
};
|
|
2365
2482
|
const handleCssChange = (filePath) => {
|
|
2366
2483
|
const previousFileMatches = regexFileContents.get(filePath);
|
|
@@ -2374,48 +2491,45 @@ function watchStyleguideForChanges(watchPath, handlers) {
|
|
|
2374
2491
|
if (currentFileMatches === null) {
|
|
2375
2492
|
return;
|
|
2376
2493
|
}
|
|
2377
|
-
|
|
2494
|
+
requestStructural();
|
|
2378
2495
|
return;
|
|
2379
2496
|
}
|
|
2380
2497
|
if (matchArraysEqual(previousFileMatches, currentFileMatches)) {
|
|
2381
2498
|
return;
|
|
2382
2499
|
}
|
|
2383
2500
|
regexFileContents.set(filePath, currentFileMatches);
|
|
2384
|
-
|
|
2501
|
+
requestStructural();
|
|
2385
2502
|
};
|
|
2386
2503
|
const handleCssUnlink = (filePath) => {
|
|
2387
2504
|
regexFileContents.delete(filePath);
|
|
2388
|
-
|
|
2505
|
+
requestStructural();
|
|
2506
|
+
};
|
|
2507
|
+
const routeEvent = (filePath, handleCss) => {
|
|
2508
|
+
if (isCssFile(filePath))
|
|
2509
|
+
handleCss(filePath);
|
|
2510
|
+
else if (isMarkdownFile(filePath))
|
|
2511
|
+
requestStructural();
|
|
2512
|
+
else if (isMarkupFile(filePath))
|
|
2513
|
+
requestMarkup(filePath);
|
|
2389
2514
|
};
|
|
2390
2515
|
const validFileTypes = [...VALID_CSS_FILE_TYPES, ".md", ...MARKUP_FILE_TYPES];
|
|
2391
2516
|
return chokidar.watch(watchPath, {
|
|
2392
2517
|
ignoreInitial: true,
|
|
2518
|
+
usePolling: USE_POLLING,
|
|
2519
|
+
interval: POLLING_INTERVAL_MS,
|
|
2520
|
+
// Wait until a file has stopped being written before emitting — collapses the
|
|
2521
|
+
// multi-event sequence an atomic-save editor (JetBrains, vim with
|
|
2522
|
+
// backupcopy=auto) produces for a single save, and guarantees the read in the
|
|
2523
|
+
// CSS handlers sees complete content rather than a half-written file.
|
|
2524
|
+
awaitWriteFinish: {
|
|
2525
|
+
stabilityThreshold: 100,
|
|
2526
|
+
pollInterval: 20
|
|
2527
|
+
},
|
|
2393
2528
|
// @ts-expect-error - chokidar types seem to be incomplete, ignore
|
|
2394
2529
|
ignored: (filePath, stats) => {
|
|
2395
2530
|
return stats?.isFile() && !validFileTypes.some((type) => filePath.endsWith(type));
|
|
2396
2531
|
}
|
|
2397
|
-
}).on("add", (filePath) => {
|
|
2398
|
-
if (isCssFile(filePath))
|
|
2399
|
-
handleCssAdd(filePath);
|
|
2400
|
-
else if (isMarkdownFile(filePath))
|
|
2401
|
-
handlers.onStructuralChange();
|
|
2402
|
-
else if (isMarkupFile(filePath))
|
|
2403
|
-
handlers.onMarkupChange(path.resolve(filePath));
|
|
2404
|
-
}).on("change", (filePath) => {
|
|
2405
|
-
if (isCssFile(filePath))
|
|
2406
|
-
handleCssChange(filePath);
|
|
2407
|
-
else if (isMarkdownFile(filePath))
|
|
2408
|
-
handlers.onStructuralChange();
|
|
2409
|
-
else if (isMarkupFile(filePath))
|
|
2410
|
-
handlers.onMarkupChange(path.resolve(filePath));
|
|
2411
|
-
}).on("unlink", (filePath) => {
|
|
2412
|
-
if (isCssFile(filePath))
|
|
2413
|
-
handleCssUnlink(filePath);
|
|
2414
|
-
else if (isMarkdownFile(filePath))
|
|
2415
|
-
handlers.onStructuralChange();
|
|
2416
|
-
else if (isMarkupFile(filePath))
|
|
2417
|
-
handlers.onMarkupChange(path.resolve(filePath));
|
|
2418
|
-
}).on("error", (error) => {
|
|
2532
|
+
}).on("add", (filePath) => routeEvent(filePath, handleCssAdd)).on("change", (filePath) => routeEvent(filePath, handleCssChange)).on("unlink", (filePath) => routeEvent(filePath, handleCssUnlink)).on("error", (error) => {
|
|
2419
2533
|
if (isTransientFsError(error))
|
|
2420
2534
|
return;
|
|
2421
2535
|
logger.error("Styleguide watcher error (ignored to keep the dev server running):", error);
|
|
@@ -2631,6 +2745,19 @@ async function buildContext(config) {
|
|
|
2631
2745
|
ownerLocationById
|
|
2632
2746
|
};
|
|
2633
2747
|
}
|
|
2748
|
+
const ASSETS_MARKER_FILE = ".kss-modern-assets";
|
|
2749
|
+
function getAssetsBuildId(theme) {
|
|
2750
|
+
return `kss-modern-BJ971T05.css
|
|
2751
|
+
${JSON.stringify(theme)}
|
|
2752
|
+
`;
|
|
2753
|
+
}
|
|
2754
|
+
async function readAssetsBuildId(markerPath) {
|
|
2755
|
+
try {
|
|
2756
|
+
return await fs.readFile(markerPath, "utf-8");
|
|
2757
|
+
} catch {
|
|
2758
|
+
return void 0;
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2634
2761
|
async function copyStyleguideAssets(config) {
|
|
2635
2762
|
const __filename = fileURLToPath(import.meta.url);
|
|
2636
2763
|
const __dirname = path.dirname(__filename);
|
|
@@ -2642,11 +2769,16 @@ async function copyStyleguideAssets(config) {
|
|
|
2642
2769
|
};
|
|
2643
2770
|
const assetsDirectoryPath = findAssetsDirectoryPath();
|
|
2644
2771
|
const assetsDirectoryOutputPath = path.join(config.outDir, "styleguide-assets");
|
|
2645
|
-
const
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2772
|
+
const markerPath = path.join(assetsDirectoryOutputPath, ASSETS_MARKER_FILE);
|
|
2773
|
+
const expectedBuildId = getAssetsBuildId(config.theme);
|
|
2774
|
+
const currentBuildId = await readAssetsBuildId(markerPath);
|
|
2775
|
+
if (currentBuildId === expectedBuildId) {
|
|
2776
|
+
return;
|
|
2649
2777
|
}
|
|
2778
|
+
await fs.remove(assetsDirectoryOutputPath);
|
|
2779
|
+
await fs.copy(assetsDirectoryPath, assetsDirectoryOutputPath);
|
|
2780
|
+
await generateFaviconFiles(assetsDirectoryOutputPath, config.theme);
|
|
2781
|
+
await fs.writeFile(markerPath, expectedBuildId);
|
|
2650
2782
|
}
|
|
2651
2783
|
async function buildAll(config) {
|
|
2652
2784
|
if (config.mode === "production" && await fs.exists(config.outDir)) {
|
|
@@ -2742,35 +2874,37 @@ async function watchStyleguide(config, onChange, onError) {
|
|
|
2742
2874
|
}
|
|
2743
2875
|
let context = initialBuild.context;
|
|
2744
2876
|
const contentDirPath = config.contentDir.endsWith("/") ? config.contentDir : `${config.contentDir}/`;
|
|
2745
|
-
|
|
2746
|
-
// css/scss/md edits can change section structure -> full rebuild + fresh context
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
}
|
|
2756
|
-
})().catch((error) => {
|
|
2757
|
-
logger.error("Error during rebuild:", error);
|
|
2758
|
-
});
|
|
2877
|
+
const queue = createRebuildQueue({
|
|
2878
|
+
// css/scss/md/yaml edits can change section structure -> full rebuild + fresh context
|
|
2879
|
+
onStructural: async () => {
|
|
2880
|
+
const localBuild = await buildAll(config);
|
|
2881
|
+
context = localBuild.context;
|
|
2882
|
+
if (onChange)
|
|
2883
|
+
onChange({ type: "structural" });
|
|
2884
|
+
if (onError && localBuild.errors) {
|
|
2885
|
+
onError(localBuild.errors);
|
|
2886
|
+
}
|
|
2759
2887
|
},
|
|
2760
|
-
//
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2888
|
+
// .pug/.html source edits -> recompile + rewrite only the sections that depend on them
|
|
2889
|
+
onMarkup: async (changedFiles) => {
|
|
2890
|
+
const dependencyGraph = getPugDependencyGraph();
|
|
2891
|
+
const affected = [...new Set(
|
|
2892
|
+
changedFiles.flatMap((changedFile) => dependencyGraph.getAffectedSections(changedFile))
|
|
2893
|
+
)];
|
|
2894
|
+
if (affected.length === 0)
|
|
2895
|
+
return;
|
|
2896
|
+
await rebuildSections(config, context, affected);
|
|
2897
|
+
if (onChange)
|
|
2898
|
+
onChange({ type: "markup", files: changedFiles, sections: affected });
|
|
2899
|
+
},
|
|
2900
|
+
onError: (error) => {
|
|
2901
|
+
logger.error("Error during rebuild:", error);
|
|
2772
2902
|
}
|
|
2773
2903
|
});
|
|
2904
|
+
watchStyleguideForChanges(contentDirPath, {
|
|
2905
|
+
onStructuralChange: queue.requestStructural,
|
|
2906
|
+
onMarkupChange: queue.requestMarkup
|
|
2907
|
+
});
|
|
2774
2908
|
}
|
|
2775
2909
|
|
|
2776
2910
|
export { buildAll, buildStyleguide, logger, parseStyleguide, rebuildSections, watchStyleguide };
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
"file": "rolldown-runtime-B1bRi_D7.js",
|
|
12
12
|
"name": "rolldown-runtime"
|
|
13
13
|
},
|
|
14
|
+
"_section-previews-D-Mr2eVX.js": {
|
|
15
|
+
"file": "section-previews-D-Mr2eVX.js",
|
|
16
|
+
"name": "section-previews"
|
|
17
|
+
},
|
|
14
18
|
"_shared-hGcWlnRM.js": {
|
|
15
19
|
"file": "shared-hGcWlnRM.js",
|
|
16
20
|
"name": "shared"
|
|
@@ -19,12 +23,12 @@
|
|
|
19
23
|
"file": "signal-ZVBNTRLw.js",
|
|
20
24
|
"name": "signal"
|
|
21
25
|
},
|
|
22
|
-
"_utils-
|
|
23
|
-
"file": "utils-
|
|
26
|
+
"_utils-DtB-AzJa.js": {
|
|
27
|
+
"file": "utils-DtB-AzJa.js",
|
|
24
28
|
"name": "utils"
|
|
25
29
|
},
|
|
26
30
|
"client/fullpage.ts": {
|
|
27
|
-
"file": "fullpage-
|
|
31
|
+
"file": "fullpage-D-fU_bAa.js",
|
|
28
32
|
"name": "fullpage",
|
|
29
33
|
"src": "client/fullpage.ts",
|
|
30
34
|
"isEntry": true,
|
|
@@ -37,15 +41,25 @@
|
|
|
37
41
|
"node_modules/html-validate/dist/esm/browser.js"
|
|
38
42
|
]
|
|
39
43
|
},
|
|
44
|
+
"client/lib/a11y-report.ts": {
|
|
45
|
+
"file": "a11y-report-BgeWSrYe.js",
|
|
46
|
+
"name": "a11y-report",
|
|
47
|
+
"src": "client/lib/a11y-report.ts",
|
|
48
|
+
"isDynamicEntry": true,
|
|
49
|
+
"imports": [
|
|
50
|
+
"_utils-DtB-AzJa.js",
|
|
51
|
+
"_section-previews-D-Mr2eVX.js"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
40
54
|
"client/lib/clipboard.ts": {
|
|
41
|
-
"file": "clipboard-
|
|
55
|
+
"file": "clipboard-CHYspHPs.js",
|
|
42
56
|
"name": "clipboard",
|
|
43
57
|
"src": "client/lib/clipboard.ts",
|
|
44
58
|
"isDynamicEntry": true,
|
|
45
59
|
"imports": [
|
|
46
60
|
"_animate-x_9xNIEv.js",
|
|
47
61
|
"_signal-ZVBNTRLw.js",
|
|
48
|
-
"_utils-
|
|
62
|
+
"_utils-DtB-AzJa.js"
|
|
49
63
|
]
|
|
50
64
|
},
|
|
51
65
|
"client/lib/editor-select.ts": {
|
|
@@ -55,24 +69,25 @@
|
|
|
55
69
|
"isDynamicEntry": true
|
|
56
70
|
},
|
|
57
71
|
"client/lib/html-validator.ts": {
|
|
58
|
-
"file": "html-validator-
|
|
72
|
+
"file": "html-validator-DJGwslsw.js",
|
|
59
73
|
"name": "html-validator",
|
|
60
74
|
"src": "client/lib/html-validator.ts",
|
|
61
75
|
"isDynamicEntry": true,
|
|
62
76
|
"imports": [
|
|
63
77
|
"_code-highlight-Fm7cxf-E.js",
|
|
64
|
-
"_utils-
|
|
65
|
-
"_shared-hGcWlnRM.js"
|
|
78
|
+
"_utils-DtB-AzJa.js",
|
|
79
|
+
"_shared-hGcWlnRM.js",
|
|
80
|
+
"_section-previews-D-Mr2eVX.js"
|
|
66
81
|
]
|
|
67
82
|
},
|
|
68
83
|
"client/lib/icons.ts": {
|
|
69
|
-
"file": "icons-
|
|
84
|
+
"file": "icons-Cip2t08v.js",
|
|
70
85
|
"name": "icons",
|
|
71
86
|
"src": "client/lib/icons.ts",
|
|
72
87
|
"isDynamicEntry": true,
|
|
73
88
|
"imports": [
|
|
74
89
|
"_animate-x_9xNIEv.js",
|
|
75
|
-
"_utils-
|
|
90
|
+
"_utils-DtB-AzJa.js"
|
|
76
91
|
]
|
|
77
92
|
},
|
|
78
93
|
"client/preview-inline.ts": {
|
|
@@ -82,7 +97,7 @@
|
|
|
82
97
|
"isEntry": true
|
|
83
98
|
},
|
|
84
99
|
"client/preview.ts": {
|
|
85
|
-
"file": "preview-
|
|
100
|
+
"file": "preview-DEipbLLB.js",
|
|
86
101
|
"name": "preview",
|
|
87
102
|
"src": "client/preview.ts",
|
|
88
103
|
"isEntry": true,
|
|
@@ -90,10 +105,11 @@
|
|
|
90
105
|
"_animate-x_9xNIEv.js",
|
|
91
106
|
"_code-highlight-Fm7cxf-E.js",
|
|
92
107
|
"_signal-ZVBNTRLw.js",
|
|
93
|
-
"_utils-
|
|
108
|
+
"_utils-DtB-AzJa.js",
|
|
94
109
|
"_shared-hGcWlnRM.js"
|
|
95
110
|
],
|
|
96
111
|
"dynamicImports": [
|
|
112
|
+
"client/lib/a11y-report.ts",
|
|
97
113
|
"client/lib/html-validator.ts",
|
|
98
114
|
"client/lib/icons.ts",
|
|
99
115
|
"client/lib/clipboard.ts",
|
|
@@ -119,7 +135,7 @@
|
|
|
119
135
|
]
|
|
120
136
|
},
|
|
121
137
|
"style.css": {
|
|
122
|
-
"file": "kss-modern-
|
|
138
|
+
"file": "kss-modern-BJ971T05.css",
|
|
123
139
|
"src": "style.css"
|
|
124
140
|
}
|
|
125
141
|
}
|