@pyreon/zero 0.12.13 → 0.12.15

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.
Files changed (51) hide show
  1. package/lib/client.js +41 -5
  2. package/lib/client.js.map +1 -1
  3. package/lib/env.js +6 -6
  4. package/lib/env.js.map +1 -1
  5. package/lib/favicon.js +2 -2
  6. package/lib/favicon.js.map +1 -1
  7. package/lib/font.js +2 -2
  8. package/lib/font.js.map +1 -1
  9. package/lib/i18n-routing.js.map +1 -1
  10. package/lib/image-plugin.js +1 -1
  11. package/lib/image-plugin.js.map +1 -1
  12. package/lib/index.js +39 -10
  13. package/lib/index.js.map +1 -1
  14. package/lib/link.js +12 -4
  15. package/lib/link.js.map +1 -1
  16. package/lib/meta.js.map +1 -1
  17. package/lib/og-image.js +2 -2
  18. package/lib/og-image.js.map +1 -1
  19. package/lib/script.js +1 -0
  20. package/lib/script.js.map +1 -1
  21. package/lib/server.js +132 -12
  22. package/lib/server.js.map +1 -1
  23. package/lib/theme.js +27 -7
  24. package/lib/theme.js.map +1 -1
  25. package/lib/types/client.d.ts +26 -0
  26. package/lib/types/client.d.ts.map +1 -1
  27. package/lib/types/config.d.ts +7 -0
  28. package/lib/types/config.d.ts.map +1 -1
  29. package/lib/types/index.d.ts +13 -1
  30. package/lib/types/index.d.ts.map +1 -1
  31. package/lib/types/link.d.ts.map +1 -1
  32. package/lib/types/server.d.ts +14 -0
  33. package/lib/types/server.d.ts.map +1 -1
  34. package/lib/types/theme.d.ts +6 -1
  35. package/lib/types/theme.d.ts.map +1 -1
  36. package/package.json +10 -10
  37. package/src/adapters/index.ts +1 -1
  38. package/src/adapters/validate.ts +2 -2
  39. package/src/client.ts +84 -6
  40. package/src/env.ts +6 -6
  41. package/src/favicon.ts +3 -3
  42. package/src/font.ts +2 -2
  43. package/src/i18n-routing.ts +1 -1
  44. package/src/image-plugin.ts +1 -1
  45. package/src/isr.ts +34 -2
  46. package/src/link.tsx +21 -5
  47. package/src/og-image.ts +2 -2
  48. package/src/script.tsx +4 -0
  49. package/src/theme.tsx +33 -11
  50. package/src/types.ts +7 -0
  51. package/src/vite-plugin.ts +204 -2
package/lib/theme.js CHANGED
@@ -1,4 +1,4 @@
1
- import { onMount, onUnmount } from "@pyreon/core";
1
+ import { onMount } from "@pyreon/core";
2
2
  import { effect, signal } from "@pyreon/reactivity";
3
3
 
4
4
  //#region ../../core/core/lib/jsx-runtime.js
@@ -55,6 +55,18 @@ const jsxs = jsx;
55
55
  const STORAGE_KEY = "zero-theme";
56
56
  /** Reactive theme signal. */
57
57
  const theme = signal("system");
58
+ /**
59
+ * Reactive signal tracking the OS color-scheme preference. Updated by the
60
+ * `matchMedia('(prefers-color-scheme: dark)').change` event registered in
61
+ * `initTheme`. Components reading `resolvedTheme()` subscribe to BOTH
62
+ * `theme` and this signal, so a user toggling dark mode at the OS level
63
+ * re-renders everything reactively — not just the `<html data-theme>`
64
+ * attribute.
65
+ *
66
+ * SSR default is `_ssrDefault` (mutable via `setSSRThemeDefault`) so the
67
+ * server-rendered theme can differ from the client's OS preference.
68
+ */
69
+ const _osPrefersDark = signal(false);
58
70
  /** SSR fallback when system preference can't be detected. Default: 'light'. */
59
71
  let _ssrDefault = "light";
60
72
  /**
@@ -64,12 +76,17 @@ let _ssrDefault = "light";
64
76
  function setSSRThemeDefault(value) {
65
77
  _ssrDefault = value;
66
78
  }
67
- /** Computed resolved theme (what's actually applied). */
79
+ /**
80
+ * Reactive read of the resolved theme. Subscribes to `theme` (explicit
81
+ * user choice) and — when `theme === 'system'` — to `_osPrefersDark`
82
+ * (OS color-scheme preference). Components using `resolvedTheme()`
83
+ * inside JSX / effects / computeds re-render when either changes.
84
+ */
68
85
  function resolvedTheme() {
69
86
  const t = theme();
70
87
  if (t === "system") {
71
88
  if (typeof window === "undefined") return _ssrDefault;
72
- return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
89
+ return _osPrefersDark() ? "dark" : "light";
73
90
  }
74
91
  return t;
75
92
  }
@@ -99,18 +116,21 @@ function initTheme() {
99
116
  } catch {}
100
117
  document.documentElement.dataset.theme = resolvedTheme();
101
118
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
102
- function onChange() {
103
- if (theme() === "system") document.documentElement.dataset.theme = resolvedTheme();
119
+ _osPrefersDark.set(mq.matches);
120
+ function onChange(e) {
121
+ _osPrefersDark.set(e.matches);
104
122
  }
105
123
  mq.addEventListener("change", onChange);
106
- onUnmount(() => mq.removeEventListener("change", onChange));
107
124
  const dispose = effect(() => {
108
125
  const mode = resolvedTheme();
109
126
  document.documentElement.dataset.theme = mode;
110
127
  const faviconLinks = document.querySelectorAll("[data-favicon-theme]");
111
128
  for (const link of faviconLinks) link.media = link.dataset.faviconTheme === mode ? "" : "not all";
112
129
  });
113
- if (dispose) onUnmount(() => dispose.dispose());
130
+ return () => {
131
+ mq.removeEventListener("change", onChange);
132
+ dispose?.dispose();
133
+ };
114
134
  });
115
135
  }
116
136
  /**
package/lib/theme.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"theme.js","names":[],"sources":["../../../core/core/lib/jsx-runtime.js","../src/theme.tsx"],"sourcesContent":["//#region src/h.ts\n/** Marker for fragment nodes — renders children without a wrapper element */\nconst Fragment = Symbol(\"Pyreon.Fragment\");\n/**\n* Hyperscript function — the compiled output of JSX.\n* `<div class=\"x\">hello</div>` → `h(\"div\", { class: \"x\" }, \"hello\")`\n*\n* Generic on P so TypeScript validates props match the component's signature\n* at the call site, then stores the result in the loosely-typed VNode.\n*/\n/** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */\nconst EMPTY_PROPS = {};\nfunction h(type, props, ...children) {\n\treturn {\n\t\ttype,\n\t\tprops: props ?? EMPTY_PROPS,\n\t\tchildren: normalizeChildren(children),\n\t\tkey: props?.key ?? null\n\t};\n}\nfunction normalizeChildren(children) {\n\tfor (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);\n\treturn children;\n}\nfunction flattenChildren(children) {\n\tconst result = [];\n\tfor (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));\n\telse result.push(child);\n\treturn result;\n}\n\n//#endregion\n//#region src/jsx-runtime.ts\n/**\n* JSX automatic runtime.\n*\n* When tsconfig has `\"jsxImportSource\": \"@pyreon/core\"`, the TS/bundler compiler\n* rewrites JSX to imports from this file automatically:\n* <div class=\"x\" /> → jsx(\"div\", { class: \"x\" })\n*/\nfunction jsx(type, props, key) {\n\tconst { children, ...rest } = props;\n\tconst propsWithKey = key != null ? {\n\t\t...rest,\n\t\tkey\n\t} : rest;\n\tif (typeof type === \"function\") return h(type, children !== void 0 ? {\n\t\t...propsWithKey,\n\t\tchildren\n\t} : propsWithKey);\n\treturn h(type, propsWithKey, ...children === void 0 ? [] : Array.isArray(children) ? children : [children]);\n}\nconst jsxs = jsx;\n\n//#endregion\nexport { Fragment, jsx, jsxs };\n//# sourceMappingURL=jsx-runtime.js.map","import type { VNodeChild } from '@pyreon/core'\nimport { onMount, onUnmount } from '@pyreon/core'\nimport { effect, signal } from '@pyreon/reactivity'\n\n// ─── Theme system ───────────────────────────────────────────────────────────\n//\n// Provides dark/light/system theme support with:\n// - System preference detection via matchMedia\n// - Persistent preference via localStorage\n// - No flash of wrong theme (inline script in HTML)\n// - Reactive theme signal for components\n\nexport type Theme = 'light' | 'dark' | 'system'\n\nconst STORAGE_KEY = 'zero-theme'\n\n/** Reactive theme signal. */\nexport const theme = signal<Theme>('system')\n\n/** SSR fallback when system preference can't be detected. Default: 'light'. */\nlet _ssrDefault: 'light' | 'dark' = 'light'\n\n/**\n * Set the default theme for SSR (when `matchMedia` is unavailable).\n * Call once at server startup before rendering.\n */\nexport function setSSRThemeDefault(value: 'light' | 'dark'): void {\n _ssrDefault = value\n}\n\n/** Computed resolved theme (what's actually applied). */\nexport function resolvedTheme(): 'light' | 'dark' {\n const t = theme()\n if (t === 'system') {\n if (typeof window === 'undefined') return _ssrDefault\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n }\n return t\n}\n\n/** Toggle between light and dark. */\nexport function toggleTheme() {\n const current = resolvedTheme()\n setTheme(current === 'dark' ? 'light' : 'dark')\n}\n\n/** Set theme explicitly. */\nexport function setTheme(t: Theme) {\n theme.set(t)\n if (typeof document !== 'undefined') {\n document.documentElement.dataset.theme = resolvedTheme()\n try {\n localStorage.setItem(STORAGE_KEY, t)\n } catch {\n // localStorage may not be available (SSR, private browsing)\n }\n }\n}\n\n/**\n * Initialize the theme system. Call once in your app entry or layout.\n * Reads from localStorage, listens for system preference changes.\n */\nexport function initTheme() {\n onMount(() => {\n // Read persisted preference\n try {\n const stored = localStorage.getItem(STORAGE_KEY) as Theme | null\n if (stored === 'light' || stored === 'dark' || stored === 'system') {\n theme.set(stored)\n }\n } catch {\n // localStorage may not be available\n }\n\n // Apply to document\n document.documentElement.dataset.theme = resolvedTheme()\n\n // Watch for system preference changes\n const mq = window.matchMedia('(prefers-color-scheme: dark)')\n function onChange() {\n if (theme() === 'system') {\n document.documentElement.dataset.theme = resolvedTheme()\n }\n }\n mq.addEventListener('change', onChange)\n onUnmount(() => mq.removeEventListener('change', onChange))\n\n // Re-apply when theme signal changes — updates data-theme + favicons\n const dispose = effect(() => {\n const mode = resolvedTheme()\n document.documentElement.dataset.theme = mode\n\n // Swap favicon variants (if dual-variant favicons are present)\n const faviconLinks = document.querySelectorAll<HTMLLinkElement>('[data-favicon-theme]')\n for (const link of faviconLinks) {\n link.media = link.dataset.faviconTheme === mode ? '' : 'not all'\n }\n })\n if (dispose) onUnmount(() => dispose.dispose())\n\n return undefined\n })\n}\n\n/**\n * Theme toggle button component.\n *\n * @example\n * import { ThemeToggle } from \"@pyreon/zero/theme\"\n * <ThemeToggle />\n */\nexport function ThemeToggle(props: { class?: string; style?: string }): VNodeChild {\n initTheme()\n\n return (\n <button\n class={props.class}\n style={props.style}\n onClick={toggleTheme}\n aria-label=\"Toggle theme\"\n title=\"Toggle theme\"\n type=\"button\"\n >\n {() =>\n resolvedTheme() === 'dark' ? (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n <line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\" />\n <line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\" />\n <line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\" />\n <line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\" />\n <line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\" />\n <line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\" />\n <line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\" />\n <line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\" />\n </svg>\n ) : (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n </svg>\n )\n }\n </button>\n )\n}\n\n/**\n * Inline script to prevent flash of wrong theme.\n * Include this in your index.html <head> BEFORE any stylesheets.\n *\n * @example\n * // index.html\n * <head>\n * <script>{themeScript}</script>\n * ...\n * </head>\n */\nexport const themeScript = `(function(){try{var t=localStorage.getItem(\"${STORAGE_KEY}\");var r=t===\"light\"?\"light\":t===\"dark\"?\"dark\":window.matchMedia(\"(prefers-color-scheme:dark)\").matches?\"dark\":\"light\";document.documentElement.dataset.theme=r;document.querySelectorAll(\"[data-favicon-theme]\").forEach(function(l){l.media=l.dataset.faviconTheme===r?\"\":\"not all\"})}catch(e){}})()`\n"],"mappings":"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"}
1
+ {"version":3,"file":"theme.js","names":[],"sources":["../../../core/core/lib/jsx-runtime.js","../src/theme.tsx"],"sourcesContent":["//#region src/h.ts\n/** Marker for fragment nodes — renders children without a wrapper element */\nconst Fragment = Symbol(\"Pyreon.Fragment\");\n/**\n* Hyperscript function — the compiled output of JSX.\n* `<div class=\"x\">hello</div>` → `h(\"div\", { class: \"x\" }, \"hello\")`\n*\n* Generic on P so TypeScript validates props match the component's signature\n* at the call site, then stores the result in the loosely-typed VNode.\n*/\n/** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */\nconst EMPTY_PROPS = {};\nfunction h(type, props, ...children) {\n\treturn {\n\t\ttype,\n\t\tprops: props ?? EMPTY_PROPS,\n\t\tchildren: normalizeChildren(children),\n\t\tkey: props?.key ?? null\n\t};\n}\nfunction normalizeChildren(children) {\n\tfor (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);\n\treturn children;\n}\nfunction flattenChildren(children) {\n\tconst result = [];\n\tfor (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));\n\telse result.push(child);\n\treturn result;\n}\n\n//#endregion\n//#region src/jsx-runtime.ts\n/**\n* JSX automatic runtime.\n*\n* When tsconfig has `\"jsxImportSource\": \"@pyreon/core\"`, the TS/bundler compiler\n* rewrites JSX to imports from this file automatically:\n* <div class=\"x\" /> → jsx(\"div\", { class: \"x\" })\n*/\nfunction jsx(type, props, key) {\n\tconst { children, ...rest } = props;\n\tconst propsWithKey = key != null ? {\n\t\t...rest,\n\t\tkey\n\t} : rest;\n\tif (typeof type === \"function\") return h(type, children !== void 0 ? {\n\t\t...propsWithKey,\n\t\tchildren\n\t} : propsWithKey);\n\treturn h(type, propsWithKey, ...children === void 0 ? [] : Array.isArray(children) ? children : [children]);\n}\nconst jsxs = jsx;\n\n//#endregion\nexport { Fragment, jsx, jsxs };\n//# sourceMappingURL=jsx-runtime.js.map","import type { VNodeChild } from '@pyreon/core'\nimport { onMount } from '@pyreon/core'\nimport { effect, signal } from '@pyreon/reactivity'\n\n// ─── Theme system ───────────────────────────────────────────────────────────\n//\n// Provides dark/light/system theme support with:\n// - System preference detection via matchMedia\n// - Persistent preference via localStorage\n// - No flash of wrong theme (inline script in HTML)\n// - Reactive theme signal for components\n\nexport type Theme = 'light' | 'dark' | 'system'\n\nconst STORAGE_KEY = 'zero-theme'\n\n/** Reactive theme signal. */\nexport const theme = signal<Theme>('system')\n\n/**\n * Reactive signal tracking the OS color-scheme preference. Updated by the\n * `matchMedia('(prefers-color-scheme: dark)').change` event registered in\n * `initTheme`. Components reading `resolvedTheme()` subscribe to BOTH\n * `theme` and this signal, so a user toggling dark mode at the OS level\n * re-renders everything reactively — not just the `<html data-theme>`\n * attribute.\n *\n * SSR default is `_ssrDefault` (mutable via `setSSRThemeDefault`) so the\n * server-rendered theme can differ from the client's OS preference.\n */\nconst _osPrefersDark = signal<boolean>(false)\n\n/** SSR fallback when system preference can't be detected. Default: 'light'. */\nlet _ssrDefault: 'light' | 'dark' = 'light'\n\n/**\n * Set the default theme for SSR (when `matchMedia` is unavailable).\n * Call once at server startup before rendering.\n */\nexport function setSSRThemeDefault(value: 'light' | 'dark'): void {\n _ssrDefault = value\n}\n\n/**\n * Reactive read of the resolved theme. Subscribes to `theme` (explicit\n * user choice) and — when `theme === 'system'` — to `_osPrefersDark`\n * (OS color-scheme preference). Components using `resolvedTheme()`\n * inside JSX / effects / computeds re-render when either changes.\n */\nexport function resolvedTheme(): 'light' | 'dark' {\n const t = theme()\n if (t === 'system') {\n if (typeof window === 'undefined') return _ssrDefault\n return _osPrefersDark() ? 'dark' : 'light'\n }\n return t\n}\n\n/** Toggle between light and dark. */\nexport function toggleTheme() {\n const current = resolvedTheme()\n setTheme(current === 'dark' ? 'light' : 'dark')\n}\n\n/** Set theme explicitly. */\nexport function setTheme(t: Theme) {\n theme.set(t)\n if (typeof document !== 'undefined') {\n document.documentElement.dataset.theme = resolvedTheme()\n try {\n localStorage.setItem(STORAGE_KEY, t)\n } catch {\n // localStorage may not be available (SSR, private browsing)\n }\n }\n}\n\n/**\n * Initialize the theme system. Call once in your app entry or layout.\n * Reads from localStorage, listens for system preference changes.\n */\nexport function initTheme() {\n onMount(() => {\n // Read persisted preference\n try {\n const stored = localStorage.getItem(STORAGE_KEY) as Theme | null\n if (stored === 'light' || stored === 'dark' || stored === 'system') {\n theme.set(stored)\n }\n } catch {\n // localStorage may not be available\n }\n\n // Apply to document\n document.documentElement.dataset.theme = resolvedTheme()\n\n // Watch for system preference changes. Seed the signal from the\n // current media-query state, then update reactively on each OS\n // preference flip. Components reading `resolvedTheme()` pick up the\n // change automatically (they subscribe to `_osPrefersDark` when\n // `theme === 'system'`).\n const mq = window.matchMedia('(prefers-color-scheme: dark)')\n _osPrefersDark.set(mq.matches)\n function onChange(e: MediaQueryListEvent) {\n _osPrefersDark.set(e.matches)\n }\n mq.addEventListener('change', onChange)\n\n // Re-apply when theme signal changes — updates data-theme + favicons\n const dispose = effect(() => {\n const mode = resolvedTheme()\n document.documentElement.dataset.theme = mode\n\n // Swap favicon variants (if dual-variant favicons are present)\n const faviconLinks = document.querySelectorAll<HTMLLinkElement>('[data-favicon-theme]')\n for (const link of faviconLinks) {\n link.media = link.dataset.faviconTheme === mode ? '' : 'not all'\n }\n })\n\n return () => {\n mq.removeEventListener('change', onChange)\n dispose?.dispose()\n }\n })\n}\n\n/**\n * Theme toggle button component.\n *\n * @example\n * import { ThemeToggle } from \"@pyreon/zero/theme\"\n * <ThemeToggle />\n */\nexport function ThemeToggle(props: { class?: string; style?: string }): VNodeChild {\n initTheme()\n\n return (\n <button\n class={props.class}\n style={props.style}\n onClick={toggleTheme}\n aria-label=\"Toggle theme\"\n title=\"Toggle theme\"\n type=\"button\"\n >\n {() =>\n resolvedTheme() === 'dark' ? (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n <line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\" />\n <line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\" />\n <line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\" />\n <line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\" />\n <line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\" />\n <line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\" />\n <line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\" />\n <line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\" />\n </svg>\n ) : (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n </svg>\n )\n }\n </button>\n )\n}\n\n/**\n * Inline script to prevent flash of wrong theme.\n * Include this in your index.html <head> BEFORE any stylesheets.\n *\n * @example\n * // index.html\n * <head>\n * <script>{themeScript}</script>\n * ...\n * </head>\n */\nexport const themeScript = `(function(){try{var t=localStorage.getItem(\"${STORAGE_KEY}\");var r=t===\"light\"?\"light\":t===\"dark\"?\"dark\":window.matchMedia(\"(prefers-color-scheme:dark)\").matches?\"dark\":\"light\";document.documentElement.dataset.theme=r;document.querySelectorAll(\"[data-favicon-theme]\").forEach(function(l){l.media=l.dataset.faviconTheme===r?\"\":\"not all\"})}catch(e){}})()`\n"],"mappings":"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"}
@@ -11,6 +11,32 @@ interface StartClientOptions {
11
11
  /**
12
12
  * Start the client-side app — hydrates SSR content or mounts fresh for SPA.
13
13
  *
14
+ * ## Loader data flow
15
+ *
16
+ * Direct navigation to a route with a `loader` function needs data to be
17
+ * available on the VERY FIRST render. This is handled in two modes:
18
+ *
19
+ * - **SSR mode (zero's default)**: the server pre-runs loaders, renders the
20
+ * HTML with loader data already applied, and embeds a JSON blob in the
21
+ * HTML as `window.__PYREON_LOADER_DATA__`. On the client we read that
22
+ * blob and call `hydrateLoaderData(router, data)` BEFORE hydrating — so
23
+ * the hydration pass sees the same data the SSR render produced
24
+ * (avoids hydration mismatches and the flash of "not found" fallback).
25
+ *
26
+ * - **SPA cold start (no SSR content)**: no `__PYREON_LOADER_DATA__` was
27
+ * embedded, so we call `router.replace(currentPath)` after mount to
28
+ * trigger the loader pipeline for the initial route. The first render
29
+ * shows whatever the component displays for `useLoaderData() === undefined`
30
+ * (typically a loading state or fallback); once loaders resolve, the
31
+ * reactive `useLoaderData` re-renders with the data. This matches
32
+ * standard SPA loading behavior.
33
+ *
34
+ * Without this wiring, direct URL navigation to a loader-backed route
35
+ * (e.g. `/posts/3`) showed the "Post not found" fallback indefinitely
36
+ * because `useLoaderData()` returned `undefined` forever. The router
37
+ * only ran loaders on in-app navigation (push/replace), not on initial
38
+ * mount.
39
+ *
14
40
  * @example
15
41
  * import { routes } from "virtual:zero/routes"
16
42
  * import { startClient } from "@pyreon/zero/client"
@@ -1 +1 @@
1
- {"version":3,"file":"client2.d.ts","names":[],"sources":["../../../src/client.ts"],"mappings":";;;;UAQiB,kBAAA;;EAEf,MAAA,EAAQ,WAAA;EAFyB;EAIjC,MAAA,GAAS,WAAA;AAAA;;;;;;;AAYX;;;iBAAgB,WAAA,CAAY,OAAA,EAAS,kBAAA"}
1
+ {"version":3,"file":"client2.d.ts","names":[],"sources":["../../../src/client.ts"],"mappings":";;;;UASiB,kBAAA;;EAEf,MAAA,EAAQ,WAAA;EAFyB;EAIjC,MAAA,GAAS,WAAA;AAAA;;;;;;;AAsCX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,WAAA,CAAY,OAAA,EAAS,kBAAA"}
@@ -5,6 +5,13 @@ type RenderMode = 'ssr' | 'ssg' | 'spa' | 'isr';
5
5
  interface ISRConfig {
6
6
  /** Revalidation interval in seconds. */
7
7
  revalidate: number;
8
+ /**
9
+ * Maximum number of distinct URL paths to keep in the in-memory cache.
10
+ * Oldest-first LRU eviction once the cap is reached. Default: `1000`.
11
+ * Set higher for SSG-heavy sites, lower for routes with unbounded URL
12
+ * space (e.g. `/user/:id` where `:id` is free-form).
13
+ */
14
+ maxEntries?: number;
8
15
  }
9
16
  interface ZeroConfig {
10
17
  /** Default rendering mode. Default: "ssr" */
@@ -1 +1 @@
1
- {"version":3,"file":"config2.d.ts","names":[],"sources":["../../../src/types.ts","../../../src/config.ts"],"mappings":";;;KA6CY,UAAA;AAAA,UAEK,SAAA;EAoCF;EAlCb,UAAA;AAAA;AAAA,UAKe,UAAA;;EAEf,IAAA,GAAO,UAAA;;EAGP,IAAA,GAAO,MAAA;EC5CmB;ED+C1B,GAAA;IC/C0D,wCDiDxD,IAAA;EAAA;ECjD8C;EDqDhD,GAAA;ICrD0D,wDDuDxD,KAAA,gCAAqC,OAAA;EAAA;;EAIvC,GAAA,GAAM,SAAA;ECpDS;EDuDf,OAAA;ECvDC;ED0DD,IAAA;EC1D8E;ED6D9E,UAAA,GAAa,UAAA;EC9DD;EDiEZ,IAAA;AAAA;;;;;;;AAzCF;;;;;AAEA;;;;iBChCgB,YAAA,CAAa,MAAA,EAAQ,UAAA,GAAa,UAAA;ADuClD;AAAA,iBClCgB,aAAA,CACd,UAAA,GAAY,UAAA,GACX,QAAA,CAAS,IAAA,CAAK,UAAA,2CAAqD,UAAA"}
1
+ {"version":3,"file":"config2.d.ts","names":[],"sources":["../../../src/types.ts","../../../src/config.ts"],"mappings":";;;KA6CY,UAAA;AAAA,UAEK,SAAA;EA2CF;EAzCb,UAAA;EA4CI;;;;;AC9EN;EDyCE,UAAA;AAAA;AAAA,UAKe,UAAA;EC9CoB;EDgDnC,IAAA,GAAO,UAAA;EChDyC;EDmDhD,IAAA,GAAO,MAAA;ECnDmD;EDsD1D,GAAA;ICjD2B,wCDmDzB,IAAA;EAAA;ECjDa;EDqDf,GAAA;ICrDC,wDDuDC,KAAA,gCAAqC,OAAA;EAAA;ECvDuC;ED2D9E,GAAA,GAAM,SAAA;EC5DN;ED+DA,OAAA;EC9DU;EDiEV,IAAA;ECjEoE;EDoEpE,UAAA,GAAa,UAAA;ECpEiE;EDuE9E,IAAA;AAAA;;;;;;;AAhDF;;;;;AAEA;;;;iBChCgB,YAAA,CAAa,MAAA,EAAQ,UAAA,GAAa,UAAA;AD8ClD;AAAA,iBCzCgB,aAAA,CACd,UAAA,GAAY,UAAA,GACX,QAAA,CAAS,IAAA,CAAK,UAAA,2CAAqD,UAAA"}
@@ -454,7 +454,12 @@ declare const theme: _pyreon_reactivity0.Signal<Theme>;
454
454
  * Call once at server startup before rendering.
455
455
  */
456
456
  declare function setSSRThemeDefault(value: 'light' | 'dark'): void;
457
- /** Computed resolved theme (what's actually applied). */
457
+ /**
458
+ * Reactive read of the resolved theme. Subscribes to `theme` (explicit
459
+ * user choice) and — when `theme === 'system'` — to `_osPrefersDark`
460
+ * (OS color-scheme preference). Components using `resolvedTheme()`
461
+ * inside JSX / effects / computeds re-render when either changes.
462
+ */
458
463
  declare function resolvedTheme(): 'light' | 'dark';
459
464
  /** Toggle between light and dark. */
460
465
  declare function toggleTheme(): void;
@@ -528,6 +533,13 @@ type RenderMode = 'ssr' | 'ssg' | 'spa' | 'isr';
528
533
  interface ISRConfig {
529
534
  /** Revalidation interval in seconds. */
530
535
  revalidate: number;
536
+ /**
537
+ * Maximum number of distinct URL paths to keep in the in-memory cache.
538
+ * Oldest-first LRU eviction once the cap is reached. Default: `1000`.
539
+ * Set higher for SSG-heavy sites, lower for routes with unbounded URL
540
+ * space (e.g. `/user/:id` where `:id` is free-form).
541
+ */
542
+ maxEntries?: number;
531
543
  }
532
544
  interface ZeroConfig {
533
545
  /** Default rendering mode. Default: "ssr" */
@@ -1 +1 @@
1
- {"version":3,"file":"index2.d.ts","names":[],"sources":["../../../src/image-plugin.ts","../../../src/image.tsx","../../../src/link.tsx","../../../src/script.tsx","../../../src/i18n-routing.ts","../../../src/meta.tsx","../../../src/theme.tsx","../../../src/types.ts","../../../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index2.d.ts","names":[],"sources":["../../../src/image-plugin.ts","../../../src/image.tsx","../../../src/link.tsx","../../../src/script.tsx","../../../src/i18n-routing.ts","../../../src/meta.tsx","../../../src/theme.tsx","../../../src/types.ts","../../../src/index.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"link2.d.ts","names":[],"sources":["../../../src/link.tsx"],"mappings":";;;UAaiB,SAAA;;EAEf,IAAA;EAFe;EAIf,QAAA;;EAEA,KAAA;EAJA;EAMA,WAAA;EAFA;EAIA,gBAAA;EAAA;EAEA,QAAA;EAEA;EAAA,QAAA;EAIA;EAFA,KAAA;EAIe;EAFf,YAAA;EAEyB;EAAzB,OAAA,KAAY,CAAA,EAAG,UAAA;AAAA;;UAIA,eAAA;EACf,IAAA;EACA,GAAA,EAAiD,aAAA,CAArB,GAAA,CAAI,iBAAA;EAChC,OAAA,GAAU,CAAA,EAAG,UAAA;EACb,YAAA;EACA,YAAA;EACA,QAAA;EACA,aAAA;EALG;EAOH,KAAA;EACA,KAAA;EACA,MAAA;EACA,GAAA;EACA,YAAA;EACA,QAAA;AAAA;;UAIe,aAAA;EARf;EAUA,GAAA,EAAiD,aAAA,CAArB,GAAA,CAAI,iBAAA;EARhC;EAUA,WAAA,GAAc,CAAA,EAAG,UAAA;EARjB;EAUA,gBAAA;EAVQ;EAYR,gBAAA;EAR4B;EAU5B,QAAA;EARgC;EAUhC,aAAA;EARiB;EAUjB,OAAA;AAAA;;;;;;;;;iBAuCc,aAAA,CAAc,IAAA;;;;;AAA9B;;;;;AAoBA;;;;;;;iBAAgB,OAAA,CAAQ,KAAA,EAAO,SAAA,GAAY,aAAA;;AAiH3C;;;;;;;;;;;AA8BA;;;;;;;;;;;;;;;;;;;;;;;iBA9BgB,UAAA,CAAW,SAAA,GAAY,KAAA,EAAO,eAAA,YAA2B,KAAA,EAAO,SAAA;;;;;;;;cA8BnE,IAAA,GAAI,KAAA,EA9B+D,SAAA"}
1
+ {"version":3,"file":"link2.d.ts","names":[],"sources":["../../../src/link.tsx"],"mappings":";;;UAaiB,SAAA;;EAEf,IAAA;EAFe;EAIf,QAAA;;EAEA,KAAA;EAJA;EAMA,WAAA;EAFA;EAIA,gBAAA;EAAA;EAEA,QAAA;EAEA;EAAA,QAAA;EAIA;EAFA,KAAA;EAIe;EAFf,YAAA;EAEyB;EAAzB,OAAA,KAAY,CAAA,EAAG,UAAA;AAAA;;UAIA,eAAA;EACf,IAAA;EACA,GAAA,EAAiD,aAAA,CAArB,GAAA,CAAI,iBAAA;EAChC,OAAA,GAAU,CAAA,EAAG,UAAA;EACb,YAAA;EACA,YAAA;EACA,QAAA;EACA,aAAA;EALG;EAOH,KAAA;EACA,KAAA;EACA,MAAA;EACA,GAAA;EACA,YAAA;EACA,QAAA;AAAA;;UAIe,aAAA;EARf;EAUA,GAAA,EAAiD,aAAA,CAArB,GAAA,CAAI,iBAAA;EARhC;EAUA,WAAA,GAAc,CAAA,EAAG,UAAA;EARjB;EAUA,gBAAA;EAVQ;EAYR,gBAAA;EAR4B;EAU5B,QAAA;EARgC;EAUhC,aAAA;EARiB;EAUjB,OAAA;AAAA;;;;;;;;;iBAuDc,aAAA,CAAc,IAAA;;;;;AAA9B;;;;;AAoBA;;;;;;;iBAAgB,OAAA,CAAQ,KAAA,EAAO,SAAA,GAAY,aAAA;;AAiH3C;;;;;;;;;;;AA8BA;;;;;;;;;;;;;;;;;;;;;;;iBA9BgB,UAAA,CAAW,SAAA,GAAY,KAAA,EAAO,eAAA,YAA2B,KAAA,EAAO,SAAA;;;;;;;;cA8BnE,IAAA,GAAI,KAAA,EA9B+D,SAAA"}
@@ -66,6 +66,13 @@ type RenderMode = 'ssr' | 'ssg' | 'spa' | 'isr';
66
66
  interface ISRConfig {
67
67
  /** Revalidation interval in seconds. */
68
68
  revalidate: number;
69
+ /**
70
+ * Maximum number of distinct URL paths to keep in the in-memory cache.
71
+ * Oldest-first LRU eviction once the cap is reached. Default: `1000`.
72
+ * Set higher for SSG-heavy sites, lower for routes with unbounded URL
73
+ * space (e.g. `/user/:id` where `:id` is free-form).
74
+ */
75
+ maxEntries?: number;
69
76
  }
70
77
  interface ZeroConfig {
71
78
  /** Default rendering mode. Default: "ssr" */
@@ -288,6 +295,13 @@ declare function scanRouteFiles(routesDir: string): Promise<string[]>;
288
295
  *
289
296
  * Wraps an SSR handler and caches responses per URL path.
290
297
  * Serves stale content immediately while revalidating in the background.
298
+ *
299
+ * Bounded by `config.maxEntries` (default: 1000) with LRU eviction. The
300
+ * `Map` preserves insertion order, so re-inserting an entry on every
301
+ * serve (touching it) keeps the LRU order correct. Without the cap,
302
+ * unbounded URL spaces like `/user/:id` would grow cache memory without
303
+ * limit over the server's lifetime — a real leak in long-running
304
+ * deployments.
291
305
  */
292
306
  declare function createISRHandler(handler: (req: Request) => Promise<Response>, config: ISRConfig): (req: Request) => Promise<Response>;
293
307
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"server2.d.ts","names":[],"sources":["../../../src/app.ts","../../../src/api-routes.ts","../../../src/types.ts","../../../src/entry-server.ts","../../../src/config.ts","../../../src/fs-router.ts","../../../src/isr.ts","../../../src/adapters/bun.ts","../../../src/adapters/cloudflare.ts","../../../src/adapters/netlify.ts","../../../src/adapters/node.ts","../../../src/adapters/static.ts","../../../src/adapters/vercel.ts","../../../src/adapters/index.ts","../../../src/not-found.ts","../../../src/middleware.ts","../../../src/vite-plugin.ts","../../../src/favicon.ts","../../../src/seo.ts","../../../src/og-image.ts","../../../src/ai.ts","../../../src/i18n-routing.ts"],"mappings":"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"}
1
+ {"version":3,"file":"server2.d.ts","names":[],"sources":["../../../src/app.ts","../../../src/api-routes.ts","../../../src/types.ts","../../../src/entry-server.ts","../../../src/config.ts","../../../src/fs-router.ts","../../../src/isr.ts","../../../src/adapters/bun.ts","../../../src/adapters/cloudflare.ts","../../../src/adapters/netlify.ts","../../../src/adapters/node.ts","../../../src/adapters/static.ts","../../../src/adapters/vercel.ts","../../../src/adapters/index.ts","../../../src/not-found.ts","../../../src/middleware.ts","../../../src/vite-plugin.ts","../../../src/favicon.ts","../../../src/seo.ts","../../../src/og-image.ts","../../../src/ai.ts","../../../src/i18n-routing.ts"],"mappings":"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"}
@@ -10,7 +10,12 @@ declare const theme: _pyreon_reactivity0.Signal<Theme>;
10
10
  * Call once at server startup before rendering.
11
11
  */
12
12
  declare function setSSRThemeDefault(value: 'light' | 'dark'): void;
13
- /** Computed resolved theme (what's actually applied). */
13
+ /**
14
+ * Reactive read of the resolved theme. Subscribes to `theme` (explicit
15
+ * user choice) and — when `theme === 'system'` — to `_osPrefersDark`
16
+ * (OS color-scheme preference). Components using `resolvedTheme()`
17
+ * inside JSX / effects / computeds re-render when either changes.
18
+ */
14
19
  declare function resolvedTheme(): 'light' | 'dark';
15
20
  /** Toggle between light and dark. */
16
21
  declare function toggleTheme(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"theme2.d.ts","names":[],"sources":["../../../src/theme.tsx"],"mappings":";;;;KAYY,KAAA;;cAKC,KAAA,EAAK,mBAAA,CAAA,MAAA,CAAA,KAAA;AALlB;;;;AAAA,iBAcgB,kBAAA,CAAmB,KAAA;AATnC;AAAA,iBAcgB,aAAA,CAAA;;iBAUA,WAAA,CAAA;;iBAMA,QAAA,CAAS,CAAA,EAAG,KAAA;;;;;iBAgBZ,SAAA,CAAA;;;;;AAtBhB;;;iBAuEgB,WAAA,CAAY,KAAA;EAAS,KAAA;EAAgB,KAAA;AAAA,IAAmB,UAAA;;;;AAjDxE;;;;;AAiDA;;;cAkEa,WAAA"}
1
+ {"version":3,"file":"theme2.d.ts","names":[],"sources":["../../../src/theme.tsx"],"mappings":";;;;KAYY,KAAA;;cAKC,KAAA,EAAK,mBAAA,CAAA,MAAA,CAAA,KAAA;AALlB;;;;AAAA,iBA2BgB,kBAAA,CAAmB,KAAA;AAtBnC;;;;;AAsBA;AAtBA,iBAgCgB,aAAA,CAAA;;iBAUA,WAAA,CAAA;;iBAMA,QAAA,CAAS,CAAA,EAAG,KAAA;;;;;iBAgBZ,SAAA,CAAA;;;;;AAhBhB;;;iBAqEgB,WAAA,CAAY,KAAA;EAAS,KAAA;EAAgB,KAAA;AAAA,IAAmB,UAAA;;;;AAAxE;;;;;;;;cAkEa,WAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/zero",
3
- "version": "0.12.13",
3
+ "version": "0.12.15",
4
4
  "description": "Pyreon Zero — zero-config full-stack framework powered by Pyreon and Vite",
5
5
  "license": "MIT",
6
6
  "author": "Vit Bokisch",
@@ -166,18 +166,18 @@
166
166
  "lint": "oxlint ."
167
167
  },
168
168
  "dependencies": {
169
- "@pyreon/core": "^0.12.13",
170
- "@pyreon/head": "^0.12.13",
171
- "@pyreon/meta": "^0.12.13",
172
- "@pyreon/router": "^0.12.13",
173
- "@pyreon/runtime-dom": "^0.12.13",
174
- "@pyreon/runtime-server": "^0.12.13",
175
- "@pyreon/server": "^0.12.13",
176
- "@pyreon/vite-plugin": "^0.12.13",
169
+ "@pyreon/core": "^0.12.15",
170
+ "@pyreon/head": "^0.12.15",
171
+ "@pyreon/meta": "^0.12.15",
172
+ "@pyreon/router": "^0.12.15",
173
+ "@pyreon/runtime-dom": "^0.12.15",
174
+ "@pyreon/runtime-server": "^0.12.15",
175
+ "@pyreon/server": "^0.12.15",
176
+ "@pyreon/vite-plugin": "^0.12.15",
177
177
  "vite": "^8.0.0"
178
178
  },
179
179
  "peerDependencies": {
180
- "@pyreon/reactivity": "^0.12.13",
180
+ "@pyreon/reactivity": "^0.12.15",
181
181
  "sharp": "^0.33.0"
182
182
  },
183
183
  "peerDependenciesMeta": {
@@ -34,6 +34,6 @@ export function resolveAdapter(config: ZeroConfig): Adapter {
34
34
  case 'netlify':
35
35
  return netlifyAdapter()
36
36
  default:
37
- throw new Error(`[zero] Unknown adapter: "${name}". Use "node", "bun", "static", "vercel", "cloudflare", or "netlify".`)
37
+ throw new Error(`[Pyreon] Unknown adapter: "${name}". Use "node", "bun", "static", "vercel", "cloudflare", or "netlify".`)
38
38
  }
39
39
  }
@@ -8,9 +8,9 @@ import type { AdapterBuildOptions } from '../types'
8
8
  export async function validateBuildInputs(options: AdapterBuildOptions): Promise<void> {
9
9
  const { existsSync } = await import('node:fs')
10
10
  if (!existsSync(options.clientOutDir)) {
11
- throw new Error(`[zero:adapter] Client build output not found: ${options.clientOutDir}. Run "vite build" first.`)
11
+ throw new Error(`[Pyreon] Client build output not found: ${options.clientOutDir}. Run "vite build" first.`)
12
12
  }
13
13
  if (!existsSync(options.serverEntry)) {
14
- throw new Error(`[zero:adapter] Server entry not found: ${options.serverEntry}. Run "vite build --ssr" first.`)
14
+ throw new Error(`[Pyreon] Server entry not found: ${options.serverEntry}. Run "vite build --ssr" first.`)
15
15
  }
16
16
  }
package/src/client.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { ComponentFn } from '@pyreon/core'
2
2
  import { h } from '@pyreon/core'
3
3
  import type { RouteRecord } from '@pyreon/router'
4
+ import { hydrateLoaderData } from '@pyreon/router'
4
5
  import { hydrateRoot, mount } from '@pyreon/runtime-dom'
5
6
  import { createApp } from './app'
6
7
 
@@ -16,6 +17,32 @@ export interface StartClientOptions {
16
17
  /**
17
18
  * Start the client-side app — hydrates SSR content or mounts fresh for SPA.
18
19
  *
20
+ * ## Loader data flow
21
+ *
22
+ * Direct navigation to a route with a `loader` function needs data to be
23
+ * available on the VERY FIRST render. This is handled in two modes:
24
+ *
25
+ * - **SSR mode (zero's default)**: the server pre-runs loaders, renders the
26
+ * HTML with loader data already applied, and embeds a JSON blob in the
27
+ * HTML as `window.__PYREON_LOADER_DATA__`. On the client we read that
28
+ * blob and call `hydrateLoaderData(router, data)` BEFORE hydrating — so
29
+ * the hydration pass sees the same data the SSR render produced
30
+ * (avoids hydration mismatches and the flash of "not found" fallback).
31
+ *
32
+ * - **SPA cold start (no SSR content)**: no `__PYREON_LOADER_DATA__` was
33
+ * embedded, so we call `router.replace(currentPath)` after mount to
34
+ * trigger the loader pipeline for the initial route. The first render
35
+ * shows whatever the component displays for `useLoaderData() === undefined`
36
+ * (typically a loading state or fallback); once loaders resolve, the
37
+ * reactive `useLoaderData` re-renders with the data. This matches
38
+ * standard SPA loading behavior.
39
+ *
40
+ * Without this wiring, direct URL navigation to a loader-backed route
41
+ * (e.g. `/posts/3`) showed the "Post not found" fallback indefinitely
42
+ * because `useLoaderData()` returned `undefined` forever. The router
43
+ * only ran loaders on in-app navigation (push/replace), not on initial
44
+ * mount.
45
+ *
19
46
  * @example
20
47
  * import { routes } from "virtual:zero/routes"
21
48
  * import { startClient } from "@pyreon/zero/client"
@@ -23,21 +50,72 @@ export interface StartClientOptions {
23
50
  * startClient({ routes })
24
51
  */
25
52
  export function startClient(options: StartClientOptions) {
53
+ // `startClient` is the browser entry point — only ever called from a
54
+ // user's `client.ts` mounted in the browser. Explicit guard documents
55
+ // that contract and gives a clearer error than `document is not defined`.
56
+ if (typeof document === 'undefined') {
57
+ throw new Error('[Pyreon] startClient() can only be called in the browser.')
58
+ }
26
59
  const container = document.getElementById('app')
27
- if (!container) throw new Error('[zero] Missing #app container element')
60
+ if (!container) throw new Error('[Pyreon] Missing #app container element')
28
61
 
29
- const { App } = createApp({
62
+ const { App, router } = createApp({
30
63
  routes: options.routes,
31
64
  routerMode: 'history',
32
65
  ...(options.layout ? { layout: options.layout } : {}),
33
66
  })
34
67
 
68
+ // ── Loader data hydration (SSR path) ───────────────────────────────────────
69
+ // If the server embedded loader data, hydrate it BEFORE mounting so the
70
+ // initial render sees the same data the SSR pass produced. This avoids
71
+ // hydration mismatches and eliminates the flash-of-fallback.
72
+ const ssrLoaderData = (window as unknown as Record<string, unknown>)
73
+ .__PYREON_LOADER_DATA__
74
+ const hasSSRLoaderData =
75
+ ssrLoaderData !== undefined &&
76
+ typeof ssrLoaderData === 'object' &&
77
+ ssrLoaderData !== null
78
+ if (hasSSRLoaderData) {
79
+ // `router` is the public Router<> type; hydrateLoaderData uses the
80
+ // internal RouterInstance shape. The cast is safe because they're
81
+ // the same object at runtime — just narrower/wider type views.
82
+ hydrateLoaderData(router as never, ssrLoaderData as Record<string, unknown>)
83
+ }
84
+
35
85
  const vnode = h(App, null)
36
86
 
37
- // If container has SSR content, hydrate. Otherwise mount fresh.
38
- if (container.childNodes.length > 0) {
39
- return hydrateRoot(container, vnode)
87
+ // ── Mount vs hydrate ───────────────────────────────────────────────────────
88
+ const hasSSRContent = container.childNodes.length > 0
89
+ const cleanup = hasSSRContent ? hydrateRoot(container, vnode) : mount(vnode, container)
90
+
91
+ // ── Loader run (SPA cold-start path) ───────────────────────────────────────
92
+ // If we had no SSR loader data AND no SSR content, this is a true SPA
93
+ // cold start. Trigger the router's loader pipeline for the current route
94
+ // via `replace()` with the same path — doesn't change the URL, just kicks
95
+ // off the loader batch. Guards, middleware, and redirects run too, which
96
+ // matches what any other route navigation would do.
97
+ //
98
+ // If we DID have SSR content but NO loader data — that's an unusual case
99
+ // (SSR disabled for this route but loader defined). Run loaders anyway so
100
+ // the client catches up.
101
+ if (!hasSSRLoaderData) {
102
+ const currentPath = router.currentRoute().path
103
+ router.replace(currentPath).catch((err: unknown) => {
104
+ // Loader failures are already reported via the route's error handling
105
+ // pipeline. We swallow the promise rejection here to prevent unhandled
106
+ // rejection warnings — the route's `errorComponent` (if any) already
107
+ // handled the display.
108
+ // @ts-ignore — `import.meta.env.DEV` is provided by Vite/Rolldown at build time
109
+ if (import.meta.env?.DEV === true) {
110
+ // oxlint-disable-next-line no-console
111
+ console.warn(
112
+ '[Pyreon] Initial loader run failed for route:',
113
+ currentPath,
114
+ err,
115
+ )
116
+ }
117
+ })
40
118
  }
41
119
 
42
- return mount(vnode, container)
120
+ return cleanup
43
121
  }
package/src/env.ts CHANGED
@@ -160,7 +160,7 @@ export function oneOf<T extends string>(
160
160
  class EnvError extends Error {
161
161
  constructor(key: string, message: string, description?: string) {
162
162
  const desc = description ? ` (${description})` : ''
163
- super(`[zero:env] ${key}${desc}: ${message}`)
163
+ super(`[Pyreon] ${key}${desc}: ${message}`)
164
164
  this.name = 'EnvError'
165
165
  }
166
166
  }
@@ -193,7 +193,7 @@ function toValidator(value: unknown): EnvValidator<unknown> {
193
193
  if (typeof value === 'boolean') return bool({ default: value })
194
194
  if (typeof value === 'string') return str({ default: value })
195
195
 
196
- throw new Error(`[zero:env] Invalid schema value: ${String(value)}. Use a default value, String/Number/Boolean, or a validator like url().`)
196
+ throw new Error(`[Pyreon] Invalid schema value: ${String(value)}. Use a default value, String/Number/Boolean, or a validator like url().`)
197
197
  }
198
198
 
199
199
  // ─── Type inference ─────────────────────────────────────────────────────────
@@ -261,8 +261,8 @@ export function validateEnv<T extends Record<string, SchemaEntry>>(
261
261
  }
262
262
 
263
263
  if (errors.length > 0) {
264
- const header = `\n[zero:env] Environment validation failed (${errors.length} error${errors.length > 1 ? 's' : ''}):\n`
265
- const body = errors.map((e) => ` ✗ ${e.replace('[zero:env] ', '')}`).join('\n')
264
+ const header = `\n[Pyreon] Environment validation failed (${errors.length} error${errors.length > 1 ? 's' : ''}):\n`
265
+ const body = errors.map((e) => ` ✗ ${e.replace('[Pyreon] ', '')}`).join('\n')
266
266
  throw new Error(header + body + '\n')
267
267
  }
268
268
 
@@ -331,13 +331,13 @@ export function schema<T>(parse: (raw: string) => T): EnvValidator<T> {
331
331
  defaultValue: undefined,
332
332
  parse(raw: string | undefined, key: string) {
333
333
  if (raw === undefined || raw === '') {
334
- throw new Error(`[zero:env] ${key}: is required but not set`)
334
+ throw new Error(`[Pyreon] ${key}: is required but not set`)
335
335
  }
336
336
  try {
337
337
  return parse(raw)
338
338
  } catch (e) {
339
339
  const msg = e instanceof Error ? e.message : String(e)
340
- throw new Error(`[zero:env] ${key}: ${msg}`)
340
+ throw new Error(`[Pyreon] ${key}: ${msg}`)
341
341
  }
342
342
  },
343
343
  }
package/src/favicon.ts CHANGED
@@ -9,7 +9,7 @@ function warnSharpMissing() {
9
9
  sharpWarned = true
10
10
  // oxlint-disable-next-line no-console
11
11
  console.warn(
12
- '\n[zero:favicon] sharp not installed — favicons will not be generated. Install for full support: bun add -D sharp\n',
12
+ '\n[Pyreon] sharp not installed — favicons will not be generated. Install for full support: bun add -D sharp\n',
13
13
  )
14
14
  }
15
15
 
@@ -25,7 +25,7 @@ function warnSharpMissing() {
25
25
  //
26
26
  // Usage:
27
27
  // import { faviconPlugin } from "@pyreon/zero"
28
- // export default { plugins: [zero(), faviconPlugin({ source: "./icon.svg" })] }
28
+ // export default { plugins: [Pyreon] }
29
29
 
30
30
  export interface FaviconLocaleConfig {
31
31
  /** Locale-specific source icon (SVG or PNG). */
@@ -404,7 +404,7 @@ async function generateFaviconSet(
404
404
  const sourcePath = join(rootDir, source)
405
405
  if (!existsSync(sourcePath)) {
406
406
  // oxlint-disable-next-line no-console
407
- console.warn(`[zero:favicon] Source not found: ${sourcePath}`)
407
+ console.warn(`[Pyreon] Source not found: ${sourcePath}`)
408
408
  return
409
409
  }
410
410
 
package/src/font.ts CHANGED
@@ -282,7 +282,7 @@ async function downloadGoogleFontsCSS(url: string): Promise<string> {
282
282
  },
283
283
  })
284
284
  if (!response.ok) {
285
- throw new Error(`Failed to fetch Google Fonts CSS: ${response.status}`)
285
+ throw new Error(`[Pyreon] Failed to fetch Google Fonts CSS: ${response.status}`)
286
286
  }
287
287
  return response.text()
288
288
  }
@@ -292,7 +292,7 @@ async function downloadGoogleFontsCSS(url: string): Promise<string> {
292
292
  */
293
293
  async function downloadFontFile(url: string): Promise<Buffer> {
294
294
  const response = await fetch(url)
295
- if (!response.ok) throw new Error(`Failed to download font: ${url}`)
295
+ if (!response.ok) throw new Error(`[Pyreon] Failed to download font: ${url}`)
296
296
  const arrayBuffer = await response.arrayBuffer()
297
297
  return Buffer.from(arrayBuffer)
298
298
  }