kss-modern 1.2.0-beta.1 → 1.2.0-beta.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/node/lib/index.mjs +157 -68
- package/dist/node/lib/pug/worker.d.mts +12 -0
- package/dist/node/lib/pug/worker.d.ts +12 -0
- package/dist/node/lib/pug/worker.mjs +6 -4
- package/dist/node/shared/{kss-modern.C3thzyxO.mjs → kss-modern.o1Fp758z.mjs} +96 -10
- package/dist/styleguide-assets/.vite/manifest.json +36 -23
- package/dist/styleguide-assets/{animate-BwJZPSbF.js → animate-DRGZltJ3.js} +1223 -1237
- package/dist/styleguide-assets/assets/worker-CejjK-QF.js +152 -0
- package/dist/styleguide-assets/{axe-BUK9a7nX.js → axe-B09yVm_c.js} +103 -105
- package/dist/styleguide-assets/{browser-bCxY1z1G.js → browser-BgMZpraI.js} +8 -8
- package/dist/styleguide-assets/{clipboard-BqN2XQ0C.js → clipboard-0X6xnPVo.js} +1 -1
- package/dist/styleguide-assets/{code-highlight-ClkzHTGA.js → code-highlight-BygtMiLu.js} +1 -1
- package/dist/styleguide-assets/fullpage-CzaJFxfS.js +177 -0
- package/dist/styleguide-assets/{html-validator-Cv_-JCAq.js → html-validator-CeH3wXbU.js} +23 -32
- package/dist/styleguide-assets/{icons-DICmq5xt.js → icons-Do1H6FzJ.js} +1 -1
- package/dist/styleguide-assets/kss-modern-DW2ZdZvd.css +3 -0
- package/dist/styleguide-assets/{preview-8L8aaFj4.js → preview-ChQyjhUb.js} +5 -5
- package/dist/styleguide-assets/rolldown-runtime-B1bRi_D7.js +27 -0
- package/dist/styleguide-assets/shared-hGcWlnRM.js +15 -0
- package/package.json +12 -9
- package/dist/styleguide-assets/assets/worker-N4ARB4CK.js +0 -12
- package/dist/styleguide-assets/fullpage-CVmYa-FG.js +0 -127
- package/dist/styleguide-assets/kss-modern-CjPjhHw0.css +0 -3
package/dist/node/lib/index.mjs
CHANGED
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import { performance } from 'node:perf_hooks';
|
|
2
3
|
import process from 'node:process';
|
|
3
4
|
import { fileURLToPath } from 'node:url';
|
|
4
5
|
import fs from 'fs-extra';
|
|
5
6
|
import { glob } from 'tinyglobby';
|
|
6
|
-
import { l as logger, s as sanitizeSpecialCharacters, I as INSERT_VITE_PUG_TAG_RE, P as PUG_SRC_RE, c as compileMarkup, p as pugErrorFile,
|
|
7
|
-
export {
|
|
7
|
+
import { l as logger, s as sanitizeSpecialCharacters, I as INSERT_VITE_PUG_TAG_RE, P as PUG_SRC_RE, a as PUG_ERROR_OVERLAY_TAG, c as compileMarkup, p as pugErrorFile, b as sectionSanitizeId, d as stripPugErrorOverlay, e as ensureStartingSlash, g as generateId, r as replaceWrapperContent } from '../shared/kss-modern.o1Fp758z.mjs';
|
|
8
|
+
export { f as createLogger } from '../shared/kss-modern.o1Fp758z.mjs';
|
|
9
|
+
import htmlLang from '@shikijs/langs/html';
|
|
10
|
+
import markdownLang from '@shikijs/langs/markdown';
|
|
11
|
+
import scssLang from '@shikijs/langs/scss';
|
|
12
|
+
import shellscriptLang from '@shikijs/langs/shellscript';
|
|
13
|
+
import typescriptLang from '@shikijs/langs/typescript';
|
|
8
14
|
import { fromAsyncCodeToHtml } from '@shikijs/markdown-it/async';
|
|
15
|
+
import auroraX from '@shikijs/themes/aurora-x';
|
|
16
|
+
import githubLightDefault from '@shikijs/themes/github-light-default';
|
|
9
17
|
import MarkdownItAsync from 'markdown-it-async';
|
|
10
|
-
import {
|
|
18
|
+
import { createHighlighterCore } from 'shiki/core';
|
|
19
|
+
import { createJavaScriptRegexEngine } from 'shiki/engine/javascript';
|
|
11
20
|
import os from 'node:os';
|
|
12
21
|
import { Worker } from 'node:worker_threads';
|
|
13
22
|
import fs$1 from 'node:fs/promises';
|
|
14
23
|
import { objectEntries } from '@antfu/utils';
|
|
15
24
|
import { readFileSync } from 'node:fs';
|
|
16
25
|
import chokidar from 'chokidar';
|
|
17
|
-
import '@biomejs/js-api';
|
|
18
26
|
import 'pug';
|
|
19
27
|
import 'consola';
|
|
20
28
|
import 'consola/utils';
|
|
29
|
+
import 'pug-load';
|
|
21
30
|
|
|
22
31
|
const HEX_COLOR_RE = /^#[0-9A-F]{6}$/i;
|
|
23
32
|
function isValidHexColor(hexCode) {
|
|
@@ -349,6 +358,20 @@ function markdownItComponent(md, options) {
|
|
|
349
358
|
}
|
|
350
359
|
|
|
351
360
|
let md;
|
|
361
|
+
let highlighter;
|
|
362
|
+
let loadedLanguages;
|
|
363
|
+
async function highlightCodeToHtml(code, options) {
|
|
364
|
+
if (!highlighter) {
|
|
365
|
+
highlighter = await createHighlighterCore({
|
|
366
|
+
themes: [githubLightDefault, auroraX],
|
|
367
|
+
langs: [htmlLang, scssLang, typescriptLang, shellscriptLang, markdownLang],
|
|
368
|
+
engine: createJavaScriptRegexEngine()
|
|
369
|
+
});
|
|
370
|
+
loadedLanguages = new Set(highlighter.getLoadedLanguages());
|
|
371
|
+
}
|
|
372
|
+
const lang = loadedLanguages.has(options.lang) ? options.lang : "text";
|
|
373
|
+
return highlighter.codeToHtml(code, { ...options, lang });
|
|
374
|
+
}
|
|
352
375
|
function shiftHeadingLevels(markdownContent, rootHeadingLevel) {
|
|
353
376
|
const getHasHeadingLevel = (level) => new RegExp(`^#{${level}} `, "m").test(markdownContent);
|
|
354
377
|
const shiftDown = (shiftAmount) => {
|
|
@@ -379,7 +402,7 @@ async function parseMarkdown(data) {
|
|
|
379
402
|
});
|
|
380
403
|
md.use(
|
|
381
404
|
fromAsyncCodeToHtml(
|
|
382
|
-
|
|
405
|
+
highlightCodeToHtml,
|
|
383
406
|
{
|
|
384
407
|
themes: {
|
|
385
408
|
light: "github-light-default",
|
|
@@ -998,45 +1021,116 @@ class PugDependencyGraph {
|
|
|
998
1021
|
}
|
|
999
1022
|
}
|
|
1000
1023
|
|
|
1001
|
-
function renderPugErrorOverlay(error) {
|
|
1024
|
+
function renderPugErrorOverlay(error, lastHtml = "") {
|
|
1002
1025
|
const id = escape(error.id);
|
|
1003
|
-
const
|
|
1004
|
-
const
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
style="box-sizing:border-box;width:100%;margin:0;padding:16px 18px;border:1px solid #f43f5e59;border-radius:12px;background:#1f1f23;font-family:ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;color:#e4e4e7;line-height:1.5;text-align:left;"
|
|
1009
|
-
>
|
|
1010
|
-
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
|
|
1011
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="#f43f5e" style="width:18px;height:18px;flex:none;" aria-hidden="true">
|
|
1012
|
-
<path fill-rule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495ZM10 5a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 10 5Zm0 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z" clip-rule="evenodd" />
|
|
1013
|
-
</svg>
|
|
1014
|
-
<span style="font-weight:600;font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:#fb7185;">Pug compile error</span>
|
|
1015
|
-
</div>
|
|
1016
|
-
<h1 style="margin:0;font-size:16px;font-weight:600;color:#fafafa;">Section <code style="font-family:ui-monospace,SFMono-Regular,Menlo,monospace;background:#f43f5e1a;border-radius:5px;padding:1px 7px;color:#fda4af;">${id}</code> failed to compile</h1>
|
|
1017
|
-
${file ? `<p style="margin:8px 0 0;font-size:13px;color:#a1a1aa;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;word-break:break-all;">${file}</p>` : ""}
|
|
1018
|
-
<pre style="margin:12px 0 0;padding:12px 14px;background:#111113;border:1px solid #2a2a30;border-radius:8px;overflow:auto;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.55;color:#f4f4f5;white-space:pre;"><code>${message}</code></pre>
|
|
1019
|
-
</div>`.trim();
|
|
1026
|
+
const message = escape(error.message).replace(/\r?\n/g, " ");
|
|
1027
|
+
const fileAttr = error.file ? ` error-file="${escape(error.file)}"` : "";
|
|
1028
|
+
const emptyAttr = lastHtml ? "" : " data-empty";
|
|
1029
|
+
const overlay = `<${PUG_ERROR_OVERLAY_TAG} error-id="${id}"${fileAttr} error-message="${message}"${emptyAttr}></${PUG_ERROR_OVERLAY_TAG}>`;
|
|
1030
|
+
return `${lastHtml}${overlay}`.trim();
|
|
1020
1031
|
}
|
|
1021
1032
|
|
|
1022
|
-
const MAX_POOL_SIZE = os.cpus().length;
|
|
1033
|
+
const MAX_POOL_SIZE = Math.max(2, os.cpus().length - 1);
|
|
1023
1034
|
const INLINE_THRESHOLD = 2;
|
|
1024
1035
|
const cache = new PugCompileCache();
|
|
1025
1036
|
const graph = new PugDependencyGraph();
|
|
1026
1037
|
function getPugDependencyGraph() {
|
|
1027
1038
|
return graph;
|
|
1028
1039
|
}
|
|
1040
|
+
let lastCompileTimings = { read: 0, parse: 0, render: 0, a11y: 0, sections: 0 };
|
|
1041
|
+
function accumulateTimings(timings) {
|
|
1042
|
+
lastCompileTimings.read += timings.read;
|
|
1043
|
+
lastCompileTimings.parse += timings.parse;
|
|
1044
|
+
lastCompileTimings.render += timings.render;
|
|
1045
|
+
lastCompileTimings.a11y += timings.a11y;
|
|
1046
|
+
lastCompileTimings.sections += 1;
|
|
1047
|
+
}
|
|
1048
|
+
function getLastCompileTimings() {
|
|
1049
|
+
return lastCompileTimings;
|
|
1050
|
+
}
|
|
1029
1051
|
const __filename$1 = fileURLToPath(import.meta.url);
|
|
1030
1052
|
const __dirname$1 = path.dirname(__filename$1);
|
|
1031
1053
|
const workerFilePath = __dirname$1.includes("dist/") ? "./pug/worker.mjs" : "./worker.ts";
|
|
1032
1054
|
const workerFilePathResolved = path.resolve(__dirname$1, workerFilePath);
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1055
|
+
const slots = Array.from({ length: MAX_POOL_SIZE }, () => ({ tail: Promise.resolve(), active: 0 }));
|
|
1056
|
+
const allWorkers = /* @__PURE__ */ new Set();
|
|
1057
|
+
function slotIndexFor(id) {
|
|
1058
|
+
let hash = 2166136261;
|
|
1059
|
+
for (let i = 0; i < id.length; i++) {
|
|
1060
|
+
hash ^= id.charCodeAt(i);
|
|
1061
|
+
hash = Math.imul(hash, 16777619);
|
|
1062
|
+
}
|
|
1063
|
+
return (hash >>> 0) % MAX_POOL_SIZE;
|
|
1064
|
+
}
|
|
1065
|
+
function spawnWorker(index) {
|
|
1066
|
+
const worker = new Worker(workerFilePathResolved, { name: `pug-worker-${index}` });
|
|
1067
|
+
allWorkers.add(worker);
|
|
1068
|
+
return worker;
|
|
1069
|
+
}
|
|
1070
|
+
function runOnWorker(worker, input) {
|
|
1071
|
+
return new Promise((resolve, reject) => {
|
|
1072
|
+
function cleanup() {
|
|
1073
|
+
worker.off("message", onMessage);
|
|
1074
|
+
worker.off("error", onError);
|
|
1075
|
+
}
|
|
1076
|
+
function onMessage(result) {
|
|
1077
|
+
cleanup();
|
|
1078
|
+
resolve(result);
|
|
1079
|
+
}
|
|
1080
|
+
function onError(error) {
|
|
1081
|
+
cleanup();
|
|
1082
|
+
reject(error);
|
|
1083
|
+
}
|
|
1084
|
+
worker.once("message", onMessage);
|
|
1085
|
+
worker.once("error", onError);
|
|
1086
|
+
worker.postMessage(input);
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
function runPinned(id, input) {
|
|
1090
|
+
const slot = slots[slotIndexFor(id)];
|
|
1091
|
+
slot.active++;
|
|
1092
|
+
const run = slot.tail.then(async () => {
|
|
1093
|
+
if (!slot.worker)
|
|
1094
|
+
slot.worker = spawnWorker(slots.indexOf(slot));
|
|
1095
|
+
const worker = slot.worker;
|
|
1096
|
+
worker.ref();
|
|
1097
|
+
try {
|
|
1098
|
+
return await runOnWorker(worker, input);
|
|
1099
|
+
} catch (error) {
|
|
1100
|
+
allWorkers.delete(worker);
|
|
1101
|
+
void worker.terminate().catch(() => {
|
|
1102
|
+
});
|
|
1103
|
+
if (slot.worker === worker)
|
|
1104
|
+
slot.worker = void 0;
|
|
1105
|
+
throw error;
|
|
1106
|
+
} finally {
|
|
1107
|
+
slot.active--;
|
|
1108
|
+
if (slot.active === 0)
|
|
1109
|
+
slot.worker?.unref();
|
|
1110
|
+
}
|
|
1111
|
+
});
|
|
1112
|
+
slot.tail = run.then(() => {
|
|
1113
|
+
}, () => {
|
|
1114
|
+
});
|
|
1115
|
+
return run;
|
|
1116
|
+
}
|
|
1117
|
+
function getPugPoolInfo() {
|
|
1118
|
+
return { cpus: os.cpus().length, maxPoolSize: MAX_POOL_SIZE, workers: allWorkers.size };
|
|
1119
|
+
}
|
|
1120
|
+
async function terminatePugWorkers() {
|
|
1121
|
+
const workers = [...allWorkers];
|
|
1122
|
+
allWorkers.clear();
|
|
1123
|
+
for (const slot of slots) {
|
|
1124
|
+
slot.worker = void 0;
|
|
1125
|
+
slot.tail = Promise.resolve();
|
|
1126
|
+
slot.active = 0;
|
|
1127
|
+
}
|
|
1128
|
+
await Promise.all(workers.map((worker) => worker.terminate()));
|
|
1037
1129
|
}
|
|
1038
1130
|
const signals = ["SIGINT", "SIGTERM", "SIGQUIT"];
|
|
1039
|
-
signals.forEach((signal) => process.on(signal,
|
|
1131
|
+
signals.forEach((signal) => process.on(signal, () => {
|
|
1132
|
+
void terminatePugWorkers();
|
|
1133
|
+
}));
|
|
1040
1134
|
async function storeResult(id, markupSource, html, dependencies) {
|
|
1041
1135
|
graph.setDependencies(id, dependencies);
|
|
1042
1136
|
const depSignatures = await computeDepSignatures(dependencies);
|
|
@@ -1046,14 +1140,16 @@ function recordFailure(mode, repository, errors, pugError) {
|
|
|
1046
1140
|
logger.error(`Pug markup failed to compile for section "${pugError.id}": ${pugError.message}`);
|
|
1047
1141
|
errors.push(pugError);
|
|
1048
1142
|
if (mode === "development") {
|
|
1049
|
-
|
|
1143
|
+
const lastHtml = cache.get(pugError.id)?.compiledHtml ?? "";
|
|
1144
|
+
repository.set(pugError.id, { markup: renderPugErrorOverlay(pugError, lastHtml) });
|
|
1050
1145
|
}
|
|
1051
1146
|
}
|
|
1052
1147
|
async function compileInline(mode, contentDir, repository, id, errors) {
|
|
1053
1148
|
const markupSource = repository.get(id).markup;
|
|
1054
1149
|
try {
|
|
1055
|
-
const { html, dependencies } = await compileMarkup(contentDir, mode, markupSource, id);
|
|
1150
|
+
const { html, dependencies, timings } = await compileMarkup(contentDir, mode, markupSource, id);
|
|
1056
1151
|
repository.set(id, { markup: html });
|
|
1152
|
+
accumulateTimings(timings);
|
|
1057
1153
|
await storeResult(id, markupSource, html, dependencies);
|
|
1058
1154
|
} catch (error) {
|
|
1059
1155
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1062,39 +1158,16 @@ async function compileInline(mode, contentDir, repository, id, errors) {
|
|
|
1062
1158
|
}
|
|
1063
1159
|
}
|
|
1064
1160
|
async function compileViaWorkerPool(mode, contentDir, repository, ids, errors) {
|
|
1065
|
-
const poolSize = Math.min(ids.length, MAX_POOL_SIZE);
|
|
1066
|
-
const waiters = [];
|
|
1067
|
-
const freeWorkers = [];
|
|
1068
|
-
function releaseWorker(worker) {
|
|
1069
|
-
const waiter = waiters.shift();
|
|
1070
|
-
if (waiter) {
|
|
1071
|
-
waiter(worker);
|
|
1072
|
-
} else {
|
|
1073
|
-
freeWorkers.push(worker);
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
function acquireWorker() {
|
|
1077
|
-
const worker = freeWorkers.pop();
|
|
1078
|
-
if (worker) {
|
|
1079
|
-
return Promise.resolve(worker);
|
|
1080
|
-
}
|
|
1081
|
-
return new Promise((resolve) => waiters.push(resolve));
|
|
1082
|
-
}
|
|
1083
|
-
workerPool = Array.from({ length: poolSize }, (_, index) => {
|
|
1084
|
-
const worker = new Worker(workerFilePathResolved, {
|
|
1085
|
-
name: `pug-worker-${index}`
|
|
1086
|
-
});
|
|
1087
|
-
freeWorkers.push(worker);
|
|
1088
|
-
return worker;
|
|
1089
|
-
});
|
|
1090
1161
|
const tasks = ids.map(async (id) => {
|
|
1091
1162
|
const markupSource = repository.get(id).markup;
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1163
|
+
let result;
|
|
1164
|
+
try {
|
|
1165
|
+
result = await runPinned(id, { id, mode, html: markupSource, contentDir });
|
|
1166
|
+
} catch (error) {
|
|
1167
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1168
|
+
recordFailure(mode, repository, errors, { id, message });
|
|
1169
|
+
return;
|
|
1170
|
+
}
|
|
1098
1171
|
if ("error" in result) {
|
|
1099
1172
|
recordFailure(mode, repository, errors, {
|
|
1100
1173
|
id,
|
|
@@ -1104,10 +1177,10 @@ async function compileViaWorkerPool(mode, contentDir, repository, ids, errors) {
|
|
|
1104
1177
|
return;
|
|
1105
1178
|
}
|
|
1106
1179
|
repository.set(id, { markup: result.html });
|
|
1180
|
+
accumulateTimings(result.timings);
|
|
1107
1181
|
await storeResult(id, markupSource, result.html, result.dependencies);
|
|
1108
1182
|
});
|
|
1109
1183
|
await Promise.all(tasks);
|
|
1110
|
-
await terminateAllWorkers();
|
|
1111
1184
|
}
|
|
1112
1185
|
async function compileIds(mode, contentDir, repository, ids) {
|
|
1113
1186
|
const clonedRepository = new Map(repository);
|
|
@@ -1129,6 +1202,7 @@ async function compileIds(mode, contentDir, repository, ids) {
|
|
|
1129
1202
|
if (misses.length === 0)
|
|
1130
1203
|
return clonedRepository;
|
|
1131
1204
|
const errors = [];
|
|
1205
|
+
lastCompileTimings = { read: 0, parse: 0, render: 0, a11y: 0, sections: 0 };
|
|
1132
1206
|
const useInline = mode === "development" && misses.length <= INLINE_THRESHOLD;
|
|
1133
1207
|
if (useInline) {
|
|
1134
1208
|
await Promise.all(misses.map((id) => compileInline(mode, contentDir, clonedRepository, id, errors)));
|
|
@@ -1189,7 +1263,7 @@ async function generateFullPageFile(data) {
|
|
|
1189
1263
|
<meta name="theme-color" media="(prefers-color-scheme: light)" content="${data.theme.light}">
|
|
1190
1264
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="${data.theme.dark}">
|
|
1191
1265
|
` : `<meta name="theme-color" content="${data.theme}">`}
|
|
1192
|
-
<script type="module" src="/styleguide-assets/fullpage-
|
|
1266
|
+
<script type="module" src="/styleguide-assets/fullpage-CzaJFxfS.js"><\/script>
|
|
1193
1267
|
${computedStyleTags}
|
|
1194
1268
|
</head>
|
|
1195
1269
|
<body${data.page.bodyclass ? ` class="${data.page.bodyclass}"` : ""}>
|
|
@@ -1511,6 +1585,7 @@ ${html ?? ""}
|
|
|
1511
1585
|
`;
|
|
1512
1586
|
}
|
|
1513
1587
|
function getMainContentRegular(section, config) {
|
|
1588
|
+
const sourceCode = stripPugErrorOverlay(section.markup);
|
|
1514
1589
|
const openInEditorPaths = {};
|
|
1515
1590
|
if (config.mode === "development" && config.launchInEditor) {
|
|
1516
1591
|
const computedRootPath = config.launchInEditor && typeof config.launchInEditor === "object" && "rootDir" in config.launchInEditor ? config.launchInEditor.rootDir : process.cwd();
|
|
@@ -1612,7 +1687,7 @@ function getMainContentRegular(section, config) {
|
|
|
1612
1687
|
<button
|
|
1613
1688
|
class="inline-flex items-center gap-1.5 p-4 cursor-pointer active:scale-90 transition hover:text-styleguide-highlight duration-200"
|
|
1614
1689
|
type="button"
|
|
1615
|
-
data-clipboard-value="${encodeURIComponent(
|
|
1690
|
+
data-clipboard-value="${encodeURIComponent(sourceCode)}"
|
|
1616
1691
|
data-clipboard-uri-encoded="true"
|
|
1617
1692
|
>
|
|
1618
1693
|
<svg class="h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
@@ -1655,7 +1730,7 @@ function getMainContentRegular(section, config) {
|
|
|
1655
1730
|
<div
|
|
1656
1731
|
id="code-fullpage-${sectionSanitizeId(section.id)}"
|
|
1657
1732
|
class="overflow-x-auto w-full code-highlight"
|
|
1658
|
-
data-source-code="${encodeURIComponent(
|
|
1733
|
+
data-source-code="${encodeURIComponent(sourceCode)}"
|
|
1659
1734
|
data-source-lang="html"
|
|
1660
1735
|
></div>
|
|
1661
1736
|
</div>
|
|
@@ -1992,7 +2067,7 @@ async function generatePreviewFile(data) {
|
|
|
1992
2067
|
<meta name="theme-color" media="(prefers-color-scheme: light)" content="${data.theme.light}">
|
|
1993
2068
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="${data.theme.dark}">
|
|
1994
2069
|
` : `<meta name="theme-color" content="${data.theme}">`}
|
|
1995
|
-
<link rel="stylesheet" type="text/css" href="/styleguide-assets/kss-modern-
|
|
2070
|
+
<link rel="stylesheet" type="text/css" href="/styleguide-assets/kss-modern-DW2ZdZvd.css">
|
|
1996
2071
|
<script>
|
|
1997
2072
|
//#region client/lib/iframe-resize.ts
|
|
1998
2073
|
var e = [
|
|
@@ -2145,7 +2220,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
2145
2220
|
//#endregion
|
|
2146
2221
|
;
|
|
2147
2222
|
<\/script>
|
|
2148
|
-
<script type="module" src="/styleguide-assets/preview-
|
|
2223
|
+
<script type="module" src="/styleguide-assets/preview-ChQyjhUb.js"><\/script>
|
|
2149
2224
|
<link rel="preload" href="/styleguide-assets/fonts/geist-mono-latin-400-normal.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
2150
2225
|
<link rel="preload" href="/styleguide-assets/fonts/geist-mono-latin-600-normal.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
2151
2226
|
<link rel="preload" href="/styleguide-assets/fonts/geist-mono-latin-300-normal.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
@@ -2568,17 +2643,21 @@ async function rebuildSections(config, context, changedSectionIds) {
|
|
|
2568
2643
|
}
|
|
2569
2644
|
if (subset.size === 0)
|
|
2570
2645
|
return;
|
|
2646
|
+
const startedAt = performance.now();
|
|
2647
|
+
const workersBefore = getPugPoolInfo().workers;
|
|
2571
2648
|
const recompiled = await compilePugMarkupIncremental(config.mode, config.contentDir, subset, subset.keys());
|
|
2572
2649
|
for (const [id, entry] of recompiled) {
|
|
2573
2650
|
context.compiledRepository.set(id, { markup: entry.markup });
|
|
2574
2651
|
reindexInsertMarkupConsumer(context, id);
|
|
2575
2652
|
}
|
|
2653
|
+
const afterCompile = performance.now();
|
|
2576
2654
|
const resolved = resolveInsertMarkupForSections(context.compiledRepository, context.sectionsById, affected);
|
|
2577
2655
|
for (const [id, markup] of resolved) {
|
|
2578
2656
|
const node = context.nodeById.get(id);
|
|
2579
2657
|
if (node)
|
|
2580
2658
|
node.markup = markup;
|
|
2581
2659
|
}
|
|
2660
|
+
const afterResolve = performance.now();
|
|
2582
2661
|
const writeTasks = [];
|
|
2583
2662
|
const previewsToWrite = /* @__PURE__ */ new Set();
|
|
2584
2663
|
for (const id of affected) {
|
|
@@ -2596,6 +2675,16 @@ async function rebuildSections(config, context, changedSectionIds) {
|
|
|
2596
2675
|
writeTasks.push(writePreviewFile(config, context, firstLevelIndex, secondLevelIndex));
|
|
2597
2676
|
}
|
|
2598
2677
|
await Promise.all(writeTasks);
|
|
2678
|
+
const afterWrite = performance.now();
|
|
2679
|
+
if (config.mode === "development") {
|
|
2680
|
+
const ms = (value) => `${value.toFixed(1)}ms`;
|
|
2681
|
+
const pool = getPugPoolInfo();
|
|
2682
|
+
const spawned = pool.workers - workersBefore;
|
|
2683
|
+
const t = getLastCompileTimings();
|
|
2684
|
+
logger.info(
|
|
2685
|
+
`Incremental rebuild: ${affected.size} section(s), ${writeTasks.length} file(s) in ${ms(afterWrite - startedAt)} (compile ${ms(afterCompile - startedAt)}, insert-markup ${ms(afterResolve - afterCompile)}, write ${ms(afterWrite - afterResolve)}) [cpus=${pool.cpus}, pool=${pool.maxPoolSize}, workers=${pool.workers}${spawned > 0 ? `, +${spawned} cold-spawned` : ""}] compile breakdown over ${t.sections} section(s): read ${ms(t.read)}, parse ${ms(t.parse)}, render ${ms(t.render)}, a11y ${ms(t.a11y)} (summed per-section; read=disk I/O, parse=lex/parse/codegen)`
|
|
2686
|
+
);
|
|
2687
|
+
}
|
|
2599
2688
|
}
|
|
2600
2689
|
async function watchStyleguide(config, onChange, onError) {
|
|
2601
2690
|
const initialBuild = await buildAll(config);
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { StyleguideConfiguration } from '../index.mjs';
|
|
2
2
|
|
|
3
3
|
type Mode = StyleguideConfiguration['mode'];
|
|
4
|
+
/** Where a section's compile time went, summed over the entry file and any <insert-vite-pug> tags. */
|
|
5
|
+
interface CompileTimings {
|
|
6
|
+
/** Reading the entry file + all includes/extends off disk (file I/O only). */
|
|
7
|
+
read: number;
|
|
8
|
+
/** pug lex + parse + codegen (CPU; excludes the include reads). */
|
|
9
|
+
parse: number;
|
|
10
|
+
/** Executing the compiled template function (pure render). */
|
|
11
|
+
render: number;
|
|
12
|
+
/** `fixAccessibilityIssues` post-processing. */
|
|
13
|
+
a11y: number;
|
|
14
|
+
}
|
|
4
15
|
|
|
5
16
|
interface PugWorkerInput {
|
|
6
17
|
id: string;
|
|
@@ -12,6 +23,7 @@ interface PugWorkerSuccess {
|
|
|
12
23
|
id: string;
|
|
13
24
|
html: string;
|
|
14
25
|
dependencies: string[];
|
|
26
|
+
timings: CompileTimings;
|
|
15
27
|
}
|
|
16
28
|
interface PugWorkerError {
|
|
17
29
|
id: string;
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { StyleguideConfiguration } from '../index.js';
|
|
2
2
|
|
|
3
3
|
type Mode = StyleguideConfiguration['mode'];
|
|
4
|
+
/** Where a section's compile time went, summed over the entry file and any <insert-vite-pug> tags. */
|
|
5
|
+
interface CompileTimings {
|
|
6
|
+
/** Reading the entry file + all includes/extends off disk (file I/O only). */
|
|
7
|
+
read: number;
|
|
8
|
+
/** pug lex + parse + codegen (CPU; excludes the include reads). */
|
|
9
|
+
parse: number;
|
|
10
|
+
/** Executing the compiled template function (pure render). */
|
|
11
|
+
render: number;
|
|
12
|
+
/** `fixAccessibilityIssues` post-processing. */
|
|
13
|
+
a11y: number;
|
|
14
|
+
}
|
|
4
15
|
|
|
5
16
|
interface PugWorkerInput {
|
|
6
17
|
id: string;
|
|
@@ -12,6 +23,7 @@ interface PugWorkerSuccess {
|
|
|
12
23
|
id: string;
|
|
13
24
|
html: string;
|
|
14
25
|
dependencies: string[];
|
|
26
|
+
timings: CompileTimings;
|
|
15
27
|
}
|
|
16
28
|
interface PugWorkerError {
|
|
17
29
|
id: string;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { parentPort } from 'node:worker_threads';
|
|
2
|
-
import { c as compileMarkup, p as pugErrorFile } from '../../shared/kss-modern.
|
|
2
|
+
import { c as compileMarkup, p as pugErrorFile } from '../../shared/kss-modern.o1Fp758z.mjs';
|
|
3
|
+
import 'node:fs';
|
|
3
4
|
import 'node:fs/promises';
|
|
4
5
|
import 'node:path';
|
|
5
|
-
import '
|
|
6
|
+
import 'node:perf_hooks';
|
|
6
7
|
import 'pug';
|
|
7
8
|
import 'consola';
|
|
8
9
|
import 'consola/utils';
|
|
10
|
+
import 'pug-load';
|
|
9
11
|
|
|
10
12
|
if (!parentPort) {
|
|
11
13
|
throw new Error("This file must be run as a worker thread");
|
|
@@ -13,8 +15,8 @@ if (!parentPort) {
|
|
|
13
15
|
parentPort.on("message", async (data) => {
|
|
14
16
|
const { id, mode, html, contentDir } = data;
|
|
15
17
|
try {
|
|
16
|
-
const { html: compiled, dependencies } = await compileMarkup(contentDir, mode, html, id);
|
|
17
|
-
parentPort.postMessage({ id, html: compiled, dependencies });
|
|
18
|
+
const { html: compiled, dependencies, timings } = await compileMarkup(contentDir, mode, html, id);
|
|
19
|
+
parentPort.postMessage({ id, html: compiled, dependencies, timings });
|
|
18
20
|
} catch (error) {
|
|
19
21
|
const message = error instanceof Error ? error.message : String(error);
|
|
20
22
|
parentPort.postMessage({ id, error: message, file: pugErrorFile(error) });
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { statSync, readFileSync } from 'node:fs';
|
|
1
2
|
import fs from 'node:fs/promises';
|
|
2
3
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
4
|
+
import { performance } from 'node:perf_hooks';
|
|
4
5
|
import pug from 'pug';
|
|
5
6
|
import { createConsola } from 'consola';
|
|
6
7
|
import { colors } from 'consola/utils';
|
|
8
|
+
import pugLoad from 'pug-load';
|
|
7
9
|
|
|
8
10
|
const sectionSanitizeId = (id2) => id2.toLowerCase().replaceAll(".", "-");
|
|
9
11
|
|
|
@@ -25,6 +27,11 @@ const logger = createLogger();
|
|
|
25
27
|
const INSERT_VITE_PUG_TAG_RE = /<insert-vite-pug src="(.+?)".*(?:[\n\r\u2028\u2029]\s*)?(modifierClass="(.+?)")? *><\/insert-vite-pug>/g;
|
|
26
28
|
const PUG_SRC_RE = /src="(.+?)"/;
|
|
27
29
|
const PUG_MODIFIER_CLASS_RE = /modifierClass="(.+?)"/;
|
|
30
|
+
const PUG_ERROR_OVERLAY_TAG = "pug-error-overlay";
|
|
31
|
+
const PUG_ERROR_OVERLAY_RE = new RegExp(`<${PUG_ERROR_OVERLAY_TAG}\\b[^>]*></${PUG_ERROR_OVERLAY_TAG}>`, "g");
|
|
32
|
+
function stripPugErrorOverlay(html) {
|
|
33
|
+
return html.replace(PUG_ERROR_OVERLAY_RE, "");
|
|
34
|
+
}
|
|
28
35
|
function fixAccessibilityIssues(html) {
|
|
29
36
|
let parsedMarkup = html;
|
|
30
37
|
const omitValue = [
|
|
@@ -80,9 +87,46 @@ function generateId() {
|
|
|
80
87
|
return value;
|
|
81
88
|
}
|
|
82
89
|
|
|
90
|
+
const parseCache = /* @__PURE__ */ new Map();
|
|
91
|
+
function signatureOf(filename) {
|
|
92
|
+
try {
|
|
93
|
+
const stat = statSync(filename);
|
|
94
|
+
return `${stat.mtimeMs}:${stat.size}`;
|
|
95
|
+
} catch {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
let installed = false;
|
|
100
|
+
const originalLoadString = pugLoad.string;
|
|
101
|
+
function installPugParseCache() {
|
|
102
|
+
if (installed)
|
|
103
|
+
return;
|
|
104
|
+
installed = true;
|
|
105
|
+
pugLoad.string = function cachedLoadString(src, options) {
|
|
106
|
+
const filename = options?.filename;
|
|
107
|
+
if (filename && typeof options.lex === "function" && typeof options.parse === "function") {
|
|
108
|
+
const sig = signatureOf(filename);
|
|
109
|
+
if (sig !== null) {
|
|
110
|
+
let parsed;
|
|
111
|
+
const cached = parseCache.get(filename);
|
|
112
|
+
if (cached && cached.sig === sig) {
|
|
113
|
+
parsed = cached.ast;
|
|
114
|
+
} else {
|
|
115
|
+
parsed = options.parse(options.lex(src, options), options);
|
|
116
|
+
parseCache.set(filename, { sig, ast: parsed });
|
|
117
|
+
}
|
|
118
|
+
return pugLoad(parsed, options);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return originalLoadString(src, options);
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
installPugParseCache();
|
|
83
126
|
let biomePromise;
|
|
84
127
|
function getBiome() {
|
|
85
128
|
biomePromise ??= (async () => {
|
|
129
|
+
const { Biome, Distribution } = await import('@biomejs/js-api');
|
|
86
130
|
const biome = await Biome.create({ distribution: Distribution.NODE });
|
|
87
131
|
const { projectKey } = biome.openProject(".");
|
|
88
132
|
biome.applyConfiguration(projectKey, {
|
|
@@ -118,7 +162,7 @@ async function biomeFormat(content) {
|
|
|
118
162
|
}
|
|
119
163
|
}
|
|
120
164
|
function createUseId(sectionId) {
|
|
121
|
-
const namespace = sectionSanitizeId(sectionId)
|
|
165
|
+
const namespace = `id-${sectionSanitizeId(sectionId)}`;
|
|
122
166
|
let autoCounter = 0;
|
|
123
167
|
return (key) => {
|
|
124
168
|
if (key === void 0) {
|
|
@@ -132,24 +176,50 @@ function pugErrorFile(error) {
|
|
|
132
176
|
const candidate = error;
|
|
133
177
|
return candidate?.path ?? candidate?.filename;
|
|
134
178
|
}
|
|
179
|
+
let includeReadMs = 0;
|
|
180
|
+
function timedRead(filePath) {
|
|
181
|
+
const t0 = performance.now();
|
|
182
|
+
const content = readFileSync(filePath, "utf8");
|
|
183
|
+
includeReadMs += performance.now() - t0;
|
|
184
|
+
return content;
|
|
185
|
+
}
|
|
135
186
|
function compilePugFile(pugFilePath, mode, sectionId, extraLocals = {}) {
|
|
136
|
-
const
|
|
187
|
+
const tRead0 = performance.now();
|
|
188
|
+
const source = readFileSync(pugFilePath, "utf8");
|
|
189
|
+
let readMs = performance.now() - tRead0;
|
|
190
|
+
const includeReadBefore = includeReadMs;
|
|
191
|
+
const tParse0 = performance.now();
|
|
192
|
+
const pugFn = pug.compile(source, {
|
|
193
|
+
filename: pugFilePath,
|
|
137
194
|
// define doctype to avoid self-closing tags on wrong places
|
|
138
195
|
doctype: "html",
|
|
139
196
|
// pretty output in dev keeps the "Show code" view readable without Biome
|
|
140
|
-
pretty: mode === "development"
|
|
197
|
+
pretty: mode === "development",
|
|
198
|
+
// pug defaults this to true, which wraps the generated function in per-line try/catch +
|
|
199
|
+
// line-mapping — measurably bloating codegen and `new Function`. We surface compile errors via
|
|
200
|
+
// our own overlay, so the precise pug line in a runtime stack isn't worth the cost.
|
|
201
|
+
compileDebug: false,
|
|
202
|
+
plugins: [{ read: timedRead }]
|
|
141
203
|
});
|
|
204
|
+
const includeReads = includeReadMs - includeReadBefore;
|
|
205
|
+
const parseMs = performance.now() - tParse0 - includeReads;
|
|
206
|
+
readMs += includeReads;
|
|
142
207
|
const dependencies = [path.resolve(pugFilePath), ...pugFn.dependencies.map((dep) => path.resolve(dep))];
|
|
208
|
+
const tRender0 = performance.now();
|
|
143
209
|
const html = pugFn({ ...extraLocals, useId: createUseId(sectionId) });
|
|
144
|
-
|
|
210
|
+
const renderMs = performance.now() - tRender0;
|
|
211
|
+
return { html, dependencies, readMs, parseMs, renderMs };
|
|
145
212
|
}
|
|
146
213
|
async function expandVitePugTags(contentDir, mode, html, sectionId) {
|
|
147
214
|
const vitePugTags = html.match(INSERT_VITE_PUG_TAG_RE);
|
|
148
215
|
if (!vitePugTags) {
|
|
149
|
-
return { html, dependencies: [] };
|
|
216
|
+
return { html, dependencies: [], timings: { read: 0, parse: 0, render: 0, a11y: 0 } };
|
|
150
217
|
}
|
|
151
218
|
let markupOutput = html;
|
|
152
219
|
const dependencies = [];
|
|
220
|
+
let read = 0;
|
|
221
|
+
let parse = 0;
|
|
222
|
+
let render = 0;
|
|
153
223
|
await Promise.all(vitePugTags.map(async (vitePugTag) => {
|
|
154
224
|
const pugSourcePath = vitePugTag.match(PUG_SRC_RE)?.[1];
|
|
155
225
|
if (!pugSourcePath) {
|
|
@@ -162,35 +232,51 @@ async function expandVitePugTags(contentDir, mode, html, sectionId) {
|
|
|
162
232
|
const pugModifierClass = vitePugTag.match(PUG_MODIFIER_CLASS_RE);
|
|
163
233
|
const pugLocals = pugModifierClass && pugModifierClass[1] ? { modifierClass: pugModifierClass[1] } : {};
|
|
164
234
|
const pugFilePath = path.join(contentDir, pugSourcePath);
|
|
165
|
-
const { html: pugOutput, dependencies: pugDependencies } = compilePugFile(pugFilePath, mode, sectionId, pugLocals);
|
|
235
|
+
const { html: pugOutput, dependencies: pugDependencies, readMs, parseMs, renderMs } = compilePugFile(pugFilePath, mode, sectionId, pugLocals);
|
|
166
236
|
dependencies.push(...pugDependencies);
|
|
237
|
+
read += readMs;
|
|
238
|
+
parse += parseMs;
|
|
239
|
+
render += renderMs;
|
|
167
240
|
markupOutput = markupOutput.replaceAll(vitePugTag, pugOutput);
|
|
168
241
|
}));
|
|
169
|
-
return { html: markupOutput, dependencies };
|
|
242
|
+
return { html: markupOutput, dependencies, timings: { read, parse, render, a11y: 0 } };
|
|
170
243
|
}
|
|
171
244
|
async function compileMarkup(contentDir, mode, html, sectionId) {
|
|
172
245
|
let result = html;
|
|
173
246
|
const dependencies = [];
|
|
247
|
+
let read = 0;
|
|
248
|
+
let parse = 0;
|
|
249
|
+
let render = 0;
|
|
174
250
|
const trimmed = html.trim();
|
|
175
251
|
const isBarePath = !trimmed.includes("<") && !trimmed.includes("\n");
|
|
176
252
|
if (isBarePath && trimmed.endsWith(".html")) {
|
|
177
253
|
const htmlFilePath = path.join(contentDir, trimmed);
|
|
254
|
+
const t0 = performance.now();
|
|
178
255
|
result = await fs.readFile(htmlFilePath, "utf-8");
|
|
256
|
+
read += performance.now() - t0;
|
|
179
257
|
dependencies.push(path.resolve(htmlFilePath));
|
|
180
258
|
} else if (isBarePath && trimmed.endsWith(".pug")) {
|
|
181
259
|
const pugFilePath = path.join(contentDir, trimmed);
|
|
182
260
|
const compiled = compilePugFile(pugFilePath, mode, sectionId);
|
|
183
261
|
result = compiled.html;
|
|
184
262
|
dependencies.push(...compiled.dependencies);
|
|
263
|
+
read += compiled.readMs;
|
|
264
|
+
parse += compiled.parseMs;
|
|
265
|
+
render += compiled.renderMs;
|
|
185
266
|
}
|
|
186
267
|
const expanded = await expandVitePugTags(contentDir, mode, result, sectionId);
|
|
187
268
|
result = expanded.html;
|
|
188
269
|
dependencies.push(...expanded.dependencies);
|
|
270
|
+
read += expanded.timings.read;
|
|
271
|
+
parse += expanded.timings.parse;
|
|
272
|
+
render += expanded.timings.render;
|
|
189
273
|
if (mode === "production") {
|
|
190
274
|
result = await biomeFormat(result);
|
|
191
275
|
}
|
|
276
|
+
const tA11y = performance.now();
|
|
192
277
|
result = fixAccessibilityIssues(result);
|
|
193
|
-
|
|
278
|
+
const a11y = performance.now() - tA11y;
|
|
279
|
+
return { html: result, dependencies: [...new Set(dependencies)], timings: { read, parse, render, a11y } };
|
|
194
280
|
}
|
|
195
281
|
|
|
196
|
-
export { INSERT_VITE_PUG_TAG_RE as I, PUG_SRC_RE as P,
|
|
282
|
+
export { INSERT_VITE_PUG_TAG_RE as I, PUG_SRC_RE as P, PUG_ERROR_OVERLAY_TAG as a, sectionSanitizeId as b, compileMarkup as c, stripPugErrorOverlay as d, ensureStartingSlash as e, createLogger as f, generateId as g, logger as l, pugErrorFile as p, replaceWrapperContent as r, sanitizeSpecialCharacters as s };
|