@decantr/core 1.0.0-beta.4 → 1.0.0-beta.6
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/LICENSE +21 -0
- package/dist/index.d.ts +12 -7
- package/dist/index.js +139 -41
- package/dist/index.js.map +1 -1
- package/package.json +11 -9
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Decantr AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EssenceFile, StructurePage } from '@decantr/essence-spec';
|
|
2
2
|
import { Pattern, ResolvedPreset, Recipe, ContentResolver } from '@decantr/registry';
|
|
3
3
|
|
|
4
|
-
type IRNodeType = 'app' | 'shell' | 'page' | 'pattern' | 'grid' | '
|
|
4
|
+
type IRNodeType = 'app' | 'shell' | 'page' | 'pattern' | 'grid' | 'nav' | 'store';
|
|
5
5
|
interface IRSpatial {
|
|
6
6
|
gap: string;
|
|
7
7
|
padding?: string;
|
|
@@ -81,12 +81,16 @@ interface IRRoute {
|
|
|
81
81
|
path: string;
|
|
82
82
|
pageId: string;
|
|
83
83
|
}
|
|
84
|
+
/** Which v3 essence layer sourced this node */
|
|
85
|
+
type IRLayer = 'dna' | 'blueprint' | 'meta';
|
|
84
86
|
interface IRNode {
|
|
85
87
|
type: IRNodeType;
|
|
86
88
|
id: string;
|
|
87
89
|
children: IRNode[];
|
|
88
90
|
spatial?: IRSpatial;
|
|
89
91
|
meta?: Record<string, unknown>;
|
|
92
|
+
/** When built from a v3 essence, indicates the originating layer */
|
|
93
|
+
layer?: IRLayer;
|
|
90
94
|
}
|
|
91
95
|
interface IRAppNode extends IRNode {
|
|
92
96
|
type: 'app';
|
|
@@ -126,10 +130,6 @@ interface IRGridNode extends IRNode {
|
|
|
126
130
|
breakpoints?: IRBreakpointEntry[] | null;
|
|
127
131
|
responsive?: 'viewport' | 'container' | null;
|
|
128
132
|
}
|
|
129
|
-
interface IRNavNode extends IRNode {
|
|
130
|
-
type: 'nav';
|
|
131
|
-
items: IRNavItem[];
|
|
132
|
-
}
|
|
133
133
|
interface IRStoreNode extends IRNode {
|
|
134
134
|
type: 'store';
|
|
135
135
|
pageSignals: {
|
|
@@ -166,7 +166,7 @@ interface ResolvedPatternEntry {
|
|
|
166
166
|
/** Build IR tree for a single page from its resolved structure + patterns */
|
|
167
167
|
declare function buildPageIR(page: StructurePage, resolvedPatterns: Map<string, ResolvedPatternEntry>, wiring: IRWiring | null, recipe: Recipe | null, density: {
|
|
168
168
|
gap: string;
|
|
169
|
-
}): IRPageNode;
|
|
169
|
+
}, layer?: IRLayer): IRPageNode;
|
|
170
170
|
|
|
171
171
|
interface ResolvedPage {
|
|
172
172
|
page: StructurePage;
|
|
@@ -188,6 +188,8 @@ interface ResolvedEssence {
|
|
|
188
188
|
shell: IRShellConfig;
|
|
189
189
|
routes: IRRoute[];
|
|
190
190
|
features: string[];
|
|
191
|
+
/** True when the source essence was v3 (DNA/Blueprint/Meta) */
|
|
192
|
+
isV3Source: boolean;
|
|
191
193
|
}
|
|
192
194
|
declare function resolveVisualEffects(recipe: Recipe, pattern: Pattern, _slot?: string): IRVisualEffect | null;
|
|
193
195
|
/** Resolve all external references in an Essence file */
|
|
@@ -202,4 +204,7 @@ declare function countPatterns(root: IRNode): number;
|
|
|
202
204
|
/** Validate IR tree structure (no orphaned grids, patterns have meta, etc.) */
|
|
203
205
|
declare function validateIR(root: IRNode): string[];
|
|
204
206
|
|
|
205
|
-
|
|
207
|
+
/** Convert a kebab-case or snake_case string to PascalCase */
|
|
208
|
+
declare function pascalCase(str: string): string;
|
|
209
|
+
|
|
210
|
+
export { type IRAppNode, type IRBreakpointEntry, type IRCardWrapping, type IRGridNode, type IRHookType, type IRLayer, type IRNavItem, type IRNode, type IRNodeType, type IRPageNode, type IRPatternMeta, type IRPatternNode, type IRRecipeDecoration, type IRRoute, type IRShellConfig, type IRShellNode, type IRSpatial, type IRStoreNode, type IRTheme, type IRVisualEffect, type IRWiring, type IRWiringSignal, type PipelineOptions, type PipelineResult, type ResolvedEssence, type ResolvedPage, buildPageIR, countPatterns, findNodes, pascalCase, resolveEssence, resolveVisualEffects, runPipeline, validateIR, walkIR };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
// src/pipeline.ts
|
|
2
|
-
import { validateEssence } from "@decantr/essence-spec";
|
|
2
|
+
import { validateEssence, isV3 as isV32, migrateV2ToV3 } from "@decantr/essence-spec";
|
|
3
3
|
import { createResolver } from "@decantr/registry";
|
|
4
4
|
|
|
5
5
|
// src/resolve.ts
|
|
6
|
-
import { isSimple, isSectioned, computeDensity } from "@decantr/essence-spec";
|
|
6
|
+
import { isSimple, isSectioned, isV3, computeDensity } from "@decantr/essence-spec";
|
|
7
|
+
|
|
8
|
+
// src/utils.ts
|
|
9
|
+
function pascalCase(str) {
|
|
10
|
+
return str.split(/[-_]/).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// src/resolve.ts
|
|
7
14
|
import { resolvePatternPreset, detectWirings } from "@decantr/registry";
|
|
8
15
|
var NAV_ICONS = {
|
|
9
16
|
overview: "layout-dashboard",
|
|
@@ -79,9 +86,6 @@ function routePath(pageId, index) {
|
|
|
79
86
|
}
|
|
80
87
|
return `/${pageId}`;
|
|
81
88
|
}
|
|
82
|
-
function pascalCase(str) {
|
|
83
|
-
return str.split(/[-_]/).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
84
|
-
}
|
|
85
89
|
function capitalize(str) {
|
|
86
90
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
87
91
|
}
|
|
@@ -116,6 +120,24 @@ function buildTheme(essence, isAddon) {
|
|
|
116
120
|
isAddon
|
|
117
121
|
};
|
|
118
122
|
}
|
|
123
|
+
function buildThemeFromV3(essence, isAddon) {
|
|
124
|
+
const dna = essence.dna;
|
|
125
|
+
return {
|
|
126
|
+
style: dna.theme.style,
|
|
127
|
+
mode: dna.theme.mode,
|
|
128
|
+
shape: dna.radius.philosophy || dna.theme.shape || null,
|
|
129
|
+
recipe: dna.theme.recipe,
|
|
130
|
+
isAddon
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function blueprintPageToStructurePage(page, defaultShell) {
|
|
134
|
+
return {
|
|
135
|
+
id: page.id,
|
|
136
|
+
shell: page.shell_override ?? defaultShell,
|
|
137
|
+
layout: page.layout,
|
|
138
|
+
...page.surface ? { surface: page.surface } : {}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
119
141
|
function convertWiring(wiringResults) {
|
|
120
142
|
if (wiringResults.length === 0) return null;
|
|
121
143
|
const signals = [];
|
|
@@ -165,11 +187,19 @@ function resolveVisualEffects(recipe, pattern, _slot) {
|
|
|
165
187
|
};
|
|
166
188
|
}
|
|
167
189
|
async function resolveEssence(essence, resolver) {
|
|
190
|
+
if (isV3(essence)) {
|
|
191
|
+
return resolveV3Essence(essence, resolver);
|
|
192
|
+
}
|
|
168
193
|
let simpleEssence;
|
|
169
194
|
if (isSimple(essence)) {
|
|
170
195
|
simpleEssence = essence;
|
|
171
196
|
} else if (isSectioned(essence)) {
|
|
172
197
|
const sectioned = essence;
|
|
198
|
+
if (sectioned.sections.length > 1) {
|
|
199
|
+
throw new Error(
|
|
200
|
+
`Sectioned essences with ${sectioned.sections.length} sections are not yet supported. Only single-section sectioned essences can be processed. Consider migrating to v3 format using migrateV2ToV3().`
|
|
201
|
+
);
|
|
202
|
+
}
|
|
173
203
|
const firstSection = sectioned.sections[0];
|
|
174
204
|
simpleEssence = {
|
|
175
205
|
version: sectioned.version,
|
|
@@ -199,26 +229,7 @@ async function resolveEssence(essence, resolver) {
|
|
|
199
229
|
const style = simpleEssence.theme.style;
|
|
200
230
|
const isAddon = style.startsWith("custom:") || !CORE_STYLES.has(style);
|
|
201
231
|
const theme = buildTheme(simpleEssence, isAddon);
|
|
202
|
-
const resolvedPages =
|
|
203
|
-
for (const page of simpleEssence.structure) {
|
|
204
|
-
const refs = extractLayoutRefs(page.layout);
|
|
205
|
-
const patterns = /* @__PURE__ */ new Map();
|
|
206
|
-
for (const ref of refs) {
|
|
207
|
-
const patternResult = await resolver.resolve("pattern", ref.id);
|
|
208
|
-
if (patternResult) {
|
|
209
|
-
const preset = resolvePatternPreset(
|
|
210
|
-
patternResult.item,
|
|
211
|
-
ref.explicitPreset,
|
|
212
|
-
recipe?.pattern_preferences?.default_presets
|
|
213
|
-
);
|
|
214
|
-
const key = ref.alias || ref.id;
|
|
215
|
-
patterns.set(key, { pattern: patternResult.item, preset });
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
const wiringResults = detectWirings(flattenLayoutForWiring(page.layout));
|
|
219
|
-
const wiring = convertWiring(wiringResults);
|
|
220
|
-
resolvedPages.push({ page, patterns, wiring });
|
|
221
|
-
}
|
|
232
|
+
const resolvedPages = await resolvePages(simpleEssence.structure, resolver, recipe);
|
|
222
233
|
const shellType = simpleEssence.structure[0]?.shell || "sidebar-main";
|
|
223
234
|
const brand = pascalCase(simpleEssence.archetype);
|
|
224
235
|
const nav = buildNavItems(simpleEssence.structure);
|
|
@@ -242,9 +253,85 @@ async function resolveEssence(essence, resolver) {
|
|
|
242
253
|
theme,
|
|
243
254
|
shell,
|
|
244
255
|
routes,
|
|
245
|
-
features: simpleEssence.features ?? []
|
|
256
|
+
features: simpleEssence.features ?? [],
|
|
257
|
+
isV3Source: false
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
async function resolveV3Essence(essence, resolver) {
|
|
261
|
+
const { dna, blueprint, meta } = essence;
|
|
262
|
+
let recipe = null;
|
|
263
|
+
const recipeResult = await resolver.resolve("recipe", dna.theme.recipe);
|
|
264
|
+
if (recipeResult) {
|
|
265
|
+
recipe = recipeResult.item;
|
|
266
|
+
}
|
|
267
|
+
const recipeSpatial = recipe?.spatial_hints;
|
|
268
|
+
const density = computeDensity(dna.personality, recipeSpatial ? {
|
|
269
|
+
density_bias: recipeSpatial.density_bias,
|
|
270
|
+
content_gap_shift: recipeSpatial.content_gap_shift
|
|
271
|
+
} : void 0);
|
|
272
|
+
const densityResult = {
|
|
273
|
+
gap: dna.spacing.content_gap || density.content_gap,
|
|
274
|
+
level: dna.spacing.density || density.level
|
|
275
|
+
};
|
|
276
|
+
const style = dna.theme.style;
|
|
277
|
+
const isAddon = style.startsWith("custom:") || !CORE_STYLES.has(style);
|
|
278
|
+
const theme = buildThemeFromV3(essence, isAddon);
|
|
279
|
+
const blueprintPages = blueprint.pages ?? (blueprint.sections ? blueprint.sections.flatMap((s) => s.pages) : [{ id: "home", layout: ["hero"] }]);
|
|
280
|
+
const defaultShell = blueprint.shell ?? (blueprint.sections?.[0]?.shell ?? "sidebar-main");
|
|
281
|
+
const structurePages = blueprintPages.map(
|
|
282
|
+
(p) => blueprintPageToStructurePage(p, defaultShell)
|
|
283
|
+
);
|
|
284
|
+
const resolvedPages = await resolvePages(structurePages, resolver, recipe);
|
|
285
|
+
const shellType = defaultShell;
|
|
286
|
+
const brand = pascalCase(meta.archetype);
|
|
287
|
+
const nav = buildNavItems(structurePages);
|
|
288
|
+
const recipeDecoration = recipe ? buildRecipeDecoration(recipe) : null;
|
|
289
|
+
const shell = {
|
|
290
|
+
type: shellType,
|
|
291
|
+
brand,
|
|
292
|
+
nav,
|
|
293
|
+
inset: false,
|
|
294
|
+
recipe: recipeDecoration
|
|
295
|
+
};
|
|
296
|
+
const routes = structurePages.map((page, i) => ({
|
|
297
|
+
path: routePath(page.id, i),
|
|
298
|
+
pageId: page.id
|
|
299
|
+
}));
|
|
300
|
+
return {
|
|
301
|
+
essence,
|
|
302
|
+
pages: resolvedPages,
|
|
303
|
+
recipe,
|
|
304
|
+
density: densityResult,
|
|
305
|
+
theme,
|
|
306
|
+
shell,
|
|
307
|
+
routes,
|
|
308
|
+
features: blueprint.features ?? [],
|
|
309
|
+
isV3Source: true
|
|
246
310
|
};
|
|
247
311
|
}
|
|
312
|
+
async function resolvePages(pages, resolver, recipe) {
|
|
313
|
+
const resolvedPages = [];
|
|
314
|
+
for (const page of pages) {
|
|
315
|
+
const refs = extractLayoutRefs(page.layout);
|
|
316
|
+
const patterns = /* @__PURE__ */ new Map();
|
|
317
|
+
for (const ref of refs) {
|
|
318
|
+
const patternResult = await resolver.resolve("pattern", ref.id);
|
|
319
|
+
if (patternResult) {
|
|
320
|
+
const preset = resolvePatternPreset(
|
|
321
|
+
patternResult.item,
|
|
322
|
+
ref.explicitPreset,
|
|
323
|
+
recipe?.pattern_preferences?.default_presets
|
|
324
|
+
);
|
|
325
|
+
const key = ref.alias || ref.id;
|
|
326
|
+
patterns.set(key, { pattern: patternResult.item, preset });
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
const wiringResults = detectWirings(flattenLayoutForWiring(page.layout));
|
|
330
|
+
const wiring = convertWiring(wiringResults);
|
|
331
|
+
resolvedPages.push({ page, patterns, wiring });
|
|
332
|
+
}
|
|
333
|
+
return resolvedPages;
|
|
334
|
+
}
|
|
248
335
|
|
|
249
336
|
// src/ir.ts
|
|
250
337
|
function isPatternRef2(item) {
|
|
@@ -273,7 +360,7 @@ function buildCardWrapping(pattern, recipe) {
|
|
|
273
360
|
background: overrides?.background?.join(" ")
|
|
274
361
|
};
|
|
275
362
|
}
|
|
276
|
-
function buildPatternNode(patternId, alias, resolved, wiring, recipe, density) {
|
|
363
|
+
function buildPatternNode(patternId, alias, resolved, wiring, recipe, density, layer) {
|
|
277
364
|
const pattern = resolved?.pattern;
|
|
278
365
|
const preset = resolved?.preset;
|
|
279
366
|
const layout = preset?.layout.layout || "column";
|
|
@@ -292,27 +379,29 @@ function buildPatternNode(patternId, alias, resolved, wiring, recipe, density) {
|
|
|
292
379
|
};
|
|
293
380
|
const card = contained && !isStandalone && pattern ? buildCardWrapping(pattern, recipe) : null;
|
|
294
381
|
const wireProps = wiring?.props[alias] || wiring?.props[patternId] || null;
|
|
382
|
+
const visualEffects = recipe && pattern ? resolveVisualEffects(recipe, pattern) : null;
|
|
295
383
|
return {
|
|
296
384
|
type: "pattern",
|
|
297
385
|
id: alias,
|
|
298
386
|
children: [],
|
|
299
387
|
pattern: patternMeta,
|
|
300
388
|
card,
|
|
301
|
-
visualEffects
|
|
389
|
+
visualEffects,
|
|
302
390
|
wireProps,
|
|
303
|
-
spatial: { gap: density.gap }
|
|
391
|
+
spatial: { gap: density.gap },
|
|
392
|
+
...layer ? { layer } : {}
|
|
304
393
|
};
|
|
305
394
|
}
|
|
306
|
-
function buildPageIR(page, resolvedPatterns, wiring, recipe, density) {
|
|
395
|
+
function buildPageIR(page, resolvedPatterns, wiring, recipe, density, layer) {
|
|
307
396
|
const children = [];
|
|
308
397
|
for (const item of page.layout) {
|
|
309
398
|
if (typeof item === "string") {
|
|
310
399
|
const resolved = resolvedPatterns.get(item);
|
|
311
|
-
children.push(buildPatternNode(item, item, resolved, wiring, recipe, density));
|
|
400
|
+
children.push(buildPatternNode(item, item, resolved, wiring, recipe, density, layer));
|
|
312
401
|
} else if (isPatternRef2(item)) {
|
|
313
402
|
const alias = item.as || item.pattern;
|
|
314
403
|
const resolved = resolvedPatterns.get(alias) || resolvedPatterns.get(item.pattern);
|
|
315
|
-
children.push(buildPatternNode(item.pattern, alias, resolved, wiring, recipe, density));
|
|
404
|
+
children.push(buildPatternNode(item.pattern, alias, resolved, wiring, recipe, density, layer));
|
|
316
405
|
} else if (isColumnLayout2(item)) {
|
|
317
406
|
const cols = item.cols;
|
|
318
407
|
const breakpoint = item.at || null;
|
|
@@ -327,7 +416,7 @@ function buildPageIR(page, resolvedPatterns, wiring, recipe, density) {
|
|
|
327
416
|
const gridChildren = [];
|
|
328
417
|
for (const col of cols) {
|
|
329
418
|
const resolved = resolvedPatterns.get(col);
|
|
330
|
-
gridChildren.push(buildPatternNode(col, col, resolved, wiring, recipe, density));
|
|
419
|
+
gridChildren.push(buildPatternNode(col, col, resolved, wiring, recipe, density, layer));
|
|
331
420
|
}
|
|
332
421
|
const totalCols = normalizedSpans ? Object.values(normalizedSpans).reduce((a, b) => a + b, 0) : cols.length;
|
|
333
422
|
const breakpoints = item.breakpoints?.map((bp) => ({ at: bp.at, cols: bp.cols })) || null;
|
|
@@ -341,7 +430,8 @@ function buildPageIR(page, resolvedPatterns, wiring, recipe, density) {
|
|
|
341
430
|
breakpoint,
|
|
342
431
|
breakpoints,
|
|
343
432
|
responsive,
|
|
344
|
-
spatial: { gap: density.gap }
|
|
433
|
+
spatial: { gap: density.gap },
|
|
434
|
+
...layer ? { layer } : {}
|
|
345
435
|
};
|
|
346
436
|
children.push(gridNode);
|
|
347
437
|
}
|
|
@@ -353,24 +443,30 @@ function buildPageIR(page, resolvedPatterns, wiring, recipe, density) {
|
|
|
353
443
|
children,
|
|
354
444
|
pageId: page.id,
|
|
355
445
|
surface,
|
|
356
|
-
wiring
|
|
446
|
+
wiring,
|
|
447
|
+
...layer ? { layer } : {}
|
|
357
448
|
};
|
|
358
449
|
}
|
|
359
450
|
|
|
360
451
|
// src/pipeline.ts
|
|
361
|
-
function
|
|
362
|
-
|
|
452
|
+
function extractRouting(essence) {
|
|
453
|
+
if (isV32(essence)) {
|
|
454
|
+
return essence.meta.platform.routing || "hash";
|
|
455
|
+
}
|
|
456
|
+
return essence.platform?.routing || "hash";
|
|
363
457
|
}
|
|
364
458
|
async function runPipeline(essence, options) {
|
|
365
459
|
const validation = validateEssence(essence);
|
|
366
460
|
if (!validation.valid) {
|
|
367
461
|
throw new Error(`Invalid essence: ${validation.errors.join(", ")}`);
|
|
368
462
|
}
|
|
463
|
+
const effectiveEssence = isV32(essence) ? essence : migrateV2ToV3(essence);
|
|
369
464
|
const resolver = createResolver({
|
|
370
465
|
contentRoot: options.contentRoot,
|
|
371
466
|
overridePaths: options.overridePaths
|
|
372
467
|
});
|
|
373
|
-
const resolved = await resolveEssence(
|
|
468
|
+
const resolved = await resolveEssence(effectiveEssence, resolver);
|
|
469
|
+
const layer = resolved.isV3Source ? "blueprint" : void 0;
|
|
374
470
|
const pageNodes = [];
|
|
375
471
|
for (const rp of resolved.pages) {
|
|
376
472
|
const pageIR = buildPageIR(
|
|
@@ -378,7 +474,8 @@ async function runPipeline(essence, options) {
|
|
|
378
474
|
rp.patterns,
|
|
379
475
|
rp.wiring,
|
|
380
476
|
resolved.recipe,
|
|
381
|
-
{ gap: resolved.density.gap }
|
|
477
|
+
{ gap: resolved.density.gap },
|
|
478
|
+
layer
|
|
382
479
|
);
|
|
383
480
|
pageNodes.push(pageIR);
|
|
384
481
|
}
|
|
@@ -398,7 +495,7 @@ async function runPipeline(essence, options) {
|
|
|
398
495
|
children: [],
|
|
399
496
|
pageSignals: pageNodes.map((p) => ({
|
|
400
497
|
name: p.pageId,
|
|
401
|
-
pascalName:
|
|
498
|
+
pascalName: pascalCase(p.pageId)
|
|
402
499
|
}))
|
|
403
500
|
};
|
|
404
501
|
const appNode = {
|
|
@@ -407,7 +504,7 @@ async function runPipeline(essence, options) {
|
|
|
407
504
|
children: filteredPages,
|
|
408
505
|
theme: resolved.theme,
|
|
409
506
|
routes: resolved.routes,
|
|
410
|
-
routing: resolved.essence
|
|
507
|
+
routing: extractRouting(resolved.essence),
|
|
411
508
|
shell: shellNode,
|
|
412
509
|
store: storeNode,
|
|
413
510
|
features: resolved.features
|
|
@@ -464,6 +561,7 @@ export {
|
|
|
464
561
|
buildPageIR,
|
|
465
562
|
countPatterns,
|
|
466
563
|
findNodes,
|
|
564
|
+
pascalCase,
|
|
467
565
|
resolveEssence,
|
|
468
566
|
resolveVisualEffects,
|
|
469
567
|
runPipeline,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/pipeline.ts","../src/resolve.ts","../src/ir.ts","../src/ir-helpers.ts"],"sourcesContent":["import type { IRAppNode, IRShellNode, IRStoreNode, IRPageNode } from './types.js';\nimport type { EssenceFile } from '@decantr/essence-spec';\nimport { validateEssence } from '@decantr/essence-spec';\nimport { createResolver } from '@decantr/registry';\nimport { resolveEssence } from './resolve.js';\nimport { buildPageIR } from './ir.js';\n\nfunction pascalCase(str: string): string {\n return str.split(/[-_]/).map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('');\n}\n\nexport interface PipelineOptions {\n /** Path to content directory (patterns, archetypes, recipes) */\n contentRoot: string;\n\n /** Override paths for local content resolution */\n overridePaths?: string[];\n\n /** Only resolve specific page(s) */\n pageFilter?: string;\n}\n\nexport interface PipelineResult {\n /** The framework-agnostic intermediate representation */\n ir: IRAppNode;\n}\n\n/**\n * Run the Design Pipeline:\n * 1. Validate Essence against schema + guard rules\n * 2. Resolve all references (patterns, recipe, wiring) from registry\n * 3. Build framework-agnostic IR tree\n * 4. Return IR (no code generation — that's the consumer's job)\n */\nexport async function runPipeline(\n essence: EssenceFile,\n options: PipelineOptions,\n): Promise<PipelineResult> {\n // 1. Validate\n const validation = validateEssence(essence);\n if (!validation.valid) {\n throw new Error(`Invalid essence: ${validation.errors.join(', ')}`);\n }\n\n // 2. Create resolver and resolve\n const resolver = createResolver({\n contentRoot: options.contentRoot,\n overridePaths: options.overridePaths,\n });\n\n const resolved = await resolveEssence(essence, resolver);\n\n // 3. Build IR pages\n const pageNodes: IRPageNode[] = [];\n for (const rp of resolved.pages) {\n const pageIR = buildPageIR(\n rp.page,\n rp.patterns,\n rp.wiring,\n resolved.recipe,\n { gap: resolved.density.gap },\n );\n pageNodes.push(pageIR);\n }\n\n // Apply page filter\n let filteredPages = pageNodes;\n if (options.pageFilter) {\n filteredPages = pageNodes.filter(p => p.pageId === options.pageFilter);\n }\n\n // 4. Build shell node\n const shellNode: IRShellNode = {\n type: 'shell',\n id: 'shell',\n children: [],\n config: resolved.shell,\n };\n\n // 5. Build store node\n const storeNode: IRStoreNode = {\n type: 'store',\n id: 'store',\n children: [],\n pageSignals: pageNodes.map(p => ({\n name: p.pageId,\n pascalName: pascalCase(p.pageId),\n })),\n };\n\n // 6. Assemble app node\n const appNode: IRAppNode = {\n type: 'app',\n id: 'app',\n children: filteredPages,\n theme: resolved.theme,\n routes: resolved.routes,\n routing: (resolved.essence as { platform?: { routing?: string } }).platform?.routing as 'hash' | 'history' || 'hash',\n shell: shellNode,\n store: storeNode,\n features: resolved.features,\n };\n\n return { ir: appNode };\n}\n","import type {\n EssenceFile, Essence, SectionedEssence, StructurePage,\n LayoutItem, PatternRef, ColumnLayout,\n} from '@decantr/essence-spec';\nimport { isSimple, isSectioned, computeDensity } from '@decantr/essence-spec';\nimport type { ContentResolver, Pattern, Recipe, ResolvedPreset } from '@decantr/registry';\nimport { resolvePatternPreset, detectWirings } from '@decantr/registry';\nimport type {\n IRWiring, IRWiringSignal, IRShellConfig, IRNavItem,\n IRRecipeDecoration, IRTheme, IRRoute, IRVisualEffect,\n} from './types.js';\n\nexport interface ResolvedPage {\n page: StructurePage;\n patterns: Map<string, { pattern: Pattern; preset: ResolvedPreset }>;\n wiring: IRWiring | null;\n}\n\nexport interface ResolvedEssence {\n essence: EssenceFile;\n pages: ResolvedPage[];\n recipe: Recipe | null;\n density: { gap: string; level: string };\n theme: IRTheme;\n shell: IRShellConfig;\n routes: IRRoute[];\n features: string[];\n}\n\n// ─── Icon Mapping ─────────────────────────────────────────────\n\nconst NAV_ICONS: Record<string, string> = {\n overview: 'layout-dashboard',\n dashboard: 'layout-dashboard',\n home: 'home',\n analytics: 'bar-chart-3',\n settings: 'settings',\n users: 'users',\n billing: 'credit-card',\n reports: 'file-text',\n catalog: 'grid',\n products: 'package',\n orders: 'shopping-cart',\n messages: 'message-square',\n notifications: 'bell',\n activity: 'activity',\n search: 'search',\n profile: 'user',\n team: 'users',\n integrations: 'puzzle',\n api: 'code',\n docs: 'book-open',\n help: 'help-circle',\n projects: 'folder',\n workflows: 'git-branch',\n monitoring: 'monitor',\n security: 'shield',\n storage: 'database',\n deployments: 'rocket',\n logs: 'scroll-text',\n};\n\n// ─── Core styles that don't need explicit addon registration ──\n\nconst CORE_STYLES = new Set(['auradecantism']);\n\n// ─── Helpers ──────────────────────────────────────────────────\n\nfunction isPatternRef(item: LayoutItem): item is PatternRef {\n return typeof item === 'object' && 'pattern' in item;\n}\n\nfunction isColumnLayout(item: LayoutItem): item is ColumnLayout {\n return typeof item === 'object' && 'cols' in item;\n}\n\nfunction extractLayoutRefs(layout: LayoutItem[]): { id: string; explicitPreset?: string; alias?: string }[] {\n const refs: { id: string; explicitPreset?: string; alias?: string }[] = [];\n for (const item of layout) {\n if (typeof item === 'string') {\n refs.push({ id: item });\n } else if (isPatternRef(item)) {\n refs.push({ id: item.pattern, explicitPreset: item.preset, alias: item.as });\n } else if (isColumnLayout(item)) {\n for (const col of item.cols) {\n refs.push({ id: col });\n }\n }\n }\n return refs;\n}\n\n/** Flatten a layout array so column children are promoted to top-level for wiring detection */\nfunction flattenLayoutForWiring(layout: LayoutItem[]): LayoutItem[] {\n const flat: LayoutItem[] = [];\n for (const item of layout) {\n if (typeof item === 'string') {\n flat.push(item);\n } else if (isPatternRef(item)) {\n flat.push(item);\n } else if (isColumnLayout(item)) {\n // Promote column children as string refs\n for (const col of item.cols) {\n flat.push(col);\n }\n }\n }\n return flat;\n}\n\nfunction routePath(pageId: string, index: number): string {\n if (index === 0) return '/';\n // AUTO: Pages ending in \"-detail\" get a dynamic :id route parameter\n if (pageId.endsWith('-detail')) {\n return `/${pageId}/:id`;\n }\n return `/${pageId}`;\n}\n\nfunction pascalCase(str: string): string {\n return str.split(/[-_]/).map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('');\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nfunction buildNavItems(pages: StructurePage[]): IRNavItem[] {\n return pages.map((page, i) => ({\n href: routePath(page.id, i),\n icon: NAV_ICONS[page.id] || 'circle',\n label: capitalize(page.id.replace(/-/g, ' ')),\n }));\n}\n\nfunction buildRecipeDecoration(recipe: Recipe): IRRecipeDecoration {\n const shell = recipe.shell;\n // The JSON may have additional fields not in the strict type\n const shellAny = shell as unknown as Record<string, unknown>;\n return {\n root: shell.root || '',\n nav: shell.nav || '',\n header: shell.header || '',\n brand: (shellAny['brand'] as string) || '',\n navLabel: (shellAny['navLabel'] as string) || '',\n // AUTO: default nav style is 'pill' per Decantr framework convention\n navStyle: shell.nav_style || 'pill',\n defaultNavState: (shellAny['default_nav_state'] as string) || 'expanded',\n dimensions: shell.dimensions || null,\n };\n}\n\nfunction buildTheme(essence: Essence, isAddon: boolean): IRTheme {\n return {\n style: essence.theme.style,\n mode: essence.theme.mode,\n shape: essence.theme.shape || null,\n recipe: essence.theme.recipe,\n isAddon,\n };\n}\n\nfunction convertWiring(wiringResults: ReturnType<typeof detectWirings>): IRWiring | null {\n if (wiringResults.length === 0) return null;\n\n const signals: IRWiringSignal[] = [];\n const props: Record<string, Record<string, string>> = {};\n const hookProps: Record<string, Record<string, string>> = {};\n const hookSet = new Set<IRWiringSignal['hookType']>();\n\n for (const result of wiringResults) {\n for (const signal of result.signals) {\n // Avoid duplicate signals\n if (!signals.some(s => s.name === signal.name)) {\n const setter = 'set' + signal.name.charAt(0).toUpperCase() + signal.name.slice(1);\n signals.push({\n name: signal.name,\n setter,\n init: signal.init,\n hookType: signal.hookType,\n });\n hookSet.add(signal.hookType);\n }\n }\n for (const [alias, aliasProps] of Object.entries(result.props)) {\n props[alias] = { ...props[alias], ...aliasProps };\n }\n // AUTO: Merge hook-based prop mappings\n for (const [alias, aliasHookProps] of Object.entries(result.hookProps)) {\n hookProps[alias] = { ...hookProps[alias], ...aliasHookProps };\n }\n }\n\n return { signals, props, hooks: [...hookSet], hookProps };\n}\n\n// ─── Visual Effects Resolution ────────────────────────────────\n\nexport function resolveVisualEffects(\n recipe: Recipe,\n pattern: Pattern,\n _slot?: string,\n): IRVisualEffect | null {\n if (!recipe.visual_effects?.enabled) return null;\n\n const typeMapping = recipe.visual_effects.type_mapping || {};\n const componentFallback = recipe.visual_effects.component_fallback || {};\n const intensity = recipe.visual_effects.intensity || 'medium';\n const intensityValues = recipe.visual_effects.intensity_values || {};\n\n // Check pattern tags / components against type_mapping\n let decorators: string[] = [];\n\n // Check if any pattern components match the component_fallback\n for (const comp of pattern.components || []) {\n const effectType = componentFallback[comp];\n if (effectType && typeMapping[effectType]) {\n decorators = [...decorators, ...typeMapping[effectType]];\n }\n }\n\n if (decorators.length === 0) return null;\n\n // Deduplicate\n decorators = [...new Set(decorators)];\n\n return {\n decorators,\n intensity: intensityValues[intensity] || {},\n };\n}\n\n// ─── Main Resolution ─────────────────────────────────────────\n\n/** Resolve all external references in an Essence file */\nexport async function resolveEssence(\n essence: EssenceFile,\n resolver: ContentResolver,\n): Promise<ResolvedEssence> {\n // Extract the simple essence (handle sectioned by flattening first section for now)\n let simpleEssence: Essence;\n if (isSimple(essence)) {\n simpleEssence = essence;\n } else if (isSectioned(essence)) {\n const sectioned = essence as SectionedEssence;\n const firstSection = sectioned.sections[0];\n simpleEssence = {\n version: sectioned.version,\n archetype: firstSection.archetype,\n theme: firstSection.theme,\n personality: sectioned.personality,\n platform: sectioned.platform,\n structure: firstSection.structure,\n features: firstSection.features || [],\n density: sectioned.density,\n guard: sectioned.guard,\n target: sectioned.target,\n };\n } else {\n throw new Error('Invalid essence format');\n }\n\n // 1. Recipe resolution\n let recipe: Recipe | null = null;\n const recipeResult = await resolver.resolve('recipe', simpleEssence.theme.recipe);\n if (recipeResult) {\n recipe = recipeResult.item;\n }\n\n // 2. Density computation\n const recipeSpatial = recipe?.spatial_hints;\n const density = computeDensity(simpleEssence.personality, recipeSpatial ? {\n density_bias: recipeSpatial.density_bias,\n content_gap_shift: recipeSpatial.content_gap_shift,\n } : undefined);\n\n // 3. Theme\n const style = simpleEssence.theme.style;\n const isAddon = style.startsWith('custom:') || !CORE_STYLES.has(style);\n const theme = buildTheme(simpleEssence, isAddon);\n\n // 4. Resolve each page\n const resolvedPages: ResolvedPage[] = [];\n for (const page of simpleEssence.structure) {\n const refs = extractLayoutRefs(page.layout);\n const patterns = new Map<string, { pattern: Pattern; preset: ResolvedPreset }>();\n\n for (const ref of refs) {\n const patternResult = await resolver.resolve('pattern', ref.id);\n if (patternResult) {\n const preset = resolvePatternPreset(\n patternResult.item,\n ref.explicitPreset,\n recipe?.pattern_preferences?.default_presets,\n );\n const key = ref.alias || ref.id;\n patterns.set(key, { pattern: patternResult.item, preset });\n }\n }\n\n // Detect wiring (flatten cols so column children are visible)\n const wiringResults = detectWirings(flattenLayoutForWiring(page.layout));\n const wiring = convertWiring(wiringResults);\n\n resolvedPages.push({ page, patterns, wiring });\n }\n\n // 5. Shell config\n const shellType = simpleEssence.structure[0]?.shell || 'sidebar-main';\n const brand = pascalCase(simpleEssence.archetype);\n const nav = buildNavItems(simpleEssence.structure);\n const recipeDecoration = recipe ? buildRecipeDecoration(recipe) : null;\n\n const shell: IRShellConfig = {\n type: shellType,\n brand,\n nav,\n inset: false,\n recipe: recipeDecoration,\n };\n\n // 6. Routes\n const routes: IRRoute[] = simpleEssence.structure.map((page, i) => ({\n path: routePath(page.id, i),\n pageId: page.id,\n }));\n\n return {\n essence,\n pages: resolvedPages,\n recipe,\n density: { gap: density.content_gap, level: density.level },\n theme,\n shell,\n routes,\n features: simpleEssence.features ?? [],\n };\n}\n","import type {\n IRPageNode, IRPatternNode, IRGridNode, IRWiring,\n IRCardWrapping, IRPatternMeta, IRVisualEffect, IRNode,\n} from './types.js';\nimport type { StructurePage, LayoutItem, PatternRef, ColumnLayout } from '@decantr/essence-spec';\nimport type { Pattern, Recipe, ResolvedPreset } from '@decantr/registry';\n\nexport interface ResolvedPatternEntry {\n pattern: Pattern;\n preset: ResolvedPreset;\n}\n\nfunction isPatternRef(item: LayoutItem): item is PatternRef {\n return typeof item === 'object' && 'pattern' in item;\n}\n\nfunction isColumnLayout(item: LayoutItem): item is ColumnLayout {\n return typeof item === 'object' && 'cols' in item;\n}\n\nfunction pascalCase(str: string): string {\n return str.split(/[-_]/).map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('');\n}\n\nfunction getPatternAlias(item: LayoutItem): string {\n if (typeof item === 'string') return item;\n if (isPatternRef(item)) return item.as || item.pattern;\n return '';\n}\n\nfunction getPatternId(item: LayoutItem): string {\n if (typeof item === 'string') return item;\n if (isPatternRef(item)) return item.pattern;\n return '';\n}\n\nfunction shouldWrapInCard(\n pattern: Pattern,\n preset: ResolvedPreset,\n recipe: Recipe | null,\n): boolean {\n // Hero/row/stack layouts are standalone\n const layout = preset.layout.layout;\n if (layout === 'hero' || layout === 'row') return false;\n\n // Pattern explicitly opts out\n if (pattern.contained === false) return false;\n\n // Recipe says no cards\n const cardWrapping = recipe?.spatial_hints?.card_wrapping;\n if (cardWrapping === 'none') return false;\n\n // Minimal: only wrap if pattern has presets (complex pattern)\n if (cardWrapping === 'minimal') {\n return Object.keys(pattern.presets).length > 0;\n }\n\n // Default: wrap\n return true;\n}\n\nfunction buildCardWrapping(\n pattern: Pattern,\n recipe: Recipe | null,\n): IRCardWrapping {\n const mode = recipe?.spatial_hints?.card_wrapping || 'always';\n const overrides = recipe?.pattern_overrides?.[pattern.id];\n return {\n mode: mode as IRCardWrapping['mode'],\n headerLabel: pattern.name,\n background: overrides?.background?.join(' '),\n };\n}\n\nfunction buildPatternNode(\n patternId: string,\n alias: string,\n resolved: ResolvedPatternEntry | undefined,\n wiring: IRWiring | null,\n recipe: Recipe | null,\n density: { gap: string },\n): IRPatternNode {\n const pattern = resolved?.pattern;\n const preset = resolved?.preset;\n\n const layout = preset?.layout.layout || 'column';\n const isStandalone = layout === 'hero' || layout === 'row';\n const contained = pattern && preset ? shouldWrapInCard(pattern, preset, recipe) : false;\n const components = pattern?.components || [];\n\n const patternMeta: IRPatternMeta = {\n patternId,\n preset: preset?.preset || 'default',\n alias,\n layout,\n contained,\n standalone: isStandalone,\n code: preset?.code ? { imports: preset.code.imports, example: preset.code.example } : null,\n components,\n };\n\n const card = contained && !isStandalone && pattern\n ? buildCardWrapping(pattern, recipe)\n : null;\n\n const wireProps = wiring?.props[alias] || wiring?.props[patternId] || null;\n\n return {\n type: 'pattern',\n id: alias,\n children: [],\n pattern: patternMeta,\n card,\n visualEffects: null,\n wireProps,\n spatial: { gap: density.gap },\n };\n}\n\n/** Build IR tree for a single page from its resolved structure + patterns */\nexport function buildPageIR(\n page: StructurePage,\n resolvedPatterns: Map<string, ResolvedPatternEntry>,\n wiring: IRWiring | null,\n recipe: Recipe | null,\n density: { gap: string },\n): IRPageNode {\n const children: IRNode[] = [];\n\n for (const item of page.layout) {\n if (typeof item === 'string') {\n // Simple string → full-width pattern\n const resolved = resolvedPatterns.get(item);\n children.push(buildPatternNode(item, item, resolved, wiring, recipe, density));\n } else if (isPatternRef(item)) {\n // PatternRef → pattern with optional preset/alias\n const alias = item.as || item.pattern;\n const resolved = resolvedPatterns.get(alias) || resolvedPatterns.get(item.pattern);\n children.push(buildPatternNode(item.pattern, alias, resolved, wiring, recipe, density));\n } else if (isColumnLayout(item)) {\n // ColumnLayout → grid with pattern children\n const cols = item.cols;\n const breakpoint = item.at || null;\n const spans = item.span || null;\n\n // Normalize spans: fill in missing columns with weight 1\n let normalizedSpans: Record<string, number> | null = null;\n if (spans) {\n normalizedSpans = {};\n for (const col of cols) {\n normalizedSpans[col] = spans[col] || 1;\n }\n }\n\n const gridChildren: IRNode[] = [];\n for (const col of cols) {\n const resolved = resolvedPatterns.get(col);\n gridChildren.push(buildPatternNode(col, col, resolved, wiring, recipe, density));\n }\n\n const totalCols = normalizedSpans\n ? Object.values(normalizedSpans).reduce((a, b) => a + b, 0)\n : cols.length;\n\n // AUTO: Pass through multi-breakpoint and container query config from ColumnLayout\n const breakpoints = item.breakpoints?.map(bp => ({ at: bp.at, cols: bp.cols })) || null;\n const responsive = item.responsive || null;\n\n const gridNode: IRGridNode = {\n type: 'grid',\n id: `grid-${cols.join('-')}`,\n children: gridChildren,\n cols: totalCols,\n spans: normalizedSpans,\n breakpoint,\n breakpoints,\n responsive,\n spatial: { gap: density.gap },\n };\n children.push(gridNode);\n }\n }\n\n const surface = page.surface || `_flex _col _gap${density.gap} _p4 _overflow[auto] _flex1`;\n\n return {\n type: 'page',\n id: page.id,\n children,\n pageId: page.id,\n surface,\n wiring,\n };\n}\n","import type { IRNode, IRPatternNode, IRGridNode } from './types.js';\n\n/** Depth-first walk of IR tree, calling visitor on each node */\nexport function walkIR(\n node: IRNode,\n visitor: (node: IRNode, parent: IRNode | null) => void,\n parent: IRNode | null = null,\n): void {\n visitor(node, parent);\n for (const child of node.children) {\n walkIR(child, visitor, node);\n }\n}\n\n/** Find all nodes of a specific type */\nexport function findNodes<T extends IRNode>(root: IRNode, type: string): T[] {\n const results: T[] = [];\n walkIR(root, (node) => {\n if (node.type === type) {\n results.push(node as T);\n }\n });\n return results;\n}\n\n/** Count total patterns in an IR tree */\nexport function countPatterns(root: IRNode): number {\n return findNodes(root, 'pattern').length;\n}\n\n/** Validate IR tree structure (no orphaned grids, patterns have meta, etc.) */\nexport function validateIR(root: IRNode): string[] {\n const errors: string[] = [];\n\n walkIR(root, (node, parent) => {\n if (node.type === 'grid') {\n const grid = node as IRGridNode;\n if (grid.children.length === 0) {\n errors.push(`Grid node \"${grid.id}\" has no children`);\n }\n }\n\n if (node.type === 'pattern') {\n const pattern = node as IRPatternNode;\n if (!pattern.pattern) {\n errors.push(`Pattern node \"${pattern.id}\" is missing pattern meta`);\n }\n if (!pattern.pattern.patternId) {\n errors.push(`Pattern node \"${pattern.id}\" has no patternId`);\n }\n }\n\n if (node.type === 'page') {\n if (!node.id) {\n errors.push('Page node is missing id');\n }\n }\n });\n\n return errors;\n}\n"],"mappings":"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","names":["isPatternRef","isColumnLayout","isPatternRef","isColumnLayout","pascalCase"]}
|
|
1
|
+
{"version":3,"sources":["../src/pipeline.ts","../src/resolve.ts","../src/utils.ts","../src/ir.ts","../src/ir-helpers.ts"],"sourcesContent":["import type { IRAppNode, IRShellNode, IRStoreNode, IRPageNode, IRLayer } from './types.js';\nimport type { EssenceFile } from '@decantr/essence-spec';\nimport { validateEssence, isV3, migrateV2ToV3 } from '@decantr/essence-spec';\nimport { createResolver } from '@decantr/registry';\nimport { resolveEssence } from './resolve.js';\nimport { buildPageIR } from './ir.js';\nimport { pascalCase } from './utils.js';\n\nfunction extractRouting(essence: EssenceFile): 'hash' | 'history' {\n if (isV3(essence)) {\n return essence.meta.platform.routing || 'hash';\n }\n return (essence as { platform?: { routing?: string } }).platform?.routing as 'hash' | 'history' || 'hash';\n}\n\nexport interface PipelineOptions {\n /** Path to content directory (patterns, archetypes, recipes) */\n contentRoot: string;\n\n /** Override paths for local content resolution */\n overridePaths?: string[];\n\n /** Only resolve specific page(s) */\n pageFilter?: string;\n}\n\nexport interface PipelineResult {\n /** The framework-agnostic intermediate representation */\n ir: IRAppNode;\n}\n\n/**\n * Run the Design Pipeline:\n * 1. Validate Essence against schema + guard rules\n * 2. Resolve all references (patterns, recipe, wiring) from registry\n * 3. Build framework-agnostic IR tree\n * 4. Return IR (no code generation — that's the consumer's job)\n */\nexport async function runPipeline(\n essence: EssenceFile,\n options: PipelineOptions,\n): Promise<PipelineResult> {\n // 1. Validate\n const validation = validateEssence(essence);\n if (!validation.valid) {\n throw new Error(`Invalid essence: ${validation.errors.join(', ')}`);\n }\n\n // 2. Auto-migrate v2 → v3 before processing\n const effectiveEssence = isV3(essence) ? essence : migrateV2ToV3(essence);\n\n // 3. Create resolver and resolve\n const resolver = createResolver({\n contentRoot: options.contentRoot,\n overridePaths: options.overridePaths,\n });\n\n const resolved = await resolveEssence(effectiveEssence, resolver);\n\n // 4. Build IR pages (v3 sources get layer metadata)\n const layer: IRLayer | undefined = resolved.isV3Source ? 'blueprint' : undefined;\n const pageNodes: IRPageNode[] = [];\n for (const rp of resolved.pages) {\n const pageIR = buildPageIR(\n rp.page,\n rp.patterns,\n rp.wiring,\n resolved.recipe,\n { gap: resolved.density.gap },\n layer,\n );\n pageNodes.push(pageIR);\n }\n\n // Apply page filter\n let filteredPages = pageNodes;\n if (options.pageFilter) {\n filteredPages = pageNodes.filter(p => p.pageId === options.pageFilter);\n }\n\n // 4. Build shell node\n const shellNode: IRShellNode = {\n type: 'shell',\n id: 'shell',\n children: [],\n config: resolved.shell,\n };\n\n // 5. Build store node\n const storeNode: IRStoreNode = {\n type: 'store',\n id: 'store',\n children: [],\n pageSignals: pageNodes.map(p => ({\n name: p.pageId,\n pascalName: pascalCase(p.pageId),\n })),\n };\n\n // 6. Assemble app node\n const appNode: IRAppNode = {\n type: 'app',\n id: 'app',\n children: filteredPages,\n theme: resolved.theme,\n routes: resolved.routes,\n routing: extractRouting(resolved.essence),\n shell: shellNode,\n store: storeNode,\n features: resolved.features,\n };\n\n return { ir: appNode };\n}\n","import type {\n EssenceFile, Essence, SectionedEssence, EssenceV3, StructurePage,\n LayoutItem, PatternRef, ColumnLayout, BlueprintPage,\n} from '@decantr/essence-spec';\nimport { isSimple, isSectioned, isV3, computeDensity } from '@decantr/essence-spec';\nimport { pascalCase } from './utils.js';\nimport type { ContentResolver, Pattern, Recipe, ResolvedPreset } from '@decantr/registry';\nimport { resolvePatternPreset, detectWirings } from '@decantr/registry';\nimport type {\n IRWiring, IRWiringSignal, IRShellConfig, IRNavItem,\n IRRecipeDecoration, IRTheme, IRRoute, IRVisualEffect,\n} from './types.js';\n\nexport interface ResolvedPage {\n page: StructurePage;\n patterns: Map<string, { pattern: Pattern; preset: ResolvedPreset }>;\n wiring: IRWiring | null;\n}\n\nexport interface ResolvedEssence {\n essence: EssenceFile;\n pages: ResolvedPage[];\n recipe: Recipe | null;\n density: { gap: string; level: string };\n theme: IRTheme;\n shell: IRShellConfig;\n routes: IRRoute[];\n features: string[];\n /** True when the source essence was v3 (DNA/Blueprint/Meta) */\n isV3Source: boolean;\n}\n\n// ─── Icon Mapping ─────────────────────────────────────────────\n\nconst NAV_ICONS: Record<string, string> = {\n overview: 'layout-dashboard',\n dashboard: 'layout-dashboard',\n home: 'home',\n analytics: 'bar-chart-3',\n settings: 'settings',\n users: 'users',\n billing: 'credit-card',\n reports: 'file-text',\n catalog: 'grid',\n products: 'package',\n orders: 'shopping-cart',\n messages: 'message-square',\n notifications: 'bell',\n activity: 'activity',\n search: 'search',\n profile: 'user',\n team: 'users',\n integrations: 'puzzle',\n api: 'code',\n docs: 'book-open',\n help: 'help-circle',\n projects: 'folder',\n workflows: 'git-branch',\n monitoring: 'monitor',\n security: 'shield',\n storage: 'database',\n deployments: 'rocket',\n logs: 'scroll-text',\n};\n\n// ─── Core styles that don't need explicit addon registration ──\n\nconst CORE_STYLES = new Set(['auradecantism']);\n\n// ─── Helpers ──────────────────────────────────────────────────\n\nfunction isPatternRef(item: LayoutItem): item is PatternRef {\n return typeof item === 'object' && 'pattern' in item;\n}\n\nfunction isColumnLayout(item: LayoutItem): item is ColumnLayout {\n return typeof item === 'object' && 'cols' in item;\n}\n\nfunction extractLayoutRefs(layout: LayoutItem[]): { id: string; explicitPreset?: string; alias?: string }[] {\n const refs: { id: string; explicitPreset?: string; alias?: string }[] = [];\n for (const item of layout) {\n if (typeof item === 'string') {\n refs.push({ id: item });\n } else if (isPatternRef(item)) {\n refs.push({ id: item.pattern, explicitPreset: item.preset, alias: item.as });\n } else if (isColumnLayout(item)) {\n for (const col of item.cols) {\n refs.push({ id: col });\n }\n }\n }\n return refs;\n}\n\n/** Flatten a layout array so column children are promoted to top-level for wiring detection */\nfunction flattenLayoutForWiring(layout: LayoutItem[]): LayoutItem[] {\n const flat: LayoutItem[] = [];\n for (const item of layout) {\n if (typeof item === 'string') {\n flat.push(item);\n } else if (isPatternRef(item)) {\n flat.push(item);\n } else if (isColumnLayout(item)) {\n // Promote column children as string refs\n for (const col of item.cols) {\n flat.push(col);\n }\n }\n }\n return flat;\n}\n\nfunction routePath(pageId: string, index: number): string {\n if (index === 0) return '/';\n // AUTO: Pages ending in \"-detail\" get a dynamic :id route parameter\n if (pageId.endsWith('-detail')) {\n return `/${pageId}/:id`;\n }\n return `/${pageId}`;\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nfunction buildNavItems(pages: StructurePage[]): IRNavItem[] {\n return pages.map((page, i) => ({\n href: routePath(page.id, i),\n icon: NAV_ICONS[page.id] || 'circle',\n label: capitalize(page.id.replace(/-/g, ' ')),\n }));\n}\n\nfunction buildRecipeDecoration(recipe: Recipe): IRRecipeDecoration {\n const shell = recipe.shell;\n // The JSON may have additional fields not in the strict type\n const shellAny = shell as unknown as Record<string, unknown>;\n return {\n root: shell.root || '',\n nav: shell.nav || '',\n header: shell.header || '',\n brand: (shellAny['brand'] as string) || '',\n navLabel: (shellAny['navLabel'] as string) || '',\n // AUTO: default nav style is 'pill' per Decantr framework convention\n navStyle: shell.nav_style || 'pill',\n defaultNavState: (shellAny['default_nav_state'] as string) || 'expanded',\n dimensions: shell.dimensions || null,\n };\n}\n\nfunction buildTheme(essence: Essence, isAddon: boolean): IRTheme {\n return {\n style: essence.theme.style,\n mode: essence.theme.mode,\n shape: essence.theme.shape || null,\n recipe: essence.theme.recipe,\n isAddon,\n };\n}\n\nfunction buildThemeFromV3(essence: EssenceV3, isAddon: boolean): IRTheme {\n const dna = essence.dna;\n return {\n style: dna.theme.style,\n mode: dna.theme.mode,\n shape: dna.radius.philosophy || dna.theme.shape || null,\n recipe: dna.theme.recipe,\n isAddon,\n };\n}\n\n/** Convert v3 BlueprintPage to the StructurePage shape used by the resolver pipeline */\nfunction blueprintPageToStructurePage(page: BlueprintPage, defaultShell: string): StructurePage {\n return {\n id: page.id,\n shell: page.shell_override ?? defaultShell,\n layout: page.layout,\n ...(page.surface ? { surface: page.surface } : {}),\n };\n}\n\nfunction convertWiring(wiringResults: ReturnType<typeof detectWirings>): IRWiring | null {\n if (wiringResults.length === 0) return null;\n\n const signals: IRWiringSignal[] = [];\n const props: Record<string, Record<string, string>> = {};\n const hookProps: Record<string, Record<string, string>> = {};\n const hookSet = new Set<IRWiringSignal['hookType']>();\n\n for (const result of wiringResults) {\n for (const signal of result.signals) {\n // Avoid duplicate signals\n if (!signals.some(s => s.name === signal.name)) {\n const setter = 'set' + signal.name.charAt(0).toUpperCase() + signal.name.slice(1);\n signals.push({\n name: signal.name,\n setter,\n init: signal.init,\n hookType: signal.hookType,\n });\n hookSet.add(signal.hookType);\n }\n }\n for (const [alias, aliasProps] of Object.entries(result.props)) {\n props[alias] = { ...props[alias], ...aliasProps };\n }\n // AUTO: Merge hook-based prop mappings\n for (const [alias, aliasHookProps] of Object.entries(result.hookProps)) {\n hookProps[alias] = { ...hookProps[alias], ...aliasHookProps };\n }\n }\n\n return { signals, props, hooks: [...hookSet], hookProps };\n}\n\n// ─── Visual Effects Resolution ────────────────────────────────\n\nexport function resolveVisualEffects(\n recipe: Recipe,\n pattern: Pattern,\n _slot?: string,\n): IRVisualEffect | null {\n if (!recipe.visual_effects?.enabled) return null;\n\n const typeMapping = recipe.visual_effects.type_mapping || {};\n const componentFallback = recipe.visual_effects.component_fallback || {};\n const intensity = recipe.visual_effects.intensity || 'medium';\n const intensityValues = recipe.visual_effects.intensity_values || {};\n\n // Check pattern tags / components against type_mapping\n let decorators: string[] = [];\n\n // Check if any pattern components match the component_fallback\n for (const comp of pattern.components || []) {\n const effectType = componentFallback[comp];\n if (effectType && typeMapping[effectType]) {\n decorators = [...decorators, ...typeMapping[effectType]];\n }\n }\n\n if (decorators.length === 0) return null;\n\n // Deduplicate\n decorators = [...new Set(decorators)];\n\n return {\n decorators,\n intensity: intensityValues[intensity] || {},\n };\n}\n\n// ─── Main Resolution ─────────────────────────────────────────\n\n/** Resolve all external references in an Essence file */\nexport async function resolveEssence(\n essence: EssenceFile,\n resolver: ContentResolver,\n): Promise<ResolvedEssence> {\n // ─── V3 path: read from dna + blueprint layers ───────────\n if (isV3(essence)) {\n return resolveV3Essence(essence, resolver);\n }\n\n // ─── V2 path: simple or sectioned ────────────────────────\n let simpleEssence: Essence;\n if (isSimple(essence)) {\n simpleEssence = essence;\n } else if (isSectioned(essence)) {\n const sectioned = essence as SectionedEssence;\n if (sectioned.sections.length > 1) {\n throw new Error(\n `Sectioned essences with ${sectioned.sections.length} sections are not yet supported. ` +\n `Only single-section sectioned essences can be processed. ` +\n `Consider migrating to v3 format using migrateV2ToV3().`,\n );\n }\n const firstSection = sectioned.sections[0];\n simpleEssence = {\n version: sectioned.version,\n archetype: firstSection.archetype,\n theme: firstSection.theme,\n personality: sectioned.personality,\n platform: sectioned.platform,\n structure: firstSection.structure,\n features: firstSection.features || [],\n density: sectioned.density,\n guard: sectioned.guard,\n target: sectioned.target,\n };\n } else {\n throw new Error('Invalid essence format');\n }\n\n // 1. Recipe resolution\n let recipe: Recipe | null = null;\n const recipeResult = await resolver.resolve('recipe', simpleEssence.theme.recipe);\n if (recipeResult) {\n recipe = recipeResult.item;\n }\n\n // 2. Density computation\n const recipeSpatial = recipe?.spatial_hints;\n const density = computeDensity(simpleEssence.personality, recipeSpatial ? {\n density_bias: recipeSpatial.density_bias,\n content_gap_shift: recipeSpatial.content_gap_shift,\n } : undefined);\n\n // 3. Theme\n const style = simpleEssence.theme.style;\n const isAddon = style.startsWith('custom:') || !CORE_STYLES.has(style);\n const theme = buildTheme(simpleEssence, isAddon);\n\n // 4. Resolve each page\n const resolvedPages = await resolvePages(simpleEssence.structure, resolver, recipe);\n\n // 5. Shell config\n const shellType = simpleEssence.structure[0]?.shell || 'sidebar-main';\n const brand = pascalCase(simpleEssence.archetype);\n const nav = buildNavItems(simpleEssence.structure);\n const recipeDecoration = recipe ? buildRecipeDecoration(recipe) : null;\n\n const shell: IRShellConfig = {\n type: shellType,\n brand,\n nav,\n inset: false,\n recipe: recipeDecoration,\n };\n\n // 6. Routes\n const routes: IRRoute[] = simpleEssence.structure.map((page, i) => ({\n path: routePath(page.id, i),\n pageId: page.id,\n }));\n\n return {\n essence,\n pages: resolvedPages,\n recipe,\n density: { gap: density.content_gap, level: density.level },\n theme,\n shell,\n routes,\n features: simpleEssence.features ?? [],\n isV3Source: false,\n };\n}\n\n// ─── V3 Resolution ──────────────────────────────────────────\n\nasync function resolveV3Essence(\n essence: EssenceV3,\n resolver: ContentResolver,\n): Promise<ResolvedEssence> {\n const { dna, blueprint, meta } = essence;\n\n // 1. Recipe resolution (from dna.theme.recipe)\n let recipe: Recipe | null = null;\n const recipeResult = await resolver.resolve('recipe', dna.theme.recipe);\n if (recipeResult) {\n recipe = recipeResult.item;\n }\n\n // 2. Density — v3 carries density directly in dna.spacing\n const recipeSpatial = recipe?.spatial_hints;\n const density = computeDensity(dna.personality, recipeSpatial ? {\n density_bias: recipeSpatial.density_bias,\n content_gap_shift: recipeSpatial.content_gap_shift,\n } : undefined);\n // V3 dna.spacing is authoritative; override computed density with DNA values\n const densityResult = {\n gap: dna.spacing.content_gap || density.content_gap,\n level: dna.spacing.density || density.level,\n };\n\n // 3. Theme from DNA layer\n const style = dna.theme.style;\n const isAddon = style.startsWith('custom:') || !CORE_STYLES.has(style);\n const theme = buildThemeFromV3(essence, isAddon);\n\n // 4. Convert blueprint pages to StructurePage and resolve\n // V3.1 essences may use sections instead of pages; flatten sections into pages\n const blueprintPages = blueprint.pages ?? (\n blueprint.sections\n ? blueprint.sections.flatMap(s => s.pages)\n : [{ id: 'home', layout: ['hero'] as LayoutItem[] }]\n );\n const defaultShell = blueprint.shell ?? (\n blueprint.sections?.[0]?.shell ?? 'sidebar-main'\n );\n const structurePages: StructurePage[] = blueprintPages.map(\n p => blueprintPageToStructurePage(p, defaultShell),\n );\n const resolvedPages = await resolvePages(structurePages, resolver, recipe);\n\n // 5. Shell config from blueprint\n const shellType = defaultShell;\n const brand = pascalCase(meta.archetype);\n const nav = buildNavItems(structurePages);\n const recipeDecoration = recipe ? buildRecipeDecoration(recipe) : null;\n\n const shell: IRShellConfig = {\n type: shellType,\n brand,\n nav,\n inset: false,\n recipe: recipeDecoration,\n };\n\n // 6. Routes\n const routes: IRRoute[] = structurePages.map((page, i) => ({\n path: routePath(page.id, i),\n pageId: page.id,\n }));\n\n return {\n essence,\n pages: resolvedPages,\n recipe,\n density: densityResult,\n theme,\n shell,\n routes,\n features: blueprint.features ?? [],\n isV3Source: true,\n };\n}\n\n// ─── Shared page resolution ────────────────────────────────\n\nasync function resolvePages(\n pages: StructurePage[],\n resolver: ContentResolver,\n recipe: Recipe | null,\n): Promise<ResolvedPage[]> {\n const resolvedPages: ResolvedPage[] = [];\n for (const page of pages) {\n const refs = extractLayoutRefs(page.layout);\n const patterns = new Map<string, { pattern: Pattern; preset: ResolvedPreset }>();\n\n for (const ref of refs) {\n const patternResult = await resolver.resolve('pattern', ref.id);\n if (patternResult) {\n const preset = resolvePatternPreset(\n patternResult.item,\n ref.explicitPreset,\n recipe?.pattern_preferences?.default_presets,\n );\n const key = ref.alias || ref.id;\n patterns.set(key, { pattern: patternResult.item, preset });\n }\n }\n\n // Detect wiring (flatten cols so column children are visible)\n const wiringResults = detectWirings(flattenLayoutForWiring(page.layout));\n const wiring = convertWiring(wiringResults);\n\n resolvedPages.push({ page, patterns, wiring });\n }\n return resolvedPages;\n}\n","/** Convert a kebab-case or snake_case string to PascalCase */\nexport function pascalCase(str: string): string {\n return str.split(/[-_]/).map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('');\n}\n","import type {\n IRPageNode, IRPatternNode, IRGridNode, IRWiring,\n IRCardWrapping, IRPatternMeta, IRVisualEffect, IRNode, IRLayer,\n} from './types.js';\nimport type { StructurePage, LayoutItem, PatternRef, ColumnLayout } from '@decantr/essence-spec';\nimport type { Pattern, Recipe, ResolvedPreset } from '@decantr/registry';\nimport { resolveVisualEffects } from './resolve.js';\n\nexport interface ResolvedPatternEntry {\n pattern: Pattern;\n preset: ResolvedPreset;\n}\n\nfunction isPatternRef(item: LayoutItem): item is PatternRef {\n return typeof item === 'object' && 'pattern' in item;\n}\n\nfunction isColumnLayout(item: LayoutItem): item is ColumnLayout {\n return typeof item === 'object' && 'cols' in item;\n}\n\nfunction getPatternAlias(item: LayoutItem): string {\n if (typeof item === 'string') return item;\n if (isPatternRef(item)) return item.as || item.pattern;\n return '';\n}\n\nfunction getPatternId(item: LayoutItem): string {\n if (typeof item === 'string') return item;\n if (isPatternRef(item)) return item.pattern;\n return '';\n}\n\nfunction shouldWrapInCard(\n pattern: Pattern,\n preset: ResolvedPreset,\n recipe: Recipe | null,\n): boolean {\n // Hero/row/stack layouts are standalone\n const layout = preset.layout.layout;\n if (layout === 'hero' || layout === 'row') return false;\n\n // Pattern explicitly opts out\n if (pattern.contained === false) return false;\n\n // Recipe says no cards\n const cardWrapping = recipe?.spatial_hints?.card_wrapping;\n if (cardWrapping === 'none') return false;\n\n // Minimal: only wrap if pattern has presets (complex pattern)\n if (cardWrapping === 'minimal') {\n return Object.keys(pattern.presets).length > 0;\n }\n\n // Default: wrap\n return true;\n}\n\nfunction buildCardWrapping(\n pattern: Pattern,\n recipe: Recipe | null,\n): IRCardWrapping {\n const mode = recipe?.spatial_hints?.card_wrapping || 'always';\n const overrides = recipe?.pattern_overrides?.[pattern.id];\n return {\n mode: mode as IRCardWrapping['mode'],\n headerLabel: pattern.name,\n background: overrides?.background?.join(' '),\n };\n}\n\nfunction buildPatternNode(\n patternId: string,\n alias: string,\n resolved: ResolvedPatternEntry | undefined,\n wiring: IRWiring | null,\n recipe: Recipe | null,\n density: { gap: string },\n layer?: IRLayer,\n): IRPatternNode {\n const pattern = resolved?.pattern;\n const preset = resolved?.preset;\n\n const layout = preset?.layout.layout || 'column';\n const isStandalone = layout === 'hero' || layout === 'row';\n const contained = pattern && preset ? shouldWrapInCard(pattern, preset, recipe) : false;\n const components = pattern?.components || [];\n\n const patternMeta: IRPatternMeta = {\n patternId,\n preset: preset?.preset || 'default',\n alias,\n layout,\n contained,\n standalone: isStandalone,\n code: preset?.code ? { imports: preset.code.imports, example: preset.code.example } : null,\n components,\n };\n\n const card = contained && !isStandalone && pattern\n ? buildCardWrapping(pattern, recipe)\n : null;\n\n const wireProps = wiring?.props[alias] || wiring?.props[patternId] || null;\n\n // Resolve visual effects from recipe + pattern when available\n const visualEffects = recipe && pattern\n ? resolveVisualEffects(recipe, pattern)\n : null;\n\n return {\n type: 'pattern',\n id: alias,\n children: [],\n pattern: patternMeta,\n card,\n visualEffects,\n wireProps,\n spatial: { gap: density.gap },\n ...(layer ? { layer } : {}),\n };\n}\n\n/** Build IR tree for a single page from its resolved structure + patterns */\nexport function buildPageIR(\n page: StructurePage,\n resolvedPatterns: Map<string, ResolvedPatternEntry>,\n wiring: IRWiring | null,\n recipe: Recipe | null,\n density: { gap: string },\n layer?: IRLayer,\n): IRPageNode {\n const children: IRNode[] = [];\n\n for (const item of page.layout) {\n if (typeof item === 'string') {\n // Simple string → full-width pattern\n const resolved = resolvedPatterns.get(item);\n children.push(buildPatternNode(item, item, resolved, wiring, recipe, density, layer));\n } else if (isPatternRef(item)) {\n // PatternRef → pattern with optional preset/alias\n const alias = item.as || item.pattern;\n const resolved = resolvedPatterns.get(alias) || resolvedPatterns.get(item.pattern);\n children.push(buildPatternNode(item.pattern, alias, resolved, wiring, recipe, density, layer));\n } else if (isColumnLayout(item)) {\n // ColumnLayout → grid with pattern children\n const cols = item.cols;\n const breakpoint = item.at || null;\n const spans = item.span || null;\n\n // Normalize spans: fill in missing columns with weight 1\n let normalizedSpans: Record<string, number> | null = null;\n if (spans) {\n normalizedSpans = {};\n for (const col of cols) {\n normalizedSpans[col] = spans[col] || 1;\n }\n }\n\n const gridChildren: IRNode[] = [];\n for (const col of cols) {\n const resolved = resolvedPatterns.get(col);\n gridChildren.push(buildPatternNode(col, col, resolved, wiring, recipe, density, layer));\n }\n\n const totalCols = normalizedSpans\n ? Object.values(normalizedSpans).reduce((a, b) => a + b, 0)\n : cols.length;\n\n // AUTO: Pass through multi-breakpoint and container query config from ColumnLayout\n const breakpoints = item.breakpoints?.map(bp => ({ at: bp.at, cols: bp.cols })) || null;\n const responsive = item.responsive || null;\n\n const gridNode: IRGridNode = {\n type: 'grid',\n id: `grid-${cols.join('-')}`,\n children: gridChildren,\n cols: totalCols,\n spans: normalizedSpans,\n breakpoint,\n breakpoints,\n responsive,\n spatial: { gap: density.gap },\n ...(layer ? { layer } : {}),\n };\n children.push(gridNode);\n }\n }\n\n const surface = page.surface || `_flex _col _gap${density.gap} _p4 _overflow[auto] _flex1`;\n\n return {\n type: 'page',\n id: page.id,\n children,\n pageId: page.id,\n surface,\n wiring,\n ...(layer ? { layer } : {}),\n };\n}\n","import type { IRNode, IRPatternNode, IRGridNode } from './types.js';\n\n/** Depth-first walk of IR tree, calling visitor on each node */\nexport function walkIR(\n node: IRNode,\n visitor: (node: IRNode, parent: IRNode | null) => void,\n parent: IRNode | null = null,\n): void {\n visitor(node, parent);\n for (const child of node.children) {\n walkIR(child, visitor, node);\n }\n}\n\n/** Find all nodes of a specific type */\nexport function findNodes<T extends IRNode>(root: IRNode, type: string): T[] {\n const results: T[] = [];\n walkIR(root, (node) => {\n if (node.type === type) {\n results.push(node as T);\n }\n });\n return results;\n}\n\n/** Count total patterns in an IR tree */\nexport function countPatterns(root: IRNode): number {\n return findNodes(root, 'pattern').length;\n}\n\n/** Validate IR tree structure (no orphaned grids, patterns have meta, etc.) */\nexport function validateIR(root: IRNode): string[] {\n const errors: string[] = [];\n\n walkIR(root, (node, parent) => {\n if (node.type === 'grid') {\n const grid = node as IRGridNode;\n if (grid.children.length === 0) {\n errors.push(`Grid node \"${grid.id}\" has no children`);\n }\n }\n\n if (node.type === 'pattern') {\n const pattern = node as IRPatternNode;\n if (!pattern.pattern) {\n errors.push(`Pattern node \"${pattern.id}\" is missing pattern meta`);\n }\n if (!pattern.pattern.patternId) {\n errors.push(`Pattern node \"${pattern.id}\" has no patternId`);\n }\n }\n\n if (node.type === 'page') {\n if (!node.id) {\n errors.push('Page node is missing id');\n }\n }\n });\n\n return errors;\n}\n"],"mappings":"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","names":["isV3","isPatternRef","isColumnLayout","isPatternRef","isColumnLayout","isV3"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decantr/core",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.6",
|
|
4
4
|
"description": "Decantr core — Design Pipeline IR engine for AI-generated UI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -18,18 +18,20 @@
|
|
|
18
18
|
"types": "./dist/index.d.ts"
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
|
-
"files": [
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
22
24
|
"publishConfig": {
|
|
23
25
|
"access": "public"
|
|
24
26
|
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@decantr/essence-spec": "1.0.0-beta.6",
|
|
29
|
+
"@decantr/registry": "1.0.0-beta.6"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {},
|
|
25
32
|
"scripts": {
|
|
26
33
|
"build": "tsup",
|
|
27
34
|
"test": "vitest run",
|
|
28
35
|
"test:watch": "vitest"
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
"@decantr/essence-spec": "workspace:*",
|
|
32
|
-
"@decantr/registry": "workspace:*"
|
|
33
|
-
},
|
|
34
|
-
"devDependencies": {}
|
|
35
|
-
}
|
|
36
|
+
}
|
|
37
|
+
}
|