@plumeria/utils 19.6.1 → 19.6.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.
package/dist/compile.js CHANGED
@@ -41,6 +41,7 @@ const path = __importStar(require("path"));
41
41
  const rs = __importStar(require("@rust-gear/glob"));
42
42
  const index_1 = require("./index");
43
43
  const index_2 = require("./index");
44
+ const dynamicKey_1 = require("./dynamicKey");
44
45
  const unwrapExport = (node) => {
45
46
  if (node?.type === 'ExportDeclaration')
46
47
  return node.declaration;
@@ -626,6 +627,7 @@ function compileCSS(options) {
626
627
  const tempStaticTable = { ...ctx.mergedStaticTable };
627
628
  const providedParams = new Set();
628
629
  const runtime = [];
630
+ const definite = new Set();
629
631
  const resolveObjectArg = (argExpr) => (0, index_1.objectExpressionToObject)({
630
632
  ...argExpr,
631
633
  properties: argExpr.properties.filter((prop) => prop.type === 'Identifier' ||
@@ -662,8 +664,11 @@ function compileCSS(options) {
662
664
  tempStaticTable[local] = argObj[key];
663
665
  providedParams.add(local);
664
666
  }
665
- else
667
+ else {
666
668
  runtime.push(local);
669
+ if ((0, dynamicKey_1.isDefinedArgument)(source))
670
+ definite.add(local);
671
+ }
667
672
  });
668
673
  }
669
674
  else if (callArgs.length === 1 &&
@@ -677,14 +682,16 @@ function compileCSS(options) {
677
682
  });
678
683
  }
679
684
  else {
680
- callArgs.forEach((_callArg, i) => {
685
+ callArgs.forEach((callArg, i) => {
681
686
  const p = func.params[i];
682
687
  if (!p)
683
688
  return;
684
689
  runtime.push(p);
690
+ if ((0, dynamicKey_1.isDefinedArgument)(callArg.expression))
691
+ definite.add(p);
685
692
  });
686
693
  }
687
- const resolved = (0, index_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx), providedParams);
694
+ const resolved = (0, index_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx), providedParams, definite);
688
695
  const { style } = resolved;
689
696
  return style;
690
697
  };
@@ -35,6 +35,14 @@ export type DynamicStyleTables = {
35
35
  createStaticHashTable: CreateStaticHashTable;
36
36
  createStaticObjectTable: CreateStaticObjectTable;
37
37
  };
38
+ export type DerivedPiece = string | {
39
+ param: string;
40
+ fallback?: string;
41
+ };
42
+ export type DerivedVar = {
43
+ name: string;
44
+ pieces: DerivedPiece[];
45
+ };
38
46
  export type DynamicStyleResult = {
39
47
  style: CSSObject;
40
48
  varGroups: Map<string, Array<{
@@ -43,6 +51,8 @@ export type DynamicStyleResult = {
43
51
  unit: string;
44
52
  written: boolean;
45
53
  }>>;
54
+ derived: DerivedVar[];
46
55
  };
47
- export declare const resolveDynamicStyle: (func: StyleFunction, runtimeParams: string[], staticTable: StaticTable, tables: DynamicStyleTables, providedParams?: ReadonlySet<string>) => DynamicStyleResult;
56
+ export declare const isDefinedArgument: (expression: Expression) => boolean;
57
+ export declare const resolveDynamicStyle: (func: StyleFunction, runtimeParams: string[], staticTable: StaticTable, tables: DynamicStyleTables, providedParams?: ReadonlySet<string>, definiteParams?: ReadonlySet<string>) => DynamicStyleResult;
48
58
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveDynamicStyle = exports.applyVarFallback = exports.splitVarByUnit = exports.isUnitlessProp = exports.styleFunctionsOf = void 0;
3
+ exports.resolveDynamicStyle = exports.isDefinedArgument = exports.applyVarFallback = exports.splitVarByUnit = exports.isUnitlessProp = exports.styleFunctionsOf = void 0;
4
4
  const zss_engine_1 = require("zss-engine");
5
5
  const zss_engine_2 = require("zss-engine");
6
6
  const parser_1 = require("./parser");
@@ -229,55 +229,222 @@ const applyVarFallback = (style, cssVar, literal, unit) => {
229
229
  }
230
230
  };
231
231
  exports.applyVarFallback = applyVarFallback;
232
- const resolveDynamicStyle = (func, runtimeParams, staticTable, tables, providedParams) => {
232
+ const ARITHMETIC = new Set(['+', '-', '*', '/', '%', '**']);
233
+ const isSign = (node) => parser_1.t.isUnaryExpression(node) && (node.operator === '-' || node.operator === '+');
234
+ const isDefinedArgument = (expression) => {
235
+ const node = (0, parser_1.unwrapExpression)(expression);
236
+ if (parser_1.t.isStringLiteral(node) ||
237
+ parser_1.t.isNumericLiteral(node) ||
238
+ parser_1.t.isBooleanLiteral(node) ||
239
+ parser_1.t.isNullLiteral(node) ||
240
+ parser_1.t.isTemplateLiteral(node))
241
+ return true;
242
+ return isSign(node) && parser_1.t.isNumericLiteral((0, parser_1.unwrapExpression)(node.argument));
243
+ };
244
+ exports.isDefinedArgument = isDefinedArgument;
245
+ const defaultError = (param, node, literal) => {
246
+ const kind = literal === null || parser_1.t.isNullLiteral(node)
247
+ ? 'null'
248
+ : typeof literal === 'boolean'
249
+ ? 'a boolean'
250
+ : literal !== undefined
251
+ ? 'an object'
252
+ : undefined;
253
+ return new Error(kind
254
+ ? `[plumeria] The default of "${param}" is ${kind}, which a dynamic style function cannot fall back on. Use a string or a number, or pass the value from the call.`
255
+ : `[plumeria] Cannot resolve the default of "${param}" at build time (${(0, parser_1.expressionLabel)(node)}). A dynamic style function falls back on it when the argument is undefined, so it has to be a string or a number plumeria can read. Pass the value from the call instead.`);
256
+ };
257
+ const replaceNodes = (node, replacements) => {
258
+ if (!node || typeof node !== 'object')
259
+ return node;
260
+ const replacement = replacements.get(node);
261
+ if (replacement)
262
+ return replacement;
263
+ if (Array.isArray(node))
264
+ return node.map((item) => replaceNodes(item, replacements));
265
+ const copy = {};
266
+ for (const key of Object.keys(node))
267
+ copy[key] =
268
+ key === 'span' ? node[key] : replaceNodes(node[key], replacements);
269
+ return copy;
270
+ };
271
+ const literalSource = (value) => {
272
+ if (typeof value === 'string')
273
+ return JSON.stringify(value);
274
+ const text = String(value);
275
+ return text.startsWith('-') ? `(${text})` : text;
276
+ };
277
+ const deriveArithmetic = (body, runtimeParams, varParams, defaults, evaluate) => {
278
+ const derived = [];
279
+ const names = new Map();
280
+ const replacements = new Map();
281
+ const render = (expression) => {
282
+ const node = (0, parser_1.unwrapExpression)(expression);
283
+ if (parser_1.t.isIdentifier(node) && runtimeParams.has(node.value)) {
284
+ const fallback = defaults.get(node.value);
285
+ return [
286
+ fallback === undefined
287
+ ? { param: node.value }
288
+ : { param: node.value, fallback: literalSource(fallback) },
289
+ ];
290
+ }
291
+ if (parser_1.t.isBinaryExpression(node) && ARITHMETIC.has(node.operator)) {
292
+ const left = render(node.left);
293
+ const right = render(node.right);
294
+ if (!left || !right)
295
+ return null;
296
+ return ['(', ...left, ` ${node.operator} `, ...right, ')'];
297
+ }
298
+ if (isSign(node)) {
299
+ const argument = render(node.argument);
300
+ return argument && ['(', node.operator, '(', ...argument, ')', ')'];
301
+ }
302
+ if ((0, parser_1.readsParams)(node, runtimeParams))
303
+ return null;
304
+ const value = evaluate(node);
305
+ return typeof value === 'number' ? [literalSource(value)] : null;
306
+ };
307
+ const register = (node, pieces) => {
308
+ const first = pieces.find((piece) => typeof piece !== 'string');
309
+ if (!first) {
310
+ replacements.set(node, {
311
+ type: 'NumericLiteral',
312
+ span: node.span,
313
+ value: evaluate(node),
314
+ });
315
+ return;
316
+ }
317
+ const key = JSON.stringify(pieces);
318
+ let name = names.get(key);
319
+ if (!name) {
320
+ name = `${first.param}-${derived.length + 1}`;
321
+ names.set(key, name);
322
+ derived.push({ name, pieces });
323
+ }
324
+ replacements.set(node, {
325
+ type: 'Identifier',
326
+ span: node.span,
327
+ value: name,
328
+ optional: false,
329
+ });
330
+ };
331
+ const visit = (expression) => {
332
+ const node = (0, parser_1.unwrapExpression)(expression);
333
+ if (parser_1.t.isObjectExpression(node)) {
334
+ node.properties.forEach((prop) => {
335
+ if (prop.type === 'KeyValueProperty')
336
+ visit(prop.value);
337
+ });
338
+ return;
339
+ }
340
+ if (parser_1.t.isTemplateLiteral(node)) {
341
+ node.expressions.forEach(visit);
342
+ return;
343
+ }
344
+ const arithmetic = parser_1.t.isBinaryExpression(node) && ARITHMETIC.has(node.operator);
345
+ if (!arithmetic && !isSign(node))
346
+ return;
347
+ if (!(0, parser_1.readsParams)(node, varParams))
348
+ return;
349
+ const pieces = render(node);
350
+ if (pieces) {
351
+ register(node, pieces.slice(1, -1));
352
+ return;
353
+ }
354
+ if (arithmetic && node.operator === '+') {
355
+ visit(node.left);
356
+ visit(node.right);
357
+ }
358
+ };
359
+ visit(body);
360
+ return {
361
+ body: replacements.size > 0 ? replaceNodes(body, replacements) : body,
362
+ derived,
363
+ };
364
+ };
365
+ const resolveDynamicStyle = (func, runtimeParams, staticTable, tables, providedParams, definiteParams) => {
233
366
  if (func.unsupportedParams)
234
367
  throw new Error('[plumeria] Dynamic styles require named parameters or object destructuring; array and rest parameters are not supported.');
235
368
  const tempStaticTable = Object.create(staticTable);
236
- const resolveBody = () => (0, parser_1.objectExpressionToObject)(func.body, tempStaticTable, tables.keyframesHashTable, tables.viewTransitionHashTable, tables.createThemeHashTable, tables.createThemeObjectTable, tables.createHashTable, tables.createStaticHashTable, tables.createStaticObjectTable);
369
+ const evaluate = (expr, table) => (0, parser_1.objectExpressionToObject)({
370
+ type: 'ObjectExpression',
371
+ span: func.body.span,
372
+ properties: [
373
+ {
374
+ type: 'KeyValueProperty',
375
+ key: {
376
+ type: 'Identifier',
377
+ span: func.body.span,
378
+ value: 'value',
379
+ optional: false,
380
+ },
381
+ value: expr,
382
+ },
383
+ ],
384
+ }, table, tables.keyframesHashTable, tables.viewTransitionHashTable, tables.createThemeHashTable, tables.createThemeObjectTable, tables.createHashTable, tables.createStaticHashTable, tables.createStaticObjectTable).value;
237
385
  const withDefault = Object.entries(func.defaults ?? {}).filter(([param]) => providedParams
238
386
  ? !providedParams.has(param)
239
387
  : tempStaticTable[param] === undefined);
388
+ const defaultLiterals = new Map();
389
+ withDefault.forEach(([param, expr]) => {
390
+ const node = (0, parser_1.unwrapExpression)(expr);
391
+ if (parser_1.t.isIdentifier(node) && node.value === 'undefined')
392
+ return;
393
+ const definite = definiteParams?.has(param) || !(0, parser_1.readsParams)(func.body, new Set([param]));
394
+ let literal;
395
+ try {
396
+ literal = evaluate(expr, staticTable);
397
+ }
398
+ catch (error) {
399
+ if (definite)
400
+ return;
401
+ throw error;
402
+ }
403
+ if (typeof literal === 'string' || typeof literal === 'number') {
404
+ defaultLiterals.set(param, literal);
405
+ return;
406
+ }
407
+ if (!definite)
408
+ throw defaultError(param, node, literal);
409
+ });
410
+ const holeDefaults = new Map([...defaultLiterals].filter(([param]) => !definiteParams?.has(param)));
240
411
  const cssVars = {};
241
412
  const varParams = Array.from(new Set([...runtimeParams, ...withDefault.map(([param]) => param)]));
242
- if (varParams.length > 0) {
243
- varParams.forEach((param) => (tempStaticTable[param] = param));
413
+ const runtimeSet = new Set(runtimeParams);
414
+ const constantTable = Object.create(staticTable);
415
+ defaultLiterals.forEach((literal, param) => {
416
+ if (!runtimeSet.has(param))
417
+ constantTable[param] = literal;
418
+ });
419
+ const { body, derived } = deriveArithmetic(func.body, runtimeSet, new Set(varParams), holeDefaults, (node) => {
420
+ try {
421
+ return evaluate(node, constantTable);
422
+ }
423
+ catch {
424
+ return undefined;
425
+ }
426
+ });
427
+ const resolveBody = () => (0, parser_1.objectExpressionToObject)(body, tempStaticTable, tables.keyframesHashTable, tables.viewTransitionHashTable, tables.createThemeHashTable, tables.createThemeObjectTable, tables.createHashTable, tables.createStaticHashTable, tables.createStaticObjectTable);
428
+ const varNames = [...varParams, ...derived.map(({ name }) => name)];
429
+ if (varNames.length > 0) {
430
+ varNames.forEach((name) => (tempStaticTable[name] = name));
244
431
  const hash = (0, zss_engine_2.genBase36Hash)(resolveBody(), 1, 8);
245
- varParams.forEach((param) => {
246
- const cssVar = `--${hash}-${param}`;
247
- tempStaticTable[param] = `var(${cssVar})`;
248
- cssVars[param] = cssVar;
432
+ varNames.forEach((name) => {
433
+ const cssVar = `--${hash}-${name}`;
434
+ tempStaticTable[name] = `var(${cssVar})`;
435
+ cssVars[name] = cssVar;
249
436
  });
250
437
  }
251
438
  const style = resolveBody();
252
439
  const varGroups = new Map();
253
- varParams.forEach((param) => {
254
- const cssVar = cssVars[param];
255
- varGroups.set(param, (0, exports.splitVarByUnit)(style, cssVar));
440
+ varNames.forEach((name) => {
441
+ varGroups.set(name, (0, exports.splitVarByUnit)(style, cssVars[name]));
256
442
  });
257
- withDefault.forEach(([param, expr]) => {
258
- const resolved = (0, parser_1.objectExpressionToObject)({
259
- type: 'ObjectExpression',
260
- span: func.body.span,
261
- properties: [
262
- {
263
- type: 'KeyValueProperty',
264
- key: {
265
- type: 'Identifier',
266
- span: func.body.span,
267
- value: 'value',
268
- optional: false,
269
- },
270
- value: expr,
271
- },
272
- ],
273
- }, staticTable, tables.keyframesHashTable, tables.viewTransitionHashTable, tables.createThemeHashTable, tables.createThemeObjectTable, tables.createHashTable, tables.createStaticHashTable, tables.createStaticObjectTable);
274
- const literal = resolved.value;
275
- if (typeof literal !== 'string' && typeof literal !== 'number')
276
- return;
443
+ defaultLiterals.forEach((literal, param) => {
277
444
  varGroups
278
445
  .get(param)
279
446
  .forEach(({ cssVar, unit, written }) => (0, exports.applyVarFallback)(style, cssVar, literal, { unit, written }));
280
447
  });
281
- return { style, varGroups };
448
+ return { style, varGroups, derived };
282
449
  };
283
450
  exports.resolveDynamicStyle = resolveDynamicStyle;
package/dist/parser.d.ts CHANGED
@@ -2,6 +2,7 @@ import type { CSSObject, Tables, StaticTable, KeyframesHashTable, ViewTransition
2
2
  import type { Module, Expression, CallExpression, Identifier, KeyValueProperty, StringLiteral, NumericLiteral, BooleanLiteral, ObjectExpression, MemberExpression, TemplateLiteral, BinaryExpression, UnaryExpression, ParenthesisExpression, VariableDeclaration, VariableDeclarator, ExportDeclaration, ConditionalExpression, JSXExpression, ArrowFunctionExpression, FunctionExpression } from '@swc/core';
3
3
  export declare function unwrapExpression(node: any): any;
4
4
  export declare const getRootIdentifier: (node: Expression) => string | null;
5
+ export declare const expressionLabel: (node: Expression) => string;
5
6
  export declare function resolveOriginError(node: Expression, rootName: string | null, localImports: Record<string, {
6
7
  actualPath: string;
7
8
  importedName: string;
@@ -45,6 +46,7 @@ export declare function traverse(node: Module | JSXExpression, visitor: {
45
46
  export declare function objectExpressionToObject(node: ObjectExpression, staticTable: StaticTable, keyframesHashTable: KeyframesHashTable, viewTransitionHashTable: ViewTransitionHashTable, createThemeHashTable: CreateThemeHashTable, createThemeObjectTable: CreateThemeObjectTable, createHashTable: CreateHashTable, createStaticHashTable: CreateStaticHashTable, createStaticObjectTable: CreateStaticObjectTable, resolveVariable?: (name: string) => any): CSSObject;
46
47
  export declare function collectLocalConstNodes(ast: Module): Map<string, any>;
47
48
  export declare function collectLocalConsts(ast: Module): Record<string, any>;
49
+ export declare function readsParams(node: any, params: Set<string>): boolean;
48
50
  export declare function resolveThemeSelector(node: Expression, staticTable: StaticTable, createStaticHashTable: CreateStaticHashTable, createStaticObjectTable: CreateStaticObjectTable): string;
49
51
  export declare function resolveFileError(actualPath: string, importedName: string): {
50
52
  filePath: string;
package/dist/parser.js CHANGED
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.appendSheet = exports.t = exports.getRootIdentifier = void 0;
36
+ exports.appendSheet = exports.t = exports.expressionLabel = exports.getRootIdentifier = void 0;
37
37
  exports.unwrapExpression = unwrapExpression;
38
38
  exports.resolveOriginError = resolveOriginError;
39
39
  exports.resolveComponentKey = resolveComponentKey;
@@ -41,6 +41,7 @@ exports.traverse = traverse;
41
41
  exports.objectExpressionToObject = objectExpressionToObject;
42
42
  exports.collectLocalConstNodes = collectLocalConstNodes;
43
43
  exports.collectLocalConsts = collectLocalConsts;
44
+ exports.readsParams = readsParams;
44
45
  exports.resolveThemeSelector = resolveThemeSelector;
45
46
  exports.resolveFileError = resolveFileError;
46
47
  exports.fileTableKeys = fileTableKeys;
@@ -127,12 +128,13 @@ const expressionLabel = (node) => {
127
128
  if (exports.t.isMemberExpression(node)) {
128
129
  const property = node.property;
129
130
  if (property.type === 'Identifier')
130
- return `${expressionLabel(node.object)}.${property.value}`;
131
+ return `${(0, exports.expressionLabel)(node.object)}.${property.value}`;
131
132
  if (property.type === 'Computed')
132
- return `${expressionLabel(node.object)}[${expressionLabel(property.expression)}]`;
133
+ return `${(0, exports.expressionLabel)(node.object)}[${(0, exports.expressionLabel)(property.expression)}]`;
133
134
  }
134
135
  return EXPRESSION_KINDS[node.type] ?? 'an expression';
135
136
  };
137
+ exports.expressionLabel = expressionLabel;
136
138
  const getNamespaceMember = (node, rootName) => {
137
139
  node = unwrapExpression(node);
138
140
  if (exports.t.isCallExpression(node)) {
@@ -309,7 +311,7 @@ function objectExpressionToObject(node, staticTable, keyframesHashTable, viewTra
309
311
  [root]: resolved,
310
312
  }));
311
313
  if (member === undefined)
312
- throw new Error(`[plumeria] Unknown style member: ${expressionLabel(val)} does not exist.`);
314
+ throw new Error(`[plumeria] Unknown style member: ${(0, exports.expressionLabel)(val)} does not exist.`);
313
315
  obj[key] = member;
314
316
  return;
315
317
  }
@@ -715,7 +717,7 @@ function evaluateTemplateLiteral(node, staticTable, keyframesHashTable, viewTran
715
717
  const expr = node.expressions[i];
716
718
  const evaluatedExpr = evaluateExpression(expr, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
717
719
  if (evaluatedExpr === null || typeof evaluatedExpr === 'object')
718
- throw new Error(`[plumeria] Template value cannot be resolved to a primitive: ${expressionLabel(expr)} inside \${} must resolve to a string or number at build time.`);
720
+ throw new Error(`[plumeria] Template value cannot be resolved to a primitive: ${(0, exports.expressionLabel)(expr)} inside \${} must resolve to a string or number at build time.`);
719
721
  result += String(evaluatedExpr);
720
722
  }
721
723
  }
@@ -872,7 +874,7 @@ function evaluateExpression(node, staticTable, keyframesHashTable, viewTransitio
872
874
  if (resolvedStatic !== undefined) {
873
875
  return resolvedStatic;
874
876
  }
875
- throw new Error(`[plumeria] Cannot resolve static member expression: ${expressionLabel(node)}. Its object must be a const or a value created by css.createStatic or css.createTheme.`);
877
+ throw new Error(`[plumeria] Cannot resolve static member expression: ${(0, exports.expressionLabel)(node)}. Its object must be a const or a value created by css.createStatic or css.createTheme.`);
876
878
  }
877
879
  if (exports.t.isBinaryExpression(node)) {
878
880
  return evaluateBinaryExpression(node, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
@@ -892,12 +894,12 @@ function evaluateExpression(node, staticTable, keyframesHashTable, viewTransitio
892
894
  if (node.operator === '~')
893
895
  return ~value;
894
896
  }
895
- throw new Error(`[plumeria] Unsupported unary operand for ${node.operator}: ${expressionLabel(node.argument)} must resolve to a number at build time.`);
897
+ throw new Error(`[plumeria] Unsupported unary operand for ${node.operator}: ${(0, exports.expressionLabel)(node.argument)} must resolve to a number at build time.`);
896
898
  }
897
899
  if (exports.t.isParenthesisExpression(node)) {
898
900
  return evaluateExpression(node.expression, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
899
901
  }
900
- throw new Error(`[plumeria] Unsupported expression type: ${expressionLabel(node)}. Style values must be literals, consts, or arithmetic and template expressions of them.`);
902
+ throw new Error(`[plumeria] Unsupported expression type: ${(0, exports.expressionLabel)(node)}. Style values must be literals, consts, or arithmetic and template expressions of them.`);
901
903
  }
902
904
  function resolveKeyframesTableMemberExpression(node, keyframesHashTable) {
903
905
  if (exports.t.isIdentifier(node)) {
@@ -1858,22 +1860,27 @@ function runScan(scanCwd, styleProp) {
1858
1860
  if (callArgs.some((a) => a.spread))
1859
1861
  return null;
1860
1862
  const runtime = [];
1863
+ const definite = new Set();
1861
1864
  if (func.named) {
1862
1865
  const argExpr = callArgs[0]?.expression;
1863
1866
  if (callArgs.length > 1 ||
1864
1867
  (argExpr && argExpr.type !== 'ObjectExpression'))
1865
1868
  return null;
1866
- const given = new Set();
1869
+ const given = new Map();
1867
1870
  (argExpr?.properties ?? []).forEach((prop) => {
1868
1871
  if (prop.type === 'Identifier')
1869
- given.add(prop.value);
1872
+ given.set(prop.value, prop);
1870
1873
  else if (prop.type === 'KeyValueProperty' &&
1871
1874
  (exports.t.isIdentifier(prop.key) || exports.t.isStringLiteral(prop.key)))
1872
- given.add(String(prop.key.value));
1875
+ given.set(String(prop.key.value), prop.value);
1873
1876
  });
1874
1877
  for (const { key, local } of func.named) {
1875
- if (given.has(key))
1878
+ const source = given.get(key);
1879
+ if (source) {
1876
1880
  runtime.push(local);
1881
+ if ((0, dynamicKey_1.isDefinedArgument)(source))
1882
+ definite.add(local);
1883
+ }
1877
1884
  else if (!func.defaults?.[local])
1878
1885
  return null;
1879
1886
  }
@@ -1883,14 +1890,20 @@ function runScan(scanCwd, styleProp) {
1883
1890
  return null;
1884
1891
  }
1885
1892
  else {
1886
- callArgs.forEach((_, i) => {
1893
+ callArgs.forEach((callArg, i) => {
1887
1894
  const param = func.params[i];
1888
- if (param)
1889
- runtime.push(param);
1895
+ if (!param)
1896
+ return;
1897
+ runtime.push(param);
1898
+ if ((0, dynamicKey_1.isDefinedArgument)(callArg.expression))
1899
+ definite.add(param);
1890
1900
  });
1891
1901
  }
1892
- const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime, dynamicStaticTable, dynamicStyleTables, new Set());
1893
- const hasVars = runtime.some((param) => (resolved.varGroups.get(param) ?? []).length > 0);
1902
+ const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime, dynamicStaticTable, dynamicStyleTables, new Set(), definite);
1903
+ const hasVars = [
1904
+ ...runtime,
1905
+ ...resolved.derived.map(({ name }) => name),
1906
+ ].some((param) => (resolved.varGroups.get(param) ?? []).length > 0);
1894
1907
  return { style: resolved.style, hasVars };
1895
1908
  };
1896
1909
  const resolveCallStylePropInScan = (expr) => {
package/dist/transform.js CHANGED
@@ -1200,18 +1200,40 @@ const transformSource = async (env) => {
1200
1200
  runtime.push({ param: p, source: callArg.expression });
1201
1201
  });
1202
1202
  }
1203
- const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime.map(({ param }) => param), tempStaticTable, dynamicStyleTables, providedParams);
1204
- const { style, varGroups } = resolved;
1205
- const vars = [];
1203
+ const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime.map(({ param }) => param), tempStaticTable, dynamicStyleTables, providedParams, new Set(runtime
1204
+ .filter(({ source }) => (0, dynamicKey_1.isDefinedArgument)(source))
1205
+ .map(({ param }) => param)));
1206
+ const { style, varGroups, derived } = resolved;
1207
+ const argSources = new Map();
1206
1208
  runtime.forEach(({ param, source }) => {
1207
- const groups = varGroups.get(param);
1208
- if (!groups?.length)
1209
- return;
1210
1209
  const argStart = source.span.start - baseByteOffset;
1211
1210
  const argEnd = source.span.end - baseByteOffset;
1212
- const argSource = sourceBuffer
1213
- .subarray(argStart, argEnd)
1214
- .toString('utf-8');
1211
+ argSources.set(param, sourceBuffer.subarray(argStart, argEnd).toString('utf-8'));
1212
+ });
1213
+ const runtimeSources = runtime.map(({ param }) => ({
1214
+ name: param,
1215
+ argSource: argSources.get(param),
1216
+ }));
1217
+ derived.forEach(({ name, pieces }) => {
1218
+ runtimeSources.push({
1219
+ name,
1220
+ argSource: pieces
1221
+ .map((piece) => {
1222
+ if (typeof piece === 'string')
1223
+ return piece;
1224
+ const argument = `(${argSources.get(piece.param)})`;
1225
+ return piece.fallback === undefined
1226
+ ? argument
1227
+ : `(${argument} === undefined ? ${piece.fallback} : ${argument})`;
1228
+ })
1229
+ .join(''),
1230
+ });
1231
+ });
1232
+ const vars = [];
1233
+ runtimeSources.forEach(({ name, argSource }) => {
1234
+ const groups = varGroups.get(name);
1235
+ if (!groups?.length)
1236
+ return;
1215
1237
  const maybeNumber = Number(argSource);
1216
1238
  groups.forEach(({ cssVar, prop, unit, written }) => {
1217
1239
  let valueExpr;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/utils",
3
- "version": "19.6.1",
3
+ "version": "19.6.2",
4
4
  "description": "Plumeria Utils",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",