@constela/start 1.2.15 → 1.2.16

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.
@@ -2448,8 +2448,17 @@ async function loadLayout2(layoutName, layoutsDir) {
2448
2448
  }
2449
2449
  try {
2450
2450
  const content = readFileSync5(layoutPath, "utf-8");
2451
- return JSON.parse(content);
2452
- } catch {
2451
+ const parsed = JSON.parse(content);
2452
+ if (parsed.imports && Object.keys(parsed.imports).length > 0) {
2453
+ const layoutDir = dirname5(layoutPath);
2454
+ const resolvedImports = await resolveImports(layoutDir, parsed.imports);
2455
+ return { ...parsed, importData: resolvedImports };
2456
+ }
2457
+ return parsed;
2458
+ } catch (error) {
2459
+ if (error instanceof Error && error.message.includes("not found")) {
2460
+ throw error;
2461
+ }
2453
2462
  throw new Error(`Invalid JSON in layout file: ${layoutPath}`);
2454
2463
  }
2455
2464
  }
@@ -2586,43 +2595,59 @@ function replaceSlot(node, content) {
2586
2595
  }
2587
2596
  return node;
2588
2597
  }
2598
+ async function collectLayoutChain(layoutName, layoutsDir, visited = /* @__PURE__ */ new Set()) {
2599
+ if (visited.has(layoutName)) {
2600
+ throw new Error(`Circular layout reference detected: ${layoutName}`);
2601
+ }
2602
+ visited.add(layoutName);
2603
+ const layout = await loadLayout2(layoutName, layoutsDir);
2604
+ const chain = [layout];
2605
+ if (layout.layout) {
2606
+ const parentChain = await collectLayoutChain(layout.layout, layoutsDir, visited);
2607
+ chain.push(...parentChain);
2608
+ }
2609
+ return chain;
2610
+ }
2589
2611
  async function processLayouts(pageInfo, layoutsDir) {
2590
2612
  const layoutName = pageInfo.page.route?.layout;
2591
2613
  if (!layoutName || !layoutsDir) {
2592
2614
  return pageInfo;
2593
2615
  }
2594
- const layout = await loadLayout2(layoutName, layoutsDir);
2595
- const normalizedLayoutView = normalizeViewNode(structuredClone(layout.view));
2596
- let wrappedView = applyLayout(pageInfo.page.view, normalizedLayoutView);
2616
+ const layoutChain = await collectLayoutChain(layoutName, layoutsDir);
2617
+ let mergedImports = { ...pageInfo.resolvedImports };
2618
+ for (let i = layoutChain.length - 1; i >= 0; i--) {
2619
+ const layout = layoutChain[i];
2620
+ if (layout?.importData) {
2621
+ mergedImports = {
2622
+ ...layout.importData,
2623
+ ...mergedImports
2624
+ // Inner layout/page imports take precedence
2625
+ };
2626
+ }
2627
+ }
2628
+ let currentView = pageInfo.page.view;
2629
+ for (const layout of layoutChain) {
2630
+ const normalizedLayoutView = normalizeViewNode(structuredClone(layout.view));
2631
+ currentView = applyLayout(currentView, normalizedLayoutView);
2632
+ }
2597
2633
  const layoutParams = pageInfo.page.route?.layoutParams;
2598
2634
  if (layoutParams && Object.keys(layoutParams).length > 0) {
2599
- wrappedView = substituteLayoutParamsInNode(wrappedView, layoutParams);
2635
+ currentView = substituteLayoutParamsInNode(currentView, layoutParams);
2600
2636
  }
2601
2637
  let updatedRoute;
2602
2638
  if (pageInfo.page.route) {
2603
2639
  const { layout: _layout, ...routeWithoutLayout } = pageInfo.page.route;
2604
2640
  updatedRoute = routeWithoutLayout;
2605
2641
  }
2606
- let updatedPageInfo = {
2642
+ const updatedPageInfo = {
2607
2643
  ...pageInfo,
2644
+ resolvedImports: mergedImports,
2608
2645
  page: {
2609
2646
  ...pageInfo.page,
2610
- view: wrappedView,
2647
+ view: currentView,
2611
2648
  route: updatedRoute
2612
2649
  }
2613
2650
  };
2614
- if (layout.layout) {
2615
- const parentLayout = await loadLayout2(layout.layout, layoutsDir);
2616
- const normalizedParentLayoutView = normalizeViewNode(structuredClone(parentLayout.view));
2617
- const doubleWrappedView = applyLayout(updatedPageInfo.page.view, normalizedParentLayoutView);
2618
- updatedPageInfo = {
2619
- ...updatedPageInfo,
2620
- page: {
2621
- ...updatedPageInfo.page,
2622
- view: doubleWrappedView
2623
- }
2624
- };
2625
- }
2626
2651
  return updatedPageInfo;
2627
2652
  }
2628
2653
  async function renderPageToHtml(program, params, runtimePath, cssPath) {
package/dist/cli/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  createDevServer,
4
4
  loadConfig,
5
5
  resolveConfig
6
- } from "../chunk-7KQYNZ2A.js";
6
+ } from "../chunk-RBEPA2Z2.js";
7
7
  import "../chunk-PUTC5BCP.js";
8
8
 
9
9
  // src/cli/index.ts
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  transformCsv,
24
24
  transformMdx,
25
25
  transformYaml
26
- } from "./chunk-7KQYNZ2A.js";
26
+ } from "./chunk-RBEPA2Z2.js";
27
27
  import {
28
28
  generateHydrationScript,
29
29
  renderPage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/start",
3
- "version": "1.2.15",
3
+ "version": "1.2.16",
4
4
  "description": "Meta-framework for Constela applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -43,11 +43,11 @@
43
43
  "postcss": "^8.5.0",
44
44
  "@tailwindcss/postcss": "^4.0.0",
45
45
  "tailwindcss": "^4.0.0",
46
- "@constela/core": "0.7.0",
47
46
  "@constela/compiler": "0.7.1",
47
+ "@constela/core": "0.7.0",
48
48
  "@constela/router": "8.0.0",
49
- "@constela/runtime": "0.10.2",
50
- "@constela/server": "3.0.1"
49
+ "@constela/server": "3.0.1",
50
+ "@constela/runtime": "0.10.2"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/mdast": "^4.0.4",