@plumeria/unplugin 12.0.8 → 13.0.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.
Files changed (3) hide show
  1. package/dist/core.js +60 -11
  2. package/dist/core.mjs +61 -12
  3. package/package.json +3 -3
package/dist/core.js CHANGED
@@ -41,6 +41,28 @@ 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
+ const declRegex = new RegExp(`--${hash}-[a-zA-Z0-9-]+:`);
56
+ if (declRegex.test(sheet)) {
57
+ hasStaleHash = true;
58
+ break;
59
+ }
60
+ }
61
+ if (hasStaleHash && !newSheets.includes(sheet)) {
62
+ acc.delete(sheet);
63
+ }
64
+ }
65
+ }
44
66
  const unpluginFactory = (options = {}, unpluginMeta) => {
45
67
  const filter = (0, pluginutils_1.createFilter)(options.include, options.exclude);
46
68
  const cssLookup = new Map();
@@ -447,21 +469,34 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
447
469
  }
448
470
  }
449
471
  else if (propName === 'createTheme' &&
450
- utils_1.t.isObjectExpression(init.arguments[0].expression)) {
472
+ init.arguments.length >= 2 &&
473
+ utils_1.t.isObjectExpression(init.arguments[1].expression)) {
451
474
  if (utils_1.t.isIdentifier(node.id)) {
452
475
  idSpans.add(node.id.span.start);
453
476
  }
454
- const obj = (0, utils_1.objectExpressionToObject)(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
477
+ let selector = '';
478
+ const selectorExpr = init.arguments[0].expression;
479
+ if (utils_1.t.isStringLiteral(selectorExpr)) {
480
+ selector = selectorExpr.value;
481
+ }
482
+ if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
483
+ throw new Error(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`);
484
+ }
485
+ const obj = (0, utils_1.objectExpressionToObject)(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
455
486
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
456
487
  if (utils_1.t.isIdentifier(node.id)) {
457
488
  const uniqueKey = `${resourcePath}-${node.id.value}`;
458
489
  scannedTables.createThemeHashTable[uniqueKey] = hash;
459
490
  scannedTables.createThemeObjectTable[hash] = obj;
491
+ if (scannedTables.createThemeSelectorTable) {
492
+ scannedTables.createThemeSelectorTable[hash] = selector;
493
+ }
460
494
  mergedCreateThemeHashTable[node.id.value] = hash;
461
495
  const themeHashMap = {};
462
- for (const [key] of Object.entries(obj)) {
496
+ for (const [key, value] of Object.entries(obj)) {
463
497
  const cssVarName = (0, zss_engine_1.camelToKebabCase)(key);
464
- themeHashMap[key] = `var(--${hash}-${cssVarName})`;
498
+ const atomicHash = (0, zss_engine_1.genBase36Hash)({ [key]: value }, 1, 8);
499
+ themeHashMap[key] = `var(--${atomicHash}-${cssVarName})`;
465
500
  }
466
501
  localCreateStyles[node.id.value] = {
467
502
  name: node.id.value,
@@ -618,17 +653,30 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
618
653
  content: JSON.stringify(`vt-${hash}`),
619
654
  });
620
655
  }
621
- else if ((propName === 'createTheme' || propName === 'createStatic') &&
656
+ else if (propName === 'createTheme' &&
657
+ args.length >= 2 &&
658
+ utils_1.t.isObjectExpression(args[1].expression)) {
659
+ let selector = '';
660
+ const selectorExpr = args[0].expression;
661
+ if (utils_1.t.isStringLiteral(selectorExpr)) {
662
+ selector = selectorExpr.value;
663
+ }
664
+ if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
665
+ throw new Error(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`);
666
+ }
667
+ const obj = (0, utils_1.objectExpressionToObject)(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
668
+ const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
669
+ scannedTables.createThemeObjectTable[hash] = obj;
670
+ if (scannedTables.createThemeSelectorTable) {
671
+ scannedTables.createThemeSelectorTable[hash] = selector;
672
+ }
673
+ }
674
+ else if (propName === 'createStatic' &&
622
675
  args.length > 0 &&
623
676
  utils_1.t.isObjectExpression(args[0].expression)) {
624
677
  const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
625
678
  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
- }
679
+ scannedTables.createStaticObjectTable[hash] = obj;
632
680
  }
633
681
  else if (propName === 'create' &&
634
682
  args.length > 0 &&
@@ -1491,6 +1539,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1491
1539
  devCssSheets.set(cssFilename, new Set());
1492
1540
  }
1493
1541
  const acc = devCssSheets.get(cssFilename);
1542
+ cleanStaleThemeRules(acc, extractedSheets);
1494
1543
  extractedSheets.forEach((sheet) => acc.add(sheet));
1495
1544
  const accCSS = await (0, utils_1.optimizer)(Array.from(acc).join(''));
1496
1545
  cssLookup.set(cssFilename, accCSS);
package/dist/core.mjs CHANGED
@@ -1,10 +1,32 @@
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
+ const declRegex = new RegExp(`--${hash}-[a-zA-Z0-9-]+:`);
20
+ if (declRegex.test(sheet)) {
21
+ hasStaleHash = true;
22
+ break;
23
+ }
24
+ }
25
+ if (hasStaleHash && !newSheets.includes(sheet)) {
26
+ acc.delete(sheet);
27
+ }
28
+ }
29
+ }
8
30
  export const unpluginFactory = (options = {}, unpluginMeta) => {
9
31
  const filter = createFilter(options.include, options.exclude);
10
32
  const cssLookup = new Map();
@@ -411,21 +433,34 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
411
433
  }
412
434
  }
413
435
  else if (propName === 'createTheme' &&
414
- t.isObjectExpression(init.arguments[0].expression)) {
436
+ init.arguments.length >= 2 &&
437
+ t.isObjectExpression(init.arguments[1].expression)) {
415
438
  if (t.isIdentifier(node.id)) {
416
439
  idSpans.add(node.id.span.start);
417
440
  }
418
- const obj = objectExpressionToObject(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
441
+ let selector = '';
442
+ const selectorExpr = init.arguments[0].expression;
443
+ if (t.isStringLiteral(selectorExpr)) {
444
+ selector = selectorExpr.value;
445
+ }
446
+ if (selector.startsWith('@') && !isAtRule(selector)) {
447
+ throw new Error(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`);
448
+ }
449
+ const obj = objectExpressionToObject(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
419
450
  const hash = genBase36Hash(obj, 1, 8);
420
451
  if (t.isIdentifier(node.id)) {
421
452
  const uniqueKey = `${resourcePath}-${node.id.value}`;
422
453
  scannedTables.createThemeHashTable[uniqueKey] = hash;
423
454
  scannedTables.createThemeObjectTable[hash] = obj;
455
+ if (scannedTables.createThemeSelectorTable) {
456
+ scannedTables.createThemeSelectorTable[hash] = selector;
457
+ }
424
458
  mergedCreateThemeHashTable[node.id.value] = hash;
425
459
  const themeHashMap = {};
426
- for (const [key] of Object.entries(obj)) {
460
+ for (const [key, value] of Object.entries(obj)) {
427
461
  const cssVarName = camelToKebabCase(key);
428
- themeHashMap[key] = `var(--${hash}-${cssVarName})`;
462
+ const atomicHash = genBase36Hash({ [key]: value }, 1, 8);
463
+ themeHashMap[key] = `var(--${atomicHash}-${cssVarName})`;
429
464
  }
430
465
  localCreateStyles[node.id.value] = {
431
466
  name: node.id.value,
@@ -582,17 +617,30 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
582
617
  content: JSON.stringify(`vt-${hash}`),
583
618
  });
584
619
  }
585
- else if ((propName === 'createTheme' || propName === 'createStatic') &&
620
+ else if (propName === 'createTheme' &&
621
+ args.length >= 2 &&
622
+ t.isObjectExpression(args[1].expression)) {
623
+ let selector = '';
624
+ const selectorExpr = args[0].expression;
625
+ if (t.isStringLiteral(selectorExpr)) {
626
+ selector = selectorExpr.value;
627
+ }
628
+ if (selector.startsWith('@') && !isAtRule(selector)) {
629
+ throw new Error(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`);
630
+ }
631
+ const obj = objectExpressionToObject(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
632
+ const hash = genBase36Hash(obj, 1, 8);
633
+ scannedTables.createThemeObjectTable[hash] = obj;
634
+ if (scannedTables.createThemeSelectorTable) {
635
+ scannedTables.createThemeSelectorTable[hash] = selector;
636
+ }
637
+ }
638
+ else if (propName === 'createStatic' &&
586
639
  args.length > 0 &&
587
640
  t.isObjectExpression(args[0].expression)) {
588
641
  const obj = objectExpressionToObject(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
589
642
  const hash = genBase36Hash(obj, 1, 8);
590
- if (propName === 'createTheme') {
591
- scannedTables.createThemeObjectTable[hash] = obj;
592
- }
593
- else {
594
- scannedTables.createStaticObjectTable[hash] = obj;
595
- }
643
+ scannedTables.createStaticObjectTable[hash] = obj;
596
644
  }
597
645
  else if (propName === 'create' &&
598
646
  args.length > 0 &&
@@ -1455,6 +1503,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1455
1503
  devCssSheets.set(cssFilename, new Set());
1456
1504
  }
1457
1505
  const acc = devCssSheets.get(cssFilename);
1506
+ cleanStaleThemeRules(acc, extractedSheets);
1458
1507
  extractedSheets.forEach((sheet) => acc.add(sheet));
1459
1508
  const accCSS = await optimizer(Array.from(acc).join(''));
1460
1509
  cssLookup.set(cssFilename, accCSS);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/unplugin",
3
- "version": "12.0.8",
3
+ "version": "13.0.1",
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.8"
89
+ "@plumeria/utils": "^13.0.1"
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",