@plumeria/vite-plugin 7.0.2 → 7.1.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 (2) hide show
  1. package/dist/index.js +434 -120
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { createFilter } from 'vite';
2
2
  import { parseSync } from '@swc/core';
3
3
  import path from 'path';
4
4
  import { genBase36Hash } from 'zss-engine';
5
- import { traverse, getStyleRecords, collectLocalConsts, objectExpressionToObject, t, extractOndemandStyles, deepMerge, scanAll, resolveImportPath, optimizer, } from '@plumeria/utils';
5
+ import { traverse, getStyleRecords, collectLocalConsts, objectExpressionToObject, t, extractOndemandStyles, deepMerge, scanAll, resolveImportPath, optimizer, processVariants, } from '@plumeria/utils';
6
6
  const TARGET_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx'];
7
7
  const EXTENSION_PATTERN = /\.(ts|tsx|js|jsx)$/;
8
8
  export function plumeria(options = {}) {
@@ -41,14 +41,19 @@ export function plumeria(options = {}) {
41
41
  handleHotUpdate(ctx) {
42
42
  if (!isDev)
43
43
  return;
44
- if (ctx.modules.length) {
45
- return ctx.modules;
44
+ const modules = [...ctx.modules];
45
+ if (!ctx.file.includes('node_modules')) {
46
+ const affectedProviders = targets
47
+ .filter((t) => t.id !== ctx.file)
48
+ .map((t) => devServer.moduleGraph.getModuleById(t.id))
49
+ .filter((m) => !!m);
50
+ affectedProviders.forEach((p) => {
51
+ if (!modules.includes(p)) {
52
+ modules.push(p);
53
+ }
54
+ });
46
55
  }
47
- const affected = targets.filter((target) => target.dependencies.some((dep) => dep === ctx.file));
48
- return affected
49
- .map((target) => devServer.moduleGraph.getModuleById(target.id))
50
- .filter((m) => !!m)
51
- .concat(ctx.modules);
56
+ return modules;
52
57
  },
53
58
  async transform(source, id) {
54
59
  if (id.includes('node_modules'))
@@ -315,11 +320,13 @@ export function plumeria(options = {}) {
315
320
  }
316
321
  return undefined;
317
322
  });
323
+ const { hashMap, sheets } = processVariants(obj);
324
+ sheets.forEach(addSheet);
318
325
  localCreateStyles[node.id.value] = {
319
326
  name: node.id.value,
320
327
  type: 'variant',
321
328
  obj,
322
- hashMap: {},
329
+ hashMap,
323
330
  isExported,
324
331
  initSpan: {
325
332
  start: node.init.span.start - ast.span.start,
@@ -532,11 +539,63 @@ export function plumeria(options = {}) {
532
539
  return;
533
540
  const styleInfo = localCreateStyles[node.value];
534
541
  if (styleInfo) {
535
- replacements.push({
536
- start: node.span.start - ast.span.start,
537
- end: node.span.end - ast.span.start,
538
- content: JSON.stringify(styleInfo.hashMap),
539
- });
542
+ if (styleInfo.type === 'variant') {
543
+ const hashMap = styleInfo.hashMap;
544
+ const independentKeys = Object.keys(hashMap).filter((k) => k !== '_compound');
545
+ const compoundGroups = hashMap._compound || [];
546
+ const independentChecks = independentKeys
547
+ .map((key) => {
548
+ const mapObj = hashMap[key];
549
+ if (typeof mapObj === 'string') {
550
+ return `classes.push("${mapObj}");`;
551
+ }
552
+ const mapStr = JSON.stringify(mapObj);
553
+ return `
554
+ var v${key} = ${mapStr};
555
+ if (props["${key}"] && v${key}[props["${key}"]]) {
556
+ classes.push(v${key}[props["${key}"]]);
557
+ } else if (v${key}["default"]) {
558
+ classes.push(v${key}["default"]);
559
+ }
560
+ `;
561
+ })
562
+ .join('\n');
563
+ const compoundChecks = compoundGroups
564
+ .map((group) => {
565
+ const keys = group.keys;
566
+ const mapObj = group.map;
567
+ const mapStr = JSON.stringify(mapObj);
568
+ const keyExpr = keys
569
+ .map((k) => `(props["${k}"] || "default")`)
570
+ .join(' + ":" + ');
571
+ return `
572
+ var c${keys.join('_')} = ${mapStr};
573
+ var k = ${keyExpr};
574
+ if (c${keys.join('_')}[k]) {
575
+ classes.push(c${keys.join('_')}[k]);
576
+ }
577
+ `;
578
+ })
579
+ .join('\n');
580
+ const runtimeFn = `(props) => {
581
+ var classes = [];
582
+ ${independentChecks}
583
+ ${compoundChecks}
584
+ return classes.join(" ");
585
+ }`;
586
+ replacements.push({
587
+ start: node.span.start - ast.span.start,
588
+ end: node.span.end - ast.span.start,
589
+ content: runtimeFn,
590
+ });
591
+ }
592
+ else {
593
+ replacements.push({
594
+ start: node.span.start - ast.span.start,
595
+ end: node.span.end - ast.span.start,
596
+ content: JSON.stringify(styleInfo.hashMap),
597
+ });
598
+ }
540
599
  return;
541
600
  }
542
601
  const varName = node.value;
@@ -730,10 +789,14 @@ export function plumeria(options = {}) {
730
789
  Object.entries(groupVariants).forEach(([optionName, style]) => {
731
790
  conditionals.push({
732
791
  test: valExpr,
792
+ testLHS: valSource,
733
793
  testString: `${valSource} === '${optionName}'`,
734
794
  truthy: style,
735
795
  falsy: {},
736
796
  groupId: currentGroupId,
797
+ groupName,
798
+ valueName: optionName,
799
+ varName,
737
800
  });
738
801
  });
739
802
  }
@@ -753,10 +816,14 @@ export function plumeria(options = {}) {
753
816
  Object.entries(variantObj).forEach(([key, style]) => {
754
817
  conditionals.push({
755
818
  test: arg,
819
+ testLHS: argSource,
756
820
  testString: `${argSource} === '${key}'`,
757
821
  truthy: style,
758
822
  falsy: {},
759
823
  groupId: currentGroupId,
824
+ groupName: undefined,
825
+ valueName: key,
826
+ varName,
760
827
  });
761
828
  });
762
829
  continue;
@@ -765,43 +832,111 @@ export function plumeria(options = {}) {
765
832
  break;
766
833
  }
767
834
  }
768
- const staticStyle = resolveStyleObject(expr);
769
- if (staticStyle) {
770
- baseStyle = deepMerge(baseStyle, staticStyle);
771
- continue;
772
- }
773
- else if (expr.type === 'ConditionalExpression') {
774
- const truthyStyle = resolveStyleObject(expr.consequent);
775
- const falsyStyle = resolveStyleObject(expr.alternate);
776
- if (truthyStyle !== null && falsyStyle !== null) {
777
- conditionals.push({
778
- test: expr.test,
779
- truthy: truthyStyle,
780
- falsy: falsyStyle,
781
- });
782
- continue;
835
+ else if (t.isIdentifier(expr)) {
836
+ const varName = expr.value;
837
+ let variantObj;
838
+ const uniqueKey = `${this.resourcePath}-${varName}`;
839
+ let hash = scannedTables.variantsHashTable[uniqueKey];
840
+ if (!hash) {
841
+ hash = mergedVariantsTable[varName];
783
842
  }
784
- }
785
- else if (expr.type === 'BinaryExpression' &&
786
- expr.operator === '&&') {
787
- const truthyStyle = resolveStyleObject(expr.right);
788
- if (truthyStyle !== null) {
789
- conditionals.push({
790
- test: expr.left,
791
- truthy: truthyStyle,
792
- falsy: {},
843
+ if (hash && scannedTables.variantsObjectTable[hash]) {
844
+ variantObj = scannedTables.variantsObjectTable[hash];
845
+ }
846
+ if (!variantObj) {
847
+ if (localCreateStyles[varName] &&
848
+ localCreateStyles[varName].obj) {
849
+ variantObj = localCreateStyles[varName].obj;
850
+ }
851
+ }
852
+ if (variantObj) {
853
+ Object.entries(variantObj).forEach(([groupName, groupVariants]) => {
854
+ if (!groupVariants)
855
+ return;
856
+ const currentGroupId = ++groupIdCounter;
857
+ Object.entries(groupVariants).forEach(([optionName, style]) => {
858
+ conditionals.push({
859
+ test: expr,
860
+ testLHS: `props["${groupName}"]`,
861
+ testString: `props["${groupName}"] === '${optionName}'`,
862
+ truthy: style,
863
+ falsy: {},
864
+ groupId: currentGroupId,
865
+ groupName: groupName,
866
+ valueName: optionName,
867
+ varName: varName,
868
+ });
869
+ });
793
870
  });
794
871
  continue;
795
872
  }
796
873
  }
797
- else if (expr.type === 'ParenthesisExpression') {
798
- const inner = expr.expression;
799
- const innerStatic = resolveStyleObject(inner);
800
- if (innerStatic) {
801
- baseStyle = deepMerge(baseStyle, innerStatic);
802
- continue;
874
+ const getSource = (node) => {
875
+ const start = node.span.start - ast.span.start;
876
+ const end = node.span.end - ast.span.start;
877
+ return source.substring(start, end);
878
+ };
879
+ const collectConditions = (node, currentTestStrings = []) => {
880
+ const staticStyle = resolveStyleObject(node);
881
+ if (staticStyle) {
882
+ if (currentTestStrings.length === 0) {
883
+ baseStyle = deepMerge(baseStyle, staticStyle);
884
+ }
885
+ else {
886
+ const combinedTest = currentTestStrings.join(' && ');
887
+ conditionals.push({
888
+ test: node,
889
+ testString: combinedTest,
890
+ truthy: staticStyle,
891
+ falsy: {},
892
+ varName: undefined,
893
+ });
894
+ }
895
+ return true;
803
896
  }
804
- }
897
+ if (node.type === 'ConditionalExpression') {
898
+ const testSource = getSource(node.test);
899
+ if (currentTestStrings.length === 0) {
900
+ const trueStyle = resolveStyleObject(node.consequent);
901
+ const falseStyle = resolveStyleObject(node.alternate);
902
+ if (trueStyle && falseStyle) {
903
+ conditionals.push({
904
+ test: node,
905
+ testString: testSource,
906
+ truthy: trueStyle,
907
+ falsy: falseStyle,
908
+ varName: undefined,
909
+ });
910
+ return true;
911
+ }
912
+ }
913
+ collectConditions(node.consequent, [
914
+ ...currentTestStrings,
915
+ `(${testSource})`,
916
+ ]);
917
+ collectConditions(node.alternate, [
918
+ ...currentTestStrings,
919
+ `!(${testSource})`,
920
+ ]);
921
+ return true;
922
+ }
923
+ else if (node.type === 'BinaryExpression' &&
924
+ node.operator === '&&') {
925
+ const leftSource = getSource(node.left);
926
+ collectConditions(node.right, [
927
+ ...currentTestStrings,
928
+ `(${leftSource})`,
929
+ ]);
930
+ return true;
931
+ }
932
+ else if (node.type === 'ParenthesisExpression') {
933
+ return collectConditions(node.expression, currentTestStrings);
934
+ }
935
+ return false;
936
+ };
937
+ const handled = collectConditions(expr);
938
+ if (handled)
939
+ continue;
805
940
  isOptimizable = false;
806
941
  break;
807
942
  }
@@ -821,99 +956,278 @@ export function plumeria(options = {}) {
821
956
  });
822
957
  }
823
958
  else {
824
- const table = {};
825
- const groups = {};
826
- let strayIdCounter = groupIdCounter + 1;
959
+ const propertyCounts = {};
960
+ const addCounts = (style) => {
961
+ Object.keys(style).forEach((key) => {
962
+ propertyCounts[key] = (propertyCounts[key] || 0) + 1;
963
+ });
964
+ };
965
+ addCounts(baseStyle);
966
+ const participation = {};
967
+ const registerParticipation = (style, sourceId) => {
968
+ Object.keys(style).forEach((key) => {
969
+ if (!participation[key])
970
+ participation[key] = new Set();
971
+ participation[key].add(sourceId);
972
+ });
973
+ };
974
+ registerParticipation(baseStyle, 'base');
975
+ conditionals
976
+ .filter((c) => c.groupId === undefined)
977
+ .forEach((c, idx) => {
978
+ const sourceId = `std_${idx}`;
979
+ registerParticipation(c.truthy, sourceId);
980
+ registerParticipation(c.falsy, sourceId);
981
+ });
982
+ const variantGroups = {};
827
983
  conditionals.forEach((c) => {
828
- const gid = c.groupId !== undefined ? c.groupId : strayIdCounter++;
829
- if (!groups[gid]) {
830
- groups[gid] = [];
984
+ if (c.groupId !== undefined) {
985
+ if (!variantGroups[c.groupId])
986
+ variantGroups[c.groupId] = [];
987
+ variantGroups[c.groupId].push(c);
988
+ }
989
+ });
990
+ Object.entries(variantGroups).forEach(([groupId, opts]) => {
991
+ const sourceId = `var_${groupId}`;
992
+ opts.forEach((opt) => {
993
+ registerParticipation(opt.truthy, sourceId);
994
+ registerParticipation(opt.falsy, sourceId);
995
+ });
996
+ });
997
+ const conflictingKeys = new Set();
998
+ Object.entries(participation).forEach(([key, sources]) => {
999
+ if (sources.size > 1) {
1000
+ conflictingKeys.add(key);
831
1001
  }
832
- groups[gid].push(c);
833
1002
  });
834
- const sortedGroupIds = Object.keys(groups)
835
- .map(Number)
836
- .sort((a, b) => a - b);
837
- let totalCombinations = 1;
838
- const groupMeta = sortedGroupIds.map((gid) => {
839
- const options = groups[gid];
840
- const isVariantGroup = options[0].groupId !== undefined;
841
- const size = isVariantGroup ? options.length : 2;
842
- const stride = totalCombinations;
843
- totalCombinations *= size;
844
- return { gid, options, size, stride, isVariantGroup };
1003
+ const baseIndependent = {};
1004
+ const baseConflict = {};
1005
+ Object.entries(baseStyle).forEach(([key, val]) => {
1006
+ if (conflictingKeys.has(key)) {
1007
+ baseConflict[key] = val;
1008
+ }
1009
+ else {
1010
+ baseIndependent[key] = val;
1011
+ }
845
1012
  });
846
- for (let i = 0; i < totalCombinations; i++) {
847
- let currentStyle = { ...baseStyle };
848
- for (const meta of groupMeta) {
849
- const localIndex = Math.floor(i / meta.stride) % meta.size;
850
- if (meta.isVariantGroup) {
851
- currentStyle = deepMerge(currentStyle, meta.options[localIndex].truthy);
1013
+ const indepConditionals = [];
1014
+ const conflictConditionals = [];
1015
+ const splitConditional = (c) => {
1016
+ const truthyIndep = {};
1017
+ const truthyConf = {};
1018
+ const falsyIndep = {};
1019
+ const falsyConf = {};
1020
+ let hasIndep = false;
1021
+ let hasConf = false;
1022
+ Object.entries(c.truthy).forEach(([k, v]) => {
1023
+ if (conflictingKeys.has(k)) {
1024
+ truthyConf[k] = v;
1025
+ hasConf = true;
852
1026
  }
853
1027
  else {
854
- const cond = meta.options[0];
855
- if (localIndex === 1) {
856
- currentStyle = deepMerge(currentStyle, cond.truthy);
857
- }
858
- else {
859
- currentStyle = deepMerge(currentStyle, cond.falsy);
860
- }
1028
+ truthyIndep[k] = v;
1029
+ hasIndep = true;
1030
+ }
1031
+ });
1032
+ Object.entries(c.falsy).forEach(([k, v]) => {
1033
+ if (conflictingKeys.has(k)) {
1034
+ falsyConf[k] = v;
1035
+ hasConf = true;
861
1036
  }
1037
+ else {
1038
+ falsyIndep[k] = v;
1039
+ hasIndep = true;
1040
+ }
1041
+ });
1042
+ if (hasIndep) {
1043
+ indepConditionals.push({
1044
+ ...c,
1045
+ truthy: truthyIndep,
1046
+ falsy: falsyIndep,
1047
+ });
1048
+ }
1049
+ if (hasConf) {
1050
+ conflictConditionals.push({
1051
+ ...c,
1052
+ truthy: truthyConf,
1053
+ falsy: falsyConf,
1054
+ });
862
1055
  }
863
- extractOndemandStyles(currentStyle, extractedSheets, scannedTables);
864
- const records = getStyleRecords(currentStyle);
865
- records.forEach((r) => extractedSheets.push(r.sheet));
866
- const className = records
867
- .map((r) => r.hash)
868
- .join(' ');
869
- table[i] = className;
870
- }
871
- const indexParts = [];
872
- for (const meta of groupMeta) {
873
- if (meta.isVariantGroup) {
874
- const exprs = meta.options
875
- .map((opt, idx) => {
876
- if (idx === 0)
877
- return null;
878
- let testStr = opt.testString;
879
- if (!testStr && opt.test) {
880
- const start = opt.test.span.start - ast.span.start;
881
- const end = opt.test.span.end - ast.span.start;
882
- testStr = source.substring(start, end);
1056
+ };
1057
+ conditionals.forEach(splitConditional);
1058
+ const classParts = [];
1059
+ if (Object.keys(baseIndependent).length > 0) {
1060
+ extractOndemandStyles(baseIndependent, extractedSheets, scannedTables);
1061
+ const records = getStyleRecords(baseIndependent);
1062
+ records.forEach((r) => addSheet(r.sheet));
1063
+ const className = records.map((r) => r.hash).join(' ');
1064
+ if (className)
1065
+ classParts.push(JSON.stringify(className));
1066
+ }
1067
+ const indepStd = indepConditionals.filter((c) => c.groupId === undefined);
1068
+ indepStd.forEach((c) => {
1069
+ const processBranch = (style) => {
1070
+ if (Object.keys(style).length === 0)
1071
+ return '""';
1072
+ extractOndemandStyles(style, extractedSheets, scannedTables);
1073
+ const records = getStyleRecords(style);
1074
+ records.forEach((r) => addSheet(r.sheet));
1075
+ return JSON.stringify(records.map((r) => r.hash).join(' '));
1076
+ };
1077
+ const tClass = processBranch(c.truthy);
1078
+ const fClass = processBranch(c.falsy);
1079
+ let testStr = c.testString;
1080
+ if (!testStr && c.test) {
1081
+ const start = c.test.span.start - ast.span.start;
1082
+ const end = c.test.span.end - ast.span.start;
1083
+ testStr = source.substring(start, end);
1084
+ }
1085
+ classParts.push(`(${testStr} ? ${tClass} : ${fClass})`);
1086
+ });
1087
+ const indepVarGroups = {};
1088
+ indepConditionals.forEach((c) => {
1089
+ if (c.groupId !== undefined) {
1090
+ if (!indepVarGroups[c.groupId])
1091
+ indepVarGroups[c.groupId] = [];
1092
+ indepVarGroups[c.groupId].push(c);
1093
+ }
1094
+ });
1095
+ Object.values(indepVarGroups).forEach((options) => {
1096
+ let commonTestExpr = null;
1097
+ const lookupMap = {};
1098
+ if (options.length > 0) {
1099
+ if (options[0].testLHS) {
1100
+ commonTestExpr = options[0].testLHS;
1101
+ }
1102
+ else if (options[0].testString) {
1103
+ commonTestExpr = options[0].testString;
1104
+ }
1105
+ else {
1106
+ const firstTest = options[0].test;
1107
+ const firstStart = firstTest.span.start - ast.span.start;
1108
+ const firstEnd = firstTest.span.end - ast.span.start;
1109
+ commonTestExpr = source.substring(firstStart, firstEnd);
1110
+ }
1111
+ options.forEach((opt) => {
1112
+ if (opt.valueName && opt.truthy) {
1113
+ extractOndemandStyles(opt.truthy, extractedSheets, scannedTables);
1114
+ const records = getStyleRecords(opt.truthy);
1115
+ records.forEach((r) => addSheet(r.sheet));
1116
+ const className = records.map((r) => r.hash).join(' ');
1117
+ if (className) {
1118
+ lookupMap[opt.valueName] = className;
1119
+ }
883
1120
  }
884
- return `(!!(${testStr}) * ${idx})`;
885
- })
886
- .filter(Boolean);
887
- if (exprs.length > 0) {
888
- const groupSum = `(${exprs.join(' + ')})`;
889
- if (meta.stride > 1) {
890
- indexParts.push(`(${groupSum} * ${meta.stride})`);
1121
+ });
1122
+ }
1123
+ if (commonTestExpr && Object.keys(lookupMap).length > 0) {
1124
+ const entries = Object.entries(lookupMap)
1125
+ .map(([key, val]) => `"${key}":"${val}"`)
1126
+ .join(',');
1127
+ classParts.push(`({${entries}}[${commonTestExpr}] || "")`);
1128
+ }
1129
+ });
1130
+ if (Object.keys(baseConflict).length > 0 ||
1131
+ conflictConditionals.length > 0) {
1132
+ const conflictStd = conflictConditionals.filter((c) => c.groupId === undefined);
1133
+ const conflictVarGroups = {};
1134
+ conflictConditionals.forEach((c) => {
1135
+ if (c.groupId !== undefined) {
1136
+ if (!conflictVarGroups[c.groupId])
1137
+ conflictVarGroups[c.groupId] = [];
1138
+ conflictVarGroups[c.groupId].push(c);
1139
+ }
1140
+ });
1141
+ const dimensions = [];
1142
+ conflictStd.forEach((c) => {
1143
+ let testStr = c.testString;
1144
+ if (!testStr && c.test) {
1145
+ const start = c.test.span.start - ast.span.start;
1146
+ const end = c.test.span.end - ast.span.start;
1147
+ testStr = source.substring(start, end);
1148
+ }
1149
+ dimensions.push({
1150
+ type: 'std',
1151
+ testExpr: testStr,
1152
+ options: [
1153
+ { value: 0, style: c.falsy, label: 'false' },
1154
+ { value: 1, style: c.truthy, label: 'true' },
1155
+ ],
1156
+ });
1157
+ });
1158
+ Object.entries(conflictVarGroups).forEach(([_groupId, opts]) => {
1159
+ let commonTestExpr = null;
1160
+ if (opts.length > 0) {
1161
+ if (opts[0].testLHS) {
1162
+ commonTestExpr = opts[0].testLHS;
1163
+ }
1164
+ else if (opts[0].testString) {
1165
+ commonTestExpr = opts[0].testString;
891
1166
  }
892
1167
  else {
893
- indexParts.push(groupSum);
1168
+ const firstTest = opts[0].test;
1169
+ const firstStart = firstTest.span.start - ast.span.start;
1170
+ const firstEnd = firstTest.span.end - ast.span.start;
1171
+ commonTestExpr = source.substring(firstStart, firstEnd);
894
1172
  }
895
1173
  }
896
- }
897
- else {
898
- const cond = meta.options[0];
899
- let testStr = cond.testString;
900
- if (!testStr && cond.test) {
901
- const start = cond.test.span.start - ast.span.start;
902
- const end = cond.test.span.end - ast.span.start;
903
- testStr = source.substring(start, end);
1174
+ const options = opts.map((opt) => ({
1175
+ value: opt.valueName,
1176
+ style: opt.truthy,
1177
+ label: opt.valueName || 'default',
1178
+ }));
1179
+ dimensions.push({
1180
+ type: 'var',
1181
+ testExpr: commonTestExpr || '""',
1182
+ options: options,
1183
+ });
1184
+ });
1185
+ const results = {};
1186
+ const recurse = (dimIndex, currentStyle, keyParts) => {
1187
+ if (dimIndex >= dimensions.length) {
1188
+ extractOndemandStyles(currentStyle, extractedSheets, scannedTables);
1189
+ const records = getStyleRecords(currentStyle);
1190
+ records.forEach((r) => addSheet(r.sheet));
1191
+ const className = records.map((r) => r.hash).join(' ');
1192
+ const finalKey = keyParts.join('__');
1193
+ if (className)
1194
+ results[finalKey] = className;
1195
+ return;
904
1196
  }
905
- const expr = `(!!(${testStr}))`;
906
- if (meta.stride > 1) {
907
- indexParts.push(`(${expr} * ${meta.stride})`);
1197
+ const dim = dimensions[dimIndex];
1198
+ dim.options.forEach((opt) => {
1199
+ const nextStyle = deepMerge(currentStyle, opt.style);
1200
+ recurse(dimIndex + 1, nextStyle, [
1201
+ ...keyParts,
1202
+ String(opt.value),
1203
+ ]);
1204
+ });
1205
+ };
1206
+ recurse(0, baseConflict, []);
1207
+ let baseConflictClass = '';
1208
+ if (Object.keys(baseConflict).length > 0) {
1209
+ extractOndemandStyles(baseConflict, extractedSheets, scannedTables);
1210
+ const records = getStyleRecords(baseConflict);
1211
+ records.forEach((r) => addSheet(r.sheet));
1212
+ baseConflictClass = records.map((r) => r.hash).join(' ');
1213
+ }
1214
+ const keyExprs = [];
1215
+ dimensions.forEach((dim) => {
1216
+ if (dim.type === 'std') {
1217
+ keyExprs.push(`(${dim.testExpr} ? "1" : "0")`);
908
1218
  }
909
1219
  else {
910
- indexParts.push(`(${expr} * 1)`);
1220
+ keyExprs.push(dim.testExpr || '""');
911
1221
  }
912
- }
1222
+ });
1223
+ const masterKeyExpr = keyExprs.length > 0 ? keyExprs.join(' + "__" + ') : '""';
1224
+ const tableJson = JSON.stringify(results);
1225
+ const fallback = baseConflictClass
1226
+ ? JSON.stringify(baseConflictClass)
1227
+ : '""';
1228
+ classParts.push(`(${tableJson}[${masterKeyExpr}] || ${fallback})`);
913
1229
  }
914
- const indexExpr = indexParts.join(' + ') || '0';
915
- const tableStr = JSON.stringify(table);
916
- const replacement = `${tableStr}[${indexExpr}]`;
1230
+ const replacement = classParts.length > 0 ? classParts.join(' + " " + ') : '""';
917
1231
  replacements.push({
918
1232
  start: node.span.start - ast.span.start,
919
1233
  end: node.span.end - ast.span.start,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/vite-plugin",
3
- "version": "7.0.2",
3
+ "version": "7.1.1",
4
4
  "type": "module",
5
5
  "description": "Plumeria Vite plugin",
6
6
  "author": "Refirst 11",
@@ -22,12 +22,12 @@
22
22
  "dist/"
23
23
  ],
24
24
  "dependencies": {
25
- "@plumeria/utils": "^7.0.2"
25
+ "@plumeria/utils": "^7.1.1"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@swc/core": "1.15.8",
29
29
  "vite": "^7.1.1",
30
- "zss-engine": "2.2.3"
30
+ "zss-engine": "2.2.4"
31
31
  },
32
32
  "publishConfig": {
33
33
  "access": "public",