@plumeria/unplugin 18.5.1 → 18.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/core.js +129 -101
  2. package/dist/core.mjs +129 -101
  3. package/package.json +2 -2
package/dist/core.js CHANGED
@@ -87,6 +87,8 @@ const destructuredPropAliases = (fn) => {
87
87
  }
88
88
  return aliases;
89
89
  };
90
+ const propDefaultMessage = (source) => `Plumeria: A style prop default must be a defined style: "${source}". ` +
91
+ `Apply a conditional or dynamic style where the element is styled.`;
90
92
  const spreadStyleMessage = (source) => `Plumeria: Spread elements in a style array are not supported: "...${source}". ` +
91
93
  `List each style explicitly.`;
92
94
  const resolveLocalStyleAlias = (aliases, expression) => {
@@ -243,10 +245,10 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
243
245
  utils_1.t.isFunctionExpression(node)) {
244
246
  const rootId = (0, utils_1.getRootIdentifier)(node);
245
247
  const isPlumeriaStyle = rootId &&
248
+ isVisibleReference(node) &&
246
249
  ((localCreateStyles[rootId] !== undefined &&
247
250
  localCreateStyles[rootId].type !== 'constant') ||
248
- mergedCreateTable[rootId] !== undefined ||
249
- mergedVariantsTable[rootId] !== undefined);
251
+ mergedCreateTable[rootId] !== undefined);
250
252
  if (!isPlumeriaStyle) {
251
253
  const origin = rootId ? localImports[rootId] : undefined;
252
254
  const failure = origin
@@ -259,6 +261,10 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
259
261
  }
260
262
  }
261
263
  };
264
+ const scannedTables = (0, utils_1.scanAll)();
265
+ const ownFailure = (0, utils_1.resolveFileError)(baseId, '');
266
+ if (ownFailure)
267
+ throwCompilationError(`Plumeria: ${ownFailure.message}`);
262
268
  for (const node of ast.body) {
263
269
  if (node.type === 'ImportDeclaration') {
264
270
  const sourcePath = node.source.value;
@@ -272,7 +278,6 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
272
278
  }
273
279
  }
274
280
  }
275
- const scannedTables = (0, utils_1.scanAll)();
276
281
  if (scannedTables.componentPropsTable) {
277
282
  const parentFiles = new Set();
278
283
  for (const compKey of Object.keys(scannedTables.componentPropsTable)) {
@@ -370,7 +375,6 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
370
375
  const viewTransitionImportMap = {};
371
376
  const createImportMap = {};
372
377
  const createFunctionImportMap = {};
373
- const variantsImportMap = {};
374
378
  const createThemeImportMap = {};
375
379
  const createStaticImportMap = {};
376
380
  const plumeriaAliases = {};
@@ -437,10 +441,6 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
437
441
  if (scannedTables.createFunctionTable[uniqueKey]) {
438
442
  createFunctionImportMap[localName] = (0, utils_1.styleFunctionsOf)(scannedTables.createFunctionTable[uniqueKey]);
439
443
  }
440
- if (scannedTables.variantsHashTable[uniqueKey]) {
441
- variantsImportMap[localName] =
442
- scannedTables.variantsHashTable[uniqueKey];
443
- }
444
444
  if (scannedTables.createThemeHashTable[uniqueKey]) {
445
445
  createThemeImportMap[localName] =
446
446
  scannedTables.createThemeHashTable[uniqueKey];
@@ -499,17 +499,6 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
499
499
  for (const key of Object.keys(createImportMap)) {
500
500
  mergedCreateTable[key] = createImportMap[key];
501
501
  }
502
- const mergedVariantsTable = {};
503
- for (const key of Object.keys(scannedTables.variantsHashTable)) {
504
- mergedVariantsTable[key] = scannedTables.variantsHashTable[key];
505
- if (key.startsWith(`${resourcePath}-`)) {
506
- const varName = key.slice(resourcePath.length + 1);
507
- mergedVariantsTable[varName] = scannedTables.variantsHashTable[key];
508
- }
509
- }
510
- for (const key of Object.keys(variantsImportMap)) {
511
- mergedVariantsTable[key] = variantsImportMap[key];
512
- }
513
502
  const mergedCreateThemeHashTable = {};
514
503
  for (const key of Object.keys(scannedTables.createThemeHashTable)) {
515
504
  mergedCreateThemeHashTable[key] =
@@ -544,7 +533,6 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
544
533
  createHashTable: mergedCreateTable,
545
534
  createStaticHashTable: mergedCreateStaticHashTable,
546
535
  createStaticObjectTable: scannedTables.createStaticObjectTable,
547
- variantsHashTable: mergedVariantsTable,
548
536
  };
549
537
  const localCreateStyles = {};
550
538
  const localStyleAliases = {};
@@ -564,8 +552,30 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
564
552
  }
565
553
  };
566
554
  const replacements = [];
555
+ const deferredSources = [];
556
+ const deferSource = (node, stripObject = false) => {
557
+ const token = `__plumeria_preserved_${deferredSources.length}__`;
558
+ deferredSources.push({
559
+ token,
560
+ start: node.span.start - baseByteOffset,
561
+ end: node.span.end - baseByteOffset,
562
+ stripObject,
563
+ });
564
+ return token;
565
+ };
567
566
  const dynamicFnCalls = [];
568
567
  const processedDecls = new Set();
568
+ const separatelyExported = new Set();
569
+ for (const statement of ast.body) {
570
+ if (statement.type !== 'ExportNamedDeclaration' || statement.source)
571
+ continue;
572
+ for (const specifier of statement.specifiers) {
573
+ if (specifier.type === 'ExportSpecifier' &&
574
+ utils_1.t.isIdentifier(specifier.orig)) {
575
+ separatelyExported.add(specifier.orig.value);
576
+ }
577
+ }
578
+ }
569
579
  const idSpans = new Set();
570
580
  const excludedSpans = new Set();
571
581
  const referenceIdents = (0, utils_1.collectReferenceIdentifiers)(ast);
@@ -645,7 +655,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
645
655
  }
646
656
  if (propName === 'create' &&
647
657
  utils_1.t.isObjectExpression(init.arguments[0].expression)) {
648
- const obj = (0, utils_1.objectExpressionToObject)(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
658
+ const obj = (0, utils_1.objectExpressionToObject)(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
649
659
  if (obj) {
650
660
  const hashMap = {};
651
661
  Object.entries(obj).forEach(([key, style]) => {
@@ -695,7 +705,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
695
705
  if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
696
706
  throwCompilationError(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
697
707
  }
698
- const obj = (0, utils_1.objectExpressionToObject)(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
708
+ const obj = (0, utils_1.objectExpressionToObject)(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
699
709
  const hash = (0, utils_1.themeHashOf)(selector, obj);
700
710
  if (utils_1.t.isIdentifier(node.id)) {
701
711
  const uniqueKey = `${resourcePath}-${node.id.value}`;
@@ -733,7 +743,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
733
743
  if (utils_1.t.isIdentifier(node.id)) {
734
744
  idSpans.add(node.id.span.start);
735
745
  }
736
- const obj = (0, utils_1.objectExpressionToObject)(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
746
+ const obj = (0, utils_1.objectExpressionToObject)(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
737
747
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
738
748
  if (utils_1.t.isIdentifier(node.id)) {
739
749
  const uniqueKey = `${resourcePath}-${node.id.value}`;
@@ -815,7 +825,9 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
815
825
  if (processedDecls.has(node))
816
826
  return;
817
827
  node.declarations.forEach((decl) => {
818
- registerStyle(decl, node.span, false);
828
+ registerStyle(decl, node.span, node.declarations.length > 1 ||
829
+ (utils_1.t.isIdentifier(decl.id) &&
830
+ separatelyExported.has(decl.id.value)));
819
831
  checkStyleAliasAssignment(decl);
820
832
  });
821
833
  },
@@ -848,7 +860,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
848
860
  if (propName === 'keyframes' && args.length > 0) {
849
861
  const expr = args[0].expression;
850
862
  if (utils_1.t.isObjectExpression(expr)) {
851
- const obj = (0, utils_1.objectExpressionToObject)(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
863
+ const obj = (0, utils_1.objectExpressionToObject)(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
852
864
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
853
865
  scannedTables.keyframesObjectTable[hash] = obj;
854
866
  replacements.push({
@@ -861,7 +873,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
861
873
  else if (propName === 'viewTransition' &&
862
874
  args.length > 0 &&
863
875
  utils_1.t.isObjectExpression(args[0].expression)) {
864
- const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
876
+ const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
865
877
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
866
878
  scannedTables.viewTransitionObjectTable[hash] = obj;
867
879
  replacements.push({
@@ -882,7 +894,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
882
894
  if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
883
895
  throwCompilationError(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
884
896
  }
885
- const obj = (0, utils_1.objectExpressionToObject)(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
897
+ const obj = (0, utils_1.objectExpressionToObject)(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
886
898
  const hash = (0, utils_1.themeHashOf)(selector, obj);
887
899
  scannedTables.createThemeObjectTable[hash] = obj;
888
900
  if (scannedTables.createThemeSelectorTable) {
@@ -892,14 +904,14 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
892
904
  else if (propName === 'createStatic' &&
893
905
  args.length > 0 &&
894
906
  utils_1.t.isObjectExpression(args[0].expression)) {
895
- const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
907
+ const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
896
908
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
897
909
  scannedTables.createStaticObjectTable[hash] = obj;
898
910
  }
899
911
  else if (propName === 'create' &&
900
912
  args.length > 0 &&
901
913
  utils_1.t.isObjectExpression(args[0].expression)) {
902
- const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
914
+ const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
903
915
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
904
916
  scannedTables.createObjectTable[hash] = obj;
905
917
  }
@@ -955,9 +967,22 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
955
967
  const end = node.span.end - baseByteOffset;
956
968
  return sourceBuffer.subarray(start, end).toString('utf-8');
957
969
  };
970
+ const isVisibleReference = (expr) => {
971
+ if (utils_1.t.isIdentifier(expr))
972
+ return referenceIdents.references.has(expr.span.start);
973
+ if (utils_1.t.isMemberExpression(expr))
974
+ return isVisibleReference(expr.object);
975
+ if (utils_1.t.isCallExpression(expr) &&
976
+ expr.callee.type !== 'Super' &&
977
+ expr.callee.type !== 'Import')
978
+ return isVisibleReference(expr.callee);
979
+ return true;
980
+ };
958
981
  const resolveStyleObject = (expr) => {
959
982
  expr = (0, utils_1.unwrapExpression)(expr);
960
983
  expr = resolveLocalStyleAlias(localStyleAliases, expr);
984
+ if (!isVisibleReference(expr))
985
+ return null;
961
986
  if (expr.type === 'ArrayExpression') {
962
987
  let merged = {};
963
988
  for (const element of expr.elements ?? []) {
@@ -973,7 +998,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
973
998
  return merged;
974
999
  }
975
1000
  if (utils_1.t.isObjectExpression(expr)) {
976
- return (0, utils_1.objectExpressionToObject)(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
1001
+ return (0, utils_1.objectExpressionToObject)(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
977
1002
  }
978
1003
  else if (utils_1.t.isMemberExpression(expr) &&
979
1004
  utils_1.t.isIdentifier(expr.object) &&
@@ -1016,9 +1041,6 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1016
1041
  const styleInfo = localCreateStyles[varName];
1017
1042
  if (styleInfo?.obj)
1018
1043
  return styleInfo.obj;
1019
- const vHash = mergedVariantsTable[varName];
1020
- if (vHash)
1021
- return scannedTables.variantsObjectTable[vHash];
1022
1044
  }
1023
1045
  return null;
1024
1046
  };
@@ -1057,6 +1079,8 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1057
1079
  const callee = expr.callee;
1058
1080
  if (!utils_1.t.isIdentifier(callee.object) || !utils_1.t.isIdentifier(callee.property))
1059
1081
  return null;
1082
+ if (!isVisibleReference(callee.object))
1083
+ return null;
1060
1084
  const styleInfo = localCreateStyles[callee.object.value];
1061
1085
  const func = styleInfo?.functions?.[callee.property.value] ??
1062
1086
  createFunctionImportMap[callee.object.value]?.[callee.property.value];
@@ -1073,7 +1097,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1073
1097
  properties: argExpr.properties.filter((prop) => prop.type === 'Identifier' ||
1074
1098
  (prop.type === 'KeyValueProperty' &&
1075
1099
  isStaticArgValue(prop.value))),
1076
- }, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
1100
+ }, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
1077
1101
  if (func.named) {
1078
1102
  const argExpr = callArgs[0]?.expression;
1079
1103
  if (callArgs.length > 1 ||
@@ -1197,6 +1221,8 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1197
1221
  utils_1.t.isStringLiteral(node.property.expression)) {
1198
1222
  return null;
1199
1223
  }
1224
+ if (!isVisibleReference(node.object))
1225
+ return null;
1200
1226
  const varName = node.object.value;
1201
1227
  const obj = resolveCreateObject(varName);
1202
1228
  return obj
@@ -1297,6 +1323,15 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1297
1323
  node = resolveLocalStyleAlias(localStyleAliases, node);
1298
1324
  if (isNoOpStyle(node))
1299
1325
  return true;
1326
+ if (node.type === 'ArrayExpression') {
1327
+ return node.elements.every((element) => {
1328
+ if (!element)
1329
+ return true;
1330
+ if (element.spread)
1331
+ throwCompilationError(spreadStyleMessage(getSource(element.expression)), element.expression);
1332
+ return collectConditions(element.expression, currentTestStrings, argOrder);
1333
+ });
1334
+ }
1300
1335
  let branchStyle = resolveStyleObject(node);
1301
1336
  if (!branchStyle) {
1302
1337
  const dynamic = resolveDynamicCall(node);
@@ -1349,14 +1384,13 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1349
1384
  return true;
1350
1385
  }
1351
1386
  }
1352
- collectConditions(node.consequent, [...currentTestStrings, `(${testSource})`], argOrder);
1353
- collectConditions(node.alternate, [...currentTestStrings, `!(${testSource})`], argOrder);
1354
- return true;
1387
+ const consequentHandled = collectConditions(node.consequent, [...currentTestStrings, `(${testSource})`], argOrder);
1388
+ const alternateHandled = collectConditions(node.alternate, [...currentTestStrings, `!(${testSource})`], argOrder);
1389
+ return consequentHandled && alternateHandled;
1355
1390
  }
1356
1391
  else if (node.type === 'BinaryExpression' &&
1357
1392
  node.operator === '&&') {
1358
- collectConditions(node.right, [...currentTestStrings, `(${getSource(node.left)})`], argOrder);
1359
- return true;
1393
+ return collectConditions(node.right, [...currentTestStrings, `(${getSource(node.left)})`], argOrder);
1360
1394
  }
1361
1395
  else if (node.type === 'ParenthesisExpression') {
1362
1396
  return collectConditions(node.expression, currentTestStrings, argOrder);
@@ -1404,37 +1438,32 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1404
1438
  possibilities = candidates;
1405
1439
  }
1406
1440
  const fallback = owner && propDefaults.get(owner)?.get(propName);
1407
- if (fallback) {
1441
+ if (fallback && !isNoOpStyle((0, utils_1.unwrapExpression)(fallback))) {
1408
1442
  const style = resolveStyleObject(fallback);
1409
- if (style) {
1410
- const atoms = {};
1411
- (0, utils_1.getStyleRecords)(style).forEach((record) => {
1412
- atoms[record.key] = record.hash;
1413
- });
1414
- const key = (0, zss_engine_1.genBase36Hash)(Object.values(atoms).join(' '), 1, 8);
1415
- possibilities = [
1416
- ...(possibilities ?? []),
1417
- { key, styleObj: style },
1418
- ];
1419
- const span = fallback.span;
1420
- {
1421
- for (let i = replacements.length - 1; i >= 0; i--) {
1422
- const replacement = replacements[i];
1423
- if (replacement.start >= span.start - baseByteOffset &&
1424
- replacement.end <= span.end - baseByteOffset)
1425
- replacements.splice(i, 1);
1426
- }
1427
- excludeSubtreeSpans(fallback);
1428
- replacements.push({
1429
- start: span.start - baseByteOffset,
1430
- end: span.end - baseByteOffset,
1431
- content: JSON.stringify(key),
1432
- });
1433
- }
1434
- }
1435
- else {
1436
- assertResolvable(fallback);
1437
- }
1443
+ if (!style)
1444
+ throwCompilationError(propDefaultMessage(getSource(fallback)), fallback);
1445
+ const atoms = {};
1446
+ (0, utils_1.getStyleRecords)(style).forEach((record) => {
1447
+ atoms[record.key] = record.hash;
1448
+ });
1449
+ const key = (0, zss_engine_1.genBase36Hash)(Object.values(atoms).join(' '), 1, 8);
1450
+ possibilities = [
1451
+ ...(possibilities ?? []),
1452
+ { key, styleObj: style },
1453
+ ];
1454
+ const span = fallback.span;
1455
+ for (let index = replacements.length - 1; index >= 0; index--) {
1456
+ const replacement = replacements[index];
1457
+ if (replacement.start >= span.start - baseByteOffset &&
1458
+ replacement.end <= span.end - baseByteOffset)
1459
+ replacements.splice(index, 1);
1460
+ }
1461
+ excludeSubtreeSpans(fallback);
1462
+ replacements.push({
1463
+ start: span.start - baseByteOffset,
1464
+ end: span.end - baseByteOffset,
1465
+ content: JSON.stringify(key),
1466
+ });
1438
1467
  }
1439
1468
  if (!possibilities || possibilities.length === 0) {
1440
1469
  return Boolean(isPropsMember ||
@@ -1492,14 +1521,8 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1492
1521
  continue;
1493
1522
  if (utils_1.t.isCallExpression(expr) && utils_1.t.isIdentifier(expr.callee)) {
1494
1523
  const varName = expr.callee.value;
1495
- const uniqueKey = `${resourcePath}-${varName}`;
1496
1524
  let variantObj;
1497
- let hash = scannedTables.variantsHashTable[uniqueKey];
1498
- if (!hash)
1499
- hash = mergedVariantsTable[varName];
1500
- if (hash && scannedTables.variantsObjectTable[hash])
1501
- variantObj = scannedTables.variantsObjectTable[hash];
1502
- if (!variantObj && localCreateStyles[varName]?.obj)
1525
+ if (isVisibleReference(expr) && localCreateStyles[varName]?.obj)
1503
1526
  variantObj = localCreateStyles[varName].obj;
1504
1527
  if (variantObj) {
1505
1528
  const callArgs = expr.arguments;
@@ -1603,14 +1626,8 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1603
1626
  }
1604
1627
  else if (utils_1.t.isIdentifier(expr)) {
1605
1628
  const varName = expr.value;
1606
- const uniqueKey = `${resourcePath}-${varName}`;
1607
1629
  let variantObj;
1608
- let hash = scannedTables.variantsHashTable[uniqueKey];
1609
- if (!hash)
1610
- hash = mergedVariantsTable[varName];
1611
- if (hash && scannedTables.variantsObjectTable[hash])
1612
- variantObj = scannedTables.variantsObjectTable[hash];
1613
- if (!variantObj && localCreateStyles[varName]?.obj)
1630
+ if (isVisibleReference(expr) && localCreateStyles[varName]?.obj)
1614
1631
  variantObj = localCreateStyles[varName].obj;
1615
1632
  if (variantObj) {
1616
1633
  Object.entries(variantObj).forEach(([groupName, groupVariants]) => {
@@ -1640,7 +1657,9 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1640
1657
  utils_1.t.isIdentifier(expr.object) &&
1641
1658
  expr.property.type === 'Computed') {
1642
1659
  const varName = expr.object.value;
1643
- const styleObj = resolveCreateObject(varName);
1660
+ const styleObj = isVisibleReference(expr)
1661
+ ? resolveCreateObject(varName)
1662
+ : null;
1644
1663
  if (styleObj) {
1645
1664
  const dynExpr = expr.property.expression;
1646
1665
  const dynSource = getSource(dynExpr);
@@ -1969,6 +1988,8 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1969
1988
  });
1970
1989
  },
1971
1990
  MemberExpression({ node }) {
1991
+ if (!isVisibleReference(node))
1992
+ return;
1972
1993
  if (utils_1.t.isIdentifier(node.object) &&
1973
1994
  (utils_1.t.isIdentifier(node.property) || node.property.type === 'Computed')) {
1974
1995
  const varName = node.object.value;
@@ -2237,7 +2258,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
2237
2258
  const expr = node.value.expression;
2238
2259
  const args = expr.type === 'ArrayExpression'
2239
2260
  ? expr.elements
2240
- .filter((el) => el !== undefined)
2261
+ .filter((el) => el != null)
2241
2262
  .map((el) => {
2242
2263
  if (el.spread)
2243
2264
  throwCompilationError(spreadStyleMessage(getSource(el.expression)), el.expression);
@@ -2270,13 +2291,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
2270
2291
  existingClassExpr = JSON.stringify(classNameAttr.value.value);
2271
2292
  }
2272
2293
  else if (classNameAttr.value?.type === 'JSXExpressionContainer') {
2273
- const start = classNameAttr.value.expression.span.start -
2274
- baseByteOffset;
2275
- const end = classNameAttr.value.expression.span.end -
2276
- baseByteOffset;
2277
- existingClassExpr = `(${sourceBuffer
2278
- .subarray(start, end)
2279
- .toString('utf-8')})`;
2294
+ existingClassExpr = `(${deferSource(classNameAttr.value.expression)})`;
2280
2295
  }
2281
2296
  }
2282
2297
  const styleAttrExisting = attributes.find((attr) => attr.type === 'JSXAttribute' &&
@@ -2291,22 +2306,19 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
2291
2306
  });
2292
2307
  if (styleAttrExisting.value?.type === 'JSXExpressionContainer') {
2293
2308
  const innerExpr = styleAttrExisting.value?.expression;
2294
- const start = innerExpr.span.start - baseByteOffset;
2295
- const end = innerExpr.span.end - baseByteOffset;
2296
- const innerSource = sourceBuffer
2297
- .subarray(start, end)
2298
- .toString('utf-8');
2299
2309
  if (innerExpr.type === 'ObjectExpression') {
2300
- const stripped = innerSource.slice(1, -1).trim();
2301
- if (stripped)
2302
- existingStyleParts.push(stripped);
2310
+ if (innerExpr.properties.length > 0)
2311
+ existingStyleParts.push(deferSource(innerExpr, true));
2303
2312
  }
2304
2313
  else {
2305
- existingStyleExpr = `...(${innerSource})`;
2314
+ existingStyleExpr = `...(${deferSource(innerExpr)})`;
2306
2315
  }
2307
2316
  }
2308
2317
  }
2309
2318
  const { classParts, isOptimizable, baseStyle, dynamicVars, propVarSpreads, } = buildClassParts(args, dynamicClassParts, existingClassExpr, true);
2319
+ if (!isOptimizable) {
2320
+ throwCompilationError(`Plumeria: Dynamic or unresolvable style object "${getSource(expr)}" is not supported.`, expr);
2321
+ }
2310
2322
  const styleParts = [
2311
2323
  ...existingStyleParts,
2312
2324
  ...foldDynamicVars(dynamicVars),
@@ -2445,6 +2457,22 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
2445
2457
  `so it cannot be passed through another prop or read as a value.`, call);
2446
2458
  }
2447
2459
  });
2460
+ for (const deferred of deferredSources) {
2461
+ let cursor = deferred.start;
2462
+ const pieces = [];
2463
+ for (const replacement of [...replacements].sort((a, b) => a.start - b.start || b.end - a.end)) {
2464
+ if (replacement.start < cursor || replacement.end > deferred.end)
2465
+ continue;
2466
+ pieces.push(sourceBuffer.subarray(cursor, replacement.start).toString('utf-8'), replacement.content);
2467
+ cursor = replacement.end;
2468
+ }
2469
+ pieces.push(sourceBuffer.subarray(cursor, deferred.end).toString('utf-8'));
2470
+ let content = pieces.join('');
2471
+ if (deferred.stripObject)
2472
+ content = content.slice(1, -1).trim();
2473
+ for (const replacement of replacements)
2474
+ replacement.content = replacement.content.replaceAll(deferred.token, content);
2475
+ }
2448
2476
  const buffer = Buffer.from(source);
2449
2477
  let offset = 0;
2450
2478
  const parts = [];
package/dist/core.mjs CHANGED
@@ -51,6 +51,8 @@ const destructuredPropAliases = (fn) => {
51
51
  }
52
52
  return aliases;
53
53
  };
54
+ const propDefaultMessage = (source) => `Plumeria: A style prop default must be a defined style: "${source}". ` +
55
+ `Apply a conditional or dynamic style where the element is styled.`;
54
56
  const spreadStyleMessage = (source) => `Plumeria: Spread elements in a style array are not supported: "...${source}". ` +
55
57
  `List each style explicitly.`;
56
58
  const resolveLocalStyleAlias = (aliases, expression) => {
@@ -207,10 +209,10 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
207
209
  t.isFunctionExpression(node)) {
208
210
  const rootId = getRootIdentifier(node);
209
211
  const isPlumeriaStyle = rootId &&
212
+ isVisibleReference(node) &&
210
213
  ((localCreateStyles[rootId] !== undefined &&
211
214
  localCreateStyles[rootId].type !== 'constant') ||
212
- mergedCreateTable[rootId] !== undefined ||
213
- mergedVariantsTable[rootId] !== undefined);
215
+ mergedCreateTable[rootId] !== undefined);
214
216
  if (!isPlumeriaStyle) {
215
217
  const origin = rootId ? localImports[rootId] : undefined;
216
218
  const failure = origin
@@ -223,6 +225,10 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
223
225
  }
224
226
  }
225
227
  };
228
+ const scannedTables = scanAll();
229
+ const ownFailure = resolveFileError(baseId, '');
230
+ if (ownFailure)
231
+ throwCompilationError(`Plumeria: ${ownFailure.message}`);
226
232
  for (const node of ast.body) {
227
233
  if (node.type === 'ImportDeclaration') {
228
234
  const sourcePath = node.source.value;
@@ -236,7 +242,6 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
236
242
  }
237
243
  }
238
244
  }
239
- const scannedTables = scanAll();
240
245
  if (scannedTables.componentPropsTable) {
241
246
  const parentFiles = new Set();
242
247
  for (const compKey of Object.keys(scannedTables.componentPropsTable)) {
@@ -334,7 +339,6 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
334
339
  const viewTransitionImportMap = {};
335
340
  const createImportMap = {};
336
341
  const createFunctionImportMap = {};
337
- const variantsImportMap = {};
338
342
  const createThemeImportMap = {};
339
343
  const createStaticImportMap = {};
340
344
  const plumeriaAliases = {};
@@ -401,10 +405,6 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
401
405
  if (scannedTables.createFunctionTable[uniqueKey]) {
402
406
  createFunctionImportMap[localName] = styleFunctionsOf(scannedTables.createFunctionTable[uniqueKey]);
403
407
  }
404
- if (scannedTables.variantsHashTable[uniqueKey]) {
405
- variantsImportMap[localName] =
406
- scannedTables.variantsHashTable[uniqueKey];
407
- }
408
408
  if (scannedTables.createThemeHashTable[uniqueKey]) {
409
409
  createThemeImportMap[localName] =
410
410
  scannedTables.createThemeHashTable[uniqueKey];
@@ -463,17 +463,6 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
463
463
  for (const key of Object.keys(createImportMap)) {
464
464
  mergedCreateTable[key] = createImportMap[key];
465
465
  }
466
- const mergedVariantsTable = {};
467
- for (const key of Object.keys(scannedTables.variantsHashTable)) {
468
- mergedVariantsTable[key] = scannedTables.variantsHashTable[key];
469
- if (key.startsWith(`${resourcePath}-`)) {
470
- const varName = key.slice(resourcePath.length + 1);
471
- mergedVariantsTable[varName] = scannedTables.variantsHashTable[key];
472
- }
473
- }
474
- for (const key of Object.keys(variantsImportMap)) {
475
- mergedVariantsTable[key] = variantsImportMap[key];
476
- }
477
466
  const mergedCreateThemeHashTable = {};
478
467
  for (const key of Object.keys(scannedTables.createThemeHashTable)) {
479
468
  mergedCreateThemeHashTable[key] =
@@ -508,7 +497,6 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
508
497
  createHashTable: mergedCreateTable,
509
498
  createStaticHashTable: mergedCreateStaticHashTable,
510
499
  createStaticObjectTable: scannedTables.createStaticObjectTable,
511
- variantsHashTable: mergedVariantsTable,
512
500
  };
513
501
  const localCreateStyles = {};
514
502
  const localStyleAliases = {};
@@ -528,8 +516,30 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
528
516
  }
529
517
  };
530
518
  const replacements = [];
519
+ const deferredSources = [];
520
+ const deferSource = (node, stripObject = false) => {
521
+ const token = `__plumeria_preserved_${deferredSources.length}__`;
522
+ deferredSources.push({
523
+ token,
524
+ start: node.span.start - baseByteOffset,
525
+ end: node.span.end - baseByteOffset,
526
+ stripObject,
527
+ });
528
+ return token;
529
+ };
531
530
  const dynamicFnCalls = [];
532
531
  const processedDecls = new Set();
532
+ const separatelyExported = new Set();
533
+ for (const statement of ast.body) {
534
+ if (statement.type !== 'ExportNamedDeclaration' || statement.source)
535
+ continue;
536
+ for (const specifier of statement.specifiers) {
537
+ if (specifier.type === 'ExportSpecifier' &&
538
+ t.isIdentifier(specifier.orig)) {
539
+ separatelyExported.add(specifier.orig.value);
540
+ }
541
+ }
542
+ }
533
543
  const idSpans = new Set();
534
544
  const excludedSpans = new Set();
535
545
  const referenceIdents = collectReferenceIdentifiers(ast);
@@ -609,7 +619,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
609
619
  }
610
620
  if (propName === 'create' &&
611
621
  t.isObjectExpression(init.arguments[0].expression)) {
612
- const obj = objectExpressionToObject(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
622
+ const obj = objectExpressionToObject(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
613
623
  if (obj) {
614
624
  const hashMap = {};
615
625
  Object.entries(obj).forEach(([key, style]) => {
@@ -659,7 +669,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
659
669
  if (selector.startsWith('@') && !isAtRule(selector)) {
660
670
  throwCompilationError(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
661
671
  }
662
- const obj = objectExpressionToObject(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
672
+ const obj = objectExpressionToObject(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
663
673
  const hash = themeHashOf(selector, obj);
664
674
  if (t.isIdentifier(node.id)) {
665
675
  const uniqueKey = `${resourcePath}-${node.id.value}`;
@@ -697,7 +707,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
697
707
  if (t.isIdentifier(node.id)) {
698
708
  idSpans.add(node.id.span.start);
699
709
  }
700
- const obj = objectExpressionToObject(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
710
+ const obj = objectExpressionToObject(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
701
711
  const hash = genBase36Hash(obj, 1, 8);
702
712
  if (t.isIdentifier(node.id)) {
703
713
  const uniqueKey = `${resourcePath}-${node.id.value}`;
@@ -779,7 +789,9 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
779
789
  if (processedDecls.has(node))
780
790
  return;
781
791
  node.declarations.forEach((decl) => {
782
- registerStyle(decl, node.span, false);
792
+ registerStyle(decl, node.span, node.declarations.length > 1 ||
793
+ (t.isIdentifier(decl.id) &&
794
+ separatelyExported.has(decl.id.value)));
783
795
  checkStyleAliasAssignment(decl);
784
796
  });
785
797
  },
@@ -812,7 +824,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
812
824
  if (propName === 'keyframes' && args.length > 0) {
813
825
  const expr = args[0].expression;
814
826
  if (t.isObjectExpression(expr)) {
815
- const obj = objectExpressionToObject(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
827
+ const obj = objectExpressionToObject(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
816
828
  const hash = genBase36Hash(obj, 1, 8);
817
829
  scannedTables.keyframesObjectTable[hash] = obj;
818
830
  replacements.push({
@@ -825,7 +837,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
825
837
  else if (propName === 'viewTransition' &&
826
838
  args.length > 0 &&
827
839
  t.isObjectExpression(args[0].expression)) {
828
- const obj = objectExpressionToObject(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
840
+ const obj = objectExpressionToObject(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
829
841
  const hash = genBase36Hash(obj, 1, 8);
830
842
  scannedTables.viewTransitionObjectTable[hash] = obj;
831
843
  replacements.push({
@@ -846,7 +858,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
846
858
  if (selector.startsWith('@') && !isAtRule(selector)) {
847
859
  throwCompilationError(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
848
860
  }
849
- const obj = objectExpressionToObject(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
861
+ const obj = objectExpressionToObject(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
850
862
  const hash = themeHashOf(selector, obj);
851
863
  scannedTables.createThemeObjectTable[hash] = obj;
852
864
  if (scannedTables.createThemeSelectorTable) {
@@ -856,14 +868,14 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
856
868
  else if (propName === 'createStatic' &&
857
869
  args.length > 0 &&
858
870
  t.isObjectExpression(args[0].expression)) {
859
- const obj = objectExpressionToObject(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
871
+ const obj = objectExpressionToObject(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
860
872
  const hash = genBase36Hash(obj, 1, 8);
861
873
  scannedTables.createStaticObjectTable[hash] = obj;
862
874
  }
863
875
  else if (propName === 'create' &&
864
876
  args.length > 0 &&
865
877
  t.isObjectExpression(args[0].expression)) {
866
- const obj = objectExpressionToObject(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
878
+ const obj = objectExpressionToObject(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
867
879
  const hash = genBase36Hash(obj, 1, 8);
868
880
  scannedTables.createObjectTable[hash] = obj;
869
881
  }
@@ -919,9 +931,22 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
919
931
  const end = node.span.end - baseByteOffset;
920
932
  return sourceBuffer.subarray(start, end).toString('utf-8');
921
933
  };
934
+ const isVisibleReference = (expr) => {
935
+ if (t.isIdentifier(expr))
936
+ return referenceIdents.references.has(expr.span.start);
937
+ if (t.isMemberExpression(expr))
938
+ return isVisibleReference(expr.object);
939
+ if (t.isCallExpression(expr) &&
940
+ expr.callee.type !== 'Super' &&
941
+ expr.callee.type !== 'Import')
942
+ return isVisibleReference(expr.callee);
943
+ return true;
944
+ };
922
945
  const resolveStyleObject = (expr) => {
923
946
  expr = unwrapExpression(expr);
924
947
  expr = resolveLocalStyleAlias(localStyleAliases, expr);
948
+ if (!isVisibleReference(expr))
949
+ return null;
925
950
  if (expr.type === 'ArrayExpression') {
926
951
  let merged = {};
927
952
  for (const element of expr.elements ?? []) {
@@ -937,7 +962,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
937
962
  return merged;
938
963
  }
939
964
  if (t.isObjectExpression(expr)) {
940
- return objectExpressionToObject(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
965
+ return objectExpressionToObject(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
941
966
  }
942
967
  else if (t.isMemberExpression(expr) &&
943
968
  t.isIdentifier(expr.object) &&
@@ -980,9 +1005,6 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
980
1005
  const styleInfo = localCreateStyles[varName];
981
1006
  if (styleInfo?.obj)
982
1007
  return styleInfo.obj;
983
- const vHash = mergedVariantsTable[varName];
984
- if (vHash)
985
- return scannedTables.variantsObjectTable[vHash];
986
1008
  }
987
1009
  return null;
988
1010
  };
@@ -1021,6 +1043,8 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1021
1043
  const callee = expr.callee;
1022
1044
  if (!t.isIdentifier(callee.object) || !t.isIdentifier(callee.property))
1023
1045
  return null;
1046
+ if (!isVisibleReference(callee.object))
1047
+ return null;
1024
1048
  const styleInfo = localCreateStyles[callee.object.value];
1025
1049
  const func = styleInfo?.functions?.[callee.property.value] ??
1026
1050
  createFunctionImportMap[callee.object.value]?.[callee.property.value];
@@ -1037,7 +1061,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1037
1061
  properties: argExpr.properties.filter((prop) => prop.type === 'Identifier' ||
1038
1062
  (prop.type === 'KeyValueProperty' &&
1039
1063
  isStaticArgValue(prop.value))),
1040
- }, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
1064
+ }, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
1041
1065
  if (func.named) {
1042
1066
  const argExpr = callArgs[0]?.expression;
1043
1067
  if (callArgs.length > 1 ||
@@ -1161,6 +1185,8 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1161
1185
  t.isStringLiteral(node.property.expression)) {
1162
1186
  return null;
1163
1187
  }
1188
+ if (!isVisibleReference(node.object))
1189
+ return null;
1164
1190
  const varName = node.object.value;
1165
1191
  const obj = resolveCreateObject(varName);
1166
1192
  return obj
@@ -1261,6 +1287,15 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1261
1287
  node = resolveLocalStyleAlias(localStyleAliases, node);
1262
1288
  if (isNoOpStyle(node))
1263
1289
  return true;
1290
+ if (node.type === 'ArrayExpression') {
1291
+ return node.elements.every((element) => {
1292
+ if (!element)
1293
+ return true;
1294
+ if (element.spread)
1295
+ throwCompilationError(spreadStyleMessage(getSource(element.expression)), element.expression);
1296
+ return collectConditions(element.expression, currentTestStrings, argOrder);
1297
+ });
1298
+ }
1264
1299
  let branchStyle = resolveStyleObject(node);
1265
1300
  if (!branchStyle) {
1266
1301
  const dynamic = resolveDynamicCall(node);
@@ -1313,14 +1348,13 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1313
1348
  return true;
1314
1349
  }
1315
1350
  }
1316
- collectConditions(node.consequent, [...currentTestStrings, `(${testSource})`], argOrder);
1317
- collectConditions(node.alternate, [...currentTestStrings, `!(${testSource})`], argOrder);
1318
- return true;
1351
+ const consequentHandled = collectConditions(node.consequent, [...currentTestStrings, `(${testSource})`], argOrder);
1352
+ const alternateHandled = collectConditions(node.alternate, [...currentTestStrings, `!(${testSource})`], argOrder);
1353
+ return consequentHandled && alternateHandled;
1319
1354
  }
1320
1355
  else if (node.type === 'BinaryExpression' &&
1321
1356
  node.operator === '&&') {
1322
- collectConditions(node.right, [...currentTestStrings, `(${getSource(node.left)})`], argOrder);
1323
- return true;
1357
+ return collectConditions(node.right, [...currentTestStrings, `(${getSource(node.left)})`], argOrder);
1324
1358
  }
1325
1359
  else if (node.type === 'ParenthesisExpression') {
1326
1360
  return collectConditions(node.expression, currentTestStrings, argOrder);
@@ -1368,37 +1402,32 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1368
1402
  possibilities = candidates;
1369
1403
  }
1370
1404
  const fallback = owner && propDefaults.get(owner)?.get(propName);
1371
- if (fallback) {
1405
+ if (fallback && !isNoOpStyle(unwrapExpression(fallback))) {
1372
1406
  const style = resolveStyleObject(fallback);
1373
- if (style) {
1374
- const atoms = {};
1375
- getStyleRecords(style).forEach((record) => {
1376
- atoms[record.key] = record.hash;
1377
- });
1378
- const key = genBase36Hash(Object.values(atoms).join(' '), 1, 8);
1379
- possibilities = [
1380
- ...(possibilities ?? []),
1381
- { key, styleObj: style },
1382
- ];
1383
- const span = fallback.span;
1384
- {
1385
- for (let i = replacements.length - 1; i >= 0; i--) {
1386
- const replacement = replacements[i];
1387
- if (replacement.start >= span.start - baseByteOffset &&
1388
- replacement.end <= span.end - baseByteOffset)
1389
- replacements.splice(i, 1);
1390
- }
1391
- excludeSubtreeSpans(fallback);
1392
- replacements.push({
1393
- start: span.start - baseByteOffset,
1394
- end: span.end - baseByteOffset,
1395
- content: JSON.stringify(key),
1396
- });
1397
- }
1398
- }
1399
- else {
1400
- assertResolvable(fallback);
1401
- }
1407
+ if (!style)
1408
+ throwCompilationError(propDefaultMessage(getSource(fallback)), fallback);
1409
+ const atoms = {};
1410
+ getStyleRecords(style).forEach((record) => {
1411
+ atoms[record.key] = record.hash;
1412
+ });
1413
+ const key = genBase36Hash(Object.values(atoms).join(' '), 1, 8);
1414
+ possibilities = [
1415
+ ...(possibilities ?? []),
1416
+ { key, styleObj: style },
1417
+ ];
1418
+ const span = fallback.span;
1419
+ for (let index = replacements.length - 1; index >= 0; index--) {
1420
+ const replacement = replacements[index];
1421
+ if (replacement.start >= span.start - baseByteOffset &&
1422
+ replacement.end <= span.end - baseByteOffset)
1423
+ replacements.splice(index, 1);
1424
+ }
1425
+ excludeSubtreeSpans(fallback);
1426
+ replacements.push({
1427
+ start: span.start - baseByteOffset,
1428
+ end: span.end - baseByteOffset,
1429
+ content: JSON.stringify(key),
1430
+ });
1402
1431
  }
1403
1432
  if (!possibilities || possibilities.length === 0) {
1404
1433
  return Boolean(isPropsMember ||
@@ -1456,14 +1485,8 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1456
1485
  continue;
1457
1486
  if (t.isCallExpression(expr) && t.isIdentifier(expr.callee)) {
1458
1487
  const varName = expr.callee.value;
1459
- const uniqueKey = `${resourcePath}-${varName}`;
1460
1488
  let variantObj;
1461
- let hash = scannedTables.variantsHashTable[uniqueKey];
1462
- if (!hash)
1463
- hash = mergedVariantsTable[varName];
1464
- if (hash && scannedTables.variantsObjectTable[hash])
1465
- variantObj = scannedTables.variantsObjectTable[hash];
1466
- if (!variantObj && localCreateStyles[varName]?.obj)
1489
+ if (isVisibleReference(expr) && localCreateStyles[varName]?.obj)
1467
1490
  variantObj = localCreateStyles[varName].obj;
1468
1491
  if (variantObj) {
1469
1492
  const callArgs = expr.arguments;
@@ -1567,14 +1590,8 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1567
1590
  }
1568
1591
  else if (t.isIdentifier(expr)) {
1569
1592
  const varName = expr.value;
1570
- const uniqueKey = `${resourcePath}-${varName}`;
1571
1593
  let variantObj;
1572
- let hash = scannedTables.variantsHashTable[uniqueKey];
1573
- if (!hash)
1574
- hash = mergedVariantsTable[varName];
1575
- if (hash && scannedTables.variantsObjectTable[hash])
1576
- variantObj = scannedTables.variantsObjectTable[hash];
1577
- if (!variantObj && localCreateStyles[varName]?.obj)
1594
+ if (isVisibleReference(expr) && localCreateStyles[varName]?.obj)
1578
1595
  variantObj = localCreateStyles[varName].obj;
1579
1596
  if (variantObj) {
1580
1597
  Object.entries(variantObj).forEach(([groupName, groupVariants]) => {
@@ -1604,7 +1621,9 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1604
1621
  t.isIdentifier(expr.object) &&
1605
1622
  expr.property.type === 'Computed') {
1606
1623
  const varName = expr.object.value;
1607
- const styleObj = resolveCreateObject(varName);
1624
+ const styleObj = isVisibleReference(expr)
1625
+ ? resolveCreateObject(varName)
1626
+ : null;
1608
1627
  if (styleObj) {
1609
1628
  const dynExpr = expr.property.expression;
1610
1629
  const dynSource = getSource(dynExpr);
@@ -1933,6 +1952,8 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1933
1952
  });
1934
1953
  },
1935
1954
  MemberExpression({ node }) {
1955
+ if (!isVisibleReference(node))
1956
+ return;
1936
1957
  if (t.isIdentifier(node.object) &&
1937
1958
  (t.isIdentifier(node.property) || node.property.type === 'Computed')) {
1938
1959
  const varName = node.object.value;
@@ -2201,7 +2222,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
2201
2222
  const expr = node.value.expression;
2202
2223
  const args = expr.type === 'ArrayExpression'
2203
2224
  ? expr.elements
2204
- .filter((el) => el !== undefined)
2225
+ .filter((el) => el != null)
2205
2226
  .map((el) => {
2206
2227
  if (el.spread)
2207
2228
  throwCompilationError(spreadStyleMessage(getSource(el.expression)), el.expression);
@@ -2234,13 +2255,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
2234
2255
  existingClassExpr = JSON.stringify(classNameAttr.value.value);
2235
2256
  }
2236
2257
  else if (classNameAttr.value?.type === 'JSXExpressionContainer') {
2237
- const start = classNameAttr.value.expression.span.start -
2238
- baseByteOffset;
2239
- const end = classNameAttr.value.expression.span.end -
2240
- baseByteOffset;
2241
- existingClassExpr = `(${sourceBuffer
2242
- .subarray(start, end)
2243
- .toString('utf-8')})`;
2258
+ existingClassExpr = `(${deferSource(classNameAttr.value.expression)})`;
2244
2259
  }
2245
2260
  }
2246
2261
  const styleAttrExisting = attributes.find((attr) => attr.type === 'JSXAttribute' &&
@@ -2255,22 +2270,19 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
2255
2270
  });
2256
2271
  if (styleAttrExisting.value?.type === 'JSXExpressionContainer') {
2257
2272
  const innerExpr = styleAttrExisting.value?.expression;
2258
- const start = innerExpr.span.start - baseByteOffset;
2259
- const end = innerExpr.span.end - baseByteOffset;
2260
- const innerSource = sourceBuffer
2261
- .subarray(start, end)
2262
- .toString('utf-8');
2263
2273
  if (innerExpr.type === 'ObjectExpression') {
2264
- const stripped = innerSource.slice(1, -1).trim();
2265
- if (stripped)
2266
- existingStyleParts.push(stripped);
2274
+ if (innerExpr.properties.length > 0)
2275
+ existingStyleParts.push(deferSource(innerExpr, true));
2267
2276
  }
2268
2277
  else {
2269
- existingStyleExpr = `...(${innerSource})`;
2278
+ existingStyleExpr = `...(${deferSource(innerExpr)})`;
2270
2279
  }
2271
2280
  }
2272
2281
  }
2273
2282
  const { classParts, isOptimizable, baseStyle, dynamicVars, propVarSpreads, } = buildClassParts(args, dynamicClassParts, existingClassExpr, true);
2283
+ if (!isOptimizable) {
2284
+ throwCompilationError(`Plumeria: Dynamic or unresolvable style object "${getSource(expr)}" is not supported.`, expr);
2285
+ }
2274
2286
  const styleParts = [
2275
2287
  ...existingStyleParts,
2276
2288
  ...foldDynamicVars(dynamicVars),
@@ -2409,6 +2421,22 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
2409
2421
  `so it cannot be passed through another prop or read as a value.`, call);
2410
2422
  }
2411
2423
  });
2424
+ for (const deferred of deferredSources) {
2425
+ let cursor = deferred.start;
2426
+ const pieces = [];
2427
+ for (const replacement of [...replacements].sort((a, b) => a.start - b.start || b.end - a.end)) {
2428
+ if (replacement.start < cursor || replacement.end > deferred.end)
2429
+ continue;
2430
+ pieces.push(sourceBuffer.subarray(cursor, replacement.start).toString('utf-8'), replacement.content);
2431
+ cursor = replacement.end;
2432
+ }
2433
+ pieces.push(sourceBuffer.subarray(cursor, deferred.end).toString('utf-8'));
2434
+ let content = pieces.join('');
2435
+ if (deferred.stripObject)
2436
+ content = content.slice(1, -1).trim();
2437
+ for (const replacement of replacements)
2438
+ replacement.content = replacement.content.replaceAll(deferred.token, content);
2439
+ }
2412
2440
  const buffer = Buffer.from(source);
2413
2441
  let offset = 0;
2414
2442
  const parts = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/unplugin",
3
- "version": "18.5.1",
3
+ "version": "18.5.3",
4
4
  "description": "Universal Plumeria plugin for various build tools",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -94,7 +94,7 @@
94
94
  "dependencies": {
95
95
  "@rollup/pluginutils": "^5.4.0",
96
96
  "unplugin": "^3.0.0",
97
- "@plumeria/utils": "^18.5.1"
97
+ "@plumeria/utils": "^18.5.3"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@swc/core": "1.15.47",