@plumeria/unplugin 12.0.7 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/core.js +59 -11
  2. package/dist/core.mjs +60 -12
  3. package/package.json +3 -3
package/dist/core.js CHANGED
@@ -41,6 +41,27 @@ const zss_engine_1 = require("zss-engine");
41
41
  const utils_1 = require("@plumeria/utils");
42
42
  exports.TARGET_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx'];
43
43
  exports.EXTENSION_PATTERN = /\.(ts|tsx|js|jsx)$/;
44
+ function cleanStaleThemeRules(acc, newSheets) {
45
+ const newCss = newSheets.join('');
46
+ const hashRegex = /--([a-z0-9]{8})-[a-zA-Z0-9-]+/g;
47
+ const hashes = new Set();
48
+ let match;
49
+ while ((match = hashRegex.exec(newCss)) !== null) {
50
+ hashes.add(match[1]);
51
+ }
52
+ for (const sheet of acc) {
53
+ let hasStaleHash = false;
54
+ for (const hash of hashes) {
55
+ if (sheet.includes(`--${hash}-`)) {
56
+ hasStaleHash = true;
57
+ break;
58
+ }
59
+ }
60
+ if (hasStaleHash && !newSheets.includes(sheet)) {
61
+ acc.delete(sheet);
62
+ }
63
+ }
64
+ }
44
65
  const unpluginFactory = (options = {}, unpluginMeta) => {
45
66
  const filter = (0, pluginutils_1.createFilter)(options.include, options.exclude);
46
67
  const cssLookup = new Map();
@@ -447,21 +468,34 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
447
468
  }
448
469
  }
449
470
  else if (propName === 'createTheme' &&
450
- utils_1.t.isObjectExpression(init.arguments[0].expression)) {
471
+ init.arguments.length >= 2 &&
472
+ utils_1.t.isObjectExpression(init.arguments[1].expression)) {
451
473
  if (utils_1.t.isIdentifier(node.id)) {
452
474
  idSpans.add(node.id.span.start);
453
475
  }
454
- const obj = (0, utils_1.objectExpressionToObject)(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
476
+ let selector = '';
477
+ const selectorExpr = init.arguments[0].expression;
478
+ if (utils_1.t.isStringLiteral(selectorExpr)) {
479
+ selector = selectorExpr.value;
480
+ }
481
+ if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
482
+ throw new Error(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`);
483
+ }
484
+ const obj = (0, utils_1.objectExpressionToObject)(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
455
485
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
456
486
  if (utils_1.t.isIdentifier(node.id)) {
457
487
  const uniqueKey = `${resourcePath}-${node.id.value}`;
458
488
  scannedTables.createThemeHashTable[uniqueKey] = hash;
459
489
  scannedTables.createThemeObjectTable[hash] = obj;
490
+ if (scannedTables.createThemeSelectorTable) {
491
+ scannedTables.createThemeSelectorTable[hash] = selector;
492
+ }
460
493
  mergedCreateThemeHashTable[node.id.value] = hash;
461
494
  const themeHashMap = {};
462
- for (const [key] of Object.entries(obj)) {
495
+ for (const [key, value] of Object.entries(obj)) {
463
496
  const cssVarName = (0, zss_engine_1.camelToKebabCase)(key);
464
- themeHashMap[key] = `var(--${hash}-${cssVarName})`;
497
+ const atomicHash = (0, zss_engine_1.genBase36Hash)({ [key]: value }, 1, 8);
498
+ themeHashMap[key] = `var(--${atomicHash}-${cssVarName})`;
465
499
  }
466
500
  localCreateStyles[node.id.value] = {
467
501
  name: node.id.value,
@@ -618,17 +652,30 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
618
652
  content: JSON.stringify(`vt-${hash}`),
619
653
  });
620
654
  }
621
- else if ((propName === 'createTheme' || propName === 'createStatic') &&
655
+ else if (propName === 'createTheme' &&
656
+ args.length >= 2 &&
657
+ utils_1.t.isObjectExpression(args[1].expression)) {
658
+ let selector = '';
659
+ const selectorExpr = args[0].expression;
660
+ if (utils_1.t.isStringLiteral(selectorExpr)) {
661
+ selector = selectorExpr.value;
662
+ }
663
+ if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
664
+ throw new Error(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`);
665
+ }
666
+ const obj = (0, utils_1.objectExpressionToObject)(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
667
+ const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
668
+ scannedTables.createThemeObjectTable[hash] = obj;
669
+ if (scannedTables.createThemeSelectorTable) {
670
+ scannedTables.createThemeSelectorTable[hash] = selector;
671
+ }
672
+ }
673
+ else if (propName === 'createStatic' &&
622
674
  args.length > 0 &&
623
675
  utils_1.t.isObjectExpression(args[0].expression)) {
624
676
  const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
625
677
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
626
- if (propName === 'createTheme') {
627
- scannedTables.createThemeObjectTable[hash] = obj;
628
- }
629
- else {
630
- scannedTables.createStaticObjectTable[hash] = obj;
631
- }
678
+ scannedTables.createStaticObjectTable[hash] = obj;
632
679
  }
633
680
  else if (propName === 'create' &&
634
681
  args.length > 0 &&
@@ -1491,6 +1538,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1491
1538
  devCssSheets.set(cssFilename, new Set());
1492
1539
  }
1493
1540
  const acc = devCssSheets.get(cssFilename);
1541
+ cleanStaleThemeRules(acc, extractedSheets);
1494
1542
  extractedSheets.forEach((sheet) => acc.add(sheet));
1495
1543
  const accCSS = await (0, utils_1.optimizer)(Array.from(acc).join(''));
1496
1544
  cssLookup.set(cssFilename, accCSS);
package/dist/core.mjs CHANGED
@@ -1,10 +1,31 @@
1
1
  import { createFilter } from '@rollup/pluginutils';
2
2
  import { parseSync } from '@swc/core';
3
3
  import * as path from 'path';
4
- import { applyCssValue, genBase36Hash, exceptionCamelCase, camelToKebabCase, } from 'zss-engine';
4
+ import { applyCssValue, genBase36Hash, exceptionCamelCase, camelToKebabCase, isAtRule, } from 'zss-engine';
5
5
  import { traverse, getStyleRecords, collectLocalConsts, objectExpressionToObject, t, extractOndemandStyles, deepMerge, scanAll, resolveImportPath, processVariants, getLeadingCommentLength, optimizer, } from '@plumeria/utils';
6
6
  export const TARGET_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx'];
7
7
  export const EXTENSION_PATTERN = /\.(ts|tsx|js|jsx)$/;
8
+ function cleanStaleThemeRules(acc, newSheets) {
9
+ const newCss = newSheets.join('');
10
+ const hashRegex = /--([a-z0-9]{8})-[a-zA-Z0-9-]+/g;
11
+ const hashes = new Set();
12
+ let match;
13
+ while ((match = hashRegex.exec(newCss)) !== null) {
14
+ hashes.add(match[1]);
15
+ }
16
+ for (const sheet of acc) {
17
+ let hasStaleHash = false;
18
+ for (const hash of hashes) {
19
+ if (sheet.includes(`--${hash}-`)) {
20
+ hasStaleHash = true;
21
+ break;
22
+ }
23
+ }
24
+ if (hasStaleHash && !newSheets.includes(sheet)) {
25
+ acc.delete(sheet);
26
+ }
27
+ }
28
+ }
8
29
  export const unpluginFactory = (options = {}, unpluginMeta) => {
9
30
  const filter = createFilter(options.include, options.exclude);
10
31
  const cssLookup = new Map();
@@ -411,21 +432,34 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
411
432
  }
412
433
  }
413
434
  else if (propName === 'createTheme' &&
414
- t.isObjectExpression(init.arguments[0].expression)) {
435
+ init.arguments.length >= 2 &&
436
+ t.isObjectExpression(init.arguments[1].expression)) {
415
437
  if (t.isIdentifier(node.id)) {
416
438
  idSpans.add(node.id.span.start);
417
439
  }
418
- const obj = objectExpressionToObject(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
440
+ let selector = '';
441
+ const selectorExpr = init.arguments[0].expression;
442
+ if (t.isStringLiteral(selectorExpr)) {
443
+ selector = selectorExpr.value;
444
+ }
445
+ if (selector.startsWith('@') && !isAtRule(selector)) {
446
+ throw new Error(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`);
447
+ }
448
+ const obj = objectExpressionToObject(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
419
449
  const hash = genBase36Hash(obj, 1, 8);
420
450
  if (t.isIdentifier(node.id)) {
421
451
  const uniqueKey = `${resourcePath}-${node.id.value}`;
422
452
  scannedTables.createThemeHashTable[uniqueKey] = hash;
423
453
  scannedTables.createThemeObjectTable[hash] = obj;
454
+ if (scannedTables.createThemeSelectorTable) {
455
+ scannedTables.createThemeSelectorTable[hash] = selector;
456
+ }
424
457
  mergedCreateThemeHashTable[node.id.value] = hash;
425
458
  const themeHashMap = {};
426
- for (const [key] of Object.entries(obj)) {
459
+ for (const [key, value] of Object.entries(obj)) {
427
460
  const cssVarName = camelToKebabCase(key);
428
- themeHashMap[key] = `var(--${hash}-${cssVarName})`;
461
+ const atomicHash = genBase36Hash({ [key]: value }, 1, 8);
462
+ themeHashMap[key] = `var(--${atomicHash}-${cssVarName})`;
429
463
  }
430
464
  localCreateStyles[node.id.value] = {
431
465
  name: node.id.value,
@@ -582,17 +616,30 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
582
616
  content: JSON.stringify(`vt-${hash}`),
583
617
  });
584
618
  }
585
- else if ((propName === 'createTheme' || propName === 'createStatic') &&
619
+ else if (propName === 'createTheme' &&
620
+ args.length >= 2 &&
621
+ t.isObjectExpression(args[1].expression)) {
622
+ let selector = '';
623
+ const selectorExpr = args[0].expression;
624
+ if (t.isStringLiteral(selectorExpr)) {
625
+ selector = selectorExpr.value;
626
+ }
627
+ if (selector.startsWith('@') && !isAtRule(selector)) {
628
+ throw new Error(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`);
629
+ }
630
+ const obj = objectExpressionToObject(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
631
+ const hash = genBase36Hash(obj, 1, 8);
632
+ scannedTables.createThemeObjectTable[hash] = obj;
633
+ if (scannedTables.createThemeSelectorTable) {
634
+ scannedTables.createThemeSelectorTable[hash] = selector;
635
+ }
636
+ }
637
+ else if (propName === 'createStatic' &&
586
638
  args.length > 0 &&
587
639
  t.isObjectExpression(args[0].expression)) {
588
640
  const obj = objectExpressionToObject(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
589
641
  const hash = genBase36Hash(obj, 1, 8);
590
- if (propName === 'createTheme') {
591
- scannedTables.createThemeObjectTable[hash] = obj;
592
- }
593
- else {
594
- scannedTables.createStaticObjectTable[hash] = obj;
595
- }
642
+ scannedTables.createStaticObjectTable[hash] = obj;
596
643
  }
597
644
  else if (propName === 'create' &&
598
645
  args.length > 0 &&
@@ -1455,6 +1502,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1455
1502
  devCssSheets.set(cssFilename, new Set());
1456
1503
  }
1457
1504
  const acc = devCssSheets.get(cssFilename);
1505
+ cleanStaleThemeRules(acc, extractedSheets);
1458
1506
  extractedSheets.forEach((sheet) => acc.add(sheet));
1459
1507
  const accCSS = await optimizer(Array.from(acc).join(''));
1460
1508
  cssLookup.set(cssFilename, accCSS);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/unplugin",
3
- "version": "12.0.7",
3
+ "version": "13.0.0",
4
4
  "description": "Universal Plumeria plugin for various build tools",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -86,13 +86,13 @@
86
86
  ],
87
87
  "dependencies": {
88
88
  "unplugin": "^3.0.0",
89
- "@plumeria/utils": "^12.0.7"
89
+ "@plumeria/utils": "^13.0.0"
90
90
  },
91
91
  "devDependencies": {
92
92
  "@rollup/pluginutils": "^5.4.0",
93
93
  "@swc/core": "1.15.40",
94
94
  "vite": "^8.0.13",
95
- "zss-engine": "2.2.8"
95
+ "zss-engine": "2.3.0"
96
96
  },
97
97
  "publishConfig": {
98
98
  "access": "public",