@plumeria/turbopack-loader 18.0.0 → 18.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +126 -30
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -222,6 +222,13 @@ async function loader(source) {
222
222
  const actualPath = (0, utils_1.resolveImportPath)(sourcePath, resourcePath);
223
223
  if (actualPath) {
224
224
  node.specifiers.forEach((specifier) => {
225
+ if (specifier.type === 'ImportNamespaceSpecifier') {
226
+ localImports[specifier.local.value] = {
227
+ actualPath,
228
+ importedName: '*',
229
+ };
230
+ return;
231
+ }
225
232
  if (specifier.type === 'ImportSpecifier' ||
226
233
  specifier.type === 'ImportDefaultSpecifier') {
227
234
  const importedName = specifier.type === 'ImportDefaultSpecifier'
@@ -802,6 +809,95 @@ async function loader(source) {
802
809
  return scannedTables.createObjectTable[hash];
803
810
  return null;
804
811
  };
812
+ const resolveBracketGroup = (node) => {
813
+ if (!utils_1.t.isMemberExpression(node) ||
814
+ !utils_1.t.isIdentifier(node.object) ||
815
+ node.property.type !== 'Computed' ||
816
+ utils_1.t.isStringLiteral(node.property.expression)) {
817
+ return null;
818
+ }
819
+ const varName = node.object.value;
820
+ const obj = resolveCreateObject(varName);
821
+ return obj ? { varName, keyExpr: node.property.expression, obj } : null;
822
+ };
823
+ const buildDecision = (node, prefix, off, counter) => {
824
+ if (node.type === 'ParenthesisExpression') {
825
+ return buildDecision(node.expression, prefix, off, counter);
826
+ }
827
+ if (node.type === 'ConditionalExpression') {
828
+ const a = buildDecision(node.consequent, prefix, off, counter);
829
+ if (!a)
830
+ return null;
831
+ const b = buildDecision(node.alternate, prefix, off, counter);
832
+ if (!b)
833
+ return null;
834
+ return {
835
+ keyExpr: `((${getSource(node.test)}) ? ${a.keyExpr} : ${b.keyExpr})`,
836
+ options: [...a.options, ...b.options],
837
+ leaves: a.leaves + b.leaves,
838
+ hasGroup: a.hasGroup || b.hasGroup,
839
+ };
840
+ }
841
+ if (node.type === 'BinaryExpression' && node.operator === '&&') {
842
+ const right = buildDecision(node.right, prefix, off, counter);
843
+ if (!right)
844
+ return null;
845
+ return {
846
+ keyExpr: `((${getSource(node.left)}) ? ${right.keyExpr} : ${JSON.stringify(off)})`,
847
+ options: right.options,
848
+ leaves: right.leaves,
849
+ hasGroup: right.hasGroup,
850
+ };
851
+ }
852
+ const group = resolveBracketGroup(node);
853
+ if (group) {
854
+ return {
855
+ keyExpr: getSource(group.keyExpr),
856
+ options: Object.entries(group.obj).map(([value, style]) => ({
857
+ value,
858
+ style: style,
859
+ })),
860
+ leaves: 1,
861
+ hasGroup: true,
862
+ };
863
+ }
864
+ const style = resolveStyleObject(node);
865
+ if (!style)
866
+ return null;
867
+ const value = `${prefix}${counter.n++}`;
868
+ return {
869
+ keyExpr: JSON.stringify(value),
870
+ options: [{ value, style }],
871
+ leaves: 1,
872
+ hasGroup: false,
873
+ };
874
+ };
875
+ const collectGroupKeys = (node, acc) => {
876
+ if (node.type === 'ParenthesisExpression') {
877
+ collectGroupKeys(node.expression, acc);
878
+ }
879
+ else if (node.type === 'ConditionalExpression') {
880
+ collectGroupKeys(node.consequent, acc);
881
+ collectGroupKeys(node.alternate, acc);
882
+ }
883
+ else if (node.type === 'BinaryExpression' && node.operator === '&&') {
884
+ collectGroupKeys(node.right, acc);
885
+ }
886
+ else {
887
+ const group = resolveBracketGroup(node);
888
+ if (group)
889
+ Object.keys(group.obj).forEach((k) => acc.add(k));
890
+ }
891
+ };
892
+ const resolveDecision = (node) => {
893
+ const groupKeys = new Set();
894
+ collectGroupKeys(node, groupKeys);
895
+ let prefix = '#';
896
+ while ([...groupKeys].some((k) => k.startsWith(prefix)))
897
+ prefix += '#';
898
+ const off = groupKeys.has('') ? `${prefix}off` : '';
899
+ return buildDecision(node, prefix, off, { n: 0 });
900
+ };
805
901
  const collectConditions = (node, currentTestStrings = []) => {
806
902
  const staticStyle = resolveStyleObject(node);
807
903
  if (staticStyle) {
@@ -855,14 +951,6 @@ async function loader(source) {
855
951
  else if (node.type === 'ParenthesisExpression') {
856
952
  return collectConditions(node.expression, currentTestStrings);
857
953
  }
858
- if (currentTestStrings.length > 0 &&
859
- utils_1.t.isMemberExpression(node) &&
860
- utils_1.t.isIdentifier(node.object) &&
861
- node.property.type === 'Computed' &&
862
- resolveCreateObject(node.object.value)) {
863
- const varName = node.object.value;
864
- throwCompilationError(`Plumeria: "${getSource(node)}" cannot be used inside a condition, because its bracket key is not a literal.\nMove the condition into the brackets instead, e.g. ${varName}[cond ? 'a' : 'b'].`, node);
865
- }
866
954
  assertResolvable(node);
867
955
  return false;
868
956
  };
@@ -1067,6 +1155,22 @@ async function loader(source) {
1067
1155
  continue;
1068
1156
  }
1069
1157
  }
1158
+ const decision = resolveDecision(expr);
1159
+ if (decision && (decision.hasGroup || decision.leaves > 2)) {
1160
+ const groupId = ++groupIdCounter;
1161
+ decision.options.forEach(({ value, style }) => conditionals.push({
1162
+ test: expr,
1163
+ testLHS: decision.keyExpr,
1164
+ testString: `${decision.keyExpr} === '${value}'`,
1165
+ truthy: style,
1166
+ falsy: {},
1167
+ groupId,
1168
+ groupName: undefined,
1169
+ valueName: value,
1170
+ varName: undefined,
1171
+ }));
1172
+ continue;
1173
+ }
1070
1174
  const handled = collectConditions(expr);
1071
1175
  if (handled)
1072
1176
  continue;
@@ -1196,7 +1300,7 @@ async function loader(source) {
1196
1300
  getSource(options[0].test);
1197
1301
  const lookupMap = {};
1198
1302
  options.forEach((opt) => {
1199
- if (opt.valueName && opt.truthy) {
1303
+ if (opt.valueName !== undefined && opt.truthy) {
1200
1304
  const className = processStyleRecords(opt.truthy)
1201
1305
  .map((r) => r.hash)
1202
1306
  .join(' ');
@@ -1234,6 +1338,15 @@ async function loader(source) {
1234
1338
  conflictVarGroups[c.groupId].push(c);
1235
1339
  }
1236
1340
  });
1341
+ Object.keys(conflictVarGroups).forEach((id) => {
1342
+ const groupId = Number(id);
1343
+ const opts = conflictVarGroups[groupId];
1344
+ if (opts.some((c) => c.valueName === ''))
1345
+ return;
1346
+ const off = conditionals.find((c) => c.groupId === groupId && c.valueName === '');
1347
+ if (off)
1348
+ opts.push({ ...off, truthy: {}, falsy: {} });
1349
+ });
1237
1350
  Object.entries(conflictVarGroups).forEach(([, opts]) => {
1238
1351
  dimensions.push({
1239
1352
  type: 'var',
@@ -1278,12 +1391,8 @@ async function loader(source) {
1278
1391
  };
1279
1392
  (0, utils_1.traverse)(ast, {
1280
1393
  JSXOpeningElement({ node }) {
1281
- let tagName = '';
1282
- if (node.name.type === 'Identifier') {
1283
- tagName = node.name.value;
1284
- }
1285
1394
  jsxOpeningElementMap.set(node.span.start, {
1286
- tagName,
1395
+ compKey: (0, utils_1.resolveComponentKey)(node.name, resourcePath, localImports),
1287
1396
  attributes: node.attributes,
1288
1397
  });
1289
1398
  },
@@ -1463,30 +1572,17 @@ async function loader(source) {
1463
1572
  return;
1464
1573
  const attrName = node.name.value;
1465
1574
  if (attrName !== styleProp) {
1466
- let parentTagName = '';
1575
+ let compKey = null;
1467
1576
  for (const [, val] of jsxOpeningElementMap) {
1468
1577
  const found = val.attributes
1469
1578
  .filter((a) => a.type === 'JSXAttribute')
1470
1579
  .find((a) => a.span.start === node.span.start);
1471
1580
  if (found) {
1472
- parentTagName = val.tagName;
1581
+ compKey = val.compKey;
1473
1582
  break;
1474
1583
  }
1475
1584
  }
1476
- if (parentTagName &&
1477
- parentTagName[0] === parentTagName[0].toUpperCase()) {
1478
- let compKey;
1479
- const imported = localImports[parentTagName];
1480
- if (imported) {
1481
- compKey = `${imported.actualPath}-${imported.importedName}`;
1482
- const resolved = (0, utils_1.resolveExport)(imported.actualPath, imported.importedName);
1483
- if (resolved) {
1484
- compKey = `${resolved.filePath}-${resolved.localName}`;
1485
- }
1486
- }
1487
- else {
1488
- compKey = `${resourcePath}-${parentTagName}`;
1489
- }
1585
+ if (compKey) {
1490
1586
  const list = scannedTables.componentPropsTable?.[compKey]?.[attrName];
1491
1587
  if (list &&
1492
1588
  node.value &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/turbopack-loader",
3
- "version": "18.0.0",
3
+ "version": "18.1.0",
4
4
  "description": "Plumeria Turbopack-loader",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -22,8 +22,8 @@
22
22
  "zero-virtual.css"
23
23
  ],
24
24
  "dependencies": {
25
- "@plumeria/compiler": "^18.0.0",
26
- "@plumeria/utils": "^18.0.0"
25
+ "@plumeria/compiler": "^18.1.0",
26
+ "@plumeria/utils": "^18.1.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@swc/core": "1.15.43",