@plumeria/compiler 10.0.6 → 10.0.8

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 +265 -68
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -190,7 +190,10 @@ function compileCSS(options) {
190
190
  mergedKeyframesTable[key] = scannedTables.keyframesHashTable[key];
191
191
  }
192
192
  for (const key of Object.keys(importMap)) {
193
- mergedKeyframesTable[key] = importMap[key];
193
+ const val = importMap[key];
194
+ if (typeof val === 'string') {
195
+ mergedKeyframesTable[key] = val;
196
+ }
194
197
  }
195
198
  const mergedViewTransitionTable = {};
196
199
  for (const key of Object.keys(scannedTables.viewTransitionHashTable)) {
@@ -198,14 +201,20 @@ function compileCSS(options) {
198
201
  scannedTables.viewTransitionHashTable[key];
199
202
  }
200
203
  for (const key of Object.keys(importMap)) {
201
- mergedViewTransitionTable[key] = importMap[key];
204
+ const val = importMap[key];
205
+ if (typeof val === 'string') {
206
+ mergedViewTransitionTable[key] = val;
207
+ }
202
208
  }
203
209
  const mergedCreateThemeHashTable = {};
204
210
  for (const key of Object.keys(scannedTables.createThemeHashTable)) {
205
211
  mergedCreateThemeHashTable[key] = scannedTables.createThemeHashTable[key];
206
212
  }
207
213
  for (const key of Object.keys(importMap)) {
208
- mergedCreateThemeHashTable[key] = importMap[key];
214
+ const val = importMap[key];
215
+ if (typeof val === 'string') {
216
+ mergedCreateThemeHashTable[key] = val;
217
+ }
209
218
  }
210
219
  const mergedCreateStaticHashTable = {};
211
220
  for (const key of Object.keys(scannedTables.createStaticHashTable)) {
@@ -213,21 +222,30 @@ function compileCSS(options) {
213
222
  scannedTables.createStaticHashTable[key];
214
223
  }
215
224
  for (const key of Object.keys(importMap)) {
216
- mergedCreateStaticHashTable[key] = importMap[key];
225
+ const val = importMap[key];
226
+ if (typeof val === 'string') {
227
+ mergedCreateStaticHashTable[key] = val;
228
+ }
217
229
  }
218
230
  const mergedCreateTable = {};
219
231
  for (const key of Object.keys(scannedTables.createHashTable)) {
220
232
  mergedCreateTable[key] = scannedTables.createHashTable[key];
221
233
  }
222
234
  for (const key of Object.keys(importMap)) {
223
- mergedCreateTable[key] = importMap[key];
235
+ const val = importMap[key];
236
+ if (typeof val === 'string') {
237
+ mergedCreateTable[key] = val;
238
+ }
224
239
  }
225
240
  const mergedVariantsTable = {};
226
241
  for (const key of Object.keys(scannedTables.variantsHashTable)) {
227
242
  mergedVariantsTable[key] = scannedTables.variantsHashTable[key];
228
243
  }
229
244
  for (const key of Object.keys(importMap)) {
230
- mergedVariantsTable[key] = importMap[key];
245
+ const val = importMap[key];
246
+ if (typeof val === 'string') {
247
+ mergedVariantsTable[key] = val;
248
+ }
231
249
  }
232
250
  const ctx = {
233
251
  mergedStaticTable,
@@ -249,52 +267,103 @@ function compileCSS(options) {
249
267
  };
250
268
  const extractAndProcessConditionals = (args, isStyleName = false) => {
251
269
  const conditionals = [];
270
+ let groupIdCounter = 0;
252
271
  let baseStyle = {};
253
- const resolveStyleObject = (expression) => {
254
- const styles = extractStylesFromExpression(expression, ctx);
255
- return styles.length === 1 ? styles[0] : null;
272
+ const resolveStyleObject = (expr) => {
273
+ if (utils_1.t.isObjectExpression(expr)) {
274
+ return (0, utils_1.objectExpressionToObject)(expr, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable);
275
+ }
276
+ else if (utils_1.t.isMemberExpression(expr) &&
277
+ utils_1.t.isIdentifier(expr.object) &&
278
+ utils_1.t.isIdentifier(expr.property)) {
279
+ const varName = expr.object.value;
280
+ const propName = expr.property.value;
281
+ const styleInfo = ctx.localCreateStyles[varName];
282
+ if (styleInfo && styleInfo.type === 'create') {
283
+ const style = styleInfo.obj[propName];
284
+ if (typeof style === 'object' && style !== null) {
285
+ return style;
286
+ }
287
+ }
288
+ const hash = ctx.mergedCreateTable[varName];
289
+ if (hash) {
290
+ const obj = ctx.scannedTables.createObjectTable[hash];
291
+ if (obj && obj[propName] && typeof obj[propName] === 'object') {
292
+ return obj[propName];
293
+ }
294
+ }
295
+ }
296
+ else if (utils_1.t.isIdentifier(expr)) {
297
+ const varName = expr.value;
298
+ const styleInfo = ctx.localCreateStyles[varName];
299
+ if (styleInfo && styleInfo.type === 'create') {
300
+ return styleInfo.obj;
301
+ }
302
+ const hash = ctx.mergedCreateTable[varName];
303
+ if (hash) {
304
+ const obj = ctx.scannedTables.createObjectTable[hash];
305
+ if (obj && typeof obj === 'object') {
306
+ return obj;
307
+ }
308
+ }
309
+ }
310
+ return null;
256
311
  };
257
312
  const getSource = (node) => ctx.sourceBuffer
258
313
  .subarray(node.span.start - ctx.baseByteOffset, node.span.end - ctx.baseByteOffset)
259
314
  .toString('utf-8');
260
- const collectConditions = (node, testStrings = []) => {
261
- const staticStyle = resolveStyleObject(node);
262
- if (staticStyle) {
263
- if (testStrings.length === 0) {
264
- baseStyle = (0, utils_1.deepMerge)(baseStyle, staticStyle);
265
- }
266
- else {
267
- conditionals.push({
268
- test: node,
269
- testString: testStrings.join(' && '),
270
- truthy: staticStyle,
271
- falsy: {},
272
- });
273
- }
274
- return true;
275
- }
315
+ const collectConditions = (node, currentTestStrings = []) => {
276
316
  if (node.type === 'ConditionalExpression') {
277
317
  const testSource = getSource(node.test);
318
+ if (currentTestStrings.length === 0) {
319
+ const trueStyle = resolveStyleObject(node.consequent);
320
+ const falseStyle = resolveStyleObject(node.alternate);
321
+ if (trueStyle && falseStyle) {
322
+ conditionals.push({
323
+ test: node,
324
+ testString: testSource,
325
+ truthy: trueStyle,
326
+ falsy: falseStyle,
327
+ varName: undefined,
328
+ });
329
+ return true;
330
+ }
331
+ }
278
332
  collectConditions(node.consequent, [
279
- ...testStrings,
333
+ ...currentTestStrings,
280
334
  `(${testSource})`,
281
335
  ]);
282
336
  collectConditions(node.alternate, [
283
- ...testStrings,
337
+ ...currentTestStrings,
284
338
  `!(${testSource})`,
285
339
  ]);
286
340
  return true;
287
341
  }
288
- else if (node.type === 'BinaryExpression' &&
289
- node.operator === '&&') {
342
+ else if (node.type === 'BinaryExpression' && node.operator === '&&') {
290
343
  collectConditions(node.right, [
291
- ...testStrings,
344
+ ...currentTestStrings,
292
345
  `(${getSource(node.left)})`,
293
346
  ]);
294
347
  return true;
295
348
  }
296
349
  else if (node.type === 'ParenthesisExpression') {
297
- return collectConditions(node.expression, testStrings);
350
+ return collectConditions(node.expression, currentTestStrings);
351
+ }
352
+ const staticStyle = resolveStyleObject(node);
353
+ if (staticStyle) {
354
+ if (currentTestStrings.length === 0) {
355
+ baseStyle = (0, utils_1.deepMerge)(baseStyle, staticStyle);
356
+ }
357
+ else {
358
+ conditionals.push({
359
+ test: node,
360
+ testString: currentTestStrings.join(' && '),
361
+ truthy: staticStyle,
362
+ falsy: {},
363
+ varName: undefined,
364
+ });
365
+ }
366
+ return true;
298
367
  }
299
368
  return false;
300
369
  };
@@ -308,8 +377,10 @@ function compileCSS(options) {
308
377
  const varName = node.callee.object.value;
309
378
  const propKey = node.callee.property.value;
310
379
  const styleInfo = ctx.localCreateStyles[varName];
311
- const atomMap = styleInfo?.obj?.[propKey];
312
- if (atomMap?.['__cssVars__']) {
380
+ const atomMap = styleInfo?.obj[propKey];
381
+ if (typeof atomMap === 'object' &&
382
+ atomMap !== null &&
383
+ '__cssVars__' in atomMap) {
313
384
  throw new Error(`[plumeria] css.use(${getSource(node)}) cannot handle dynamic style functions. Use styleName instead.\n`);
314
385
  }
315
386
  }
@@ -334,6 +405,116 @@ function compileCSS(options) {
334
405
  };
335
406
  for (const arg of args) {
336
407
  checkFunctionKey(arg.expression);
408
+ const expr = arg.expression;
409
+ if (utils_1.t.isCallExpression(expr)) {
410
+ if (utils_1.t.isIdentifier(expr.callee)) {
411
+ const varName = expr.callee.value;
412
+ const styleInfo = ctx.localCreateStyles[varName];
413
+ if (styleInfo && styleInfo.type === 'variant') {
414
+ const variantObj = styleInfo.obj;
415
+ const callArgs = expr.arguments;
416
+ if (callArgs.length === 1 && !callArgs[0].spread) {
417
+ const argExpr = callArgs[0].expression;
418
+ if (argExpr.type === 'ObjectExpression') {
419
+ for (const prop of argExpr.properties) {
420
+ let groupName;
421
+ let valExpr;
422
+ if (prop.type === 'KeyValueProperty' &&
423
+ prop.key.type === 'Identifier') {
424
+ groupName = prop.key.value;
425
+ valExpr = prop.value;
426
+ }
427
+ else if (prop.type === 'Identifier') {
428
+ groupName = prop.value;
429
+ valExpr = prop;
430
+ }
431
+ if (groupName && valExpr) {
432
+ const groupVariants = variantObj[groupName];
433
+ if (!groupVariants)
434
+ continue;
435
+ const currentGroupId = ++groupIdCounter;
436
+ const valSource = getSource(valExpr);
437
+ if (valExpr.type === 'StringLiteral') {
438
+ const groupVariantsAsObj = groupVariants;
439
+ if (groupVariantsAsObj[valExpr.value])
440
+ baseStyle = (0, utils_1.deepMerge)(baseStyle, groupVariantsAsObj[valExpr.value]);
441
+ continue;
442
+ }
443
+ Object.entries(groupVariants).forEach(([optionName, style]) => {
444
+ conditionals.push({
445
+ test: valExpr,
446
+ testLHS: valSource,
447
+ testString: `${valSource} === '${optionName}'`,
448
+ truthy: style,
449
+ falsy: {},
450
+ groupId: currentGroupId,
451
+ groupName,
452
+ valueName: optionName,
453
+ varName,
454
+ });
455
+ });
456
+ }
457
+ }
458
+ continue;
459
+ }
460
+ const argSource = getSource(argExpr);
461
+ if (utils_1.t.isStringLiteral(argExpr)) {
462
+ if (variantObj[argExpr.value])
463
+ baseStyle = (0, utils_1.deepMerge)(baseStyle, variantObj[argExpr.value]);
464
+ continue;
465
+ }
466
+ const currentGroupId = ++groupIdCounter;
467
+ Object.entries(variantObj).forEach(([key, style]) => {
468
+ conditionals.push({
469
+ test: argExpr,
470
+ testLHS: argSource,
471
+ testString: `${argSource} === '${key}'`,
472
+ truthy: style,
473
+ falsy: {},
474
+ groupId: currentGroupId,
475
+ groupName: undefined,
476
+ valueName: key,
477
+ varName,
478
+ });
479
+ });
480
+ continue;
481
+ }
482
+ }
483
+ }
484
+ else if (utils_1.t.isMemberExpression(expr.callee)) {
485
+ const callee = expr.callee;
486
+ if (utils_1.t.isIdentifier(callee.object) &&
487
+ utils_1.t.isIdentifier(callee.property)) {
488
+ const varName = callee.object.value;
489
+ const propName = callee.property.value;
490
+ const styleInfo = ctx.localCreateStyles[varName];
491
+ if (styleInfo && styleInfo.functions?.[propName]) {
492
+ const func = styleInfo.functions[propName];
493
+ const callArgs = expr.arguments;
494
+ if (callArgs.length === 1 && !callArgs[0].spread) {
495
+ const argExpr = callArgs[0].expression;
496
+ const tempStaticTable = { ...ctx.mergedStaticTable };
497
+ if (argExpr.type === 'ObjectExpression') {
498
+ const argObj = (0, utils_1.objectExpressionToObject)(argExpr, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable);
499
+ func.params.forEach((p) => {
500
+ if (argObj[p] !== undefined)
501
+ tempStaticTable[p] = argObj[p];
502
+ });
503
+ }
504
+ else {
505
+ func.params.forEach((p) => {
506
+ tempStaticTable[p] = `var(--${propName}-${p})`;
507
+ });
508
+ }
509
+ const resolved = (0, utils_1.objectExpressionToObject)(func.body, tempStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable);
510
+ if (resolved)
511
+ baseStyle = (0, utils_1.deepMerge)(baseStyle, resolved);
512
+ continue;
513
+ }
514
+ }
515
+ }
516
+ }
517
+ }
337
518
  if (collectConditions(arg.expression))
338
519
  continue;
339
520
  const extractedStyles = extractStylesFromExpression(arg.expression, ctx);
@@ -348,8 +529,11 @@ function compileCSS(options) {
348
529
  processStyle(cond.falsy);
349
530
  }
350
531
  };
532
+ const processedNodes = new WeakSet();
351
533
  const processCall = (node) => {
352
- node._processed = true;
534
+ if (processedNodes.has(node))
535
+ return;
536
+ processedNodes.add(node);
353
537
  const callee = node.callee;
354
538
  let propName;
355
539
  if (utils_1.t.isMemberExpression(callee) &&
@@ -412,12 +596,10 @@ function compileCSS(options) {
412
596
  if (utils_1.t.isMemberExpression(callee) &&
413
597
  utils_1.t.isIdentifier(callee.object) &&
414
598
  utils_1.t.isIdentifier(callee.property)) {
415
- if (plumeriaAliases[callee.object.value] ===
416
- 'NAMESPACE')
599
+ if (plumeriaAliases[callee.object.value] === 'NAMESPACE')
417
600
  pName = callee.property.value;
418
601
  }
419
- else if (utils_1.t.isIdentifier(callee) &&
420
- plumeriaAliases[callee.value]) {
602
+ else if (utils_1.t.isIdentifier(callee) && plumeriaAliases[callee.value]) {
421
603
  pName = plumeriaAliases[callee.value];
422
604
  }
423
605
  if (pName &&
@@ -431,27 +613,26 @@ function compileCSS(options) {
431
613
  if (pName === 'create') {
432
614
  const obj = (0, utils_1.objectExpressionToObject)(arg, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable, resolveVariable);
433
615
  if (obj) {
434
- ctx.localCreateStyles[node.id.value] = { type: 'create', obj };
435
- Object.entries(obj).forEach(([_, style]) => {
436
- if (typeof style !== 'object' || style === null)
437
- return;
438
- (0, utils_1.getStyleRecords)(style).forEach((r) => extractedSheets.push(r.sheet));
439
- });
616
+ const styleFunctions = {};
440
617
  arg.properties.forEach((prop) => {
441
618
  if (prop.type !== 'KeyValueProperty' ||
442
619
  prop.key.type !== 'Identifier')
443
620
  return;
444
- const isArrow = prop.value.type === 'ArrowFunctionExpression';
445
- const isFunc = prop.value.type === 'FunctionExpression';
446
- if (!isArrow && !isFunc)
621
+ const func = prop.value;
622
+ if (func.type !== 'ArrowFunctionExpression' &&
623
+ func.type !== 'FunctionExpression')
447
624
  return;
448
- const key = prop.key.value;
449
- const params = prop.value.params.map((p) => p.type === 'Identifier' ? p.value : (p.pat?.value ?? 'arg'));
450
- const tempStaticTable = { ...ctx.mergedStaticTable };
451
- params.forEach((paramName) => {
452
- tempStaticTable[paramName] = `var(--${key}-${paramName})`;
625
+ const params = func.params.map((p) => {
626
+ if (utils_1.t.isIdentifier(p))
627
+ return p.value;
628
+ if (typeof p === 'object' &&
629
+ p !== null &&
630
+ 'pat' in p &&
631
+ utils_1.t.isIdentifier(p.pat))
632
+ return p.pat.value;
633
+ return 'arg';
453
634
  });
454
- let actualBody = prop.value.body;
635
+ let actualBody = func.body;
455
636
  if (actualBody?.type === 'ParenthesisExpression')
456
637
  actualBody = actualBody.expression;
457
638
  if (actualBody?.type === 'BlockStatement') {
@@ -461,19 +642,30 @@ function compileCSS(options) {
461
642
  if (actualBody?.type === 'ParenthesisExpression')
462
643
  actualBody = actualBody.expression;
463
644
  }
464
- if (!actualBody || actualBody.type !== 'ObjectExpression')
465
- return;
466
- const substituted = (0, utils_1.objectExpressionToObject)(actualBody, tempStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable);
467
- if (!substituted)
468
- return;
469
- (0, utils_1.getStyleRecords)(substituted).forEach((r) => extractedSheets.push(r.sheet));
645
+ if (actualBody && actualBody.type === 'ObjectExpression') {
646
+ styleFunctions[prop.key.value] = {
647
+ params,
648
+ body: actualBody,
649
+ };
650
+ }
470
651
  });
652
+ ctx.localCreateStyles[node.id.value] = {
653
+ type: 'create',
654
+ obj,
655
+ functions: styleFunctions,
656
+ };
471
657
  }
472
658
  }
473
659
  else if (pName === 'variants') {
474
660
  const obj = (0, utils_1.objectExpressionToObject)(arg, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable, resolveVariable);
475
- if (obj)
476
- ctx.localCreateStyles[node.id.value] = { type: 'variant', obj };
661
+ if (obj) {
662
+ const { hashMap } = (0, utils_1.processVariants)(obj);
663
+ ctx.localCreateStyles[node.id.value] = {
664
+ type: 'variant',
665
+ obj,
666
+ hashMap,
667
+ };
668
+ }
477
669
  }
478
670
  else if (pName === 'createTheme') {
479
671
  const obj = (0, utils_1.objectExpressionToObject)(arg, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, ctx.mergedVariantsTable);
@@ -488,9 +680,12 @@ function compileCSS(options) {
488
680
  }
489
681
  }
490
682
  }
491
- if (utils_1.t.isIdentifier(node.id)) {
492
- if (node.init)
493
- traverseInternal(node.init);
683
+ },
684
+ });
685
+ (0, utils_1.traverse)(ast, {
686
+ VariableDeclarator({ node }) {
687
+ if (utils_1.t.isIdentifier(node.id) && node.init) {
688
+ traverseInternal(node.init);
494
689
  }
495
690
  },
496
691
  FunctionDeclaration({ node }) {
@@ -498,19 +693,21 @@ function compileCSS(options) {
498
693
  traverseInternal(node.body);
499
694
  },
500
695
  CallExpression: (path) => {
501
- if (!path.node._processed)
696
+ if (!processedNodes.has(path.node))
502
697
  processCall(path.node);
503
698
  },
504
699
  JSXAttribute({ node }) {
505
- if (node.name?.value !== 'styleName')
700
+ if (node.name.value !== 'styleName')
506
701
  return;
507
702
  if (!node.value || node.value.type !== 'JSXExpressionContainer')
508
703
  return;
704
+ if (node.value.expression.type === 'JSXEmptyExpression')
705
+ return;
509
706
  const expr = node.value.expression;
510
707
  const args = expr.type === 'ArrayExpression'
511
708
  ? expr.elements
512
- .filter(Boolean)
513
- .map((el) => ({ expression: el.expression ?? el }))
709
+ .filter((el) => el !== undefined)
710
+ .map((el) => ({ expression: el.expression }))
514
711
  : [{ expression: expr }];
515
712
  extractAndProcessConditionals(args, true);
516
713
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/compiler",
3
- "version": "10.0.6",
3
+ "version": "10.0.8",
4
4
  "description": "Plumeria swc based compiler for statically extracting css",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -21,7 +21,7 @@
21
21
  "dist/"
22
22
  ],
23
23
  "dependencies": {
24
- "@plumeria/utils": "^10.0.6"
24
+ "@plumeria/utils": "^10.0.8"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@rust-gear/glob": "1.0.0",