@yahoo/uds 3.134.0 → 3.134.1
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/cli/dist/lib/args.cjs +7 -3
- package/dist/cli/dist/lib/args.js +7 -3
- package/dist/components/client/Menu/Menu.ItemCheckbox.d.cts +1 -1
- package/dist/components/client/Menu/Menu.ItemCheckbox.d.ts +1 -1
- package/dist/styles/styler.d.cts +26 -26
- package/dist/styles/styler.d.ts +26 -26
- package/dist/tailwind/dist/commands/css.cjs +1 -0
- package/dist/tailwind/dist/commands/css.d.cts.map +1 -1
- package/dist/tailwind/dist/commands/css.d.ts.map +1 -1
- package/dist/tailwind/dist/commands/css.helpers.cjs +8 -1
- package/dist/tailwind/dist/commands/css.helpers.js +8 -1
- package/dist/tailwind/dist/commands/css.helpers.js.map +1 -1
- package/dist/tailwind/dist/commands/css.js +1 -0
- package/dist/tailwind/dist/commands/css.js.map +1 -1
- package/dist/tailwind/dist/css/generate.cjs +7 -4
- package/dist/tailwind/dist/css/generate.d.cts.map +1 -1
- package/dist/tailwind/dist/css/generate.d.ts.map +1 -1
- package/dist/tailwind/dist/css/generate.js +7 -4
- package/dist/tailwind/dist/css/generate.js.map +1 -1
- package/dist/tailwind/dist/css/nodeUtils.cjs +19 -8
- package/dist/tailwind/dist/css/nodeUtils.js +19 -8
- package/dist/tailwind/dist/css/nodeUtils.js.map +1 -1
- package/dist/tailwind/dist/css/perf.cjs +92 -0
- package/dist/tailwind/dist/css/perf.js +89 -0
- package/dist/tailwind/dist/css/perf.js.map +1 -0
- package/dist/tailwind/dist/css/purgeWorker.cjs +47 -0
- package/dist/tailwind/dist/css/purgeWorker.d.cts +2 -0
- package/dist/tailwind/dist/css/purgeWorker.d.ts +2 -0
- package/dist/tailwind/dist/css/purgeWorker.js +48 -0
- package/dist/tailwind/dist/css/purgeWorker.js.map +1 -0
- package/dist/tailwind/dist/css/runner.cjs +158 -145
- package/dist/tailwind/dist/css/runner.js +158 -145
- package/dist/tailwind/dist/css/runner.js.map +1 -1
- package/dist/tailwind/dist/css/workerPool.cjs +89 -0
- package/dist/tailwind/dist/css/workerPool.js +90 -0
- package/dist/tailwind/dist/css/workerPool.js.map +1 -0
- package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +95 -15
- package/dist/tailwind/dist/purger/optimized/ast/expressions.js +95 -15
- package/dist/tailwind/dist/purger/optimized/ast/expressions.js.map +1 -1
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +38 -14
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.cts.map +1 -1
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.d.ts.map +1 -1
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +39 -15
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.js.map +1 -1
- package/dist/tailwind/dist/purger/optimized/types.d.cts +10 -0
- package/dist/tailwind/dist/purger/optimized/types.d.cts.map +1 -1
- package/dist/tailwind/dist/purger/optimized/types.d.ts +10 -0
- package/dist/tailwind/dist/purger/optimized/types.d.ts.map +1 -1
- package/dist/uds/generated/componentData.cjs +557 -557
- package/dist/uds/generated/componentData.js +557 -557
- package/generated/componentData.json +915 -915
- package/package.json +1 -1
- package/dist/tailwind/dist/purger/optimized/ast/jsx.cjs +0 -16
- package/dist/tailwind/dist/purger/optimized/ast/jsx.js +0 -17
- package/dist/tailwind/dist/purger/optimized/ast/jsx.js.map +0 -1
|
@@ -3,6 +3,7 @@ import { gray, green, magenta } from "../cli/dist/lib/colors.js";
|
|
|
3
3
|
import { print } from "../cli/dist/lib/print.js";
|
|
4
4
|
import { spinStart, spinStop } from "../cli/dist/lib/spinner.js";
|
|
5
5
|
import { createLogger } from "../cli/dist/lib/logger.js";
|
|
6
|
+
import { captureMemory, clearTimings, measureAsync, printPerfSummary } from "./perf.js";
|
|
6
7
|
import { resolveEntryPaths } from "../utils/entryPoints.js";
|
|
7
8
|
import { findPackageRoot, findPackageSourceDir, getPackageUdsScope, loadConfigFile, scanDirectoriesForSafelist, scanDirectoryForSafelist } from "./nodeUtils.js";
|
|
8
9
|
import { defaultTokensConfig } from "../config/dist/index.js";
|
|
@@ -11,6 +12,7 @@ import { formatCssDuration, getMainCssSummaryMessage, getOutputFileSection, getS
|
|
|
11
12
|
import { extractRuntimeConfigValues, extractVariantDefaults, formatBytes, getConfigurableCssVariables, getMotionVarPrefixes } from "./utils.js";
|
|
12
13
|
import { getPruneVarSafelist } from "./generate.helpers.js";
|
|
13
14
|
import { generateCSS, generateSimpleModeCSS } from "./generate.js";
|
|
15
|
+
import { createWorkerPool } from "./workerPool.js";
|
|
14
16
|
import fs from "node:fs";
|
|
15
17
|
//#region src/css/runner.ts
|
|
16
18
|
const getScopedPackageOutputPath = (packageName, outFile) => {
|
|
@@ -247,170 +249,181 @@ const runThemeMode = async (options, context) => {
|
|
|
247
249
|
if (themeConfig.config && appConfig === defaultTokensConfig) log.warn(`App config not found: ${themeConfig.config}, using defaults`);
|
|
248
250
|
const packageDirs = [];
|
|
249
251
|
const generateThemeModeCSS = async (opts) => {
|
|
252
|
+
clearTimings();
|
|
253
|
+
captureMemory("start");
|
|
250
254
|
const genStartTime = performance.now();
|
|
251
255
|
const genLog = opts?.isWatch ? createLogger({ silent: true }) : log;
|
|
252
256
|
const scopedCssOutputs = [];
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
257
|
+
const pool = await createWorkerPool({
|
|
258
|
+
variants: context.variants,
|
|
259
|
+
autoVariants: context.autoVariants,
|
|
260
|
+
componentData: context.componentData
|
|
261
|
+
}, options.workers);
|
|
262
|
+
try {
|
|
263
|
+
genLog.spinStart(`Scanning app and packages... (${pool.workerCount} worker${pool.workerCount === 1 ? "" : "s"})`);
|
|
264
|
+
const scopedPackageTargets = [];
|
|
265
|
+
const processInheritedPackage = async (packageName) => {
|
|
266
|
+
const packageDir = findPackageSourceDir(packageName);
|
|
267
|
+
if (!packageDir) return {
|
|
268
|
+
packageName,
|
|
269
|
+
status: "not-found"
|
|
270
|
+
};
|
|
271
|
+
if (!packageDirs.includes(packageDir)) packageDirs.push(packageDir);
|
|
272
|
+
return {
|
|
273
|
+
packageName,
|
|
274
|
+
status: "ok",
|
|
275
|
+
scanResult: await scanDirectoryForSafelist(packageDir, colorModes, context.variants, context.autoVariants, context.componentData, appVariantDefaults, runtimeConfigValues, true, pool)
|
|
276
|
+
};
|
|
277
|
+
};
|
|
278
|
+
const processScopedPackage = async (packageName, scopedPackageValue) => {
|
|
279
|
+
const scopedPackageConfig = normalizeScopedPackageConfig(scopedPackageValue);
|
|
280
|
+
const packageRoot = findPackageRoot(packageName);
|
|
281
|
+
const packageDir = findPackageSourceDir(packageName);
|
|
282
|
+
if (!packageRoot || !packageDir) return;
|
|
283
|
+
const scopeClass = getPackageUdsScope(packageName);
|
|
284
|
+
if (!scopeClass) return;
|
|
285
|
+
const entryDirs = resolveScopedEntryDirs(packageRoot, packageDir, scopedPackageConfig.entry);
|
|
286
|
+
entryDirs.forEach((entryDir) => {
|
|
287
|
+
if (!packageDirs.includes(entryDir)) packageDirs.push(entryDir);
|
|
288
|
+
});
|
|
289
|
+
scopedPackageTargets.push({
|
|
290
|
+
packageName,
|
|
291
|
+
packageRoot,
|
|
292
|
+
packageDir,
|
|
293
|
+
entryDirs,
|
|
294
|
+
scopeClass,
|
|
295
|
+
config: scopedPackageConfig
|
|
296
|
+
});
|
|
297
|
+
};
|
|
298
|
+
const [appScanResult, inheritedResults] = await Promise.all([
|
|
299
|
+
measureAsync("scan", () => scanDirectoriesForSafelist(entryDirs, colorModes, context.variants, context.autoVariants, context.componentData, appVariantDefaults, runtimeConfigValues, false, pool)),
|
|
300
|
+
Promise.all((themeConfig.inherit ?? []).map((packageName) => measureAsync(`scan:inherit:${packageName}`, () => processInheritedPackage(packageName)))),
|
|
301
|
+
Promise.all(Object.entries(themeConfig.scoped ?? {}).map(([packageName, scopedPackageConfig]) => processScopedPackage(packageName, scopedPackageConfig)))
|
|
302
|
+
]);
|
|
278
303
|
genLog.spinStop("✅", getScanSummaryMessage({
|
|
279
|
-
label:
|
|
280
|
-
filesScanned:
|
|
281
|
-
filesWithComponents:
|
|
282
|
-
componentCount:
|
|
283
|
-
mode: "
|
|
304
|
+
label: "app",
|
|
305
|
+
filesScanned: appScanResult.filesScanned,
|
|
306
|
+
filesWithComponents: appScanResult.filesWithComponents,
|
|
307
|
+
componentCount: appScanResult.components.length,
|
|
308
|
+
mode: "app"
|
|
284
309
|
}));
|
|
285
|
-
if (options.verbose) printVerboseScanFiles(genLog, workspaceDir,
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
310
|
+
if (options.verbose) printVerboseScanFiles(genLog, workspaceDir, appScanResult.filePaths);
|
|
311
|
+
for (const result of inheritedResults) if (result.status === "not-found") genLog.spinStop("⚠️", `Package not found: ${result.packageName}`);
|
|
312
|
+
else {
|
|
313
|
+
genLog.spinStop("✅", getScanSummaryMessage({
|
|
314
|
+
label: result.packageName,
|
|
315
|
+
filesScanned: result.scanResult.filesScanned,
|
|
316
|
+
filesWithComponents: result.scanResult.filesWithComponents,
|
|
317
|
+
componentCount: result.scanResult.components.length,
|
|
318
|
+
mode: "inherit"
|
|
319
|
+
}));
|
|
320
|
+
if (options.verbose) printVerboseScanFiles(genLog, workspaceDir, result.scanResult.filePaths);
|
|
295
321
|
}
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
322
|
+
const inheritedClasses = [...appScanResult.safelist];
|
|
323
|
+
const inheritedComponents = new Set(appScanResult.components);
|
|
324
|
+
for (const result of inheritedResults) if (result.status === "ok") {
|
|
325
|
+
inheritedClasses.push(...result.scanResult.safelist);
|
|
326
|
+
result.scanResult.components.forEach((comp) => inheritedComponents.add(comp));
|
|
300
327
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
});
|
|
305
|
-
scopedPackageTargets.push({
|
|
306
|
-
packageName,
|
|
307
|
-
packageRoot,
|
|
308
|
-
packageDir,
|
|
309
|
-
entryDirs,
|
|
310
|
-
scopeClass,
|
|
311
|
-
config: scopedPackageConfig
|
|
312
|
-
});
|
|
313
|
-
};
|
|
314
|
-
await (themeConfig.inherit ?? []).reduce(async (promise, packageName) => {
|
|
315
|
-
await promise;
|
|
316
|
-
await processInheritedPackage(packageName);
|
|
317
|
-
}, Promise.resolve());
|
|
318
|
-
await Object.entries(themeConfig.scoped ?? {}).reduce(async (promise, [packageName, scopedPackageConfig]) => {
|
|
319
|
-
await promise;
|
|
320
|
-
await processScopedPackage(packageName, scopedPackageConfig);
|
|
321
|
-
}, Promise.resolve());
|
|
322
|
-
const mainSafelist = deduplicateSafelist([
|
|
323
|
-
...inheritedClasses,
|
|
324
|
-
...getThemeAndScaleClasses(colorModes),
|
|
325
|
-
...getInternalSafelistClasses()
|
|
326
|
-
]);
|
|
327
|
-
const allMotionComponents = [...inheritedComponents];
|
|
328
|
-
const mainCssResult = await generateCSS([...themeConfig.css?.safelist ?? [], ...mainSafelist], appConfig, {
|
|
329
|
-
scope: options.scope,
|
|
330
|
-
contentDir: entryDirs,
|
|
331
|
-
cssOptions: themeConfig.css,
|
|
332
|
-
safeVarPrefixes: [
|
|
333
|
-
...getMotionVarPrefixes(context.componentData, allMotionComponents),
|
|
334
|
-
...getConfigurableCssVariables(),
|
|
335
|
-
...getPruneVarSafelist(themeConfig.css)
|
|
336
|
-
]
|
|
337
|
-
});
|
|
338
|
-
ensureOutputDirectory(outputPath);
|
|
339
|
-
fs.writeFileSync(outputPath, mainCssResult.css);
|
|
340
|
-
for (const scopedPackageTarget of scopedPackageTargets) {
|
|
341
|
-
const packageConfig = await loadConfigFile(isAbsolutePath(scopedPackageTarget.config.config) ? scopedPackageTarget.config.config : joinPath(scopedPackageTarget.packageRoot, scopedPackageTarget.config.config)) ?? defaultTokensConfig;
|
|
342
|
-
const packageVariantDefaults = extractVariantDefaults(packageConfig);
|
|
343
|
-
const packageRuntimeConfigValues = extractRuntimeConfigValues(packageConfig);
|
|
344
|
-
const packageScanResult = await scanDirectoriesForSafelist(scopedPackageTarget.entryDirs, colorModes, context.variants, context.autoVariants, context.componentData, packageVariantDefaults, packageRuntimeConfigValues, true);
|
|
345
|
-
genLog.spinStop("✅", getScanSummaryMessage({
|
|
346
|
-
label: scopedPackageTarget.packageName,
|
|
347
|
-
filesScanned: packageScanResult.filesScanned,
|
|
348
|
-
filesWithComponents: packageScanResult.filesWithComponents,
|
|
349
|
-
componentCount: packageScanResult.components.length,
|
|
350
|
-
mode: "scoped"
|
|
351
|
-
}));
|
|
352
|
-
if (options.verbose) printVerboseScanFiles(genLog, workspaceDir, packageScanResult.filePaths);
|
|
353
|
-
const packageSafelist = deduplicateSafelist([
|
|
354
|
-
...packageScanResult.safelist,
|
|
328
|
+
genLog.spinStart("Generating main CSS...");
|
|
329
|
+
const mainSafelist = deduplicateSafelist([
|
|
330
|
+
...inheritedClasses,
|
|
355
331
|
...getThemeAndScaleClasses(colorModes),
|
|
356
332
|
...getInternalSafelistClasses()
|
|
357
333
|
]);
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
334
|
+
const allMotionComponents = [...inheritedComponents];
|
|
335
|
+
captureMemory("before-gen");
|
|
336
|
+
const mainCssResult = await measureAsync("gen", () => generateCSS([...themeConfig.css?.safelist ?? [], ...mainSafelist], appConfig, {
|
|
337
|
+
scope: options.scope,
|
|
338
|
+
contentDir: entryDirs,
|
|
361
339
|
cssOptions: themeConfig.css,
|
|
362
|
-
referenceCss: themeConfig.css?.optimization?.deduplicateScopedCss === false ? void 0 : mainCssResult.css,
|
|
363
340
|
safeVarPrefixes: [
|
|
364
|
-
...getMotionVarPrefixes(context.componentData,
|
|
341
|
+
...getMotionVarPrefixes(context.componentData, allMotionComponents),
|
|
365
342
|
...getConfigurableCssVariables(),
|
|
366
343
|
...getPruneVarSafelist(themeConfig.css)
|
|
367
344
|
]
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
ensureOutputDirectory(
|
|
371
|
-
fs.writeFileSync(
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
345
|
+
}));
|
|
346
|
+
captureMemory("after-gen");
|
|
347
|
+
ensureOutputDirectory(outputPath);
|
|
348
|
+
fs.writeFileSync(outputPath, mainCssResult.css);
|
|
349
|
+
for (const scopedPackageTarget of scopedPackageTargets) {
|
|
350
|
+
const packageConfig = await loadConfigFile(isAbsolutePath(scopedPackageTarget.config.config) ? scopedPackageTarget.config.config : joinPath(scopedPackageTarget.packageRoot, scopedPackageTarget.config.config)) ?? defaultTokensConfig;
|
|
351
|
+
const packageVariantDefaults = extractVariantDefaults(packageConfig);
|
|
352
|
+
const packageRuntimeConfigValues = extractRuntimeConfigValues(packageConfig);
|
|
353
|
+
const packageScanResult = await scanDirectoriesForSafelist(scopedPackageTarget.entryDirs, colorModes, context.variants, context.autoVariants, context.componentData, packageVariantDefaults, packageRuntimeConfigValues, true, pool);
|
|
354
|
+
genLog.spinStop("✅", getScanSummaryMessage({
|
|
355
|
+
label: scopedPackageTarget.packageName,
|
|
356
|
+
filesScanned: packageScanResult.filesScanned,
|
|
357
|
+
filesWithComponents: packageScanResult.filesWithComponents,
|
|
358
|
+
componentCount: packageScanResult.components.length,
|
|
359
|
+
mode: "scoped"
|
|
360
|
+
}));
|
|
361
|
+
if (options.verbose) printVerboseScanFiles(genLog, workspaceDir, packageScanResult.filePaths);
|
|
362
|
+
const packageSafelist = deduplicateSafelist([
|
|
363
|
+
...packageScanResult.safelist,
|
|
364
|
+
...getThemeAndScaleClasses(colorModes),
|
|
365
|
+
...getInternalSafelistClasses()
|
|
366
|
+
]);
|
|
367
|
+
const scopedCssResult = await generateCSS([...themeConfig.css?.safelist ?? [], ...packageSafelist], packageConfig, {
|
|
368
|
+
scope: scopedPackageTarget.scopeClass,
|
|
369
|
+
contentDir: scopedPackageTarget.entryDirs,
|
|
370
|
+
cssOptions: themeConfig.css,
|
|
371
|
+
referenceCss: themeConfig.css?.optimization?.deduplicateScopedCss === false ? void 0 : mainCssResult.css,
|
|
372
|
+
safeVarPrefixes: [
|
|
373
|
+
...getMotionVarPrefixes(context.componentData, [...packageScanResult.components]),
|
|
374
|
+
...getConfigurableCssVariables(),
|
|
375
|
+
...getPruneVarSafelist(themeConfig.css)
|
|
376
|
+
]
|
|
377
|
+
});
|
|
378
|
+
const scopedOutputPath = resolveOutputPath(workspaceDir, getScopedPackageOutputPath(scopedPackageTarget.packageName, scopedPackageTarget.config.outFile));
|
|
379
|
+
ensureOutputDirectory(scopedOutputPath);
|
|
380
|
+
fs.writeFileSync(scopedOutputPath, scopedCssResult.css);
|
|
381
|
+
scopedCssOutputs.push({
|
|
382
|
+
label: scopedPackageTarget.packageName,
|
|
383
|
+
outputPath: scopedOutputPath,
|
|
384
|
+
sizeGzipBytes: scopedCssResult.sizeGzipBytes,
|
|
385
|
+
optimizationStats: scopedCssResult.optimizationStats
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
const mainCssSummary = getMainCssSummaryMessage({
|
|
389
|
+
sizeGzipBytes: mainCssResult.sizeGzipBytes,
|
|
390
|
+
optimizationStats: mainCssResult.optimizationStats,
|
|
392
391
|
formatBytes
|
|
393
392
|
});
|
|
394
|
-
genLog.spinStop("✅",
|
|
395
|
-
|
|
393
|
+
genLog.spinStop("✅", mainCssSummary.summaryLine);
|
|
394
|
+
mainCssSummary.detailLines.forEach((detailLine) => {
|
|
396
395
|
genLog.print(detailLine);
|
|
397
396
|
});
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
duration
|
|
410
|
-
outputPath,
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
397
|
+
scopedCssOutputs.forEach((scopedCssOutput) => {
|
|
398
|
+
const scopedCssSummary = getScopedCssSummaryMessage(scopedCssOutput.label, {
|
|
399
|
+
sizeGzipBytes: scopedCssOutput.sizeGzipBytes,
|
|
400
|
+
optimizationStats: scopedCssOutput.optimizationStats,
|
|
401
|
+
formatBytes
|
|
402
|
+
});
|
|
403
|
+
genLog.spinStop("✅", scopedCssSummary.summaryLine);
|
|
404
|
+
scopedCssSummary.detailLines.forEach((detailLine) => {
|
|
405
|
+
genLog.print(detailLine);
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
const duration = Math.round(performance.now() - genStartTime);
|
|
409
|
+
const outputFileSection = getOutputFileSection(workspaceDir, [outputPath, ...scopedCssOutputs.map((scopedCssOutput) => scopedCssOutput.outputPath)]);
|
|
410
|
+
genLog.newline();
|
|
411
|
+
genLog.print(outputFileSection.label);
|
|
412
|
+
outputFileSection.paths.forEach((filePath) => {
|
|
413
|
+
genLog.listItem(filePath);
|
|
414
|
+
});
|
|
415
|
+
genLog.newline();
|
|
416
|
+
genLog.print(`${magenta("Total time:")} ${formatCssDuration(duration)}`);
|
|
417
|
+
printPerfSummary(duration);
|
|
418
|
+
return {
|
|
419
|
+
duration,
|
|
420
|
+
outputPath,
|
|
421
|
+
outputPaths: outputFileSection.paths,
|
|
422
|
+
packageDirs
|
|
423
|
+
};
|
|
424
|
+
} finally {
|
|
425
|
+
await pool.destroy();
|
|
426
|
+
}
|
|
414
427
|
};
|
|
415
428
|
await generateThemeModeCSS();
|
|
416
429
|
if (options.watch) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","names":[],"sources":["../../src/css/runner.ts"],"sourcesContent":["import fs from 'node:fs';\n\nimport { createLogger, gray, green, magenta, print, spinStart, spinStop } from '@yahoo/uds-cli/lib';\nimport type { UniversalTokensConfig } from '@yahoo/uds-config';\nimport { defaultTokensConfig } from '@yahoo/uds-config';\n\nimport type { SerializedComponentInfo } from '../commands/generateComponentData';\nimport {\n deduplicateSafelist,\n getInternalSafelistClasses,\n getThemeAndScaleClasses,\n} from '../purger/optimized/utils/safelist';\nimport type { EntryValue, ResolvedEntryPath } from '../utils/entryPoints';\nimport { DEFAULT_ENTRY, resolveEntryPaths } from '../utils/entryPoints';\nimport { generateCSS, generateSimpleModeCSS } from './generate';\nimport { getPruneVarSafelist } from './generate.helpers';\nimport {\n findPackageRoot,\n findPackageSourceDir,\n getPackageUdsScope,\n loadConfigFile,\n scanDirectoriesForSafelist,\n scanDirectoryForSafelist,\n} from './nodeUtils';\nimport {\n formatCssDuration,\n getMainCssSummaryMessage,\n getOutputFileSection,\n getScanSummaryMessage,\n getScopedCssSummaryMessage,\n getVerboseScanFileList,\n getWatchDirectoryGroups,\n} from './runner.helpers';\nimport type {\n UDSScopedPackageConfig,\n UDSScopedPackageValue,\n UDSThemeConfig,\n UDSThemeConfigInput,\n UDSThemeContext,\n} from './theme';\nimport {\n extractRuntimeConfigValues,\n extractVariantDefaults,\n formatBytes,\n getConfigurableCssVariables,\n getMotionVarPrefixes,\n} from './utils';\n\ntype CssCommandContext = {\n variants: Record<string, Record<string, string>>;\n autoVariants: Record<string, Record<string, string>>;\n componentData: Record<string, SerializedComponentInfo>;\n};\n\ntype CssCommandOptions = {\n workspaceDir: string;\n outFile: string;\n themeConfigPath: string;\n scope?: string;\n entryOption?: EntryValue;\n configOption?: string;\n watch: boolean;\n silent: boolean;\n verbose?: boolean;\n};\n\ntype ThemeModeSetup = {\n themeConfig: UDSThemeConfig;\n colorModes: ('dark' | 'light')[];\n entries: ResolvedEntryPath[];\n appConfig: UniversalTokensConfig;\n appVariantDefaults: ReturnType<typeof extractVariantDefaults>;\n runtimeConfigValues: ReturnType<typeof extractRuntimeConfigValues>;\n effectiveSilent: boolean;\n};\n\ntype ScopedPackageBuildTarget = {\n packageName: string;\n packageRoot: string;\n packageDir: string;\n entryDirs: string[];\n scopeClass: string;\n config: UDSScopedPackageConfig;\n};\n\ntype GeneratedCssOutput = {\n label: string;\n outputPath: string;\n sizeGzipBytes: number;\n optimizationStats?: {\n originalSizeGzip: number;\n fontFacesRemoved: number;\n emptyRulesRemoved: number;\n };\n};\n\nconst getScopedPackageOutputPath = (packageName: string, outFile?: string): string => {\n if (typeof outFile === 'string' && outFile.trim().length > 0) {\n return outFile;\n }\n\n const packageLeafName = packageName.split('/').pop() ?? packageName;\n return `dist/${packageLeafName}.css`;\n};\n\nconst normalizeScopedPackageConfig = (\n scopedPackageValue: UDSScopedPackageValue,\n): UDSScopedPackageConfig => {\n if (typeof scopedPackageValue === 'string') {\n return { config: scopedPackageValue };\n }\n\n return scopedPackageValue;\n};\n\nconst resolveScopedEntryDirs = (\n packageRoot: string,\n packageDir: string,\n entry: string | string[] | undefined,\n): string[] => {\n if (entry === undefined) {\n return [packageDir];\n }\n\n return resolveEntryPaths(entry, packageRoot).map((resolvedEntry) => resolvedEntry.absolutePath);\n};\n\nconst PATH_SEPARATOR = '/';\n\nconst normalizePath = (value: string): string => value.replace(/\\\\/g, PATH_SEPARATOR);\n\nconst isAbsolutePath = (value: string): boolean => {\n const normalizedValue = normalizePath(value);\n return normalizedValue.startsWith(PATH_SEPARATOR) || /^[A-Za-z]:\\//.test(normalizedValue);\n};\n\nconst joinPath = (...parts: string[]): string => {\n const filteredParts = parts.filter((part) => part.length > 0);\n if (filteredParts.length === 0) {\n return '';\n }\n\n const normalizedParts = filteredParts.map((part, index) => {\n const normalizedPart = normalizePath(part);\n if (index === 0) {\n return normalizedPart.replace(/\\/+$/g, '');\n }\n return normalizedPart.replace(/^\\/+|\\/+$/g, '');\n });\n\n return normalizedParts\n .join(PATH_SEPARATOR)\n .replace(/\\/+/g, PATH_SEPARATOR)\n .replace(/\\/\\.\\//g, PATH_SEPARATOR);\n};\n\nconst dirnamePath = (value: string): string => {\n const normalizedValue = normalizePath(value).replace(/\\/+$/g, '');\n const lastSeparatorIndex = normalizedValue.lastIndexOf(PATH_SEPARATOR);\n if (lastSeparatorIndex <= 0) {\n return lastSeparatorIndex === 0 ? PATH_SEPARATOR : '.';\n }\n\n return normalizedValue.slice(0, lastSeparatorIndex);\n};\n\nconst basenamePath = (value: string): string => {\n const normalizedValue = normalizePath(value).replace(/\\/+$/g, '');\n const lastSeparatorIndex = normalizedValue.lastIndexOf(PATH_SEPARATOR);\n return lastSeparatorIndex >= 0 ? normalizedValue.slice(lastSeparatorIndex + 1) : normalizedValue;\n};\n\nconst resolveOutputPath = (workspaceDir: string, outFile: string): string =>\n isAbsolutePath(outFile) ? outFile : joinPath(workspaceDir, outFile);\n\nconst ensureOutputDirectory = (outputPath: string): void => {\n const outputDir = dirnamePath(outputPath);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n};\n\nconst SOURCE_FILE_PATTERN = /\\.(jsx?|tsx?)$/i;\n\ntype WatchTarget = {\n watchPath: string;\n recursive: boolean;\n fileNames?: string[];\n};\n\nconst getWatchDirs = (dirs: string[]): string[] => [\n ...new Set(\n dirs.filter((dir) => !normalizePath(dir).split(PATH_SEPARATOR).includes('node_modules')),\n ),\n];\n\nconst isCoveredByRecursiveWatch = (watchPath: string, targetPath: string): boolean =>\n targetPath === watchPath || targetPath.startsWith(`${watchPath}${PATH_SEPARATOR}`);\n\nconst getEntryWatchTargets = (entries: ResolvedEntryPath[]): WatchTarget[] => {\n const directoryTargets = getWatchDirs(\n entries.filter((entry) => entry.kind === 'directory').map((entry) => entry.absolutePath),\n ).map((watchPath) => ({ watchPath, recursive: true }));\n\n const fileNamesByDirectory = new Map<string, Set<string>>();\n\n entries\n .filter(\n (entry): entry is ResolvedEntryPath & { kind: 'file'; fileName: string } =>\n entry.kind === 'file' && typeof entry.fileName === 'string',\n )\n .forEach((entry) => {\n if (\n directoryTargets.some((target) =>\n isCoveredByRecursiveWatch(target.watchPath, entry.absolutePath),\n )\n ) {\n return;\n }\n\n const fileNames = fileNamesByDirectory.get(entry.watchDirectory) ?? new Set<string>();\n fileNames.add(entry.fileName);\n fileNamesByDirectory.set(entry.watchDirectory, fileNames);\n });\n\n const fileTargets = [...fileNamesByDirectory.entries()].map(([watchPath, fileNames]) => ({\n watchPath,\n recursive: false,\n fileNames: [...fileNames],\n }));\n\n return [...directoryTargets, ...fileTargets];\n};\n\nconst watchSourceFiles = (targets: WatchTarget[], onFileChange: () => void): void => {\n targets.forEach((target) => {\n fs.watch(target.watchPath, { recursive: target.recursive }, (_eventType, filename) => {\n if (!filename || !SOURCE_FILE_PATTERN.test(filename)) {\n return;\n }\n\n if (target.fileNames && !target.fileNames.includes(basenamePath(String(filename)))) {\n return;\n }\n\n onFileChange();\n });\n });\n};\n\nconst createDebouncedAction = (action: () => void, delayMs: number): (() => void) => {\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n return () => {\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n debounceTimer = setTimeout(action, delayMs);\n };\n};\n\nconst createQueuedRegenerator = <T>(options: {\n onStart?: () => void;\n onSuccess?: (result: T) => void;\n onError: (message: string) => void;\n regenerateOnce: () => Promise<T>;\n}): (() => Promise<void>) => {\n let isGenerating = false;\n let pendingRegenerate = false;\n\n const regenerate = async (): Promise<void> => {\n if (isGenerating) {\n pendingRegenerate = true;\n return;\n }\n\n isGenerating = true;\n try {\n options.onStart?.();\n const result = await options.regenerateOnce();\n options.onSuccess?.(result);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'CSS generation failed';\n options.onError(message);\n } finally {\n isGenerating = false;\n\n if (pendingRegenerate) {\n pendingRegenerate = false;\n await regenerate();\n }\n }\n };\n\n return regenerate;\n};\n\nconst printVerboseScanFiles = (\n log: ReturnType<typeof createLogger>,\n workspaceDir: string,\n filePaths: string[],\n): void => {\n getVerboseScanFileList(workspaceDir, filePaths).forEach((filePath) => {\n log.listItem(filePath);\n });\n};\n\nconst runCssCommand = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const themeConfigExists = fs.existsSync(\n joinPath(options.workspaceDir, String(options.themeConfigPath)),\n );\n\n if (!themeConfigExists) {\n await runSimpleMode(options, context);\n return;\n }\n\n await runThemeMode(options, context);\n};\n\nconst runSimpleMode = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const entry = options.entryOption ?? DEFAULT_ENTRY;\n const configPath = typeof options.configOption === 'string' ? options.configOption : undefined;\n\n if (!options.watch && !options.silent) {\n spinStart('Generating CSS...');\n }\n\n try {\n const result = await generateSimpleModeCSS({\n workspaceDir: options.workspaceDir,\n entry,\n outFile: String(options.outFile),\n variants: context.variants,\n autoVariants: context.autoVariants,\n componentData: context.componentData,\n scope: options.scope,\n configPath,\n isWatch: options.watch,\n silent: options.silent,\n verbose: options.verbose,\n });\n\n if (options.watch) {\n await runSimpleModeWatch(options, context, entry, configPath, result.packageDirs ?? []);\n }\n } catch (error) {\n spinStop('❌', error instanceof Error ? error.message : 'CSS generation failed');\n process.exitCode = 1;\n }\n};\n\nconst runSimpleModeWatch = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n entry: EntryValue,\n configPath: string | undefined,\n packageDirs: string[],\n): Promise<void> => {\n const resolvedEntries = resolveEntryPaths(entry, options.workspaceDir);\n const entryWatchTargets = getEntryWatchTargets(resolvedEntries);\n const fallbackTargets = getWatchDirs(packageDirs).map((watchPath) => ({\n watchPath,\n recursive: true,\n }));\n const watchTargets = packageDirs.length > 0 ? fallbackTargets : entryWatchTargets;\n\n if (!options.silent) {\n print('');\n print(`${magenta('Watching for changes...')}`);\n watchTargets.forEach((target) => print(` ${gray('•')} ${target.watchPath}`));\n print(`${gray('Press Ctrl+C to stop')}`);\n print('');\n }\n\n const regenerate = createQueuedRegenerator({\n onStart: () => {\n if (!options.silent) {\n const timestamp = new Date().toLocaleTimeString();\n print(`${gray(`[${timestamp}]`)} Change detected, regenerating...`);\n }\n },\n regenerateOnce: async () => {\n await generateSimpleModeCSS({\n workspaceDir: options.workspaceDir,\n entry,\n outFile: String(options.outFile),\n variants: context.variants,\n autoVariants: context.autoVariants,\n componentData: context.componentData,\n scope: options.scope,\n configPath,\n isWatch: true,\n silent: true,\n });\n },\n onSuccess: () => {\n if (!options.silent) {\n const updatedAt = new Date().toLocaleTimeString();\n print(`${gray(`[${updatedAt}]`)} ${green('CSS updated')}`);\n print('');\n }\n },\n onError: (message) => {\n print(`Error: ${message}`);\n },\n });\n\n watchSourceFiles(\n watchTargets,\n createDebouncedAction(() => {\n void regenerate();\n }, 100),\n );\n\n await new Promise(() => {});\n};\n\nconst loadThemeModeSetup = async (options: CssCommandOptions): Promise<ThemeModeSetup | null> => {\n const themeConfigInput = await loadConfigFile<UDSThemeConfigInput>(\n String(options.themeConfigPath),\n );\n if (!themeConfigInput) {\n return null;\n }\n\n const themeContext: UDSThemeContext = {\n cwd: options.workspaceDir,\n watch: options.watch,\n };\n const themeConfig: UDSThemeConfig =\n typeof themeConfigInput === 'function'\n ? await themeConfigInput(themeContext)\n : themeConfigInput;\n\n let appConfig: UniversalTokensConfig = defaultTokensConfig;\n if (themeConfig.config) {\n const loadedConfig = await loadConfigFile<UniversalTokensConfig>(themeConfig.config);\n if (loadedConfig) {\n appConfig = loadedConfig;\n }\n }\n\n return {\n themeConfig,\n colorModes: themeConfig.colorModes ?? ['dark'],\n entries: resolveEntryPaths(themeConfig.entry, options.workspaceDir),\n appConfig,\n appVariantDefaults: extractVariantDefaults(appConfig),\n runtimeConfigValues: extractRuntimeConfigValues(appConfig),\n effectiveSilent: options.silent || themeConfig.silent === true,\n };\n};\n\nconst runThemeMode = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const workspaceDir = options.workspaceDir;\n const outputPath = resolveOutputPath(workspaceDir, String(options.outFile));\n let effectiveSilent = options.silent;\n let log = createLogger({ silent: effectiveSilent });\n\n log.spinStart('Loading theme configuration...');\n\n try {\n const setup = await loadThemeModeSetup(options);\n if (!setup) {\n log.spinStop('❌', `Theme config not found: ${options.themeConfigPath}`);\n process.exitCode = 1;\n return;\n }\n\n const { themeConfig, colorModes, entries, appConfig, appVariantDefaults, runtimeConfigValues } =\n setup;\n effectiveSilent = setup.effectiveSilent;\n log = createLogger({ silent: effectiveSilent });\n const entryDirs = entries.map((entry) => entry.absolutePath);\n\n if (!effectiveSilent) {\n log.spinStop('✅', 'Theme configuration loaded');\n }\n\n if (themeConfig.config && appConfig === defaultTokensConfig) {\n log.warn(`App config not found: ${themeConfig.config}, using defaults`);\n }\n const packageDirs: string[] = [];\n\n const generateThemeModeCSS = async (opts?: { isWatch?: boolean }) => {\n const genStartTime = performance.now();\n const genLog = opts?.isWatch ? createLogger({ silent: true }) : log;\n const scopedCssOutputs: GeneratedCssOutput[] = [];\n\n genLog.spinStart('Scanning app code...');\n const appScanResult = await scanDirectoriesForSafelist(\n entryDirs,\n colorModes,\n context.variants,\n context.autoVariants,\n context.componentData,\n appVariantDefaults,\n runtimeConfigValues,\n );\n genLog.spinStop(\n '✅',\n getScanSummaryMessage({\n label: 'app',\n filesScanned: appScanResult.filesScanned,\n filesWithComponents: appScanResult.filesWithComponents,\n componentCount: appScanResult.components.length,\n mode: 'app',\n }),\n );\n if (options.verbose) {\n printVerboseScanFiles(genLog, workspaceDir, appScanResult.filePaths);\n }\n\n genLog.spinStart('Generating main CSS...');\n\n const inheritedClasses: string[] = [...appScanResult.safelist];\n const inheritedComponents = new Set<string>(appScanResult.components);\n const scopedPackageTargets: ScopedPackageBuildTarget[] = [];\n\n const processInheritedPackage = async (packageName: string) => {\n genLog.spinStart(`Processing package: ${packageName}...`);\n\n const packageDir = findPackageSourceDir(packageName);\n if (!packageDir) {\n genLog.spinStop('⚠️', `Package not found: ${packageName}`);\n return;\n }\n\n if (!packageDirs.includes(packageDir)) {\n packageDirs.push(packageDir);\n }\n\n const packageScanResult = await scanDirectoryForSafelist(\n packageDir,\n colorModes,\n context.variants,\n context.autoVariants,\n context.componentData,\n appVariantDefaults,\n runtimeConfigValues,\n true,\n );\n inheritedClasses.push(...packageScanResult.safelist);\n packageScanResult.components.forEach((comp) => inheritedComponents.add(comp));\n genLog.spinStop(\n '✅',\n getScanSummaryMessage({\n label: packageName,\n filesScanned: packageScanResult.filesScanned,\n filesWithComponents: packageScanResult.filesWithComponents,\n componentCount: packageScanResult.components.length,\n mode: 'inherit',\n }),\n );\n if (options.verbose) {\n printVerboseScanFiles(genLog, workspaceDir, packageScanResult.filePaths);\n }\n };\n\n const processScopedPackage = async (\n packageName: string,\n scopedPackageValue: UDSScopedPackageValue,\n ) => {\n genLog.spinStart(`Processing scoped package: ${packageName}...`);\n const scopedPackageConfig = normalizeScopedPackageConfig(scopedPackageValue);\n\n const packageRoot = findPackageRoot(packageName);\n const packageDir = findPackageSourceDir(packageName);\n if (!packageRoot || !packageDir) {\n genLog.spinStop('⚠️', `Scoped package not found: ${packageName}`);\n return;\n }\n\n const scopeClass = getPackageUdsScope(packageName);\n if (!scopeClass) {\n genLog.spinStop('⚠️', `Scoped package missing package.json uds.scope: ${packageName}`);\n return;\n }\n\n const entryDirs = resolveScopedEntryDirs(\n packageRoot,\n packageDir,\n scopedPackageConfig.entry,\n );\n entryDirs.forEach((entryDir) => {\n if (!packageDirs.includes(entryDir)) {\n packageDirs.push(entryDir);\n }\n });\n\n scopedPackageTargets.push({\n packageName,\n packageRoot,\n packageDir,\n entryDirs,\n scopeClass,\n config: scopedPackageConfig,\n });\n };\n\n await (themeConfig.inherit ?? []).reduce(async (promise, packageName) => {\n await promise;\n await processInheritedPackage(packageName);\n }, Promise.resolve());\n\n await Object.entries(themeConfig.scoped ?? {}).reduce(\n async (promise, [packageName, scopedPackageConfig]) => {\n await promise;\n await processScopedPackage(packageName, scopedPackageConfig);\n },\n Promise.resolve(),\n );\n\n const mainSafelist = deduplicateSafelist([\n ...inheritedClasses,\n ...getThemeAndScaleClasses(colorModes),\n ...getInternalSafelistClasses(),\n ]);\n\n const allMotionComponents: string[] = [...inheritedComponents];\n\n const mainCssResult = await generateCSS(\n [...(themeConfig.css?.safelist ?? []), ...mainSafelist],\n appConfig,\n {\n scope: options.scope,\n contentDir: entryDirs,\n cssOptions: themeConfig.css,\n safeVarPrefixes: [\n ...getMotionVarPrefixes(context.componentData, allMotionComponents),\n ...getConfigurableCssVariables(),\n ...getPruneVarSafelist(themeConfig.css),\n ],\n },\n );\n\n ensureOutputDirectory(outputPath);\n fs.writeFileSync(outputPath, mainCssResult.css);\n\n for (const scopedPackageTarget of scopedPackageTargets) {\n const packageConfigPath = isAbsolutePath(scopedPackageTarget.config.config)\n ? scopedPackageTarget.config.config\n : joinPath(scopedPackageTarget.packageRoot, scopedPackageTarget.config.config);\n const packageConfig =\n (await loadConfigFile<UniversalTokensConfig>(packageConfigPath)) ?? defaultTokensConfig;\n const packageVariantDefaults = extractVariantDefaults(packageConfig);\n const packageRuntimeConfigValues = extractRuntimeConfigValues(packageConfig);\n const packageScanResult = await scanDirectoriesForSafelist(\n scopedPackageTarget.entryDirs,\n colorModes,\n context.variants,\n context.autoVariants,\n context.componentData,\n packageVariantDefaults,\n packageRuntimeConfigValues,\n true,\n );\n genLog.spinStop(\n '✅',\n getScanSummaryMessage({\n label: scopedPackageTarget.packageName,\n filesScanned: packageScanResult.filesScanned,\n filesWithComponents: packageScanResult.filesWithComponents,\n componentCount: packageScanResult.components.length,\n mode: 'scoped',\n }),\n );\n if (options.verbose) {\n printVerboseScanFiles(genLog, workspaceDir, packageScanResult.filePaths);\n }\n const packageSafelist = deduplicateSafelist([\n ...packageScanResult.safelist,\n ...getThemeAndScaleClasses(colorModes),\n ...getInternalSafelistClasses(),\n ]);\n const scopedCssResult = await generateCSS(\n [...(themeConfig.css?.safelist ?? []), ...packageSafelist],\n packageConfig,\n {\n scope: scopedPackageTarget.scopeClass,\n contentDir: scopedPackageTarget.entryDirs,\n cssOptions: themeConfig.css,\n referenceCss:\n themeConfig.css?.optimization?.deduplicateScopedCss === false\n ? undefined\n : mainCssResult.css,\n safeVarPrefixes: [\n ...getMotionVarPrefixes(context.componentData, [...packageScanResult.components]),\n ...getConfigurableCssVariables(),\n ...getPruneVarSafelist(themeConfig.css),\n ],\n },\n );\n\n const scopedOutputPath = resolveOutputPath(\n workspaceDir,\n getScopedPackageOutputPath(\n scopedPackageTarget.packageName,\n scopedPackageTarget.config.outFile,\n ),\n );\n ensureOutputDirectory(scopedOutputPath);\n fs.writeFileSync(scopedOutputPath, scopedCssResult.css);\n scopedCssOutputs.push({\n label: scopedPackageTarget.packageName,\n outputPath: scopedOutputPath,\n sizeGzipBytes: scopedCssResult.sizeGzipBytes,\n optimizationStats: scopedCssResult.optimizationStats,\n });\n }\n\n const mainCssSummary = getMainCssSummaryMessage({\n sizeGzipBytes: mainCssResult.sizeGzipBytes,\n optimizationStats: mainCssResult.optimizationStats,\n formatBytes,\n });\n genLog.spinStop('✅', mainCssSummary.summaryLine);\n mainCssSummary.detailLines.forEach((detailLine) => {\n genLog.print(detailLine);\n });\n\n scopedCssOutputs.forEach((scopedCssOutput) => {\n const scopedCssSummary = getScopedCssSummaryMessage(scopedCssOutput.label, {\n sizeGzipBytes: scopedCssOutput.sizeGzipBytes,\n optimizationStats: scopedCssOutput.optimizationStats,\n formatBytes,\n });\n genLog.spinStop('✅', scopedCssSummary.summaryLine);\n scopedCssSummary.detailLines.forEach((detailLine) => {\n genLog.print(detailLine);\n });\n });\n\n const duration = Math.round(performance.now() - genStartTime);\n const outputFileSection = getOutputFileSection(workspaceDir, [\n outputPath,\n ...scopedCssOutputs.map((scopedCssOutput) => scopedCssOutput.outputPath),\n ]);\n\n genLog.newline();\n genLog.print(outputFileSection.label);\n outputFileSection.paths.forEach((filePath) => {\n genLog.listItem(filePath);\n });\n genLog.newline();\n genLog.print(`${magenta('Total time:')} ${formatCssDuration(duration)}`);\n\n return {\n duration,\n outputPath,\n outputPaths: outputFileSection.paths,\n packageDirs,\n };\n };\n\n await generateThemeModeCSS();\n\n if (options.watch) {\n const entryWatchTargets = getEntryWatchTargets(entries);\n const entryWatchDirs = getWatchDirs(entryWatchTargets.map((target) => target.watchPath));\n const { filteredPackageDirs } = getWatchDirectoryGroups(entryWatchDirs, [\n ...entryDirs,\n ...packageDirs,\n ]);\n\n if (!effectiveSilent) {\n log.newline();\n log.print(`${magenta('Watching for changes...')}`);\n entryDirs.forEach((entryDir) => {\n log.listItem(`App: ${entryDir}`);\n });\n filteredPackageDirs.forEach((dir) => {\n log.listItem(`Package: ${dir}`);\n });\n log.print(`${gray('Press Ctrl+C to stop')}`);\n log.newline();\n }\n\n const regenerate = createQueuedRegenerator({\n onStart: () => {\n if (!effectiveSilent) {\n const timestamp = new Date().toLocaleTimeString();\n log.print(`${gray(`[${timestamp}]`)} Change detected, regenerating...`);\n }\n },\n regenerateOnce: async () => generateThemeModeCSS({ isWatch: true }),\n onSuccess: (result) => {\n if (!effectiveSilent) {\n const updatedAt = new Date().toLocaleTimeString();\n const updatedMessage =\n result?.duration == null\n ? 'CSS updated'\n : `CSS updated (${formatCssDuration(result.duration)})`;\n log.print(`${gray(`[${updatedAt}]`)} ${green(updatedMessage)}`);\n log.newline();\n }\n },\n onError: (message) => {\n log.print(message);\n },\n });\n\n const watchDebounce = themeConfig.css?.watchDebounce ?? 100;\n\n watchSourceFiles(\n [\n ...entryWatchTargets,\n ...filteredPackageDirs\n .filter(\n (packageDir) =>\n !entryWatchTargets.some((target) =>\n isCoveredByRecursiveWatch(target.watchPath, packageDir),\n ),\n )\n .map((watchPath) => ({ watchPath, recursive: true })),\n ],\n createDebouncedAction(() => {\n void regenerate();\n }, watchDebounce),\n );\n\n await new Promise(() => {});\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'CSS generation failed';\n if (effectiveSilent) {\n spinStop('❌', message);\n } else {\n log.spinStop('❌', message);\n }\n process.exitCode = 1;\n }\n};\n\nexport { runCssCommand };\nexport type { CssCommandContext, CssCommandOptions };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runner.js","names":[],"sources":["../../src/css/runner.ts"],"sourcesContent":["import fs from 'node:fs';\n\nimport { createLogger, gray, green, magenta, print, spinStart, spinStop } from '@yahoo/uds-cli/lib';\nimport type { UniversalTokensConfig } from '@yahoo/uds-config';\nimport { defaultTokensConfig } from '@yahoo/uds-config';\n\nimport type { SerializedComponentInfo } from '../commands/generateComponentData';\nimport {\n deduplicateSafelist,\n getInternalSafelistClasses,\n getThemeAndScaleClasses,\n} from '../purger/optimized/utils/safelist';\nimport type { EntryValue, ResolvedEntryPath } from '../utils/entryPoints';\nimport { DEFAULT_ENTRY, resolveEntryPaths } from '../utils/entryPoints';\nimport { generateCSS, generateSimpleModeCSS } from './generate';\nimport { getPruneVarSafelist } from './generate.helpers';\nimport {\n findPackageRoot,\n findPackageSourceDir,\n getPackageUdsScope,\n loadConfigFile,\n scanDirectoriesForSafelist,\n scanDirectoryForSafelist,\n} from './nodeUtils';\nimport { captureMemory, clearTimings, measureAsync, printPerfSummary } from './perf';\nimport {\n formatCssDuration,\n getMainCssSummaryMessage,\n getOutputFileSection,\n getScanSummaryMessage,\n getScopedCssSummaryMessage,\n getVerboseScanFileList,\n getWatchDirectoryGroups,\n} from './runner.helpers';\nimport type {\n UDSScopedPackageConfig,\n UDSScopedPackageValue,\n UDSThemeConfig,\n UDSThemeConfigInput,\n UDSThemeContext,\n} from './theme';\nimport {\n extractRuntimeConfigValues,\n extractVariantDefaults,\n formatBytes,\n getConfigurableCssVariables,\n getMotionVarPrefixes,\n} from './utils';\nimport { createWorkerPool } from './workerPool';\n\ntype CssCommandContext = {\n variants: Record<string, Record<string, string>>;\n autoVariants: Record<string, Record<string, string>>;\n componentData: Record<string, SerializedComponentInfo>;\n};\n\ntype CssCommandOptions = {\n workspaceDir: string;\n outFile: string;\n themeConfigPath: string;\n scope?: string;\n entryOption?: EntryValue;\n configOption?: string;\n watch: boolean;\n silent: boolean;\n verbose?: boolean;\n workers?: number;\n};\n\ntype ThemeModeSetup = {\n themeConfig: UDSThemeConfig;\n colorModes: ('dark' | 'light')[];\n entries: ResolvedEntryPath[];\n appConfig: UniversalTokensConfig;\n appVariantDefaults: ReturnType<typeof extractVariantDefaults>;\n runtimeConfigValues: ReturnType<typeof extractRuntimeConfigValues>;\n effectiveSilent: boolean;\n};\n\ntype ScopedPackageBuildTarget = {\n packageName: string;\n packageRoot: string;\n packageDir: string;\n entryDirs: string[];\n scopeClass: string;\n config: UDSScopedPackageConfig;\n};\n\ntype GeneratedCssOutput = {\n label: string;\n outputPath: string;\n sizeGzipBytes: number;\n optimizationStats?: {\n originalSizeGzip: number;\n fontFacesRemoved: number;\n emptyRulesRemoved: number;\n };\n};\n\nconst getScopedPackageOutputPath = (packageName: string, outFile?: string): string => {\n if (typeof outFile === 'string' && outFile.trim().length > 0) {\n return outFile;\n }\n\n const packageLeafName = packageName.split('/').pop() ?? packageName;\n return `dist/${packageLeafName}.css`;\n};\n\nconst normalizeScopedPackageConfig = (\n scopedPackageValue: UDSScopedPackageValue,\n): UDSScopedPackageConfig => {\n if (typeof scopedPackageValue === 'string') {\n return { config: scopedPackageValue };\n }\n\n return scopedPackageValue;\n};\n\nconst resolveScopedEntryDirs = (\n packageRoot: string,\n packageDir: string,\n entry: string | string[] | undefined,\n): string[] => {\n if (entry === undefined) {\n return [packageDir];\n }\n\n return resolveEntryPaths(entry, packageRoot).map((resolvedEntry) => resolvedEntry.absolutePath);\n};\n\nconst PATH_SEPARATOR = '/';\n\nconst normalizePath = (value: string): string => value.replace(/\\\\/g, PATH_SEPARATOR);\n\nconst isAbsolutePath = (value: string): boolean => {\n const normalizedValue = normalizePath(value);\n return normalizedValue.startsWith(PATH_SEPARATOR) || /^[A-Za-z]:\\//.test(normalizedValue);\n};\n\nconst joinPath = (...parts: string[]): string => {\n const filteredParts = parts.filter((part) => part.length > 0);\n if (filteredParts.length === 0) {\n return '';\n }\n\n const normalizedParts = filteredParts.map((part, index) => {\n const normalizedPart = normalizePath(part);\n if (index === 0) {\n return normalizedPart.replace(/\\/+$/g, '');\n }\n return normalizedPart.replace(/^\\/+|\\/+$/g, '');\n });\n\n return normalizedParts\n .join(PATH_SEPARATOR)\n .replace(/\\/+/g, PATH_SEPARATOR)\n .replace(/\\/\\.\\//g, PATH_SEPARATOR);\n};\n\nconst dirnamePath = (value: string): string => {\n const normalizedValue = normalizePath(value).replace(/\\/+$/g, '');\n const lastSeparatorIndex = normalizedValue.lastIndexOf(PATH_SEPARATOR);\n if (lastSeparatorIndex <= 0) {\n return lastSeparatorIndex === 0 ? PATH_SEPARATOR : '.';\n }\n\n return normalizedValue.slice(0, lastSeparatorIndex);\n};\n\nconst basenamePath = (value: string): string => {\n const normalizedValue = normalizePath(value).replace(/\\/+$/g, '');\n const lastSeparatorIndex = normalizedValue.lastIndexOf(PATH_SEPARATOR);\n return lastSeparatorIndex >= 0 ? normalizedValue.slice(lastSeparatorIndex + 1) : normalizedValue;\n};\n\nconst resolveOutputPath = (workspaceDir: string, outFile: string): string =>\n isAbsolutePath(outFile) ? outFile : joinPath(workspaceDir, outFile);\n\nconst ensureOutputDirectory = (outputPath: string): void => {\n const outputDir = dirnamePath(outputPath);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n};\n\nconst SOURCE_FILE_PATTERN = /\\.(jsx?|tsx?)$/i;\n\ntype WatchTarget = {\n watchPath: string;\n recursive: boolean;\n fileNames?: string[];\n};\n\nconst getWatchDirs = (dirs: string[]): string[] => [\n ...new Set(\n dirs.filter((dir) => !normalizePath(dir).split(PATH_SEPARATOR).includes('node_modules')),\n ),\n];\n\nconst isCoveredByRecursiveWatch = (watchPath: string, targetPath: string): boolean =>\n targetPath === watchPath || targetPath.startsWith(`${watchPath}${PATH_SEPARATOR}`);\n\nconst getEntryWatchTargets = (entries: ResolvedEntryPath[]): WatchTarget[] => {\n const directoryTargets = getWatchDirs(\n entries.filter((entry) => entry.kind === 'directory').map((entry) => entry.absolutePath),\n ).map((watchPath) => ({ watchPath, recursive: true }));\n\n const fileNamesByDirectory = new Map<string, Set<string>>();\n\n entries\n .filter(\n (entry): entry is ResolvedEntryPath & { kind: 'file'; fileName: string } =>\n entry.kind === 'file' && typeof entry.fileName === 'string',\n )\n .forEach((entry) => {\n if (\n directoryTargets.some((target) =>\n isCoveredByRecursiveWatch(target.watchPath, entry.absolutePath),\n )\n ) {\n return;\n }\n\n const fileNames = fileNamesByDirectory.get(entry.watchDirectory) ?? new Set<string>();\n fileNames.add(entry.fileName);\n fileNamesByDirectory.set(entry.watchDirectory, fileNames);\n });\n\n const fileTargets = [...fileNamesByDirectory.entries()].map(([watchPath, fileNames]) => ({\n watchPath,\n recursive: false,\n fileNames: [...fileNames],\n }));\n\n return [...directoryTargets, ...fileTargets];\n};\n\nconst watchSourceFiles = (targets: WatchTarget[], onFileChange: () => void): void => {\n targets.forEach((target) => {\n fs.watch(target.watchPath, { recursive: target.recursive }, (_eventType, filename) => {\n if (!filename || !SOURCE_FILE_PATTERN.test(filename)) {\n return;\n }\n\n if (target.fileNames && !target.fileNames.includes(basenamePath(String(filename)))) {\n return;\n }\n\n onFileChange();\n });\n });\n};\n\nconst createDebouncedAction = (action: () => void, delayMs: number): (() => void) => {\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n return () => {\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n debounceTimer = setTimeout(action, delayMs);\n };\n};\n\nconst createQueuedRegenerator = <T>(options: {\n onStart?: () => void;\n onSuccess?: (result: T) => void;\n onError: (message: string) => void;\n regenerateOnce: () => Promise<T>;\n}): (() => Promise<void>) => {\n let isGenerating = false;\n let pendingRegenerate = false;\n\n const regenerate = async (): Promise<void> => {\n if (isGenerating) {\n pendingRegenerate = true;\n return;\n }\n\n isGenerating = true;\n try {\n options.onStart?.();\n const result = await options.regenerateOnce();\n options.onSuccess?.(result);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'CSS generation failed';\n options.onError(message);\n } finally {\n isGenerating = false;\n\n if (pendingRegenerate) {\n pendingRegenerate = false;\n await regenerate();\n }\n }\n };\n\n return regenerate;\n};\n\nconst printVerboseScanFiles = (\n log: ReturnType<typeof createLogger>,\n workspaceDir: string,\n filePaths: string[],\n): void => {\n getVerboseScanFileList(workspaceDir, filePaths).forEach((filePath) => {\n log.listItem(filePath);\n });\n};\n\nconst runCssCommand = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const themeConfigExists = fs.existsSync(\n joinPath(options.workspaceDir, String(options.themeConfigPath)),\n );\n\n if (!themeConfigExists) {\n await runSimpleMode(options, context);\n return;\n }\n\n await runThemeMode(options, context);\n};\n\nconst runSimpleMode = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const entry = options.entryOption ?? DEFAULT_ENTRY;\n const configPath = typeof options.configOption === 'string' ? options.configOption : undefined;\n\n if (!options.watch && !options.silent) {\n spinStart('Generating CSS...');\n }\n\n try {\n const result = await generateSimpleModeCSS({\n workspaceDir: options.workspaceDir,\n entry,\n outFile: String(options.outFile),\n variants: context.variants,\n autoVariants: context.autoVariants,\n componentData: context.componentData,\n scope: options.scope,\n configPath,\n isWatch: options.watch,\n silent: options.silent,\n verbose: options.verbose,\n });\n\n if (options.watch) {\n await runSimpleModeWatch(options, context, entry, configPath, result.packageDirs ?? []);\n }\n } catch (error) {\n spinStop('❌', error instanceof Error ? error.message : 'CSS generation failed');\n process.exitCode = 1;\n }\n};\n\nconst runSimpleModeWatch = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n entry: EntryValue,\n configPath: string | undefined,\n packageDirs: string[],\n): Promise<void> => {\n const resolvedEntries = resolveEntryPaths(entry, options.workspaceDir);\n const entryWatchTargets = getEntryWatchTargets(resolvedEntries);\n const fallbackTargets = getWatchDirs(packageDirs).map((watchPath) => ({\n watchPath,\n recursive: true,\n }));\n const watchTargets = packageDirs.length > 0 ? fallbackTargets : entryWatchTargets;\n\n if (!options.silent) {\n print('');\n print(`${magenta('Watching for changes...')}`);\n watchTargets.forEach((target) => print(` ${gray('•')} ${target.watchPath}`));\n print(`${gray('Press Ctrl+C to stop')}`);\n print('');\n }\n\n const regenerate = createQueuedRegenerator({\n onStart: () => {\n if (!options.silent) {\n const timestamp = new Date().toLocaleTimeString();\n print(`${gray(`[${timestamp}]`)} Change detected, regenerating...`);\n }\n },\n regenerateOnce: async () => {\n await generateSimpleModeCSS({\n workspaceDir: options.workspaceDir,\n entry,\n outFile: String(options.outFile),\n variants: context.variants,\n autoVariants: context.autoVariants,\n componentData: context.componentData,\n scope: options.scope,\n configPath,\n isWatch: true,\n silent: true,\n });\n },\n onSuccess: () => {\n if (!options.silent) {\n const updatedAt = new Date().toLocaleTimeString();\n print(`${gray(`[${updatedAt}]`)} ${green('CSS updated')}`);\n print('');\n }\n },\n onError: (message) => {\n print(`Error: ${message}`);\n },\n });\n\n watchSourceFiles(\n watchTargets,\n createDebouncedAction(() => {\n void regenerate();\n }, 100),\n );\n\n await new Promise(() => {});\n};\n\nconst loadThemeModeSetup = async (options: CssCommandOptions): Promise<ThemeModeSetup | null> => {\n const themeConfigInput = await loadConfigFile<UDSThemeConfigInput>(\n String(options.themeConfigPath),\n );\n if (!themeConfigInput) {\n return null;\n }\n\n const themeContext: UDSThemeContext = {\n cwd: options.workspaceDir,\n watch: options.watch,\n };\n const themeConfig: UDSThemeConfig =\n typeof themeConfigInput === 'function'\n ? await themeConfigInput(themeContext)\n : themeConfigInput;\n\n let appConfig: UniversalTokensConfig = defaultTokensConfig;\n if (themeConfig.config) {\n const loadedConfig = await loadConfigFile<UniversalTokensConfig>(themeConfig.config);\n if (loadedConfig) {\n appConfig = loadedConfig;\n }\n }\n\n return {\n themeConfig,\n colorModes: themeConfig.colorModes ?? ['dark'],\n entries: resolveEntryPaths(themeConfig.entry, options.workspaceDir),\n appConfig,\n appVariantDefaults: extractVariantDefaults(appConfig),\n runtimeConfigValues: extractRuntimeConfigValues(appConfig),\n effectiveSilent: options.silent || themeConfig.silent === true,\n };\n};\n\nconst runThemeMode = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const workspaceDir = options.workspaceDir;\n const outputPath = resolveOutputPath(workspaceDir, String(options.outFile));\n let effectiveSilent = options.silent;\n let log = createLogger({ silent: effectiveSilent });\n\n log.spinStart('Loading theme configuration...');\n\n try {\n const setup = await loadThemeModeSetup(options);\n if (!setup) {\n log.spinStop('❌', `Theme config not found: ${options.themeConfigPath}`);\n process.exitCode = 1;\n return;\n }\n\n const { themeConfig, colorModes, entries, appConfig, appVariantDefaults, runtimeConfigValues } =\n setup;\n effectiveSilent = setup.effectiveSilent;\n log = createLogger({ silent: effectiveSilent });\n const entryDirs = entries.map((entry) => entry.absolutePath);\n\n if (!effectiveSilent) {\n log.spinStop('✅', 'Theme configuration loaded');\n }\n\n if (themeConfig.config && appConfig === defaultTokensConfig) {\n log.warn(`App config not found: ${themeConfig.config}, using defaults`);\n }\n const packageDirs: string[] = [];\n\n const generateThemeModeCSS = async (opts?: { isWatch?: boolean }) => {\n clearTimings();\n captureMemory('start');\n const genStartTime = performance.now();\n const genLog = opts?.isWatch ? createLogger({ silent: true }) : log;\n const scopedCssOutputs: GeneratedCssOutput[] = [];\n\n // Create worker pool for parallel file processing\n const pool = await createWorkerPool(\n {\n variants: context.variants,\n autoVariants: context.autoVariants,\n componentData: context.componentData,\n },\n options.workers,\n );\n\n try {\n genLog.spinStart(\n `Scanning app and packages... (${pool.workerCount} worker${pool.workerCount === 1 ? '' : 's'})`,\n );\n\n const scopedPackageTargets: ScopedPackageBuildTarget[] = [];\n\n const processInheritedPackage = async (packageName: string) => {\n const packageDir = findPackageSourceDir(packageName);\n if (!packageDir) {\n return { packageName, status: 'not-found' as const };\n }\n\n if (!packageDirs.includes(packageDir)) {\n packageDirs.push(packageDir);\n }\n\n const packageScanResult = await scanDirectoryForSafelist(\n packageDir,\n colorModes,\n context.variants,\n context.autoVariants,\n context.componentData,\n appVariantDefaults,\n runtimeConfigValues,\n true,\n pool,\n );\n\n return {\n packageName,\n status: 'ok' as const,\n scanResult: packageScanResult,\n };\n };\n\n const processScopedPackage = async (\n packageName: string,\n scopedPackageValue: UDSScopedPackageValue,\n ) => {\n const scopedPackageConfig = normalizeScopedPackageConfig(scopedPackageValue);\n\n const packageRoot = findPackageRoot(packageName);\n const packageDir = findPackageSourceDir(packageName);\n if (!packageRoot || !packageDir) {\n return;\n }\n\n const scopeClass = getPackageUdsScope(packageName);\n if (!scopeClass) {\n return;\n }\n\n const entryDirs = resolveScopedEntryDirs(\n packageRoot,\n packageDir,\n scopedPackageConfig.entry,\n );\n entryDirs.forEach((entryDir) => {\n if (!packageDirs.includes(entryDir)) {\n packageDirs.push(entryDir);\n }\n });\n\n scopedPackageTargets.push({\n packageName,\n packageRoot,\n packageDir,\n entryDirs,\n scopeClass,\n config: scopedPackageConfig,\n });\n };\n\n // Run app scan, inherited package scans, and scoped package resolution in parallel\n const [appScanResult, inheritedResults] = await Promise.all([\n measureAsync('scan', () =>\n scanDirectoriesForSafelist(\n entryDirs,\n colorModes,\n context.variants,\n context.autoVariants,\n context.componentData,\n appVariantDefaults,\n runtimeConfigValues,\n false,\n pool,\n ),\n ),\n Promise.all(\n (themeConfig.inherit ?? []).map((packageName) =>\n measureAsync(`scan:inherit:${packageName}`, () =>\n processInheritedPackage(packageName),\n ),\n ),\n ),\n Promise.all(\n Object.entries(themeConfig.scoped ?? {}).map(([packageName, scopedPackageConfig]) =>\n processScopedPackage(packageName, scopedPackageConfig),\n ),\n ),\n ]);\n\n // Print app scan results\n genLog.spinStop(\n '✅',\n getScanSummaryMessage({\n label: 'app',\n filesScanned: appScanResult.filesScanned,\n filesWithComponents: appScanResult.filesWithComponents,\n componentCount: appScanResult.components.length,\n mode: 'app',\n }),\n );\n if (options.verbose) {\n printVerboseScanFiles(genLog, workspaceDir, appScanResult.filePaths);\n }\n\n // Print inherited package results\n for (const result of inheritedResults) {\n if (result.status === 'not-found') {\n genLog.spinStop('⚠️', `Package not found: ${result.packageName}`);\n } else {\n genLog.spinStop(\n '✅',\n getScanSummaryMessage({\n label: result.packageName,\n filesScanned: result.scanResult.filesScanned,\n filesWithComponents: result.scanResult.filesWithComponents,\n componentCount: result.scanResult.components.length,\n mode: 'inherit',\n }),\n );\n if (options.verbose) {\n printVerboseScanFiles(genLog, workspaceDir, result.scanResult.filePaths);\n }\n }\n }\n\n // Merge results from all scans\n const inheritedClasses: string[] = [...appScanResult.safelist];\n const inheritedComponents = new Set<string>(appScanResult.components);\n for (const result of inheritedResults) {\n if (result.status === 'ok') {\n inheritedClasses.push(...result.scanResult.safelist);\n result.scanResult.components.forEach((comp) => inheritedComponents.add(comp));\n }\n }\n\n genLog.spinStart('Generating main CSS...');\n\n const mainSafelist = deduplicateSafelist([\n ...inheritedClasses,\n ...getThemeAndScaleClasses(colorModes),\n ...getInternalSafelistClasses(),\n ]);\n\n const allMotionComponents: string[] = [...inheritedComponents];\n\n captureMemory('before-gen');\n const mainCssResult = await measureAsync('gen', () =>\n generateCSS([...(themeConfig.css?.safelist ?? []), ...mainSafelist], appConfig, {\n scope: options.scope,\n contentDir: entryDirs,\n cssOptions: themeConfig.css,\n safeVarPrefixes: [\n ...getMotionVarPrefixes(context.componentData, allMotionComponents),\n ...getConfigurableCssVariables(),\n ...getPruneVarSafelist(themeConfig.css),\n ],\n }),\n );\n captureMemory('after-gen');\n\n ensureOutputDirectory(outputPath);\n fs.writeFileSync(outputPath, mainCssResult.css);\n\n for (const scopedPackageTarget of scopedPackageTargets) {\n const packageConfigPath = isAbsolutePath(scopedPackageTarget.config.config)\n ? scopedPackageTarget.config.config\n : joinPath(scopedPackageTarget.packageRoot, scopedPackageTarget.config.config);\n const packageConfig =\n (await loadConfigFile<UniversalTokensConfig>(packageConfigPath)) ?? defaultTokensConfig;\n const packageVariantDefaults = extractVariantDefaults(packageConfig);\n const packageRuntimeConfigValues = extractRuntimeConfigValues(packageConfig);\n const packageScanResult = await scanDirectoriesForSafelist(\n scopedPackageTarget.entryDirs,\n colorModes,\n context.variants,\n context.autoVariants,\n context.componentData,\n packageVariantDefaults,\n packageRuntimeConfigValues,\n true,\n pool,\n );\n genLog.spinStop(\n '✅',\n getScanSummaryMessage({\n label: scopedPackageTarget.packageName,\n filesScanned: packageScanResult.filesScanned,\n filesWithComponents: packageScanResult.filesWithComponents,\n componentCount: packageScanResult.components.length,\n mode: 'scoped',\n }),\n );\n if (options.verbose) {\n printVerboseScanFiles(genLog, workspaceDir, packageScanResult.filePaths);\n }\n const packageSafelist = deduplicateSafelist([\n ...packageScanResult.safelist,\n ...getThemeAndScaleClasses(colorModes),\n ...getInternalSafelistClasses(),\n ]);\n const scopedCssResult = await generateCSS(\n [...(themeConfig.css?.safelist ?? []), ...packageSafelist],\n packageConfig,\n {\n scope: scopedPackageTarget.scopeClass,\n contentDir: scopedPackageTarget.entryDirs,\n cssOptions: themeConfig.css,\n referenceCss:\n themeConfig.css?.optimization?.deduplicateScopedCss === false\n ? undefined\n : mainCssResult.css,\n safeVarPrefixes: [\n ...getMotionVarPrefixes(context.componentData, [...packageScanResult.components]),\n ...getConfigurableCssVariables(),\n ...getPruneVarSafelist(themeConfig.css),\n ],\n },\n );\n\n const scopedOutputPath = resolveOutputPath(\n workspaceDir,\n getScopedPackageOutputPath(\n scopedPackageTarget.packageName,\n scopedPackageTarget.config.outFile,\n ),\n );\n ensureOutputDirectory(scopedOutputPath);\n fs.writeFileSync(scopedOutputPath, scopedCssResult.css);\n scopedCssOutputs.push({\n label: scopedPackageTarget.packageName,\n outputPath: scopedOutputPath,\n sizeGzipBytes: scopedCssResult.sizeGzipBytes,\n optimizationStats: scopedCssResult.optimizationStats,\n });\n }\n\n const mainCssSummary = getMainCssSummaryMessage({\n sizeGzipBytes: mainCssResult.sizeGzipBytes,\n optimizationStats: mainCssResult.optimizationStats,\n formatBytes,\n });\n genLog.spinStop('✅', mainCssSummary.summaryLine);\n mainCssSummary.detailLines.forEach((detailLine) => {\n genLog.print(detailLine);\n });\n\n scopedCssOutputs.forEach((scopedCssOutput) => {\n const scopedCssSummary = getScopedCssSummaryMessage(scopedCssOutput.label, {\n sizeGzipBytes: scopedCssOutput.sizeGzipBytes,\n optimizationStats: scopedCssOutput.optimizationStats,\n formatBytes,\n });\n genLog.spinStop('✅', scopedCssSummary.summaryLine);\n scopedCssSummary.detailLines.forEach((detailLine) => {\n genLog.print(detailLine);\n });\n });\n\n const duration = Math.round(performance.now() - genStartTime);\n const outputFileSection = getOutputFileSection(workspaceDir, [\n outputPath,\n ...scopedCssOutputs.map((scopedCssOutput) => scopedCssOutput.outputPath),\n ]);\n\n genLog.newline();\n genLog.print(outputFileSection.label);\n outputFileSection.paths.forEach((filePath) => {\n genLog.listItem(filePath);\n });\n genLog.newline();\n genLog.print(`${magenta('Total time:')} ${formatCssDuration(duration)}`);\n printPerfSummary(duration);\n\n return {\n duration,\n outputPath,\n outputPaths: outputFileSection.paths,\n packageDirs,\n };\n } finally {\n await pool.destroy();\n }\n };\n\n await generateThemeModeCSS();\n\n if (options.watch) {\n const entryWatchTargets = getEntryWatchTargets(entries);\n const entryWatchDirs = getWatchDirs(entryWatchTargets.map((target) => target.watchPath));\n const { filteredPackageDirs } = getWatchDirectoryGroups(entryWatchDirs, [\n ...entryDirs,\n ...packageDirs,\n ]);\n\n if (!effectiveSilent) {\n log.newline();\n log.print(`${magenta('Watching for changes...')}`);\n entryDirs.forEach((entryDir) => {\n log.listItem(`App: ${entryDir}`);\n });\n filteredPackageDirs.forEach((dir) => {\n log.listItem(`Package: ${dir}`);\n });\n log.print(`${gray('Press Ctrl+C to stop')}`);\n log.newline();\n }\n\n const regenerate = createQueuedRegenerator({\n onStart: () => {\n if (!effectiveSilent) {\n const timestamp = new Date().toLocaleTimeString();\n log.print(`${gray(`[${timestamp}]`)} Change detected, regenerating...`);\n }\n },\n regenerateOnce: async () => generateThemeModeCSS({ isWatch: true }),\n onSuccess: (result) => {\n if (!effectiveSilent) {\n const updatedAt = new Date().toLocaleTimeString();\n const updatedMessage =\n result?.duration == null\n ? 'CSS updated'\n : `CSS updated (${formatCssDuration(result.duration)})`;\n log.print(`${gray(`[${updatedAt}]`)} ${green(updatedMessage)}`);\n log.newline();\n }\n },\n onError: (message) => {\n log.print(message);\n },\n });\n\n const watchDebounce = themeConfig.css?.watchDebounce ?? 100;\n\n watchSourceFiles(\n [\n ...entryWatchTargets,\n ...filteredPackageDirs\n .filter(\n (packageDir) =>\n !entryWatchTargets.some((target) =>\n isCoveredByRecursiveWatch(target.watchPath, packageDir),\n ),\n )\n .map((watchPath) => ({ watchPath, recursive: true })),\n ],\n createDebouncedAction(() => {\n void regenerate();\n }, watchDebounce),\n );\n\n await new Promise(() => {});\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'CSS generation failed';\n if (effectiveSilent) {\n spinStop('❌', message);\n } else {\n log.spinStop('❌', message);\n }\n process.exitCode = 1;\n }\n};\n\nexport { runCssCommand };\nexport type { CssCommandContext, CssCommandOptions };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
2
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
let node_os = require("node:os");
|
|
4
|
+
let node_worker_threads = require("node:worker_threads");
|
|
5
|
+
//#region src/css/workerPool.ts
|
|
6
|
+
const createWorkerPool = async (config, numWorkers) => {
|
|
7
|
+
const workerCount = numWorkers ?? Math.max(1, (0, node_os.cpus)().length - 1);
|
|
8
|
+
const workerUrl = new URL("./purgeWorker.js", require("url").pathToFileURL(__filename).href);
|
|
9
|
+
const workers = [];
|
|
10
|
+
const available = [];
|
|
11
|
+
const pending = /* @__PURE__ */ new Map();
|
|
12
|
+
const queue = [];
|
|
13
|
+
let nextId = 0;
|
|
14
|
+
await Promise.all(Array.from({ length: workerCount }, () => {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const worker = new node_worker_threads.Worker(workerUrl);
|
|
17
|
+
let initialized = false;
|
|
18
|
+
worker.on("message", (msg) => {
|
|
19
|
+
if (msg.type === "ready") {
|
|
20
|
+
initialized = true;
|
|
21
|
+
workers.push(worker);
|
|
22
|
+
available.push(worker);
|
|
23
|
+
resolve();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (msg.type === "result" || msg.type === "error") {
|
|
27
|
+
const task = msg.id != null ? pending.get(msg.id) : void 0;
|
|
28
|
+
if (task) {
|
|
29
|
+
pending.delete(msg.id);
|
|
30
|
+
if (msg.type === "result") task.resolve(msg.result);
|
|
31
|
+
else task.reject(new Error(msg.error ?? "Unknown worker error"));
|
|
32
|
+
}
|
|
33
|
+
available.push(worker);
|
|
34
|
+
if (queue.length > 0 && available.length > 0) {
|
|
35
|
+
const next = queue.shift();
|
|
36
|
+
const nextWorker = available.pop();
|
|
37
|
+
pending.set(next.msg.id, next.task);
|
|
38
|
+
nextWorker.postMessage(next.msg);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
worker.on("error", (err) => {
|
|
43
|
+
if (!initialized) reject(err);
|
|
44
|
+
});
|
|
45
|
+
worker.postMessage({
|
|
46
|
+
type: "init",
|
|
47
|
+
config: JSON.parse(JSON.stringify(config))
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}));
|
|
51
|
+
const processFile = (options) => {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
const id = nextId++;
|
|
54
|
+
const msg = {
|
|
55
|
+
type: "task",
|
|
56
|
+
id,
|
|
57
|
+
code: options.code,
|
|
58
|
+
filePath: options.filePath,
|
|
59
|
+
colorModes: options.colorModes,
|
|
60
|
+
variantDefaults: options.variantDefaults,
|
|
61
|
+
runtimeConfigValues: options.runtimeConfigValues,
|
|
62
|
+
includeAllClassNamePrimitives: options.includeAllClassNamePrimitives
|
|
63
|
+
};
|
|
64
|
+
const task = {
|
|
65
|
+
resolve,
|
|
66
|
+
reject
|
|
67
|
+
};
|
|
68
|
+
if (available.length > 0) {
|
|
69
|
+
const worker = available.pop();
|
|
70
|
+
pending.set(id, task);
|
|
71
|
+
worker.postMessage(msg);
|
|
72
|
+
} else queue.push({
|
|
73
|
+
msg,
|
|
74
|
+
task
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
const destroy = async () => {
|
|
79
|
+
for (const worker of workers) worker.postMessage({ type: "done" });
|
|
80
|
+
await Promise.all(workers.map((w) => new Promise((res) => w.on("exit", () => res()))));
|
|
81
|
+
};
|
|
82
|
+
return {
|
|
83
|
+
processFile,
|
|
84
|
+
destroy,
|
|
85
|
+
workerCount
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
//#endregion
|
|
89
|
+
exports.createWorkerPool = createWorkerPool;
|