@decantr/core 1.0.0-beta.4 → 1.0.0-beta.5

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/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' | 'slot' | 'nav' | 'store';
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
- export { type IRAppNode, type IRBreakpointEntry, type IRCardWrapping, type IRGridNode, type IRHookType, type IRNavItem, type IRNavNode, 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, resolveEssence, resolveVisualEffects, runPipeline, validateIR, walkIR };
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: null,
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 pascalCase2(str) {
362
- return str.split(/[-_]/).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
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(essence, resolver);
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: pascalCase2(p.pageId)
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.platform?.routing || "hash",
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.4",
3
+ "version": "1.0.0-beta.5",
4
4
  "description": "Decantr core — Design Pipeline IR engine for AI-generated UI",
5
5
  "license": "MIT",
6
6
  "repository": {