@voltro/web 0.30.0 → 0.30.2

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/ssr.d.ts CHANGED
@@ -423,8 +423,22 @@ export declare interface RenderPageOptions {
423
423
  /** URL pattern's resolved params. `{}` for static, no-param routes. */
424
424
  readonly params: Readonly<Record<string, string>>;
425
425
  /** Pathname this render resolves under. Used by `useLocation()` on
426
- * the server side. */
426
+ * the server side. Query-free by contract — see {@link RenderPageOptions.search}. */
427
427
  readonly pathname: string;
428
+ /**
429
+ * The request's query string, INCLUDING the leading `?` (or `''`).
430
+ *
431
+ * The server used to hardcode `''` here, on the grounds that the client reads
432
+ * `window.location.search` on hydration. That is true, and it is exactly why
433
+ * discarding it was a defect: the client reading the REAL value is what turns
434
+ * a dropped query string into a hydration mismatch, on every page whose markup
435
+ * depends on `?tab=…`. Reported by a consumer against a sidebar's active-item
436
+ * highlight on `/teams/:id?tab=…`.
437
+ *
438
+ * Omitted on the STATIC prerender, where there is genuinely no request and one
439
+ * artefact serves every visitor — `''` is the truthful value there.
440
+ */
441
+ readonly search?: string;
428
442
  /** Page (leaf) loader data — pre-resolved by the caller. The build /
429
443
  * SSR pipeline runs the descriptor's `loader` (if any) and passes the
430
444
  * result here; reachable via `useLoaderData()` inside the page. */
package/dist/ssr.js CHANGED
@@ -1,77 +1,81 @@
1
- import { _ as e, a as t, g as n, m as r, n as i, p as a, s as o, t as s } from "./routerState-DAT472IC.js";
2
- import { T as c, c as l, d as u, h as d, l as f, r as p, t as m } from "./serverContext-CV1ieZKF.js";
3
- import { createElement as h } from "react";
4
- import { makePreloadSeedBag as g, makeStoreSeedBag as _, seedPreloadedSubscription as v, setPreloadSeedResolver as y, setStoreSeedResolver as b } from "@voltro/client";
5
- import { renderToPipeableStream as x, renderToString as S } from "react-dom/server";
6
- import { AsyncLocalStorage as C } from "node:async_hooks";
1
+ import { s as e } from "./defaultFallbacks-B4Ak-R6R.js";
2
+ import { _ as t, a as n, g as r, m as i, n as a, p as o, s, t as c } from "./routerState-DAT472IC.js";
3
+ import { E as l, c as u, d, l as f, r as p, t as m, w as h } from "./serverContext-3i6Dr4ev.js";
4
+ import { createElement as g } from "react";
5
+ import { makePreloadSeedBag as _, makeStoreSeedBag as v, seedPreloadedSubscription as y, setPreloadSeedResolver as b, setStoreSeedResolver as x } from "@voltro/client";
6
+ import { renderToPipeableStream as S, renderToString as C } from "react-dom/server";
7
+ import { AsyncLocalStorage as w } from "node:async_hooks";
7
8
  //#region src/storeSeedScope.ts
8
- var w = new C();
9
- b(() => w.getStore()?.store ?? null), y(() => w.getStore()?.preload ?? null);
10
- var T = async (e) => {
9
+ var T = new w();
10
+ x(() => T.getStore()?.store ?? null), b(() => T.getStore()?.preload ?? null);
11
+ var E = async (e) => {
11
12
  let t = {
12
- store: _(),
13
- preload: g()
13
+ store: v(),
14
+ preload: _()
14
15
  };
15
16
  return {
16
- result: await w.run(t, e),
17
+ result: await T.run(t, e),
17
18
  storeSeeds: t.store.seeds,
18
19
  preloadSeeds: t.preload.seeds
19
20
  };
20
- }, E = () => {
21
+ }, D = () => {
21
22
  let e = {
22
- store: _(),
23
- preload: g()
23
+ store: v(),
24
+ preload: _()
24
25
  };
25
- return w.enterWith(e), e.store;
26
- }, D = () => w.getStore()?.store.seeds ?? null, O = () => w.getStore()?.preload.seeds ?? null, k = (e) => {
27
- let n = D(), r = O(), i = e.storeSeeds !== void 0 || n === null || n.length === 0 ? e : {
26
+ return T.enterWith(e), e.store;
27
+ }, O = () => T.getStore()?.store.seeds ?? null, k = () => T.getStore()?.preload.seeds ?? null, A = (e) => {
28
+ let t = O(), r = k(), i = e.storeSeeds !== void 0 || t === null || t.length === 0 ? e : {
28
29
  ...e,
29
- storeSeeds: n
30
+ storeSeeds: t
30
31
  };
31
- return t(e.preloadSeeds !== void 0 || r === null || r.length === 0 ? i : {
32
+ return n(e.preloadSeeds !== void 0 || r === null || r.length === 0 ? i : {
32
33
  ...i,
33
34
  preloadSeeds: r
34
35
  });
35
- }, A = (e, t, n, r, i) => {
36
- let a = h(l.Provider, { value: i ? n : f }, h(e));
36
+ }, j = (e, t, n, r, i) => {
37
+ let a = g(u.Provider, { value: i ? n : f }, g(e));
37
38
  if (!t) return a;
38
39
  for (let e = t.length - 1; e >= 0; e--) {
39
40
  let n = t[e];
40
41
  if (n.Layout) {
41
42
  let t = n.Layout;
42
- a = h(l.Provider, { value: n.loader === void 0 ? f : r(e) }, h(t, { children: a }));
43
+ a = g(u.Provider, { value: n.loader === void 0 ? f : r(e) }, g(t, { children: a }));
43
44
  }
44
45
  }
45
46
  return a;
46
- }, j = (e) => {
47
- let { descriptor: t, params: n, pathname: r, loaderData: i, segmentLoaderData: a, requestContext: o, outerWrap: s, locale: l, pageSlot: f } = e, p = c(t.meta, n, i, l), g = {
48
- pathname: r,
49
- search: "",
50
- params: n,
51
- loaderData: i,
47
+ }, M = (t) => {
48
+ let { descriptor: n, params: r, pathname: i, search: a, loaderData: o, segmentLoaderData: s, requestContext: c, outerWrap: u, locale: f, pageSlot: p } = t, _ = l(n.meta, r, o, f), v = {
49
+ pathname: i,
50
+ search: a ?? "",
51
+ params: r,
52
+ loaderData: o,
52
53
  navigate: () => {
53
54
  throw Error("navigate() is not supported during server-side rendering. Trigger navigations on the client only.");
54
55
  },
55
56
  prefetch: () => {},
56
57
  registerBlocker: () => () => {},
57
58
  blocked: null
58
- }, _ = f ? u : t.Component;
59
- if (!_) throw Error(`SSR received a descriptor with no Component for "${r}". Lazy page routes are a client-only optimization and must not be used on the server.`);
60
- let v = h(d.Provider, { value: g }, A(_, t.chain, f ? void 0 : i, (e) => a?.[e], !f && t.loader !== void 0));
61
- return o && (v = h(m.Provider, { value: o }, v)), s && (v = s(v)), {
62
- tree: v,
63
- meta: p
59
+ }, y = p ? d : n.Component;
60
+ if (!y) throw Error(`SSR received a descriptor with no Component for "${i}". Lazy page routes are a client-only optimization and must not be used on the server.`);
61
+ let b = h(v, j(y, n.chain, p ? void 0 : o, (e) => s?.[e], !p && n.loader !== void 0));
62
+ return b = g(e, {
63
+ chrome: null,
64
+ children: b
65
+ }), c && (b = g(m.Provider, { value: c }, b)), u && (b = u(b)), {
66
+ tree: b,
67
+ meta: _
64
68
  };
65
- }, M = (e) => {
66
- let { tree: t, meta: n } = j(e);
69
+ }, N = (e) => {
70
+ let { tree: t, meta: n } = M(e);
67
71
  return {
68
- html: S(t),
72
+ html: C(t),
69
73
  meta: n
70
74
  };
71
- }, N = (e) => {
72
- let { tree: t, meta: n } = j(e);
75
+ }, P = (e) => {
76
+ let { tree: t, meta: n } = M(e);
73
77
  return {
74
- stream: x(t, {
78
+ stream: S(t, {
75
79
  ...e.bootstrapModules ? { bootstrapModules: [...e.bootstrapModules] } : {},
76
80
  ...e.onShellReady ? { onShellReady: e.onShellReady } : {},
77
81
  ...e.onShellError ? { onShellError: e.onShellError } : {},
@@ -79,20 +83,20 @@ var T = async (e) => {
79
83
  }),
80
84
  meta: n
81
85
  };
82
- }, P = (e) => {
86
+ }, F = (e) => {
83
87
  if (!e) return "";
84
88
  let t = [];
85
- if (typeof e.title == "string" && t.push(`<title>${F(e.title)}</title>`), e.description && t.push(`<meta name="description" content="${I(e.description)}" />`), e.noIndex && t.push("<meta name=\"robots\" content=\"noindex, nofollow\" />"), e.canonical && t.push(`<link rel="canonical" href="${I(e.canonical)}" />`), e.tags) for (let n of e.tags) {
86
- let e = n.name ? `name="${I(n.name)}"` : n.property ? `property="${I(n.property)}"` : "";
87
- e && t.push(`<meta ${e} content="${I(n.content)}" />`);
89
+ if (typeof e.title == "string" && t.push(`<title>${I(e.title)}</title>`), e.description && t.push(`<meta name="description" content="${L(e.description)}" />`), e.noIndex && t.push("<meta name=\"robots\" content=\"noindex, nofollow\" />"), e.canonical && t.push(`<link rel="canonical" href="${L(e.canonical)}" />`), e.tags) for (let n of e.tags) {
90
+ let e = n.name ? `name="${L(n.name)}"` : n.property ? `property="${L(n.property)}"` : "";
91
+ e && t.push(`<meta ${e} content="${L(n.content)}" />`);
88
92
  }
89
93
  if (e.links) for (let n of e.links) {
90
94
  let e = [
91
- `rel="${I(n.rel)}"`,
92
- `href="${I(n.href)}"`,
93
- n.hreflang ? `hreflang="${I(n.hreflang)}"` : "",
94
- n.type ? `type="${I(n.type)}"` : "",
95
- n.title ? `title="${I(n.title)}"` : ""
95
+ `rel="${L(n.rel)}"`,
96
+ `href="${L(n.href)}"`,
97
+ n.hreflang ? `hreflang="${L(n.hreflang)}"` : "",
98
+ n.type ? `type="${L(n.type)}"` : "",
99
+ n.title ? `title="${L(n.title)}"` : ""
96
100
  ].filter(Boolean).join(" ");
97
101
  t.push(`<link ${e} />`);
98
102
  }
@@ -101,6 +105,6 @@ var T = async (e) => {
101
105
  t.push(`<script type="application/ld+json" data-voltro-page-jsonld>${e}<\/script>`);
102
106
  }
103
107
  return t.join("\n ");
104
- }, F = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"), I = (e) => e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
108
+ }, I = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"), L = (e) => e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
105
109
  //#endregion
106
- export { s as ROUTER_STATE_SCRIPT_ID, o as assertDeferralSupported, E as beginStoreSeeds, O as currentPreloadSeeds, D as currentStoreSeeds, i as encodeRouterState, a as isDeferredLoaderResult, p as parseCookieHeader, r as prepareDeferredLoaderData, n as renderDeferredRegistryScript, P as renderMetaToHtml, M as renderPageToHtml, N as renderPageToStream, k as renderRouterStateScript, v as seedPreloadedSubscription, e as serialiseStateForInlining, T as withStoreSeeds };
110
+ export { c as ROUTER_STATE_SCRIPT_ID, s as assertDeferralSupported, D as beginStoreSeeds, k as currentPreloadSeeds, O as currentStoreSeeds, a as encodeRouterState, o as isDeferredLoaderResult, p as parseCookieHeader, i as prepareDeferredLoaderData, r as renderDeferredRegistryScript, F as renderMetaToHtml, N as renderPageToHtml, P as renderPageToStream, A as renderRouterStateScript, y as seedPreloadedSubscription, t as serialiseStateForInlining, E as withStoreSeeds };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/web",
3
- "version": "0.30.0",
3
+ "version": "0.30.2",
4
4
  "description": "The Voltro web framework — file-based routing, render modes (SSR / SSG / islands), the page-export contract, data hooks, and the browser mount.",
5
5
  "keywords": [
6
6
  "voltro",
@@ -52,8 +52,8 @@
52
52
  "node": ">=24.0.0"
53
53
  },
54
54
  "dependencies": {
55
- "@voltro/client": "0.30.0",
56
- "@voltro/ui": "0.30.0"
55
+ "@voltro/client": "0.30.2",
56
+ "@voltro/ui": "0.30.2"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "@effect/platform": "^0.97.0",