@plumeria/turbopack-loader 18.5.0 → 18.5.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 +147 -15
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -130,6 +130,26 @@ const destructuredPropAliases = (fn) => {
130
130
  }
131
131
  return aliases;
132
132
  };
133
+ const spreadStyleMessage = (source) => `Plumeria: Spread elements in a style array are not supported: "...${source}". ` +
134
+ `List each style explicitly.`;
135
+ const resolveLocalStyleAlias = (aliases, expression) => {
136
+ let current = expression;
137
+ const seen = new Set();
138
+ while (utils_1.t.isIdentifier(current)) {
139
+ const name = current.value;
140
+ if (seen.has(name))
141
+ break;
142
+ seen.add(name);
143
+ const candidates = aliases[name];
144
+ if (!candidates || candidates.length === 0)
145
+ break;
146
+ const candidate = candidates.find((candidate) => candidate.context === current.ctxt);
147
+ if (!candidate)
148
+ break;
149
+ current = candidate.expression;
150
+ }
151
+ return current;
152
+ };
133
153
  const isStaticArgValue = (node) => node.type === 'StringLiteral' ||
134
154
  node.type === 'NumericLiteral' ||
135
155
  node.type === 'BooleanLiteral' ||
@@ -270,11 +290,32 @@ async function loader(source) {
270
290
  }
271
291
  const components = [];
272
292
  const propAliases = new Map();
293
+ const propDefaults = new Map();
294
+ const declaredProps = new Map();
273
295
  const addComponent = (name, fn) => {
274
296
  components.push({ name, node: fn });
297
+ const first = fn.params[0];
298
+ const pattern = unwrapPatternDefault(first?.pat ?? first);
299
+ const defaults = new Map();
300
+ for (const item of pattern?.properties ?? []) {
301
+ if (item.type === 'AssignmentPatternProperty' && item.value)
302
+ defaults.set(item.key.value, item.value);
303
+ if (item.type === 'KeyValuePatternProperty' &&
304
+ item.value?.type === 'AssignmentPattern')
305
+ defaults.set(item.key.value, item.value.right);
306
+ }
307
+ propDefaults.set(name, defaults);
275
308
  const aliases = destructuredPropAliases(fn);
276
309
  if (aliases.size > 0)
277
310
  propAliases.set(name, aliases);
311
+ const declared = new Set();
312
+ for (const item of pattern?.properties ?? []) {
313
+ const key = item.key;
314
+ if (utils_1.t.isIdentifier(key) || utils_1.t.isStringLiteral(key))
315
+ declared.add(String(key.value));
316
+ }
317
+ if (declared.size > 0)
318
+ declaredProps.set(name, declared);
278
319
  };
279
320
  for (const node of ast.body) {
280
321
  const statement = unwrapExport(node);
@@ -507,12 +548,15 @@ async function loader(source) {
507
548
  const checkStyleAliasAssignment = (decl) => {
508
549
  if (!utils_1.t.isIdentifier(decl.id) || !decl.init)
509
550
  return;
510
- const init = decl.init;
551
+ const init = (0, utils_1.unwrapExpression)(decl.init);
511
552
  if (utils_1.t.isMemberExpression(init) && utils_1.t.isIdentifier(init.object)) {
512
553
  const objName = init.object.value;
513
554
  if (localCreateStyles[objName] !== undefined ||
514
555
  mergedCreateTable[objName] !== undefined) {
515
- localStyleAliases[decl.id.value] = init;
556
+ (localStyleAliases[decl.id.value] ??= []).push({
557
+ expression: init,
558
+ context: decl.id.ctxt,
559
+ });
516
560
  }
517
561
  }
518
562
  };
@@ -943,8 +987,23 @@ async function loader(source) {
943
987
  };
944
988
  const resolveStyleObject = (expr) => {
945
989
  expr = (0, utils_1.unwrapExpression)(expr);
990
+ expr = resolveLocalStyleAlias(localStyleAliases, expr);
946
991
  if (!isVisibleReference(expr))
947
992
  return null;
993
+ if (expr.type === 'ArrayExpression') {
994
+ let merged = {};
995
+ for (const element of expr.elements ?? []) {
996
+ if (!element)
997
+ continue;
998
+ if (element.spread)
999
+ throwCompilationError(spreadStyleMessage(getSource(element.expression)), element.expression);
1000
+ const style = resolveStyleObject(element.expression);
1001
+ if (!style)
1002
+ return null;
1003
+ merged = (0, utils_1.deepMerge)(merged, style);
1004
+ }
1005
+ return merged;
1006
+ }
948
1007
  if (utils_1.t.isObjectExpression(expr)) {
949
1008
  return (0, utils_1.objectExpressionToObject)(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
950
1009
  }
@@ -1004,6 +1063,26 @@ async function loader(source) {
1004
1063
  return Boolean(localCreateStyles[callee.object.value]?.functions?.[callee.property.value] ??
1005
1064
  createFunctionImportMap[callee.object.value]?.[callee.property.value]);
1006
1065
  };
1066
+ const carriesStyleReference = (expression) => {
1067
+ const node = (0, utils_1.unwrapExpression)(expression);
1068
+ if (node.type === 'ArrayExpression')
1069
+ return node.elements.some((element) => !!element && carriesStyleReference(element.expression));
1070
+ if (isStyleFunctionCall(node))
1071
+ return true;
1072
+ if (utils_1.t.isObjectExpression(node))
1073
+ return false;
1074
+ return resolveStyleObject(node) !== null;
1075
+ };
1076
+ const assertNoStyleArraySpread = (expression) => {
1077
+ const node = (0, utils_1.unwrapExpression)(expression);
1078
+ if (node.type !== 'ArrayExpression')
1079
+ return;
1080
+ const spread = node.elements.find((element) => element?.spread);
1081
+ if (!spread)
1082
+ return;
1083
+ if (carriesStyleReference(node))
1084
+ throwCompilationError(spreadStyleMessage(getSource(spread.expression)), spread.expression);
1085
+ };
1007
1086
  const resolveDynamicCall = (expr, forceRuntime = false) => {
1008
1087
  if (!utils_1.t.isCallExpression(expr) || !utils_1.t.isMemberExpression(expr.callee))
1009
1088
  return null;
@@ -1021,6 +1100,7 @@ async function loader(source) {
1021
1100
  if (callArgs.some((a) => a.spread))
1022
1101
  return null;
1023
1102
  const tempStaticTable = { ...mergedStaticTable };
1103
+ const providedParams = new Set();
1024
1104
  const runtime = [];
1025
1105
  const resolveObjectArg = (argExpr) => (0, utils_1.objectExpressionToObject)({
1026
1106
  ...argExpr,
@@ -1057,8 +1137,10 @@ async function loader(source) {
1057
1137
  }
1058
1138
  if (!forceRuntime &&
1059
1139
  isStaticArgValue(source) &&
1060
- argObj[key] !== undefined)
1140
+ argObj[key] !== undefined) {
1061
1141
  tempStaticTable[local] = argObj[key];
1142
+ providedParams.add(local);
1143
+ }
1062
1144
  else
1063
1145
  runtime.push({ param: local, source });
1064
1146
  });
@@ -1069,8 +1151,10 @@ async function loader(source) {
1069
1151
  return null;
1070
1152
  const argObj = resolveObjectArg(callArgs[0].expression) ?? {};
1071
1153
  func.params.forEach((p) => {
1072
- if (argObj[p] !== undefined)
1154
+ if (argObj[p] !== undefined) {
1073
1155
  tempStaticTable[p] = argObj[p];
1156
+ providedParams.add(p);
1157
+ }
1074
1158
  });
1075
1159
  }
1076
1160
  else {
@@ -1081,7 +1165,7 @@ async function loader(source) {
1081
1165
  runtime.push({ param: p, source: callArg.expression });
1082
1166
  });
1083
1167
  }
1084
- const resolved = (0, utils_1.resolveDynamicStyle)(func, runtime.map(({ param }) => param), tempStaticTable, dynamicStyleTables);
1168
+ const resolved = (0, utils_1.resolveDynamicStyle)(func, runtime.map(({ param }) => param), tempStaticTable, dynamicStyleTables, providedParams);
1085
1169
  if (!resolved)
1086
1170
  return null;
1087
1171
  const { style, varGroups } = resolved;
@@ -1118,10 +1202,7 @@ async function loader(source) {
1118
1202
  };
1119
1203
  const buildClassParts = (args, dynamicClassParts = [], existingClass = '', isStyleProp = false) => {
1120
1204
  args.forEach((arg) => {
1121
- const expr = arg.expression;
1122
- if (utils_1.t.isIdentifier(expr) && localStyleAliases[expr.value]) {
1123
- arg.expression = localStyleAliases[expr.value];
1124
- }
1205
+ arg.expression = resolveLocalStyleAlias(localStyleAliases, arg.expression);
1125
1206
  });
1126
1207
  const conditionals = [];
1127
1208
  const dynamicVars = [];
@@ -1245,12 +1326,17 @@ async function loader(source) {
1245
1326
  };
1246
1327
  const collectConditions = (node, currentTestStrings = [], argOrder) => {
1247
1328
  node = (0, utils_1.unwrapExpression)(node);
1329
+ node = resolveLocalStyleAlias(localStyleAliases, node);
1248
1330
  if (isNoOpStyle(node))
1249
1331
  return true;
1250
1332
  if (node.type === 'ArrayExpression') {
1251
- return node.elements.every((element) => !element ||
1252
- (!element.spread &&
1253
- collectConditions(element.expression, currentTestStrings, argOrder)));
1333
+ return node.elements.every((element) => {
1334
+ if (!element)
1335
+ return true;
1336
+ if (element.spread)
1337
+ throwCompilationError(spreadStyleMessage(getSource(element.expression)), element.expression);
1338
+ return collectConditions(element.expression, currentTestStrings, argOrder);
1339
+ });
1254
1340
  }
1255
1341
  let branchStyle = resolveStyleObject(node);
1256
1342
  if (!branchStyle) {
@@ -1326,6 +1412,12 @@ async function loader(source) {
1326
1412
  utils_1.t.isIdentifier(expr.property);
1327
1413
  if (!utils_1.t.isIdentifier(expr) && !isParamMember)
1328
1414
  return false;
1415
+ const paramObject = isParamMember
1416
+ ? expr.object.value
1417
+ : undefined;
1418
+ const isPropsMember = Boolean(paramObject &&
1419
+ localCreateStyles[paramObject] === undefined &&
1420
+ mergedCreateTable[paramObject] === undefined);
1329
1421
  const varName = utils_1.t.isIdentifier(expr)
1330
1422
  ? expr.value
1331
1423
  : expr.property.value;
@@ -1350,8 +1442,42 @@ async function loader(source) {
1350
1442
  if (candidates.length > 0)
1351
1443
  possibilities = candidates;
1352
1444
  }
1353
- if (!possibilities || possibilities.length === 0)
1354
- return false;
1445
+ const fallback = owner && propDefaults.get(owner)?.get(propName);
1446
+ if (fallback) {
1447
+ const style = resolveStyleObject(fallback);
1448
+ if (style) {
1449
+ const atoms = {};
1450
+ (0, utils_1.getStyleRecords)(style).forEach((record) => {
1451
+ atoms[record.key] = record.hash;
1452
+ });
1453
+ const key = (0, zss_engine_1.genBase36Hash)(Object.values(atoms).join(' '), 1, 8);
1454
+ possibilities = [
1455
+ ...(possibilities ?? []),
1456
+ { key, styleObj: style },
1457
+ ];
1458
+ const span = fallback.span;
1459
+ {
1460
+ for (let i = replacements.length - 1; i >= 0; i--) {
1461
+ const replacement = replacements[i];
1462
+ if (replacement.start >= span.start - baseByteOffset &&
1463
+ replacement.end <= span.end - baseByteOffset)
1464
+ replacements.splice(i, 1);
1465
+ }
1466
+ excludeSubtreeSpans(fallback);
1467
+ replacements.push({
1468
+ start: span.start - baseByteOffset,
1469
+ end: span.end - baseByteOffset,
1470
+ content: JSON.stringify(key),
1471
+ });
1472
+ }
1473
+ }
1474
+ else {
1475
+ assertResolvable(fallback);
1476
+ }
1477
+ }
1478
+ if (!possibilities || possibilities.length === 0) {
1479
+ return Boolean(isPropsMember || (owner && declaredProps.get(owner)?.has(propName)));
1480
+ }
1355
1481
  const carriesVars = possibilities.some((entry) => entry.hasVars);
1356
1482
  if (carriesVars && !isStyleProp) {
1357
1483
  throwCompilationError(`Plumeria: "${varName}" carries a dynamic function key, and css.use() returns only a class name. ` +
@@ -2079,6 +2205,8 @@ async function loader(source) {
2079
2205
  }
2080
2206
  }
2081
2207
  if (compKey) {
2208
+ if (node.value?.type === 'JSXExpressionContainer')
2209
+ assertNoStyleArraySpread(node.value.expression);
2082
2210
  const list = scannedTables.componentPropsTable?.[compKey]?.[attrName];
2083
2211
  if (list &&
2084
2212
  node.value &&
@@ -2160,7 +2288,11 @@ async function loader(source) {
2160
2288
  const args = expr.type === 'ArrayExpression'
2161
2289
  ? expr.elements
2162
2290
  .filter((el) => el != null)
2163
- .map((el) => ({ expression: el.expression }))
2291
+ .map((el) => {
2292
+ if (el.spread)
2293
+ throwCompilationError(spreadStyleMessage(getSource(el.expression)), el.expression);
2294
+ return { expression: el.expression };
2295
+ })
2164
2296
  : [{ expression: expr }];
2165
2297
  const dynamicClassParts = [];
2166
2298
  const existingStyleParts = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/turbopack-loader",
3
- "version": "18.5.0",
3
+ "version": "18.5.1",
4
4
  "description": "Plumeria Turbopack-loader",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -29,8 +29,8 @@
29
29
  "zero-virtual.css"
30
30
  ],
31
31
  "dependencies": {
32
- "@plumeria/compiler": "^18.5.0",
33
- "@plumeria/utils": "^18.5.0"
32
+ "@plumeria/compiler": "^18.5.1",
33
+ "@plumeria/utils": "^18.5.1"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@swc/core": "1.15.47",