@plumeria/turbopack-loader 18.5.0 → 18.5.2

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