@plumeria/turbopack-loader 16.4.1 → 16.5.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.
package/dist/index.js CHANGED
@@ -41,20 +41,11 @@ const zss_engine_1 = require("zss-engine");
41
41
  const utils_1 = require("@plumeria/utils");
42
42
  const split_css_rules_1 = require("./split-css-rules");
43
43
  const file_lock_1 = require("./file-lock");
44
- let lastValidCss = '';
45
44
  async function loader(source) {
46
45
  const callback = this.async();
47
46
  const resourcePath = this.resourcePath;
48
47
  const isProduction = process.env.NODE_ENV === 'production';
49
48
  const VIRTUAL_FILE_PATH = path.resolve(__dirname, '..', 'zero-virtual.css');
50
- let isThemeCSS = false;
51
- if (!lastValidCss && !isProduction) {
52
- try {
53
- lastValidCss = fs.readFileSync(VIRTUAL_FILE_PATH, 'utf-8');
54
- }
55
- catch (e) {
56
- }
57
- }
58
49
  if (resourcePath.includes('node_modules') ||
59
50
  !source.includes('@plumeria/core')) {
60
51
  return callback(null, source);
@@ -335,17 +326,7 @@ async function loader(source) {
335
326
  const processedDecls = new Set();
336
327
  const idSpans = new Set();
337
328
  const excludedSpans = new Set();
338
- const checkVariantAssignment = (decl) => {
339
- const init = decl.init;
340
- if (init && utils_1.t.isCallExpression(init) && utils_1.t.isIdentifier(init.callee)) {
341
- const varName = init.callee.value;
342
- if ((localCreateStyles[varName] &&
343
- localCreateStyles[varName].type === 'variant') ||
344
- mergedVariantsTable[varName]) {
345
- throwCompilationError(`Plumeria: Assigning the return value of css.variants() to a variable is not supported.\nPlease pass the variant function directly to styleName or css.use(). Found assignment to: ${utils_1.t.isIdentifier(decl.id) ? decl.id.value : 'unknown'}`, init);
346
- }
347
- }
348
- };
329
+ const referenceIdents = (0, utils_1.collectReferenceIdentifiers)(ast);
349
330
  const registerStyle = (node, declSpan, isExported) => {
350
331
  let propName;
351
332
  const init = node.init;
@@ -449,7 +430,6 @@ async function loader(source) {
449
430
  else if (propName === 'createTheme' &&
450
431
  init.arguments.length >= 2 &&
451
432
  utils_1.t.isObjectExpression(init.arguments[1].expression)) {
452
- isThemeCSS = true;
453
433
  if (utils_1.t.isIdentifier(node.id)) {
454
434
  idSpans.add(node.id.span.start);
455
435
  }
@@ -570,7 +550,6 @@ async function loader(source) {
570
550
  if (utils_1.t.isVariableDeclaration(node.declaration)) {
571
551
  processedDecls.add(node.declaration);
572
552
  node.declaration.declarations.forEach((decl) => {
573
- checkVariantAssignment(decl);
574
553
  registerStyle(decl, node.span, true);
575
554
  checkStyleAliasAssignment(decl);
576
555
  });
@@ -580,7 +559,6 @@ async function loader(source) {
580
559
  if (processedDecls.has(node))
581
560
  return;
582
561
  node.declarations.forEach((decl) => {
583
- checkVariantAssignment(decl);
584
562
  registerStyle(decl, node.span, false);
585
563
  checkStyleAliasAssignment(decl);
586
564
  });
@@ -635,7 +613,6 @@ async function loader(source) {
635
613
  else if (propName === 'createTheme' &&
636
614
  args.length >= 2 &&
637
615
  utils_1.t.isObjectExpression(args[1].expression)) {
638
- isThemeCSS = true;
639
616
  let selector = '';
640
617
  const selectorExpr = args[0].expression;
641
618
  if (utils_1.t.isStringLiteral(selectorExpr)) {
@@ -717,10 +694,17 @@ async function loader(source) {
717
694
  else if (utils_1.t.isMemberExpression(expr) &&
718
695
  utils_1.t.isIdentifier(expr.object) &&
719
696
  (utils_1.t.isIdentifier(expr.property) || expr.property.type === 'Computed')) {
720
- if (expr.property.type === 'Computed')
721
- return null;
722
697
  const varName = expr.object.value;
723
- const propName = expr.property.value;
698
+ let propName;
699
+ if (expr.property.type === 'Computed') {
700
+ const keyExpr = expr.property.expression;
701
+ if (!utils_1.t.isStringLiteral(keyExpr))
702
+ return null;
703
+ propName = keyExpr.value;
704
+ }
705
+ else {
706
+ propName = expr.property.value;
707
+ }
724
708
  const styleInfo = localCreateStyles[varName];
725
709
  if (styleInfo?.obj[propName]) {
726
710
  const style = styleInfo.obj[propName];
@@ -829,6 +813,14 @@ async function loader(source) {
829
813
  else if (node.type === 'ParenthesisExpression') {
830
814
  return collectConditions(node.expression, currentTestStrings);
831
815
  }
816
+ if (currentTestStrings.length > 0 &&
817
+ utils_1.t.isMemberExpression(node) &&
818
+ utils_1.t.isIdentifier(node.object) &&
819
+ node.property.type === 'Computed' &&
820
+ resolveCreateObject(node.object.value)) {
821
+ const varName = node.object.value;
822
+ 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);
823
+ }
832
824
  assertResolvable(node);
833
825
  return false;
834
826
  };
@@ -1306,17 +1298,6 @@ async function loader(source) {
1306
1298
  return;
1307
1299
  }
1308
1300
  }
1309
- if (localStyle && localStyle.type === 'variant') {
1310
- const variantMap = localStyle.hashMap[propName];
1311
- if (variantMap) {
1312
- replacements.push({
1313
- start: node.span.start - baseByteOffset,
1314
- end: node.span.end - baseByteOffset,
1315
- content: `(${JSON.stringify(variantMap)})`,
1316
- });
1317
- return;
1318
- }
1319
- }
1320
1301
  let hash = scannedTables.createHashTable[uniqueKey];
1321
1302
  if (!hash) {
1322
1303
  hash = mergedCreateTable[varName];
@@ -1377,13 +1358,21 @@ async function loader(source) {
1377
1358
  return;
1378
1359
  if (idSpans.has(node.span.start))
1379
1360
  return;
1380
- const styleInfo = localCreateStyles[node.value];
1381
- if (styleInfo) {
1361
+ if (!referenceIdents.references.has(node.span.start))
1362
+ return;
1363
+ const prefix = referenceIdents.shorthands.has(node.span.start)
1364
+ ? `${node.value}: `
1365
+ : '';
1366
+ const pushReplacement = (content) => {
1382
1367
  replacements.push({
1383
1368
  start: node.span.start - baseByteOffset,
1384
1369
  end: node.span.end - baseByteOffset,
1385
- content: `(${JSON.stringify(styleInfo.hashMap)})`,
1370
+ content: `${prefix}${content}`,
1386
1371
  });
1372
+ };
1373
+ const styleInfo = localCreateStyles[node.value];
1374
+ if (styleInfo) {
1375
+ pushReplacement(`(${JSON.stringify(styleInfo.hashMap)})`);
1387
1376
  return;
1388
1377
  }
1389
1378
  const varName = node.value;
@@ -1402,11 +1391,7 @@ async function loader(source) {
1402
1391
  hashMap[key] = atomicMap[key];
1403
1392
  }
1404
1393
  });
1405
- replacements.push({
1406
- start: node.span.start - baseByteOffset,
1407
- end: node.span.end - baseByteOffset,
1408
- content: `(${JSON.stringify(hashMap)})`,
1409
- });
1394
+ pushReplacement(`(${JSON.stringify(hashMap)})`);
1410
1395
  }
1411
1396
  }
1412
1397
  let themeHash = mergedCreateThemeHashTable[varName];
@@ -1416,11 +1401,7 @@ async function loader(source) {
1416
1401
  if (themeHash) {
1417
1402
  const atomicMap = scannedTables.createAtomicMapTable[themeHash];
1418
1403
  if (atomicMap) {
1419
- replacements.push({
1420
- start: node.span.start - baseByteOffset,
1421
- end: node.span.end - baseByteOffset,
1422
- content: `(${JSON.stringify(atomicMap)})`,
1423
- });
1404
+ pushReplacement(`(${JSON.stringify(atomicMap)})`);
1424
1405
  return;
1425
1406
  }
1426
1407
  }
@@ -1431,11 +1412,7 @@ async function loader(source) {
1431
1412
  if (staticHash) {
1432
1413
  const staticObj = scannedTables.createStaticObjectTable[staticHash];
1433
1414
  if (staticObj) {
1434
- replacements.push({
1435
- start: node.span.start - baseByteOffset,
1436
- end: node.span.end - baseByteOffset,
1437
- content: `(${JSON.stringify(staticObj)})`,
1438
- });
1415
+ pushReplacement(`(${JSON.stringify(staticObj)})`);
1439
1416
  }
1440
1417
  }
1441
1418
  },
@@ -1728,12 +1705,27 @@ async function loader(source) {
1728
1705
  }
1729
1706
  },
1730
1707
  });
1708
+ const buildExportedInit = (info) => {
1709
+ const keys = Object.keys(info.obj);
1710
+ if (isProduction || keys.length === 0) {
1711
+ return JSON.stringify('');
1712
+ }
1713
+ const head = JSON.stringify(`Plumeria: "${info.name}.`);
1714
+ const tail = JSON.stringify(`" was read at runtime. The file that read it was not compiled ` +
1715
+ `because it does not reference "@plumeria/core" — add ` +
1716
+ `import '@plumeria/core'; to it (see the stack below). Defined in ` +
1717
+ `${path.relative(process.cwd(), resourcePath)}.`);
1718
+ return (`(()=>{const k=new Set(${JSON.stringify(keys)});` +
1719
+ `return new Proxy({},{get(t,p){` +
1720
+ `if(typeof p==="string"&&k.has(p))throw new Error(${head}+p+${tail});` +
1721
+ `return t[p];}});})()`);
1722
+ };
1731
1723
  Object.values(localCreateStyles).forEach((info) => {
1732
1724
  if (info.isExported) {
1733
1725
  replacements.push({
1734
1726
  start: info.initSpan.start,
1735
1727
  end: info.initSpan.end,
1736
- content: JSON.stringify(''),
1728
+ content: buildExportedInit(info),
1737
1729
  });
1738
1730
  }
1739
1731
  else {
@@ -1764,16 +1756,15 @@ async function loader(source) {
1764
1756
  if (!relativeImportPath.startsWith('.')) {
1765
1757
  relativeImportPath = './' + relativeImportPath;
1766
1758
  }
1767
- const hash = (0, zss_engine_1.genBase36Hash)(optInCSS, 1, 8);
1768
- const postfix = `\nimport "${relativeImportPath}?v=${hash}";`;
1759
+ const postfix = `\nimport "${relativeImportPath}";`;
1769
1760
  if (process.env.NODE_ENV === 'production') {
1770
1761
  return callback(null, transformedSource);
1771
1762
  }
1772
1763
  if (extractedSheets.length > 0 && process.env.NODE_ENV === 'development') {
1773
1764
  const LOCK_DIR_PATH = VIRTUAL_FILE_PATH + '.lock';
1774
1765
  await (0, file_lock_1.acquireLock)(LOCK_DIR_PATH);
1766
+ let currentCss = '';
1775
1767
  try {
1776
- let currentCss = '';
1777
1768
  try {
1778
1769
  currentCss = fs.readFileSync(VIRTUAL_FILE_PATH, 'utf-8');
1779
1770
  }
@@ -1789,18 +1780,14 @@ async function loader(source) {
1789
1780
  hasNewRule = true;
1790
1781
  }
1791
1782
  }
1792
- if (hasNewRule || isThemeCSS) {
1783
+ if (hasNewRule) {
1793
1784
  const nextCss = (0, utils_1.orderMediaLast)(Array.from(ruleSet)).join('\n\n') + '\n';
1794
1785
  fs.writeFileSync(VIRTUAL_FILE_PATH, nextCss, 'utf-8');
1795
- lastValidCss = nextCss;
1796
- }
1797
- else {
1798
- lastValidCss = currentCss;
1799
1786
  }
1800
1787
  }
1801
1788
  catch (innerError) {
1802
1789
  try {
1803
- fs.writeFileSync(VIRTUAL_FILE_PATH, lastValidCss, 'utf-8');
1790
+ fs.writeFileSync(VIRTUAL_FILE_PATH, currentCss, 'utf-8');
1804
1791
  }
1805
1792
  catch (e) {
1806
1793
  }
@@ -1810,13 +1797,6 @@ async function loader(source) {
1810
1797
  (0, file_lock_1.releaseLockSync)(LOCK_DIR_PATH);
1811
1798
  }
1812
1799
  }
1813
- else if (!isProduction) {
1814
- try {
1815
- lastValidCss = fs.readFileSync(VIRTUAL_FILE_PATH, 'utf-8');
1816
- }
1817
- catch (e) {
1818
- }
1819
- }
1820
1800
  return callback(null, transformedSource + postfix);
1821
1801
  }
1822
1802
  catch (error) {
@@ -7,6 +7,14 @@ function splitCssRules(css) {
7
7
  let depth = 0;
8
8
  let inComment = false;
9
9
  let inString = null;
10
+ let hasContent = false;
11
+ const flush = () => {
12
+ const trimmed = currentRule.trim();
13
+ if (trimmed)
14
+ rules.push(trimmed);
15
+ currentRule = '';
16
+ hasContent = false;
17
+ };
10
18
  for (let i = 0; i < css.length; i++) {
11
19
  const char = css[i];
12
20
  const nextChar = css[i + 1];
@@ -16,6 +24,8 @@ function splitCssRules(css) {
16
24
  currentRule += '/';
17
25
  i++;
18
26
  inComment = false;
27
+ if (depth === 0 && !hasContent)
28
+ flush();
19
29
  }
20
30
  continue;
21
31
  }
@@ -41,26 +51,22 @@ function splitCssRules(css) {
41
51
  if (char === '"' || char === "'") {
42
52
  currentRule += char;
43
53
  inString = char;
54
+ hasContent = true;
44
55
  continue;
45
56
  }
46
57
  currentRule += char;
58
+ if (char.trim())
59
+ hasContent = true;
47
60
  if (char === '{') {
48
61
  depth++;
49
62
  }
50
63
  else if (char === '}') {
51
64
  depth--;
52
- if (depth === 0) {
53
- const trimmed = currentRule.trim();
54
- if (trimmed)
55
- rules.push(trimmed);
56
- currentRule = '';
57
- }
65
+ if (depth === 0)
66
+ flush();
58
67
  }
59
68
  else if (char === ';' && depth === 0) {
60
- const trimmed = currentRule.trim();
61
- if (trimmed)
62
- rules.push(trimmed);
63
- currentRule = '';
69
+ flush();
64
70
  }
65
71
  }
66
72
  const trimmed = currentRule.trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/turbopack-loader",
3
- "version": "16.4.1",
3
+ "version": "16.5.0",
4
4
  "description": "Plumeria Turbopack-loader",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -22,7 +22,7 @@
22
22
  "zero-virtual.css"
23
23
  ],
24
24
  "dependencies": {
25
- "@plumeria/utils": "^16.4.1"
25
+ "@plumeria/utils": "^16.5.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@swc/core": "1.15.43",