postcss-calc 11.1.1 → 11.2.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.
Files changed (47) hide show
  1. package/README.md +40 -18
  2. package/package.json +16 -11
  3. package/src/index.js +8 -5
  4. package/src/lib/analyze.js +228 -0
  5. package/src/lib/block-index.js +118 -0
  6. package/src/lib/calculation-type.js +25 -0
  7. package/src/lib/compile.js +80 -0
  8. package/src/lib/convertUnits.js +15 -1
  9. package/src/lib/functions.js +364 -0
  10. package/src/lib/limits.js +49 -0
  11. package/src/lib/node.js +85 -39
  12. package/src/lib/opaque.js +20 -0
  13. package/src/lib/parser.js +493 -257
  14. package/src/lib/print.js +75 -0
  15. package/src/lib/regex.js +4 -0
  16. package/src/lib/scan.js +61 -0
  17. package/src/lib/serialize.js +574 -207
  18. package/src/lib/simplify/abs.js +1 -1
  19. package/src/lib/simplify/bucket.js +18 -23
  20. package/src/lib/simplify/call.js +6 -92
  21. package/src/lib/simplify/product.js +7 -4
  22. package/src/lib/simplify/round.js +4 -4
  23. package/src/lib/simplify/sum.js +22 -10
  24. package/src/lib/simplify.js +20 -5
  25. package/src/reduce.js +46 -118
  26. package/types/index.d.ts +4 -0
  27. package/types/lib/analyze.d.ts +18 -0
  28. package/types/lib/block-index.d.ts +35 -0
  29. package/types/lib/calculation-type.d.ts +18 -0
  30. package/types/lib/compile.d.ts +37 -0
  31. package/types/lib/convertUnits.d.ts +8 -1
  32. package/types/lib/functions.d.ts +40 -0
  33. package/types/lib/limits.d.ts +8 -0
  34. package/types/lib/node.d.ts +31 -9
  35. package/types/lib/opaque.d.ts +9 -0
  36. package/types/lib/parser.d.ts +47 -49
  37. package/types/lib/print.d.ts +16 -0
  38. package/types/lib/regex.d.ts +2 -0
  39. package/types/lib/scan.d.ts +35 -0
  40. package/types/lib/serialize.d.ts +19 -2
  41. package/types/lib/simplify/bucket.d.ts +2 -2
  42. package/types/lib/simplify/call.d.ts +4 -18
  43. package/types/lib/simplify/round.d.ts +3 -1
  44. package/types/lib/simplify.d.ts +5 -2
  45. package/types/reduce.d.ts +47 -6
  46. package/src/lib/tokenizer.js +0 -139
  47. package/types/lib/tokenizer.d.ts +0 -32
@@ -0,0 +1,18 @@
1
+ import { analyze } from './analyze.js';
2
+ import { MAX_CALCULATION_DEPTH, checkCalculationDepth } from './limits.js';
3
+ export type Node = import('./node.js').Node;
4
+ export type CalculationType = {
5
+ kind: 'number';
6
+ } | {
7
+ kind: 'dimension';
8
+ base: string | null;
9
+ } | {
10
+ kind: 'unknown';
11
+ } | {
12
+ kind: 'failure';
13
+ };
14
+ /** @typedef {import('./node.js').Node} Node */
15
+ /** @typedef {{kind: 'number'} | {kind: 'dimension', base: string | null} | {kind: 'unknown'} | {kind: 'failure'}} CalculationType */
16
+ /** @param {Node} node @return {CalculationType} */
17
+ declare function checkCalculationType(node: Node): CalculationType;
18
+ export { MAX_CALCULATION_DEPTH, checkCalculationDepth, checkCalculationType, analyze, };
@@ -0,0 +1,37 @@
1
+ export type Candidate = import('./scan.js').Candidate;
2
+ export type ResolvedReduceCalcOptions = import('../reduce.js').ResolvedReduceCalcOptions;
3
+ export type Replacement = import('../reduce.js').Replacement;
4
+ export type CSSToken = import('@csstools/css-tokenizer').CSSToken;
5
+ export type BlockIndex = ReturnType<typeof import('./block-index.js').indexBlocks>;
6
+ export type CompileContext = {
7
+ options: ResolvedReduceCalcOptions;
8
+ value: string;
9
+ tokens: CSSToken[];
10
+ index: BlockIndex;
11
+ };
12
+ /** @typedef {import('./scan.js').Candidate} Candidate */
13
+ /** @typedef {import('../reduce.js').ResolvedReduceCalcOptions} ResolvedReduceCalcOptions */
14
+ /** @typedef {import('../reduce.js').Replacement} Replacement */
15
+ /** @typedef {import('@csstools/css-tokenizer').CSSToken} CSSToken */
16
+ /** @typedef {ReturnType<typeof import('./block-index.js').indexBlocks>} BlockIndex */
17
+ /** @typedef {{options: ResolvedReduceCalcOptions, value: string, tokens: CSSToken[], index: BlockIndex}} CompileContext */
18
+ /**
19
+ * Parse, analyze, and simplify one candidate. Analysis is the validity/status
20
+ * gate over the original tree; simplification then runs independently as a
21
+ * composable AST transformation that may synthesize nodes.
22
+ *
23
+ * @param {Candidate} candidate
24
+ * @param {CompileContext} ctx
25
+ * @return {Replacement}
26
+ */
27
+ declare function compileCandidate(candidate: Candidate, ctx: CompileContext): Replacement;
28
+ /**
29
+ * Compile candidates independently so one malformed calculation is preserved
30
+ * without preventing unrelated candidates from being reduced.
31
+ *
32
+ * @param {Candidate[]} candidates
33
+ * @param {CompileContext} ctx
34
+ * @return {Replacement[]}
35
+ */
36
+ declare function compileCandidates(candidates: Candidate[], ctx: CompileContext): Replacement[];
37
+ export { compileCandidate, compileCandidates };
@@ -14,4 +14,11 @@ declare function baseOf(unit: string): BaseType | null;
14
14
  * @return {number | null}
15
15
  */
16
16
  declare function convert(value: number, from: string, to: string): number | null;
17
- export { baseOf, convert };
17
+ /**
18
+ * Return a base type only for units present in the static conversion table.
19
+ * Units with context-dependent values (em, rem, vw, etc.) return null.
20
+ * @param {string} unit
21
+ * @return {BaseType | null}
22
+ */
23
+ declare function staticBaseOf(unit: string): BaseType | null;
24
+ export { baseOf, staticBaseOf, convert };
@@ -0,0 +1,40 @@
1
+ export type Node = import('./node.js').Node;
2
+ export type CalculationType = {
3
+ kind: 'number';
4
+ } | {
5
+ kind: 'dimension';
6
+ base: string | null;
7
+ } | {
8
+ kind: 'unknown';
9
+ } | {
10
+ kind: 'failure';
11
+ };
12
+ export type MathSimplifier = (name: string, args: Node[]) => Node;
13
+ export type TypeAnalyzer = (args: CalculationType[], nodes: Node[]) => CalculationType;
14
+ export type MathFunction = {
15
+ analyze: TypeAnalyzer;
16
+ simplify?: MathSimplifier;
17
+ isKeyword?: (node: Node, index: number) => boolean;
18
+ calculation?: boolean;
19
+ };
20
+ /** @param {CalculationType} type @return {boolean} */
21
+ declare function isFailure(type: CalculationType): boolean;
22
+ /** @param {CalculationType} a @param {CalculationType} b @return {CalculationType} */
23
+ declare function addTypes(a: CalculationType, b: CalculationType): CalculationType;
24
+ declare const mathFunctions: Map<string, MathFunction>;
25
+ /**
26
+ * @param {string} name
27
+ * @return {{normalizedName: string, definition: MathFunction} | undefined}
28
+ */
29
+ declare function lookupMathFunction(name: string): {
30
+ normalizedName: string;
31
+ definition: MathFunction;
32
+ } | undefined;
33
+ declare const QUICK_MATH_TEST: RegExp;
34
+ /** @param {string} name @return {boolean} */
35
+ declare function isCalculationFunction(name: string): boolean;
36
+ /** @param {string} name @return {boolean} */
37
+ declare function isSupportedMathFunction(name: string): boolean;
38
+ /** @param {string} value @return {boolean} */
39
+ declare function hasPotentialMathFunction(value: string): boolean;
40
+ export { addTypes, mathFunctions, lookupMathFunction, QUICK_MATH_TEST, isFailure, isCalculationFunction, isSupportedMathFunction, hasPotentialMathFunction, };
@@ -0,0 +1,8 @@
1
+ /** @typedef {import('./node.js').Node} Node */
2
+ export type Node = import('./node.js').Node;
3
+ declare const MAX_CALCULATION_DEPTH = 1024;
4
+ /** @param {number} depth @return {void} */
5
+ declare function assertDepth(depth: number): void;
6
+ /** @param {Node} node @param {number} [depth] @return {void} */
7
+ declare function checkCalculationDepth(node: Node, depth?: number): void;
8
+ export { MAX_CALCULATION_DEPTH, assertDepth, checkCalculationDepth };
@@ -6,15 +6,25 @@ export type Dim = {
6
6
  type: 'Dim';
7
7
  value: number;
8
8
  unit: string;
9
+ rawUnit?: string;
9
10
  };
10
11
  export type Ident = {
11
12
  type: 'Ident';
12
13
  name: string;
14
+ rawName?: string;
13
15
  };
14
16
  export type Call = {
15
17
  type: 'Call';
16
18
  name: string;
17
19
  args: Node[];
20
+ rawName?: string;
21
+ };
22
+ export type OpaqueComponent = string | Node | OpaqueComponent[];
23
+ export type OpaqueCall = {
24
+ type: 'OpaqueCall';
25
+ name: string;
26
+ components: OpaqueComponent[];
27
+ rawName?: string;
18
28
  };
19
29
  export type SumTerm = {
20
30
  sign: 1 | -1;
@@ -33,17 +43,19 @@ export type Product = {
33
43
  type: 'Product';
34
44
  factors: ProductFactor[];
35
45
  };
36
- export type Node = Num | Dim | Ident | Call | Sum | Product;
46
+ export type Node = Num | Dim | Ident | Call | OpaqueCall | Sum | Product;
37
47
  /**
38
48
  * @typedef {{type: 'Num', value: number}} Num
39
- * @typedef {{type: 'Dim', value: number, unit: string}} Dim
40
- * @typedef {{type: 'Ident', name: string}} Ident
41
- * @typedef {{type: 'Call', name: string, args: Node[]}} Call
49
+ * @typedef {{type: 'Dim', value: number, unit: string, rawUnit?: string}} Dim
50
+ * @typedef {{type: 'Ident', name: string, rawName?: string}} Ident
51
+ * @typedef {{type: 'Call', name: string, args: Node[], rawName?: string}} Call
52
+ * @typedef {string | Node | OpaqueComponent[]} OpaqueComponent
53
+ * @typedef {{type: 'OpaqueCall', name: string, components: OpaqueComponent[], rawName?: string}} OpaqueCall
42
54
  * @typedef {{sign: 1 | -1, node: Node}} SumTerm Sign is always +1 when node is Num or Dim.
43
55
  * @typedef {{type: 'Sum', terms: SumTerm[], grouped?: boolean}} Sum
44
56
  * @typedef {{exponent: 1 | -1, node: Node}} ProductFactor exponent +1 = numerator, -1 = denominator.
45
57
  * @typedef {{type: 'Product', factors: ProductFactor[]}} Product
46
- * @typedef {Num | Dim | Ident | Call | Sum | Product} Node
58
+ * @typedef {Num | Dim | Ident | Call | OpaqueCall | Sum | Product} Node
47
59
  */
48
60
  /**
49
61
  * @param {number} value
@@ -53,20 +65,30 @@ declare function num(value: number): Num;
53
65
  /**
54
66
  * @param {number} value
55
67
  * @param {string} unit
68
+ * @param {string} [rawUnit]
56
69
  * @return {Dim}
57
70
  */
58
- declare function dim(value: number, unit: string): Dim;
71
+ declare function dim(value: number, unit: string, rawUnit?: string): Dim;
59
72
  /**
60
73
  * @param {string} name
74
+ * @param {string} [rawName]
61
75
  * @return {Ident}
62
76
  */
63
- declare function ident(name: string): Ident;
77
+ declare function ident(name: string, rawName?: string): Ident;
64
78
  /**
65
79
  * @param {string} name
66
80
  * @param {Node[]} args
81
+ * @param {string} [rawName]
67
82
  * @return {Call}
68
83
  */
69
- declare function call(name: string, args: Node[]): Call;
84
+ declare function call(name: string, args: Node[], rawName?: string): Call;
85
+ /**
86
+ * @param {string} name
87
+ * @param {OpaqueComponent[]} components
88
+ * @param {string} [rawName]
89
+ * @return {OpaqueCall}
90
+ */
91
+ declare function opaqueCall(name: string, components: OpaqueComponent[], rawName?: string): OpaqueCall;
70
92
  /**
71
93
  * @param {SumTerm[]} rawTerms
72
94
  * @return {Node}
@@ -83,4 +105,4 @@ declare function mkProduct(rawFactors: ProductFactor[]): Node;
83
105
  * @return {Node}
84
106
  */
85
107
  declare function negate(node: Node): Node;
86
- export { num, dim, ident, call, mkSum, mkProduct, negate };
108
+ export { num, dim, ident, call, opaqueCall, mkSum, mkProduct, negate };
@@ -0,0 +1,9 @@
1
+ /** @typedef {import('./node.js').Node} Node */
2
+ /** @typedef {import('./node.js').OpaqueComponent} OpaqueComponent */
3
+ export type Node = import('./node.js').Node;
4
+ export type OpaqueComponent = import('./node.js').OpaqueComponent;
5
+ /** @param {OpaqueComponent[]} components @param {(node: Node) => Node} simplify @return {OpaqueComponent[]} */
6
+ declare function simplifyComponents(components: OpaqueComponent[], simplify: (node: Node) => Node): OpaqueComponent[];
7
+ /** @param {OpaqueComponent[]} components @param {string[]} buffer @param {(node: Node, buffer: string[]) => void} serialize @return {void} */
8
+ declare function serializeComponents(components: OpaqueComponent[], buffer: string[], serialize: (node: Node, buffer: string[]) => void): void;
9
+ export { simplifyComponents, serializeComponents };
@@ -1,51 +1,49 @@
1
- export type Token = import('./tokenizer.js').Token;
2
- export type TokenType = import('./tokenizer.js').TokenType;
1
+ export type CSSToken = import('@csstools/css-tokenizer').CSSToken;
3
2
  export type Node = import('./node.js').Node;
4
- export type PrefixParselet = (p: Parser, token: Token) => Node;
5
- declare class Parser {
6
- /** @private */
7
- i;
8
- /** @private @readonly */
9
- tokens;
10
- /**
11
- * @param {Token[]} tokens
12
- */
13
- constructor(tokens: Token[]);
14
- /** @return {Token} */
15
- peek(): Token;
16
- /** @return {Token} */
17
- next(): Token;
18
- /**
19
- * @param {TokenType} type
20
- * @param {string} [value]
21
- * @return {Token}
22
- */
23
- expect(type: TokenType, value?: string): Token;
24
- /**
25
- * @param {string} value
26
- * @param {string} [value2]
27
- * @return {boolean}
28
- */
29
- isPunct(value: string, value2?: string): boolean;
30
- /**
31
- * @param {string} value
32
- * @return {boolean}
33
- */
34
- matchPunct(value: string): boolean;
35
- /**
36
- * @param {string} value
37
- * @return {Token}
38
- */
39
- expectPunct(value: string): Token;
40
- /**
41
- * @param {number} [minBp]
42
- * @return {Node}
43
- */
44
- parseExpr(minBp?: number): Node;
45
- }
46
- /**
47
- * @param {Token[]} tokens
48
- * @return {Node}
49
- */
50
- declare function parse(tokens: Token[]): Node;
3
+ export type OpaqueComponent = import('./node.js').OpaqueComponent;
4
+ export type BlockIndex = ReturnType<typeof import('./block-index.js').indexBlocks>;
5
+ export type TokenBase = {
6
+ raw: string;
7
+ pos: number;
8
+ ws: boolean;
9
+ index: number;
10
+ };
11
+ export type NumberToken = TokenBase & {
12
+ type: 'number';
13
+ value: number;
14
+ signCharacter?: '+' | '-';
15
+ };
16
+ export type DimensionToken = TokenBase & {
17
+ type: 'dimension';
18
+ value: number;
19
+ unit: string;
20
+ rawUnit: string;
21
+ signCharacter?: '+' | '-';
22
+ };
23
+ export type IdentToken = TokenBase & {
24
+ type: 'ident';
25
+ value: string;
26
+ };
27
+ export type FunctionToken = TokenBase & {
28
+ type: 'function';
29
+ value: string;
30
+ };
31
+ export type Punctuator = '(' | ')' | ',' | '+' | '-' | '*' | '/';
32
+ export type PunctToken = TokenBase & {
33
+ type: 'punct';
34
+ value: Punctuator;
35
+ };
36
+ export type EofToken = TokenBase & {
37
+ type: 'eof';
38
+ value: '';
39
+ raw: '';
40
+ };
41
+ export type Token = NumberToken | DimensionToken | IdentToken | FunctionToken | PunctToken | EofToken;
42
+ export type ParseInput = Readonly<{
43
+ tokens: CSSToken[];
44
+ end: number;
45
+ index: BlockIndex;
46
+ }>;
47
+ /** @param {CSSToken[]} tokens @param {number} start @param {number} end @param {BlockIndex} index @return {Node} */
48
+ declare function parse(tokens: CSSToken[], start: number, end: number, index: BlockIndex): Node;
51
49
  export { parse };
@@ -0,0 +1,16 @@
1
+ export type ResolvedReduceCalcOptions = import('../reduce.js').ResolvedReduceCalcOptions;
2
+ export type Replacement = import('../reduce.js').Replacement;
3
+ export type SerializeOptions = import('./serialize.js').SerializeOptions;
4
+ /**
5
+ * Serialize compiled candidates and splice the resulting text into the
6
+ * original source. Replacements are already non-overlapping because the
7
+ * finder treats a supported outer function as one range.
8
+ *
9
+ * @param {string} value
10
+ * @param {Replacement[]} replacements
11
+ * @param {ResolvedReduceCalcOptions} options
12
+ * @param {SerializeOptions} serializeOptions
13
+ * @return {string}
14
+ */
15
+ declare function applyReplacements(value: string, replacements: Replacement[], options: ResolvedReduceCalcOptions, serializeOptions: SerializeOptions): string;
16
+ export { applyReplacements };
@@ -0,0 +1,2 @@
1
+ declare const CSS_NUMBER_PREFIX: RegExp;
2
+ export { CSS_NUMBER_PREFIX };
@@ -0,0 +1,35 @@
1
+ export type Candidate = {
2
+ name: string;
3
+ normalizedName: string;
4
+ start: number;
5
+ end: number;
6
+ rootSpelling: string;
7
+ calculation: boolean;
8
+ sliceStart: number;
9
+ sliceEnd: number;
10
+ closed: boolean;
11
+ };
12
+ /**
13
+ * @typedef {object} Candidate
14
+ * @property {string} name
15
+ * @property {string} normalizedName
16
+ * @property {number} start
17
+ * @property {number} end
18
+ * @property {string} rootSpelling
19
+ * @property {boolean} calculation
20
+ * @property {number} sliceStart
21
+ * @property {number} sliceEnd
22
+ * @property {boolean} closed
23
+ */
24
+ /**
25
+ * Find complete supported math-function ranges. A supported function is
26
+ * treated as one candidate even when parsing it later fails, so nested
27
+ * calculations cannot produce partial output for an invalid outer function.
28
+ *
29
+ * @param {string} value
30
+ * @param {import('@csstools/css-tokenizer').CSSToken[]} tokens
31
+ * @param {ReturnType<typeof import('./block-index.js').indexBlocks>} index
32
+ * @return {Candidate[]}
33
+ */
34
+ declare function findCalculations(value: string, tokens: import('@csstools/css-tokenizer').CSSToken[], index: ReturnType<typeof import('./block-index.js').indexBlocks>): Candidate[];
35
+ export { findCalculations };
@@ -12,9 +12,13 @@ export type SerializeOptions = {
12
12
  */
13
13
  calcName?: string;
14
14
  /**
15
- * Serialize finite negative scalars without a wrapper. Internal selector-only mode.
15
+ * Deprecated alias for `unwrapSingleValue`.
16
16
  */
17
17
  unwrapSingleNegativeNumber?: boolean;
18
+ /**
19
+ * Serialize fully resolved finite scalar results without calculation syntax.
20
+ */
21
+ unwrapSingleValue?: boolean;
18
22
  };
19
23
  /**
20
24
  * @param {Node} node
@@ -22,4 +26,17 @@ export type SerializeOptions = {
22
26
  * @return {string}
23
27
  */
24
28
  declare function serialize(node: Node, opts?: SerializeOptions): string;
25
- export { serialize };
29
+ /**
30
+ * @param {{tree: Node, status: 'resolved' | 'unresolved', rootName: string, rootSpelling: string, calculation?: boolean, original?: string}} result
31
+ * @param {SerializeOptions} [opts]
32
+ * @return {string}
33
+ */
34
+ declare function serializeResult(result: {
35
+ tree: Node;
36
+ status: 'resolved' | 'unresolved';
37
+ rootName: string;
38
+ rootSpelling: string;
39
+ calculation?: boolean;
40
+ original?: string;
41
+ }, opts?: SerializeOptions): string;
42
+ export { serialize, serializeResult };
@@ -1,20 +1,20 @@
1
1
  export type UnitBucket = {
2
2
  unit: string;
3
+ rawUnit?: string;
3
4
  total: number;
4
5
  /**
5
6
  * largest |term| accumulated into `total`, for noise detection
6
7
  */
7
8
  scale: number;
8
9
  base: import('../convertUnits.js').BaseType | null;
9
- order: number;
10
10
  };
11
11
  /**
12
12
  * @typedef {object} UnitBucket
13
13
  * @property {string} unit
14
+ * @property {string} [rawUnit]
14
15
  * @property {number} total
15
16
  * @property {number} scale largest |term| accumulated into `total`, for noise detection
16
17
  * @property {import('../convertUnits.js').BaseType | null} base
17
- * @property {number} order
18
18
  */
19
19
  /** Mutates `buckets` in place — totals of survivor buckets accumulate the
20
20
  * converted values of merged neighbors. Caller must not reuse the input.
@@ -1,23 +1,9 @@
1
1
  export type Node = import('../node.js').Node;
2
2
  export type SimplifyFn = import('../simplify.js').SimplifyFn;
3
3
  export type MathSimplifier = (name: string, args: Node[]) => Node;
4
- declare const QUICK_MATH_TEST: RegExp;
5
- /**
6
- * Fast check to determine whether a CSS component value could contain
7
- * a supported calculation or math function call (or an escape sequence
8
- * that could decode to one).
9
- *
10
- * @param {string} value
11
- * @return {boolean}
12
- */
13
- declare function hasPotentialMathFunction(value: string): boolean;
14
- /**
15
- * Whether a bare CSS math function has an implemented simplifier.
16
- *
17
- * @param {string} name
18
- * @return {boolean}
19
- */
20
- declare function isSupportedMathFunction(name: string): boolean;
4
+ /** @typedef {import('../node.js').Node} Node */
5
+ /** @typedef {import('../simplify.js').SimplifyFn} SimplifyFn */
6
+ /** @typedef {(name: string, args: Node[]) => Node} MathSimplifier */
21
7
  /**
22
8
  * @param {Extract<Node, { type: 'Call' }>} node
23
9
  * @param {SimplifyFn} simplify
@@ -26,4 +12,4 @@ declare function isSupportedMathFunction(name: string): boolean;
26
12
  declare function simplifyCall(node: Extract<Node, {
27
13
  type: 'Call';
28
14
  }>, simplify: SimplifyFn): Node;
29
- export { isSupportedMathFunction, simplifyCall, hasPotentialMathFunction, QUICK_MATH_TEST, };
15
+ export { simplifyCall };
@@ -1,4 +1,6 @@
1
1
  export type Node = import('../node.js').Node;
2
+ /** @typedef {import('../node.js').Node} Node */
3
+ declare const ROUND_STRATEGIES: Set<string>;
2
4
  export type RoundStrategy = 'nearest' | 'up' | 'down' | 'to-zero';
3
5
  /** @typedef {'nearest' | 'up' | 'down' | 'to-zero'} RoundStrategy */
4
6
  /**
@@ -6,4 +8,4 @@ export type RoundStrategy = 'nearest' | 'up' | 'down' | 'to-zero';
6
8
  * @return {Node}
7
9
  */
8
10
  declare function simplifyRound(args: Node[]): Node;
9
- export { simplifyRound };
11
+ export { ROUND_STRATEGIES, simplifyRound };
@@ -3,13 +3,16 @@ export type SimplifyFn = (node: Node) => Node;
3
3
  /**
4
4
  * @typedef {import('./node.js').Node} Node
5
5
  *
6
- * Recursive simplifier reference, threaded into Sum/Product/Call. Lets
6
+ * Recursive simplifier reference, threaded into Sum/Product/Call/OpaqueCall. Lets
7
7
  * leaf fold modules avoid circular imports of the entry function.
8
8
  * @typedef {(node: Node) => Node} SimplifyFn
9
9
  */
10
10
  /**
11
+ * Simplify is an independent, composable AST transformation. It may
12
+ * synthesize canonical nodes while preserving the Node -> Node contract.
11
13
  * @param {Node} node
14
+ * @param {number} [depth]
12
15
  * @return {Node}
13
16
  */
14
- declare function simplify(node: Node): Node;
17
+ declare function simplify(node: Node, depth?: number): Node;
15
18
  export { simplify };
package/types/reduce.d.ts CHANGED
@@ -1,11 +1,14 @@
1
- import { hasPotentialMathFunction, QUICK_MATH_TEST } from './lib/simplify/call.js';
2
1
  export type ReduceCalcOptions = {
3
2
  precision?: number | false;
4
3
  warnWhenCannotResolve?: boolean;
5
4
  /**
6
- * Serialize finite negative results without a `calc()` wrapper. Defaults to `false`.
5
+ * Deprecated alias for `unwrapSingleValue`.
7
6
  */
8
7
  unwrapSingleNegativeNumber?: boolean;
8
+ /**
9
+ * Serialize fully resolved finite scalar results without calculation syntax. Defaults to `false`.
10
+ */
11
+ unwrapSingleValue?: boolean;
9
12
  /**
10
13
  * Invoked when parse/simplify throws.
11
14
  */
@@ -20,14 +23,53 @@ export type TransformContext = {
20
23
  options: ResolvedReduceCalcOptions;
21
24
  value: string;
22
25
  tokens: import('@csstools/css-tokenizer').CSSToken[];
23
- replacements: Replacement[];
24
26
  };
25
27
  export type Replacement = {
26
28
  start: number;
27
29
  end: number;
28
- node: import('./lib/node.js').Node;
29
- calcName: string;
30
+ result: CalculationResult;
31
+ };
32
+ export type CalculationResult = {
33
+ tree: import('./lib/node.js').Node;
34
+ status: 'resolved' | 'unresolved';
35
+ rootName: string;
36
+ rootSpelling: string;
37
+ calculation: boolean;
38
+ original: string | undefined;
30
39
  };
40
+ /**
41
+ * @typedef {object} ReduceCalcOptions
42
+ * @property {number | false} [precision]
43
+ * @property {boolean} [warnWhenCannotResolve]
44
+ * @property {boolean} [unwrapSingleNegativeNumber] Deprecated alias for `unwrapSingleValue`.
45
+ * @property {boolean} [unwrapSingleValue] Serialize fully resolved finite scalar results without calculation syntax. Defaults to `false`.
46
+ * @property {(error: Error, input: string) => void} [onParseError] Invoked when parse/simplify throws.
47
+ * @property {(message: string) => void} [onWarn] Invoked when `warnWhenCannotResolve` is set and an expression cannot be reduced to a single value.
48
+ */
49
+ /** @typedef {Required<Omit<ReduceCalcOptions, 'onParseError' | 'onWarn'>> & Pick<ReduceCalcOptions, 'onParseError' | 'onWarn'>} ResolvedReduceCalcOptions */
50
+ /**
51
+ * Fields threaded through the internal token-range walk.
52
+ *
53
+ * @typedef {object} TransformContext
54
+ * @property {ResolvedReduceCalcOptions} options
55
+ * @property {string} value
56
+ * @property {import('@csstools/css-tokenizer').CSSToken[]} tokens
57
+ */
58
+ /**
59
+ * @typedef {object} Replacement
60
+ * @property {number} start
61
+ * @property {number} end
62
+ * @property {CalculationResult} result
63
+ */
64
+ /**
65
+ * @typedef {object} CalculationResult
66
+ * @property {import('./lib/node.js').Node} tree
67
+ * @property {'resolved' | 'unresolved'} status
68
+ * @property {string} rootName
69
+ * @property {string} rootSpelling
70
+ * @property {boolean} calculation
71
+ * @property {string | undefined} original
72
+ */
31
73
  /**
32
74
  * Simplify every supported CSS math function in a component-value string.
33
75
  * Text outside those functions is preserved byte-for-byte.
@@ -37,5 +79,4 @@ export type Replacement = {
37
79
  * @return {string}
38
80
  */
39
81
  declare function reduceCalc(value: string, opts?: ReduceCalcOptions): string;
40
- export { QUICK_MATH_TEST, hasPotentialMathFunction };
41
82
  export default reduceCalc;