@constela/start 1.2.19 → 1.2.21

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.
@@ -2,7 +2,7 @@ import {
2
2
  generateHydrationScript,
3
3
  renderPage,
4
4
  wrapHtml
5
- } from "./chunk-7YAQ4TPR.js";
5
+ } from "./chunk-GYIQEWAI.js";
6
6
 
7
7
  // src/router/file-router.ts
8
8
  import fg from "fast-glob";
@@ -2807,6 +2807,11 @@ async function renderPageToHtml(program, params, runtimePath, cssPath, externalI
2807
2807
  if (externalImports && Object.keys(externalImports).length > 0) {
2808
2808
  wrapOptions.importMap = externalImports;
2809
2809
  }
2810
+ const themeState = program.state?.["theme"];
2811
+ if (themeState?.initial) {
2812
+ wrapOptions.defaultTheme = themeState.initial;
2813
+ wrapOptions.themeStorageKey = "theme";
2814
+ }
2810
2815
  return wrapHtml(
2811
2816
  content,
2812
2817
  hydrationScript,
@@ -2923,13 +2928,12 @@ async function build2(options) {
2923
2928
  let boundPageInfo = pageInfo;
2924
2929
  if (pathEntry.data && pageInfo.page.getStaticPaths?.source) {
2925
2930
  const source = pageInfo.page.getStaticPaths.source;
2926
- const sourceName = typeof source === "string" ? source : source.name;
2927
- if (sourceName) {
2931
+ if (typeof source === "string") {
2928
2932
  boundPageInfo = {
2929
2933
  ...pageInfo,
2930
2934
  loadedData: {
2931
2935
  ...pageInfo.loadedData,
2932
- [sourceName]: pathEntry.data
2936
+ [source]: pathEntry.data
2933
2937
  // Replace array with current item
2934
2938
  }
2935
2939
  };
@@ -55,7 +55,11 @@ if (container_${jsId}) {
55
55
  createApp(widgetProgram_${jsId}, container_${jsId});
56
56
  }`;
57
57
  }).join("\n") : "";
58
- const routeDeclaration = route ? `const route = ${escapeJsonForScript(JSON.stringify(route))};` : "";
58
+ const routeDeclaration = route ? `const route = {
59
+ params: ${escapeJsonForScript(JSON.stringify(route.params || {}))},
60
+ query: Object.fromEntries(new URLSearchParams(window.location.search)),
61
+ path: window.location.pathname
62
+ };` : "";
59
63
  const hydrateOptions = route ? `{
60
64
  program,
61
65
  container: document.getElementById('app'),
@@ -71,7 +75,7 @@ ${routeDeclaration ? "\n" + routeDeclaration : ""}${widgetDeclarations ? "\n" +
71
75
  hydrateApp(${hydrateOptions});${widgetMounting}`;
72
76
  }
73
77
  function wrapHtml(content, hydrationScript, head, options) {
74
- const htmlClass = options?.theme === "dark" ? ' class="dark"' : "";
78
+ const htmlClass = options?.defaultTheme === "dark" || options?.theme === "dark" ? ' class="dark"' : "";
75
79
  let processedScript = hydrationScript;
76
80
  let importMapScript = "";
77
81
  if (options?.runtimePath) {
@@ -94,6 +98,25 @@ ${importMapJson}
94
98
  importMapScript = `<script type="importmap">
95
99
  ${importMapJson}
96
100
  </script>
101
+ `;
102
+ }
103
+ let themeScript = "";
104
+ if (options?.themeStorageKey) {
105
+ if (!/^[a-zA-Z0-9_-]+$/.test(options.themeStorageKey)) {
106
+ throw new Error(`Invalid themeStorageKey: ${options.themeStorageKey}. Only alphanumeric characters, underscores, and hyphens are allowed.`);
107
+ }
108
+ themeScript = `<script>
109
+ (function() {
110
+ try {
111
+ var theme = localStorage.getItem('${options.themeStorageKey}');
112
+ if (theme === 'dark') {
113
+ document.documentElement.classList.add('dark');
114
+ } else if (theme === 'light') {
115
+ document.documentElement.classList.remove('dark');
116
+ }
117
+ } catch (e) {}
118
+ })();
119
+ </script>
97
120
  `;
98
121
  }
99
122
  return `<!DOCTYPE html>
@@ -101,7 +124,7 @@ ${importMapJson}
101
124
  <head>
102
125
  <meta charset="utf-8">
103
126
  <meta name="viewport" content="width=device-width, initial-scale=1">
104
- ${importMapScript}${head ?? ""}
127
+ ${themeScript}${importMapScript}${head ?? ""}
105
128
  </head>
106
129
  <body>
107
130
  <div id="app">${content}</div>
package/dist/cli/index.js CHANGED
@@ -3,8 +3,8 @@ import {
3
3
  createDevServer,
4
4
  loadConfig,
5
5
  resolveConfig
6
- } from "../chunk-JOQOX3XZ.js";
7
- import "../chunk-7YAQ4TPR.js";
6
+ } from "../chunk-57VB6R2P.js";
7
+ import "../chunk-GYIQEWAI.js";
8
8
 
9
9
  // src/cli/index.ts
10
10
  import { Command } from "commander";
package/dist/index.js CHANGED
@@ -23,12 +23,12 @@ import {
23
23
  transformCsv,
24
24
  transformMdx,
25
25
  transformYaml
26
- } from "./chunk-JOQOX3XZ.js";
26
+ } from "./chunk-57VB6R2P.js";
27
27
  import {
28
28
  generateHydrationScript,
29
29
  renderPage,
30
30
  wrapHtml
31
- } from "./chunk-7YAQ4TPR.js";
31
+ } from "./chunk-GYIQEWAI.js";
32
32
 
33
33
  // src/build/ssg.ts
34
34
  import { mkdir, writeFile } from "fs/promises";
@@ -112,7 +112,18 @@ async function generateSinglePage(pattern, outDir, program, params = {}) {
112
112
  path: pattern
113
113
  };
114
114
  const hydrationScript = generateHydrationScript(program, void 0, routeContext);
115
- const html = wrapHtml(content, hydrationScript);
115
+ const wrapOptions = {};
116
+ const themeState = program.state?.["theme"];
117
+ if (themeState?.initial) {
118
+ wrapOptions.defaultTheme = themeState.initial;
119
+ wrapOptions.themeStorageKey = "theme";
120
+ }
121
+ const html = wrapHtml(
122
+ content,
123
+ hydrationScript,
124
+ void 0,
125
+ Object.keys(wrapOptions).length > 0 ? wrapOptions : void 0
126
+ );
116
127
  await writeFile(outputPath, html, "utf-8");
117
128
  return outputPath;
118
129
  }
@@ -16,6 +16,10 @@ interface WrapHtmlOptions {
16
16
  importMap?: Record<string, string>;
17
17
  /** Path to bundled runtime for production builds. When provided, replaces @constela/runtime imports and excludes importmap. */
18
18
  runtimePath?: string;
19
+ /** localStorage key for theme persistence. When provided, generates anti-flash script. */
20
+ themeStorageKey?: string;
21
+ /** Default theme to use when no stored preference exists */
22
+ defaultTheme?: 'dark' | 'light';
19
23
  }
20
24
  interface WidgetConfig {
21
25
  /** The DOM element ID where the widget should be mounted */
@@ -2,7 +2,7 @@ import {
2
2
  generateHydrationScript,
3
3
  renderPage,
4
4
  wrapHtml
5
- } from "../chunk-7YAQ4TPR.js";
5
+ } from "../chunk-GYIQEWAI.js";
6
6
  export {
7
7
  generateHydrationScript,
8
8
  renderPage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/start",
3
- "version": "1.2.19",
3
+ "version": "1.2.21",
4
4
  "description": "Meta-framework for Constela applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",