chaincss 2.1.39 → 2.3.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/compiler/accessibility-engine.d.ts +57 -0
- package/dist/compiler/constraint-solver.d.ts +85 -0
- package/dist/compiler/css-if-transpiler.d.ts +33 -0
- package/dist/compiler/design-orchestrator.d.ts +119 -0
- package/dist/compiler/intent-api.d.ts +73 -0
- package/dist/compiler/intent-engine.d.ts +19 -1
- package/dist/compiler/layout-intelligence.d.ts +71 -0
- package/dist/compiler/pass-manager.d.ts +157 -0
- package/dist/compiler/pattern-learner.d.ts +112 -0
- package/dist/compiler/responsive-inference.d.ts +63 -0
- package/dist/compiler/scroll-timeline.d.ts +91 -0
- package/dist/compiler/semantic-tokens.d.ts +57 -0
- package/dist/compiler/source-optimizer.d.ts +109 -0
- package/dist/compiler/style-ir.d.ts +183 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +4126 -2
- package/package.json +1 -1
- package/src/compiler/accessibility-engine.ts +502 -0
- package/src/compiler/constraint-solver.ts +407 -0
- package/src/compiler/css-if-transpiler.ts +117 -0
- package/src/compiler/design-orchestrator.ts +322 -0
- package/src/compiler/intent-api.ts +505 -0
- package/src/compiler/intent-engine.ts +291 -1
- package/src/compiler/layout-intelligence.ts +697 -0
- package/src/compiler/pass-manager.ts +657 -0
- package/src/compiler/pattern-learner.ts +398 -0
- package/src/compiler/responsive-inference.ts +415 -0
- package/src/compiler/scroll-timeline.ts +284 -0
- package/src/compiler/semantic-tokens.ts +468 -0
- package/src/compiler/source-optimizer.ts +541 -0
- package/src/compiler/style-ir.ts +495 -0
- package/src/index.ts +209 -0
- package/ROADMAP.md +0 -31
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
// src/compiler/style-ir.ts
|
|
2
|
+
/**
|
|
3
|
+
* ChainCSS Intermediate Representation (IR)
|
|
4
|
+
*
|
|
5
|
+
* The single source of truth that all compiler passes read from and write to.
|
|
6
|
+
* Replaces direct object mutation with a typed, traceable AST.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* StyleDefinition → parseIR() → StyleIR → [passes] → generateCSS()
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { StyleDefinition, AtRule, CompileResult, AtomicClass, CompileStats } from '../core/types.js';
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// IR Types
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
/** Unique identifier for every IR node */
|
|
19
|
+
export type IRNodeId = string;
|
|
20
|
+
|
|
21
|
+
/** Source location for debugging and source maps */
|
|
22
|
+
export interface SourceLocation {
|
|
23
|
+
file?: string;
|
|
24
|
+
line?: number;
|
|
25
|
+
column?: number;
|
|
26
|
+
component?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** A single CSS declaration (property: value) */
|
|
30
|
+
export interface IRDeclaration {
|
|
31
|
+
id: IRNodeId;
|
|
32
|
+
property: string;
|
|
33
|
+
value: string | number;
|
|
34
|
+
important?: boolean;
|
|
35
|
+
source?: SourceLocation;
|
|
36
|
+
/** Transform history — who modified this and why */
|
|
37
|
+
history: IRTransformRecord[];
|
|
38
|
+
/** Metadata from passes */
|
|
39
|
+
meta: Record<string, any>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** A CSS rule (selector + declarations + nested rules) */
|
|
43
|
+
export interface IRRule {
|
|
44
|
+
id: IRNodeId;
|
|
45
|
+
selector: string;
|
|
46
|
+
declarations: IRDeclaration[];
|
|
47
|
+
pseudoClasses: IRPseudoClass[];
|
|
48
|
+
atRules: IRAtRule[];
|
|
49
|
+
nestedRules: IRRule[];
|
|
50
|
+
/** Conditional if() expressions */
|
|
51
|
+
conditions: IRCondition[];
|
|
52
|
+
/** Dead code flag — set by optimizer passes */
|
|
53
|
+
isDead: boolean;
|
|
54
|
+
/** Specificity — set by graph pass */
|
|
55
|
+
specificity: number;
|
|
56
|
+
/** Content hash for deduplication */
|
|
57
|
+
hash: string;
|
|
58
|
+
source: SourceLocation;
|
|
59
|
+
history: IRTransformRecord[];
|
|
60
|
+
meta: Record<string, any>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Pseudo-class block (hover, focus, etc.) */
|
|
64
|
+
export interface IRPseudoClass {
|
|
65
|
+
id: IRNodeId;
|
|
66
|
+
name: string; // 'hover', 'focus', 'active', etc.
|
|
67
|
+
declarations: IRDeclaration[];
|
|
68
|
+
source: SourceLocation;
|
|
69
|
+
history: IRTransformRecord[];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** At-rule block (media, keyframes, supports, etc.) */
|
|
73
|
+
export interface IRAtRule {
|
|
74
|
+
id: IRNodeId;
|
|
75
|
+
type: 'media' | 'keyframes' | 'font-face' | 'supports' | 'container' | 'layer';
|
|
76
|
+
query?: string;
|
|
77
|
+
name?: string;
|
|
78
|
+
declarations: IRDeclaration[];
|
|
79
|
+
nestedRules: IRRule[];
|
|
80
|
+
source: SourceLocation;
|
|
81
|
+
history: IRTransformRecord[];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** CSS if() conditional */
|
|
85
|
+
export interface IRCondition {
|
|
86
|
+
id: IRNodeId;
|
|
87
|
+
property: string;
|
|
88
|
+
variable: string;
|
|
89
|
+
conditions: Record<string, string | number>;
|
|
90
|
+
defaultValue: string | number;
|
|
91
|
+
source: SourceLocation;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Transform record — who touched this node and why */
|
|
95
|
+
export interface IRTransformRecord {
|
|
96
|
+
pass: string; // e.g., 'intent-engine', 'math-engine', 'graph-compiler'
|
|
97
|
+
action: string; // e.g., 'corrected-value', 'resolved-unit', 'eliminated'
|
|
98
|
+
timestamp: number;
|
|
99
|
+
previous?: any; // value before transform
|
|
100
|
+
reason?: string; // human-readable explanation
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** The full IR tree */
|
|
104
|
+
export interface StyleIR {
|
|
105
|
+
id: string;
|
|
106
|
+
rules: IRRule[];
|
|
107
|
+
diagnostics: IRDiagnostic[];
|
|
108
|
+
meta: {
|
|
109
|
+
version: string;
|
|
110
|
+
createdAt: number;
|
|
111
|
+
sourceFiles: string[];
|
|
112
|
+
passCount: number;
|
|
113
|
+
passes: string[];
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Diagnostic attached to an IR node */
|
|
118
|
+
export interface IRDiagnostic {
|
|
119
|
+
id: IRNodeId;
|
|
120
|
+
nodeId: IRNodeId;
|
|
121
|
+
severity: 'error' | 'warning' | 'info' | 'hint';
|
|
122
|
+
message: string;
|
|
123
|
+
suggestion?: string;
|
|
124
|
+
pass: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ============================================================================
|
|
128
|
+
// ID Generator
|
|
129
|
+
// ============================================================================
|
|
130
|
+
|
|
131
|
+
let idCounter = 0;
|
|
132
|
+
function nextId(prefix: string = 'ir'): IRNodeId {
|
|
133
|
+
return prefix + '-' + (idCounter++).toString(36) + '-' + Date.now().toString(36);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function resetIdCounter(): void {
|
|
137
|
+
idCounter = 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ============================================================================
|
|
141
|
+
// IR Factory — create nodes safely
|
|
142
|
+
// ============================================================================
|
|
143
|
+
|
|
144
|
+
function record(pass: string, action: string, previous?: any, reason?: string): IRTransformRecord {
|
|
145
|
+
return { pass, action, timestamp: Date.now(), previous, reason };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function createDeclaration(
|
|
149
|
+
property: string,
|
|
150
|
+
value: string | number,
|
|
151
|
+
source?: SourceLocation,
|
|
152
|
+
meta: Record<string, any> = {}
|
|
153
|
+
): IRDeclaration {
|
|
154
|
+
return {
|
|
155
|
+
id: nextId('decl'),
|
|
156
|
+
property,
|
|
157
|
+
value,
|
|
158
|
+
source,
|
|
159
|
+
history: [record('parser', 'created', undefined, 'Parsed from StyleDefinition')],
|
|
160
|
+
meta,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function createRule(
|
|
165
|
+
selector: string,
|
|
166
|
+
source?: SourceLocation
|
|
167
|
+
): IRRule {
|
|
168
|
+
return {
|
|
169
|
+
id: nextId('rule'),
|
|
170
|
+
selector,
|
|
171
|
+
declarations: [],
|
|
172
|
+
pseudoClasses: [],
|
|
173
|
+
atRules: [],
|
|
174
|
+
nestedRules: [],
|
|
175
|
+
conditions: [],
|
|
176
|
+
isDead: false,
|
|
177
|
+
specificity: 0,
|
|
178
|
+
hash: '',
|
|
179
|
+
source: source || {},
|
|
180
|
+
history: [record('parser', 'created', undefined, 'Parsed from StyleDefinition')],
|
|
181
|
+
meta: {},
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function createIR(sourceFiles: string[] = []): StyleIR {
|
|
186
|
+
return {
|
|
187
|
+
id: nextId('ir'),
|
|
188
|
+
rules: [],
|
|
189
|
+
diagnostics: [],
|
|
190
|
+
meta: {
|
|
191
|
+
version: '1.0.0',
|
|
192
|
+
createdAt: Date.now(),
|
|
193
|
+
sourceFiles,
|
|
194
|
+
passCount: 0,
|
|
195
|
+
passes: [],
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// ============================================================================
|
|
201
|
+
// Parser: StyleDefinition → StyleIR
|
|
202
|
+
// ============================================================================
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Parse a StyleDefinition (or Record<string, any>) into the IR.
|
|
206
|
+
* This is the bridge — existing code produces StyleDefinition,
|
|
207
|
+
* this converts it to typed IR for all downstream passes.
|
|
208
|
+
*/
|
|
209
|
+
export function parseIR(
|
|
210
|
+
styles: Record<string, StyleDefinition> | Record<string, any>,
|
|
211
|
+
sourceFile?: string
|
|
212
|
+
): StyleIR {
|
|
213
|
+
const ir = createIR(sourceFile ? [sourceFile] : []);
|
|
214
|
+
|
|
215
|
+
for (const [componentName, styleDef] of Object.entries(styles)) {
|
|
216
|
+
if (!styleDef || typeof styleDef !== 'object') continue;
|
|
217
|
+
|
|
218
|
+
const selectors = Array.isArray(styleDef.selectors)
|
|
219
|
+
? styleDef.selectors
|
|
220
|
+
: styleDef.selector
|
|
221
|
+
? [styleDef.selector]
|
|
222
|
+
: ['.' + componentName];
|
|
223
|
+
|
|
224
|
+
for (const selector of selectors) {
|
|
225
|
+
const rule = createRule(selector, {
|
|
226
|
+
file: sourceFile,
|
|
227
|
+
component: componentName,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// Parse declarations
|
|
231
|
+
for (const [prop, value] of Object.entries(styleDef)) {
|
|
232
|
+
// Skip metadata
|
|
233
|
+
if (prop === 'selectors' || prop === 'selector' || prop.startsWith('_')) continue;
|
|
234
|
+
// Skip complex sub-objects (handled separately)
|
|
235
|
+
if (prop === 'hover' || prop === 'atRules' || prop === 'nestedRules' || prop === 'themes') continue;
|
|
236
|
+
|
|
237
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
238
|
+
rule.declarations.push(createDeclaration(prop, value, rule.source));
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Parse hover pseudo-class
|
|
243
|
+
if (styleDef.hover && typeof styleDef.hover === 'object') {
|
|
244
|
+
const pc: IRPseudoClass = {
|
|
245
|
+
id: nextId('hover'),
|
|
246
|
+
name: 'hover',
|
|
247
|
+
declarations: [],
|
|
248
|
+
source: rule.source,
|
|
249
|
+
history: [record('parser', 'created', undefined, 'Parsed hover block')],
|
|
250
|
+
};
|
|
251
|
+
for (const [prop, value] of Object.entries(styleDef.hover)) {
|
|
252
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
253
|
+
pc.declarations.push(createDeclaration(prop, value, rule.source));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
rule.pseudoClasses.push(pc);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Parse at-rules
|
|
260
|
+
if (styleDef.atRules && Array.isArray(styleDef.atRules)) {
|
|
261
|
+
for (const atRule of styleDef.atRules) {
|
|
262
|
+
const irAtRule: IRAtRule = {
|
|
263
|
+
id: nextId('atrule'),
|
|
264
|
+
type: atRule.type || 'media',
|
|
265
|
+
query: atRule.query,
|
|
266
|
+
name: atRule.name,
|
|
267
|
+
declarations: [],
|
|
268
|
+
nestedRules: [],
|
|
269
|
+
source: rule.source,
|
|
270
|
+
history: [record('parser', 'created', undefined, 'Parsed at-rule')],
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
if (atRule.styles && typeof atRule.styles === 'object') {
|
|
274
|
+
for (const [prop, value] of Object.entries(atRule.styles)) {
|
|
275
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
276
|
+
irAtRule.declarations.push(createDeclaration(prop, value, rule.source));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
rule.atRules.push(irAtRule);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Parse CSS if() conditions
|
|
286
|
+
if (styleDef._ifConditions && Array.isArray(styleDef._ifConditions)) {
|
|
287
|
+
for (const cond of styleDef._ifConditions) {
|
|
288
|
+
rule.conditions.push({
|
|
289
|
+
id: nextId('cond'),
|
|
290
|
+
property: cond.property,
|
|
291
|
+
variable: cond.variable,
|
|
292
|
+
conditions: cond.conditions || {},
|
|
293
|
+
defaultValue: cond.defaultValue || '',
|
|
294
|
+
source: rule.source,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
ir.rules.push(rule);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return ir;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// ============================================================================
|
|
307
|
+
// Generator: StyleIR → CSS string
|
|
308
|
+
// ============================================================================
|
|
309
|
+
|
|
310
|
+
function kebab(prop: string): string {
|
|
311
|
+
return prop.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Generate a CSS string from the IR.
|
|
316
|
+
* This replaces the ad-hoc CSS generation scattered across modules.
|
|
317
|
+
*/
|
|
318
|
+
export function generateCSS(ir: StyleIR, options?: { minify?: boolean }): string {
|
|
319
|
+
let css = '';
|
|
320
|
+
|
|
321
|
+
for (const rule of ir.rules) {
|
|
322
|
+
if (rule.isDead) continue;
|
|
323
|
+
|
|
324
|
+
// Regular declarations
|
|
325
|
+
if (rule.declarations.length > 0) {
|
|
326
|
+
css += rule.selector + ' {\n';
|
|
327
|
+
for (const decl of rule.declarations) {
|
|
328
|
+
css += ' ' + kebab(decl.property) + ': ' + decl.value + ';\n';
|
|
329
|
+
}
|
|
330
|
+
css += '}\n';
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Pseudo-classes
|
|
334
|
+
for (const pc of rule.pseudoClasses) {
|
|
335
|
+
if (pc.declarations.length > 0) {
|
|
336
|
+
css += rule.selector + ':' + pc.name + ' {\n';
|
|
337
|
+
for (const decl of pc.declarations) {
|
|
338
|
+
css += ' ' + kebab(decl.property) + ': ' + decl.value + ';\n';
|
|
339
|
+
}
|
|
340
|
+
css += '}\n';
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// At-rules
|
|
345
|
+
for (const atRule of rule.atRules) {
|
|
346
|
+
if (atRule.type === 'media' && atRule.query) {
|
|
347
|
+
css += '@media ' + atRule.query + ' {\n';
|
|
348
|
+
css += rule.selector + ' {\n';
|
|
349
|
+
for (const decl of atRule.declarations) {
|
|
350
|
+
css += ' ' + kebab(decl.property) + ': ' + decl.value + ';\n';
|
|
351
|
+
}
|
|
352
|
+
css += '}\n}\n';
|
|
353
|
+
} else if (atRule.type === 'keyframes' && atRule.name) {
|
|
354
|
+
css += '@keyframes ' + atRule.name + ' {\n';
|
|
355
|
+
for (const decl of atRule.declarations) {
|
|
356
|
+
css += ' ' + decl.property + ' { ' + kebab(decl.property) + ': ' + decl.value + '; }\n';
|
|
357
|
+
}
|
|
358
|
+
css += '}\n';
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// CSS if() conditions
|
|
363
|
+
if (rule.conditions.length > 0) {
|
|
364
|
+
css += '/* Native CSS if() */\n';
|
|
365
|
+
css += rule.selector + ' {\n';
|
|
366
|
+
for (const cond of rule.conditions) {
|
|
367
|
+
const entries = Object.entries(cond.conditions);
|
|
368
|
+
if (entries.length === 1) {
|
|
369
|
+
const [c, v] = entries[0];
|
|
370
|
+
css += ' ' + kebab(cond.property) + ': if(style(' + cond.variable + ': ' + c + '): ' + v + ' else ' + cond.defaultValue + ');\n';
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
css += '}\n';
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return css;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// ============================================================================
|
|
381
|
+
// IR Utilities
|
|
382
|
+
// ============================================================================
|
|
383
|
+
|
|
384
|
+
/** Count all nodes in the IR */
|
|
385
|
+
export function countNodes(ir: StyleIR): { rules: number; declarations: number; pseudoClasses: number; atRules: number; conditions: number } {
|
|
386
|
+
let declarations = 0, pseudoClasses = 0, atRules = 0, conditions = 0;
|
|
387
|
+
for (const rule of ir.rules) {
|
|
388
|
+
declarations += rule.declarations.length;
|
|
389
|
+
pseudoClasses += rule.pseudoClasses.length;
|
|
390
|
+
atRules += rule.atRules.length;
|
|
391
|
+
conditions += rule.conditions.length;
|
|
392
|
+
}
|
|
393
|
+
return { rules: ir.rules.length, declarations, pseudoClasses, atRules, conditions };
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Find a rule by selector */
|
|
397
|
+
export function findRule(ir: StyleIR, selector: string): IRRule | undefined {
|
|
398
|
+
return ir.rules.find(r => r.selector === selector);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/** Clone an IR (deep copy) */
|
|
402
|
+
export function cloneIR(ir: StyleIR): StyleIR {
|
|
403
|
+
return JSON.parse(JSON.stringify(ir));
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/** Debug: print IR summary */
|
|
407
|
+
export function debugIR(ir: StyleIR): string {
|
|
408
|
+
const counts = countNodes(ir);
|
|
409
|
+
return [
|
|
410
|
+
'StyleIR {',
|
|
411
|
+
' id: ' + ir.id,
|
|
412
|
+
' rules: ' + counts.rules,
|
|
413
|
+
' declarations: ' + counts.declarations,
|
|
414
|
+
' pseudoClasses: ' + counts.pseudoClasses,
|
|
415
|
+
' atRules: ' + counts.atRules,
|
|
416
|
+
' conditions: ' + counts.conditions,
|
|
417
|
+
' diagnostics: ' + ir.diagnostics.length,
|
|
418
|
+
' passes: [' + ir.meta.passes.join(', ') + ']',
|
|
419
|
+
'}',
|
|
420
|
+
].join('\n');
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// ============================================================================
|
|
424
|
+
// Pass Infrastructure
|
|
425
|
+
// ============================================================================
|
|
426
|
+
|
|
427
|
+
export type IRPass = (ir: StyleIR) => StyleIR;
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Apply a transform pass to the IR.
|
|
431
|
+
* Records the pass in metadata for debugging.
|
|
432
|
+
*/
|
|
433
|
+
export function applyPass(ir: StyleIR, pass: IRPass, passName: string): StyleIR {
|
|
434
|
+
const result = pass(ir);
|
|
435
|
+
result.meta.passCount++;
|
|
436
|
+
result.meta.passes.push(passName);
|
|
437
|
+
return result;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Apply multiple passes in sequence.
|
|
442
|
+
*/
|
|
443
|
+
export function applyPasses(ir: StyleIR, passes: Array<{ name: string; pass: IRPass }>): StyleIR {
|
|
444
|
+
let current = ir;
|
|
445
|
+
for (const { name, pass } of passes) {
|
|
446
|
+
current = applyPass(current, pass, name);
|
|
447
|
+
}
|
|
448
|
+
return current;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// ============================================================================
|
|
452
|
+
// Bridge: compile StyleDefinition through IR
|
|
453
|
+
// ============================================================================
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Full pipeline: StyleDefinition → IR → passes → CSS.
|
|
457
|
+
* Drop-in replacement for existing compile() calls.
|
|
458
|
+
*/
|
|
459
|
+
export function compileViaIR(
|
|
460
|
+
styles: Record<string, StyleDefinition>,
|
|
461
|
+
passes: Array<{ name: string; pass: IRPass }> = [],
|
|
462
|
+
options?: { minify?: boolean; sourceFile?: string }
|
|
463
|
+
): { css: string; ir: StyleIR } {
|
|
464
|
+
let ir = parseIR(styles, options?.sourceFile);
|
|
465
|
+
|
|
466
|
+
// Apply all transform passes
|
|
467
|
+
for (const { name, pass } of passes) {
|
|
468
|
+
ir = applyPass(ir, pass, name);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
const css = generateCSS(ir, options);
|
|
472
|
+
return { css, ir };
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// ============================================================================
|
|
476
|
+
// Exports
|
|
477
|
+
// ============================================================================
|
|
478
|
+
|
|
479
|
+
export const styleIR = {
|
|
480
|
+
createIR,
|
|
481
|
+
parseIR,
|
|
482
|
+
generateCSS,
|
|
483
|
+
createRule,
|
|
484
|
+
createDeclaration,
|
|
485
|
+
countNodes,
|
|
486
|
+
findRule,
|
|
487
|
+
cloneIR,
|
|
488
|
+
debugIR,
|
|
489
|
+
applyPass,
|
|
490
|
+
applyPasses,
|
|
491
|
+
compileViaIR,
|
|
492
|
+
resetIdCounter,
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
export default styleIR;
|
package/src/index.ts
CHANGED
|
@@ -162,6 +162,215 @@ export type { BreakpointsMap, ResponsiveStyle } from './compiler/breakpoints.js'
|
|
|
162
162
|
// ============================================================================
|
|
163
163
|
export const VERSION = '3.0.0';
|
|
164
164
|
|
|
165
|
+
// ============================================================================
|
|
166
|
+
// Default Export - Keep original chain for backward compatibility
|
|
167
|
+
// ============================================================================
|
|
168
|
+
// ============================================================================
|
|
169
|
+
// 🆕 Design System Orchestrator (v2.3)
|
|
170
|
+
// ============================================================================
|
|
171
|
+
export {
|
|
172
|
+
orchestrator,
|
|
173
|
+
contrastRatio,
|
|
174
|
+
checkContrast,
|
|
175
|
+
auditContrast,
|
|
176
|
+
createContextualToken,
|
|
177
|
+
resolveContextual,
|
|
178
|
+
generateContextualCSS,
|
|
179
|
+
validateTokenRelationships,
|
|
180
|
+
} from './compiler/design-orchestrator.js';
|
|
181
|
+
export type { ContrastResult, ContrastReport, ContextualToken, TokenContext } from './compiler/design-orchestrator.js';
|
|
182
|
+
|
|
183
|
+
// ============================================================================
|
|
184
|
+
// Default Export - Keep original chain for backward compatibility
|
|
185
|
+
// ============================================================================
|
|
186
|
+
// ============================================================================
|
|
187
|
+
// 🆕 Scroll Timeline Engine (v2.3)
|
|
188
|
+
// ============================================================================
|
|
189
|
+
export {
|
|
190
|
+
scrollTimeline,
|
|
191
|
+
compileScrollAnimation,
|
|
192
|
+
compileScrollAnimations,
|
|
193
|
+
createScrollAnimation,
|
|
194
|
+
getScrollPresets,
|
|
195
|
+
SCROLL_PRESETS,
|
|
196
|
+
} from './compiler/scroll-timeline.js';
|
|
197
|
+
export type { ScrollTimelineConfig, ScrollAnimation, ScrollTimelineResult, KeyframeStep } from './compiler/scroll-timeline.js';
|
|
198
|
+
|
|
199
|
+
// ============================================================================
|
|
200
|
+
// Default Export - Keep original chain for backward compatibility
|
|
201
|
+
// ============================================================================
|
|
202
|
+
// ============================================================================
|
|
203
|
+
// 🆕 Style IR System (v2.3)
|
|
204
|
+
// ============================================================================
|
|
205
|
+
export {
|
|
206
|
+
styleIR,
|
|
207
|
+
createIR,
|
|
208
|
+
parseIR,
|
|
209
|
+
generateCSS,
|
|
210
|
+
createRule,
|
|
211
|
+
createDeclaration,
|
|
212
|
+
applyPass,
|
|
213
|
+
applyPasses,
|
|
214
|
+
compileViaIR,
|
|
215
|
+
countNodes,
|
|
216
|
+
debugIR,
|
|
217
|
+
resetIdCounter,
|
|
218
|
+
} from './compiler/style-ir.js';
|
|
219
|
+
export type {
|
|
220
|
+
StyleIR,
|
|
221
|
+
IRRule,
|
|
222
|
+
IRDeclaration,
|
|
223
|
+
IRPseudoClass,
|
|
224
|
+
IRAtRule,
|
|
225
|
+
IRCondition,
|
|
226
|
+
IRTransformRecord,
|
|
227
|
+
IRDiagnostic,
|
|
228
|
+
IRNodeId,
|
|
229
|
+
SourceLocation,
|
|
230
|
+
IRPass,
|
|
231
|
+
} from './compiler/style-ir.js';
|
|
232
|
+
|
|
233
|
+
// ============================================================================
|
|
234
|
+
// Default Export - Keep original chain for backward compatibility
|
|
235
|
+
// ============================================================================
|
|
236
|
+
// ============================================================================
|
|
237
|
+
// 🆕 Multi-Pass Optimization Pipeline (v2.3)
|
|
238
|
+
// ============================================================================
|
|
239
|
+
export {
|
|
240
|
+
PassManager,
|
|
241
|
+
runDefaultPipeline,
|
|
242
|
+
DEFAULT_PIPELINE,
|
|
243
|
+
intentRecoveryPass,
|
|
244
|
+
unitResolutionPass,
|
|
245
|
+
validationPass,
|
|
246
|
+
specificitySortPass,
|
|
247
|
+
deadEliminationPass,
|
|
248
|
+
atomicExtractionPass,
|
|
249
|
+
mediaQueryPackingPass,
|
|
250
|
+
cssIfTranspilePass,
|
|
251
|
+
cssCompressionPass,
|
|
252
|
+
diagnosticsExportPass,
|
|
253
|
+
} from './compiler/pass-manager.js';
|
|
254
|
+
export type { PassName, PassPriority, PassDefinition, PassResult, PipelineResult } from './compiler/pass-manager.js';
|
|
255
|
+
|
|
256
|
+
// ============================================================================
|
|
257
|
+
// Default Export - Keep original chain for backward compatibility
|
|
258
|
+
// ============================================================================
|
|
259
|
+
// ============================================================================
|
|
260
|
+
// 🆕 Constraint-Based Styling Engine (v2.3)
|
|
261
|
+
// ============================================================================
|
|
262
|
+
export {
|
|
263
|
+
constraintSolver,
|
|
264
|
+
resolveConstraint,
|
|
265
|
+
resolveStickyUntil,
|
|
266
|
+
resolveContainerQuery,
|
|
267
|
+
parseConstraint,
|
|
268
|
+
constraintSolverPass,
|
|
269
|
+
} from './compiler/constraint-solver.js';
|
|
270
|
+
export type { Constraint, ConstraintOperator, ConstraintTarget, ResolvedConstraint } from './compiler/constraint-solver.js';
|
|
271
|
+
|
|
272
|
+
// ============================================================================
|
|
273
|
+
// Default Export - Keep original chain for backward compatibility
|
|
274
|
+
// ============================================================================
|
|
275
|
+
// ============================================================================
|
|
276
|
+
// 🆕 Layout Intelligence Engine (v2.3)
|
|
277
|
+
// ============================================================================
|
|
278
|
+
export {
|
|
279
|
+
layoutIntelligence,
|
|
280
|
+
recognizeLayout,
|
|
281
|
+
suggestMacro,
|
|
282
|
+
getLayoutPatterns,
|
|
283
|
+
layoutIntelligencePass,
|
|
284
|
+
} from './compiler/layout-intelligence.js';
|
|
285
|
+
export type { LayoutPattern, PatternMatch, PatternReport } from './compiler/layout-intelligence.js';
|
|
286
|
+
|
|
287
|
+
// ============================================================================
|
|
288
|
+
// Default Export - Keep original chain for backward compatibility
|
|
289
|
+
// ============================================================================
|
|
290
|
+
// ============================================================================
|
|
291
|
+
// 🆕 Automatic Responsive Inference (v2.3)
|
|
292
|
+
// ============================================================================
|
|
293
|
+
export {
|
|
294
|
+
responsiveInference,
|
|
295
|
+
analyzeResponsive,
|
|
296
|
+
generateResponsiveReport,
|
|
297
|
+
autoFixIssue,
|
|
298
|
+
autoFixAll,
|
|
299
|
+
responsiveInferencePass,
|
|
300
|
+
} from './compiler/responsive-inference.js';
|
|
301
|
+
export type { ResponsiveIssue, ResponsiveReport } from './compiler/responsive-inference.js';
|
|
302
|
+
|
|
303
|
+
// ============================================================================
|
|
304
|
+
// Default Export - Keep original chain for backward compatibility
|
|
305
|
+
// ============================================================================
|
|
306
|
+
// ============================================================================
|
|
307
|
+
// 🆕 Style Pattern Learner (v2.3)
|
|
308
|
+
// ============================================================================
|
|
309
|
+
export {
|
|
310
|
+
patternLearner,
|
|
311
|
+
learnPatterns,
|
|
312
|
+
getExtractionCandidates,
|
|
313
|
+
patternLearningPass,
|
|
314
|
+
} from './compiler/pattern-learner.js';
|
|
315
|
+
export type { StyleFingerprint, PatternCluster, LearningReport } from './compiler/pattern-learner.js';
|
|
316
|
+
|
|
317
|
+
// ============================================================================
|
|
318
|
+
// Default Export - Keep original chain for backward compatibility
|
|
319
|
+
// ============================================================================
|
|
320
|
+
// ============================================================================
|
|
321
|
+
// 🆕 Source-Aware Optimization Engine (v2.3)
|
|
322
|
+
// ============================================================================
|
|
323
|
+
export {
|
|
324
|
+
sourceOptimizer,
|
|
325
|
+
optimizeSource,
|
|
326
|
+
sourceOptimizerPass,
|
|
327
|
+
} from './compiler/source-optimizer.js';
|
|
328
|
+
export type { OptimizationReport, DuplicateGroup, DeadRule, SpecificityConflict, AnimationConflict, MediaQueryRedundancy } from './compiler/source-optimizer.js';
|
|
329
|
+
|
|
330
|
+
// ============================================================================
|
|
331
|
+
// Default Export - Keep original chain for backward compatibility
|
|
332
|
+
// ============================================================================
|
|
333
|
+
// ============================================================================
|
|
334
|
+
// 🆕 Semantic Token System (v2.3)
|
|
335
|
+
// ============================================================================
|
|
336
|
+
export {
|
|
337
|
+
semanticTokens,
|
|
338
|
+
resolveSemantic,
|
|
339
|
+
getSemanticIntents,
|
|
340
|
+
getSemanticDescription,
|
|
341
|
+
semanticTokensPass,
|
|
342
|
+
} from './compiler/semantic-tokens.js';
|
|
343
|
+
export type { SurfaceIntent, TextIntent, ElevationIntent, StateIntent, SpacingIntent, SemanticMapping, ThemeContext } from './compiler/semantic-tokens.js';
|
|
344
|
+
|
|
345
|
+
// ============================================================================
|
|
346
|
+
// Default Export - Keep original chain for backward compatibility
|
|
347
|
+
// ============================================================================
|
|
348
|
+
// ============================================================================
|
|
349
|
+
// 🆕 Accessibility Intelligence Engine (v2.3)
|
|
350
|
+
// ============================================================================
|
|
351
|
+
export {
|
|
352
|
+
accessibilityEngine,
|
|
353
|
+
auditAccessibility,
|
|
354
|
+
checkRule,
|
|
355
|
+
accessibilityPass,
|
|
356
|
+
} from './compiler/accessibility-engine.js';
|
|
357
|
+
export type { AccessibilityIssue, AccessibilityReport } from './compiler/accessibility-engine.js';
|
|
358
|
+
|
|
359
|
+
// ============================================================================
|
|
360
|
+
// Default Export - Keep original chain for backward compatibility
|
|
361
|
+
// ============================================================================
|
|
362
|
+
// ============================================================================
|
|
363
|
+
// 🆕 Intent-Based API (v2.3)
|
|
364
|
+
// ============================================================================
|
|
365
|
+
export {
|
|
366
|
+
intentAPI,
|
|
367
|
+
resolveIntent,
|
|
368
|
+
getAvailableIntents,
|
|
369
|
+
getIntentsByCategory,
|
|
370
|
+
getIntentDescription,
|
|
371
|
+
intentAPIPass,
|
|
372
|
+
} from './compiler/intent-api.js';
|
|
373
|
+
|
|
165
374
|
// ============================================================================
|
|
166
375
|
// Default Export - Keep original chain for backward compatibility
|
|
167
376
|
// ============================================================================
|