@voltro/web 0.51.0 → 0.52.0

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
@@ -7,6 +7,7 @@ import { ProcedureTypeMap } from '@voltro/client';
7
7
  import { ReactNode } from 'react';
8
8
  import { seedPreloadedSubscription } from '@voltro/client';
9
9
  import { seedPreloadedSubscriptionFailure } from '@voltro/client';
10
+ import { ServerRequestContextValue } from '@voltro/client';
10
11
  import { StoreSeed } from '@voltro/client';
11
12
  import { StoreSeedBag } from '@voltro/client';
12
13
 
@@ -571,6 +572,11 @@ export declare interface RenderPageStreamOptions extends RenderPageOptions {
571
572
  /** Bootstrap `<script>` module URLs injected by React at the end of the
572
573
  * shell — the client bundle that hydrates the streamed HTML. */
573
574
  readonly bootstrapModules?: ReadonlyArray<string>;
575
+ /** Per-request CSP nonce — React stamps it onto every script IT emits
576
+ * (bootstrap modules, Suspense settle scripts). The shell's own tags are
577
+ * stamped by the CLI's `stampScriptNonce`; the POLICY header is the
578
+ * middleware's (plan 08 §7). */
579
+ readonly nonce?: string;
574
580
  }
575
581
 
576
582
  export declare interface RenderPageStreamResult {
@@ -726,16 +732,6 @@ export { seedPreloadedSubscriptionFailure }
726
732
  */
727
733
  export declare const serialiseStateForInlining: (state: unknown) => string;
728
734
 
729
- declare interface ServerRequestContextValue {
730
- readonly cookies: Readonly<Record<string, string>>;
731
- readonly headers: Readonly<Record<string, string>>;
732
- /** Raw request URL as it came off the wire (path + query). Useful
733
- * for SSR pages that need to read `?q=…` style search params
734
- * without touching anything client-only. Empty string for build-
735
- * time SSG renders where there is no incoming request. */
736
- readonly url: string;
737
- }
738
-
739
735
  /**
740
736
  * Run one request's render with a fresh seed bag; return what it collected
741
737
  * alongside the render's own result.
package/dist/ssr.js CHANGED
@@ -1,8 +1,8 @@
1
- import { s as e } from "./defaultFallbacks-B4Ak-R6R.js";
1
+ import { s as e } from "./defaultFallbacks-SQ45vAhz.js";
2
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-38JTbYPa.js";
4
- import { createElement as g } from "react";
5
- import { makePreloadSeedBag as _, makeStoreSeedBag as v, seedPreloadedSubscription as y, seedPreloadedSubscriptionFailure as b, setPreloadSeedResolver as x, setStoreSeedResolver as S } from "@voltro/client";
3
+ import { C as l, a as u, c as d, o as f, t as p, x as m } from "./serverContext-CzmZZwuQ.js";
4
+ import { createElement as h } from "react";
5
+ import { ServerRequestContext as g, makePreloadSeedBag as _, makeStoreSeedBag as v, seedPreloadedSubscription as y, seedPreloadedSubscriptionFailure as b, setPreloadSeedResolver as x, setStoreSeedResolver as S } from "@voltro/client";
6
6
  import { renderToPipeableStream as C, renderToString as w } from "react-dom/server";
7
7
  import { AsyncLocalStorage as T } from "node:async_hooks";
8
8
  //#region src/storeSeedScope.ts
@@ -34,13 +34,13 @@ var D = async (e) => {
34
34
  preloadSeeds: r
35
35
  });
36
36
  }, M = (e, t, n, r, i) => {
37
- let a = g(u.Provider, { value: i ? n : f }, g(e));
37
+ let a = h(u.Provider, { value: i ? n : f }, h(e));
38
38
  if (!t) return a;
39
39
  for (let e = t.length - 1; e >= 0; e--) {
40
40
  let n = t[e];
41
41
  if (n.Layout) {
42
42
  let t = n.Layout;
43
- a = g(u.Provider, { value: n.loader === void 0 ? f : r(e) }, g(t, { children: a }));
43
+ a = h(u.Provider, { value: n.loader === void 0 ? f : r(e) }, h(t, { children: a }));
44
44
  }
45
45
  }
46
46
  return a;
@@ -58,11 +58,11 @@ var D = async (e) => {
58
58
  blocked: null
59
59
  }, y = p ? d : n.Component;
60
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, M(y, n.chain, p ? void 0 : o, (e) => s?.[e], !p && n.loader !== void 0));
62
- return b = g(e, {
61
+ let b = m(v, M(y, n.chain, p ? void 0 : o, (e) => s?.[e], !p && n.loader !== void 0));
62
+ return b = h(e, {
63
63
  chrome: null,
64
64
  children: b
65
- }), c && (b = g(m.Provider, { value: c }, b)), u && (b = u(b)), {
65
+ }), c && (b = h(g.Provider, { value: c }, b)), u && (b = u(b)), {
66
66
  tree: b,
67
67
  meta: _
68
68
  };
@@ -77,6 +77,7 @@ var D = async (e) => {
77
77
  return {
78
78
  stream: C(t, {
79
79
  ...e.bootstrapModules ? { bootstrapModules: [...e.bootstrapModules] } : {},
80
+ ...e.nonce === void 0 ? {} : { nonce: e.nonce },
80
81
  ...e.onShellReady ? { onShellReady: e.onShellReady } : {},
81
82
  ...e.onShellError ? { onShellError: e.onShellError } : {},
82
83
  ...e.onAllReady ? { onAllReady: e.onAllReady } : {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/web",
3
- "version": "0.51.0",
3
+ "version": "0.52.0",
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",
@@ -48,7 +48,12 @@
48
48
  "import": "./dist/middleware.js",
49
49
  "default": "./dist/middleware.js"
50
50
  },
51
- "./package.json": "./package.json"
51
+ "./package.json": "./package.json",
52
+ "./islands": {
53
+ "types": "./dist/islands.d.ts",
54
+ "import": "./dist/islands.js",
55
+ "default": "./dist/islands.js"
56
+ }
52
57
  },
53
58
  "main": "./dist/index.js",
54
59
  "module": "./dist/index.js",
@@ -58,8 +63,8 @@
58
63
  "node": ">=24.0.0"
59
64
  },
60
65
  "dependencies": {
61
- "@voltro/client": "0.51.0",
62
- "@voltro/ui": "0.51.0"
66
+ "@voltro/client": "0.52.0",
67
+ "@voltro/ui": "0.52.0"
63
68
  },
64
69
  "peerDependencies": {
65
70
  "@effect/platform": "^0.97.0",
@@ -1,10 +0,0 @@
1
- import { createContext as e } from "react";
2
- //#region src/globalContext.ts
3
- var t = (t, n) => {
4
- let r = globalThis, i = Symbol.for(`@voltro/web/context:${t}`), a = r[i];
5
- if (a) return a;
6
- let o = e(n);
7
- return r[i] = o, o;
8
- };
9
- //#endregion
10
- export { t };
@@ -1,81 +0,0 @@
1
- import { t as e } from "./frameworkBoot-CV_o2tIk.js";
2
- import { o as t, r as n, t as r } from "./routerState-DAT472IC.js";
3
- import { StrictMode as i, createElement as a } from "react";
4
- import { createRoot as o, hydrateRoot as s } from "react-dom/client";
5
- import { applyPreloadSeeds as c, applyStoreSeeds as l } from "@voltro/client";
6
- import { jsx as u } from "react/jsx-runtime";
7
- //#region src/islands.tsx
8
- var d = /* @__PURE__ */ new Map(), f = (e, t) => {
9
- d.set(t.name, e);
10
- let n = t.hydrate ?? "visible", r = (r) => a("div", {
11
- "data-voltro-island": "",
12
- "data-island-name": t.name,
13
- "data-island-hydrate": n,
14
- "data-island-props": m(r)
15
- }, a(e, r));
16
- return r.displayName = `Island(${t.name})`, r;
17
- }, p = (e) => d.get(e), m = (e) => JSON.stringify(e ?? {}).replace(/</g, "\\u003c"), h = (e) => {
18
- if (!e) return {};
19
- try {
20
- return JSON.parse(e);
21
- } catch {
22
- return {};
23
- }
24
- }, g = () => {
25
- let e = document.querySelectorAll("[data-voltro-island]:not([data-voltro-hydrated])");
26
- for (let t of e) {
27
- let e = t.dataset.islandName ?? "", n = d.get(e);
28
- if (!n) {
29
- console.warn(`[voltro] island "${e}" referenced in DOM but not registered. Did the island file get imported in this bundle?`);
30
- continue;
31
- }
32
- let r = h(t.dataset.islandProps ?? null), i = t.dataset.islandHydrate ?? "visible";
33
- t.setAttribute("data-voltro-hydrated", "pending");
34
- let o = () => {
35
- t.getAttribute("data-voltro-hydrated") !== "done" && (t.setAttribute("data-voltro-hydrated", "done"), s(t, a(n, r)));
36
- };
37
- if (i === "load") o();
38
- else if (i === "idle") {
39
- let e = globalThis.requestIdleCallback;
40
- e ? e(o) : setTimeout(o, 0);
41
- } else if (i === "visible") {
42
- let e = new IntersectionObserver((t) => {
43
- t.some((e) => e.isIntersecting) && (e.disconnect(), o());
44
- }, { rootMargin: "64px" });
45
- e.observe(t);
46
- } else if (i === "interaction") {
47
- let e = () => {
48
- t.removeEventListener("pointerdown", e), t.removeEventListener("keydown", e), o();
49
- };
50
- t.addEventListener("pointerdown", e, { passive: !0 }), t.addEventListener("keydown", e);
51
- }
52
- }
53
- }, _ = () => !1, v = "__voltroIslandsBundleNoticeShown", y = (e) => {
54
- if (!e) return;
55
- let t = globalThis;
56
- t[v] !== !0 && (t[v] = !0, console.info("[voltro] islands mode: hydration is scoped to this page's islands, but the JS payload is NOT reduced — the full app bundle is still downloaded and evaluated. Islands buy CPU, not bytes, today. See the \"Render modes\" docs page."));
57
- }, b = (e) => `${window.location.protocol === "https:" ? "wss:" : "ws:"}//${window.location.host}/ws/${e}`, x = (a, d) => {
58
- let f = document.getElementById(d.rootId ?? "root");
59
- if (!f) throw Error(`@voltro/web: no #${d.rootId ?? "root"} element in the document`);
60
- let p = Object.entries(d.apis).map(([e, t]) => ({
61
- name: e,
62
- group: t.group,
63
- descriptors: t.descriptors ?? {},
64
- wsUrl: t.wsUrl ?? b(e),
65
- headers: t.headers
66
- })), m = document.getElementById(r), h = n(m?.textContent, window.location.pathname), v = h !== null && f.children.length > 0, x = document.querySelector("meta[name=\"voltro-interactive\"]")?.getAttribute("content") ?? "full";
67
- if (x === "none") return;
68
- if (x === "islands") {
69
- y(_()), g();
70
- return;
71
- }
72
- v && t(h), l(h?.storeSeeds), c(h?.preloadSeeds);
73
- let S = /* @__PURE__ */ u(i, { children: /* @__PURE__ */ u(e, {
74
- App: a,
75
- apis: p,
76
- ...d.Devtools ? { Devtools: d.Devtools } : {}
77
- }) });
78
- v ? s(f, S) : o(f).render(S);
79
- };
80
- //#endregion
81
- export { f as a, g as i, y as n, p as r, x as t };