praxis-kit 3.1.1 → 4.0.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.
@@ -1,5 +1,6 @@
1
1
  import { Plugin } from 'vite';
2
2
  import { Cardinality, ChildRulePosition, Severity } from '@praxis-kit/core';
3
+ import { DiagnosticInput } from '@praxis-kit/diagnostics';
3
4
  import ts from 'typescript';
4
5
 
5
6
  /**
@@ -34,7 +35,7 @@ type ComponentConstraint = {
34
35
 
35
36
  /** A diagnostic produced by the static analysis pass. */
36
37
  type Diagnostic = {
37
- message: string;
38
+ diagnostic: DiagnosticInput;
38
39
  /** 1-based line number in the source file. */
39
40
  line: number;
40
41
  /** 1-based column number. */
@@ -62,6 +63,78 @@ type PluginOptions = {
62
63
  severity?: Severity;
63
64
  };
64
65
 
66
+ /**
67
+ * Pure analysis entry point. Parses `code` as TypeScript/TSX, extracts
68
+ * enforcement.children constraints from factory calls, and validates JSX usage
69
+ * sites in the same file.
70
+ *
71
+ * Statically-analyzable scope:
72
+ * - Single file: component must be defined and used in the same source file.
73
+ * - Literal-only children: JSX sites that include any JSX expression ({...})
74
+ * are skipped — their child count is unknowable at build time.
75
+ * - Named const declarations: `export const X = factory(...)` and destructured
76
+ * patterns are not collected; cross-file analysis is future work.
77
+ */
78
+ declare function analyze(code: string, filename: string, options?: PluginOptions): Diagnostic[];
79
+
80
+ /**
81
+ * Compile-time variant class precomputation.
82
+ *
83
+ * Extracts `styling.variants`, `styling.defaults`, and `styling.compounds` from
84
+ * factory call ASTs, enumerates all statically-known prop combinations, computes
85
+ * the variant class string for each, and injects the resulting map as
86
+ * `styling.precomputedClasses` directly into the source.
87
+ *
88
+ * At runtime, `VariantClassResolver` checks `precomputedClasses` before
89
+ * calling CVA — a plain object lookup replaces a CVA invocation + LRU cache
90
+ * write for every covered combination.
91
+ *
92
+ * **Skipped when any of the following are true:**
93
+ * - `styling.variants` is absent or contains non-literal values
94
+ * - `styling.compounds` contains non-literal conditions or class values
95
+ * - The total number of combinations exceeds MAX_COMBINATIONS
96
+ * - The styling object already has a `precomputedClasses` property
97
+ */
98
+
99
+ /**
100
+ * Builds a precomputed class map for the given styling object literal.
101
+ *
102
+ * Returns null when static extraction is not possible (non-literal values,
103
+ * no variants, or combination count exceeds MAX_COMBINATIONS).
104
+ */
105
+ declare function buildPrecomputedClasses(stylingObj: ts.ObjectLiteralExpression): Record<string, string> | null;
106
+ /**
107
+ * Injects precomputed variant class maps into all factory calls in the given
108
+ * source file that have fully-static `styling.variants` configurations.
109
+ *
110
+ * Returns null when no factory calls with injectable variants are found.
111
+ */
112
+ declare function injectPrecomputedClasses(source: ts.SourceFile, calleeNames: ReadonlySet<string>): string | null;
113
+
114
+ /**
115
+ * Compile-time dead compound variant pruning.
116
+ *
117
+ * Removes entries from `styling.compounds` whose conditions can never fire:
118
+ * - condition key is not in `styling.variants`
119
+ * - condition value (string) is not a valid value for that variant key
120
+ * - condition value (array) has no element that is a valid value
121
+ *
122
+ * Only entries whose conditions are all statically evaluable (string/array
123
+ * literals throughout) are candidates for pruning — dynamic conditions (variable
124
+ * references, computed values) are left unchanged.
125
+ *
126
+ * Returns null if no factory calls with `styling.compounds` are found, or if
127
+ * every compound in every factory call passes the validity check.
128
+ */
129
+
130
+ /**
131
+ * Applies dead-compound pruning to the given TypeScript source file.
132
+ *
133
+ * Returns null when the file has no factory calls with `styling.compounds`, or
134
+ * when every compound entry passes validity — i.e., when no pruning is needed.
135
+ */
136
+ declare function pruneDeadCompounds(source: ts.SourceFile, calleeNames: ReadonlySet<string>): string | null;
137
+
65
138
  type ComponentTokens = {
66
139
  base: string[];
67
140
  variantClasses: string[];
@@ -80,6 +153,7 @@ type DesignTokenManifest = {
80
153
  * destructured patterns fall through (same scope as `collectConstraints`).
81
154
  */
82
155
  declare function collectFileTokens(source: ts.SourceFile, calleeNames: ReadonlySet<string>): Map<string, ComponentTokens>;
156
+ /** Builds a DesignTokenManifest from the accumulated per-component token maps, including a flat sorted `allClasses` union. */
83
157
  declare function buildManifest(allTokens: Map<string, ComponentTokens>): DesignTokenManifest;
84
158
  type DesignTokensOptions = {
85
159
  /**
@@ -108,6 +182,22 @@ type DesignTokensOptions = {
108
182
  */
109
183
  declare function designTokensPlugin(options?: DesignTokensOptions): Plugin;
110
184
 
185
+ type ImportBinding = {
186
+ /** The exported name in the source module (the name before `as`, if any). */
187
+ readonly importedName: string;
188
+ /** The module specifier string (e.g. `'./Button'`). */
189
+ readonly specifier: string;
190
+ };
191
+
192
+ /**
193
+ * Applies the asChild → render-prop transform to the given TypeScript source
194
+ * file and returns the printed output.
195
+ *
196
+ * Returns null if no `asChild` attribute is found in the source (fast path —
197
+ * avoids parsing overhead for files that don't use the pattern).
198
+ */
199
+ declare function transformAsChild(source: ts.SourceFile): string | null;
200
+
111
201
  /**
112
202
  * Compile-time static composition transform.
113
203
  *
@@ -169,125 +259,6 @@ declare function extractStaticComponents(source: ts.SourceFile, calleeNames: Rea
169
259
  */
170
260
  declare function composeStatically(source: ts.SourceFile, calleeNames: ReadonlySet<string>, importedComponents?: ReadonlyMap<string, StaticComponent>): string | null;
171
261
 
172
- type ImportBinding = {
173
- /** The exported name in the source module (the name before `as`, if any). */
174
- readonly importedName: string;
175
- /** The module specifier string (e.g. `'./Button'`). */
176
- readonly specifier: string;
177
- };
178
-
179
- /**
180
- * Pure analysis entry point. Parses `code` as TypeScript/TSX, extracts
181
- * enforcement.children constraints from factory calls, and validates JSX usage
182
- * sites in the same file.
183
- *
184
- * Statically-analyzable scope:
185
- * - Single file: component must be defined and used in the same source file.
186
- * - Literal-only children: JSX sites that include any JSX expression ({...})
187
- * are skipped — their child count is unknowable at build time.
188
- * - Named const declarations: `export const X = factory(...)` and destructured
189
- * patterns are not collected; cross-file analysis is future work.
190
- */
191
- declare function analyze(code: string, filename: string, options?: PluginOptions): Diagnostic[];
192
-
193
- /**
194
- * Compile-time asChild → render-prop transform.
195
- *
196
- * Rewrites JSX usage sites of the form:
197
- * <Component asChild ...props>
198
- * <childTag ...childProps>children</childTag>
199
- * </Component>
200
- *
201
- * to the render-prop form:
202
- * <Component render={(_p) => <childTag ...childProps {..._p} />} ...props />
203
- *
204
- * The render-prop form eliminates the Slot/cloneElement/mergeProps path at
205
- * runtime — resolved props are passed directly to the render callback with no
206
- * element cloning.
207
- *
208
- * **Safety conditions** — the transform is skipped if any of these are true:
209
- * 1. The child has a dynamic `className` expression (cannot merge safely).
210
- * A string-literal `className` IS handled: the transform generates
211
- * `{..._p, className: _p.className + ' childCls'}`.
212
- * 2. The child has a bare `style` or `on*` attribute without an initializer.
213
- * Static object-literal and expression-valued `style` props are merged:
214
- * `style={{..._p.style, ...childStyle}}`. Event handlers are composed:
215
- * `onClick={(_e) => { (childHandler)(_e); _p.onClick?.(_e); }}`.
216
- * 3. The component name starts with a lowercase letter (HTML intrinsic — not
217
- * a polymorphic component).
218
- * 4. There are zero or more than one meaningful child elements.
219
- *
220
- * The transform is conservative: any condition that is not statically clear
221
- * causes the node to be left unchanged.
222
- */
223
-
224
- /**
225
- * Applies the asChild → render-prop transform to the given TypeScript source
226
- * file and returns the printed output.
227
- *
228
- * Returns null if no `asChild` attribute is found in the source (fast path —
229
- * avoids parsing overhead for files that don't use the pattern).
230
- */
231
- declare function transformAsChild(source: ts.SourceFile): string | null;
232
-
233
- /**
234
- * Compile-time dead compound variant pruning.
235
- *
236
- * Removes entries from `styling.compounds` whose conditions can never fire:
237
- * - condition key is not in `styling.variants`
238
- * - condition value (string) is not a valid value for that variant key
239
- * - condition value (array) has no element that is a valid value
240
- *
241
- * Only entries whose conditions are all statically evaluable (string/array
242
- * literals throughout) are candidates for pruning — dynamic conditions (variable
243
- * references, computed values) are left unchanged.
244
- *
245
- * Returns null if no factory calls with `styling.compounds` are found, or if
246
- * every compound in every factory call passes the validity check.
247
- */
248
-
249
- /**
250
- * Applies dead-compound pruning to the given TypeScript source file.
251
- *
252
- * Returns null when the file has no factory calls with `styling.compounds`, or
253
- * when every compound entry passes validity — i.e., when no pruning is needed.
254
- */
255
- declare function pruneDeadCompounds(source: ts.SourceFile, calleeNames: ReadonlySet<string>): string | null;
256
-
257
- /**
258
- * Compile-time variant class precomputation.
259
- *
260
- * Extracts `styling.variants`, `styling.defaults`, and `styling.compounds` from
261
- * factory call ASTs, enumerates all statically-known prop combinations, computes
262
- * the variant class string for each, and injects the resulting map as
263
- * `styling.precomputedClasses` directly into the source.
264
- *
265
- * At runtime, `VariantClassResolver` checks `precomputedClasses` before
266
- * calling CVA — a plain object lookup replaces a CVA invocation + LRU cache
267
- * write for every covered combination.
268
- *
269
- * **Skipped when any of the following are true:**
270
- * - `styling.variants` is absent or contains non-literal values
271
- * - `styling.compounds` contains non-literal conditions or class values
272
- * - The total number of combinations exceeds MAX_COMBINATIONS
273
- * - The styling object already has a `precomputedClasses` property
274
- */
275
-
276
- /**
277
- * Builds a precomputed class map for the given styling object literal.
278
- *
279
- * Returns null when static extraction is not possible (non-literal values,
280
- * no variants, or combination count exceeds MAX_COMBINATIONS).
281
- */
282
- declare function buildPrecomputedClasses(stylingObj: ts.ObjectLiteralExpression): Record<string, string> | null;
283
- /**
284
- * Injects precomputed variant class maps into all factory calls in the given
285
- * source file that have fully-static `styling.variants` configurations.
286
- *
287
- * Returns null when no factory calls with injectable variants are found.
288
- */
289
- declare function injectPrecomputedClasses(source: ts.SourceFile, calleeNames: ReadonlySet<string>): string | null;
290
-
291
262
  /**
292
263
  * Vite plugin that performs static enforcement.children cardinality checks at
293
264
  * build time for components created with createContractComponent.