@lomray/vite-ssr-boost 8.2.0 → 8.3.0-beta.1

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 (41) hide show
  1. package/README.md +21 -13
  2. package/SECURITY.md +1 -1
  3. package/adapters/express/entry.d.ts +1 -1
  4. package/adapters/express/entry.js.map +1 -1
  5. package/adapters/express/render.d.ts +4 -1
  6. package/adapters/express/render.js +1 -1
  7. package/adapters/express/render.js.map +1 -1
  8. package/browser/entry.js +1 -1
  9. package/browser/entry.js.map +1 -1
  10. package/browser/stream.d.ts +5 -0
  11. package/browser/stream.js +2 -0
  12. package/browser/stream.js.map +1 -0
  13. package/core/compose-html.d.ts +3 -4
  14. package/core/compose-html.js +1 -1
  15. package/core/compose-html.js.map +1 -1
  16. package/core/data-stream.d.ts +50 -0
  17. package/core/data-stream.js +2 -0
  18. package/core/data-stream.js.map +1 -0
  19. package/core/html-boundary.d.ts +7 -0
  20. package/core/html-boundary.js +2 -0
  21. package/core/html-boundary.js.map +1 -0
  22. package/core/render.d.ts +7 -1
  23. package/core/render.js +1 -1
  24. package/core/render.js.map +1 -1
  25. package/core/script.d.ts +6 -0
  26. package/core/script.js +2 -0
  27. package/core/script.js.map +1 -0
  28. package/edge/render-to-stream.js +1 -1
  29. package/edge/render-to-stream.js.map +1 -1
  30. package/helpers/build-custom-state.d.ts +1 -1
  31. package/helpers/build-custom-state.js +1 -1
  32. package/helpers/build-custom-state.js.map +1 -1
  33. package/helpers/build-router-state.d.ts +1 -1
  34. package/helpers/build-router-state.js +1 -1
  35. package/helpers/build-router-state.js.map +1 -1
  36. package/node/render-to-stream.js +1 -1
  37. package/node/render-to-stream.js.map +1 -1
  38. package/package.json +13 -5
  39. package/services/diagnostics.d.ts +8 -3
  40. package/services/diagnostics.js +1 -1
  41. package/services/diagnostics.js.map +1 -1
package/README.md CHANGED
@@ -20,18 +20,6 @@
20
20
 
21
21
  ## Quick start
22
22
 
23
- **Start a new app** with the `minimal` template (default):
24
-
25
- ```bash
26
- npm create @lomray/ssr-app@latest my-app
27
- ```
28
-
29
- Choose the `full` template by passing the flag after `--`:
30
-
31
- ```bash
32
- npm create @lomray/ssr-app@latest my-app -- --template full
33
- ```
34
-
35
23
  **Add to an existing app:**
36
24
 
37
25
  ```bash
@@ -50,8 +38,22 @@ The [migration guide](./docs/guide/migrate-existing-spa.md) walks through the fi
50
38
  | `src/server.ts` | Add the server entry and request-scoped setup. |
51
39
  | `package.json` | Use the `ssr-boost` dev, build and start commands. |
52
40
 
41
+ **Start a new app** with the `minimal` template (default):
42
+
43
+ ```bash
44
+ npm create @lomray/ssr-app@latest my-app
45
+ ```
46
+
47
+ Choose the `full` template by passing the flag after `--`:
48
+
49
+ ```bash
50
+ npm create @lomray/ssr-app@latest my-app -- --template full
51
+ ```
52
+
53
53
  Starting a new app? Choose one of the [template branches](./docs/examples/index.md) with the [`npm create` command](./docs/guide/getting-started.md#create-a-new-app) or clone the branch directly.
54
54
 
55
+ To defer loader work, return `{ title, slow: fetchUsers() }` and render `slow` with Suspense and `<Await>`; see the [streaming guide](./docs/guide/data-streaming.md).
56
+
55
57
  ## Who this is for
56
58
 
57
59
  - Teams adding SSR to a Vite SPA with React Router route objects.
@@ -66,10 +68,14 @@ Starting a new app? Choose one of the [template branches](./docs/examples/index.
66
68
  - Your React version within the package's peer range: React and React DOM `>=18.2.0`.
67
69
  - Your hosting choice, provided it can run the selected SSR transport or serve SPA files.
68
70
 
71
+ Loader and action promises support `<Await>` and React 19 `use()` during hydration by default. [Stream loader data](./docs/guide/data-streaming.md) shows the loader pattern and `hydration: 'early'` for shell interaction before slow boundaries finish.
72
+
69
73
  ## What you add
70
74
 
71
75
  Add `SsrBoost()` to the Vite plugins, wire `client.ts` and `server.ts`, and replace the Vite scripts with `ssr-boost` commands. The [migration guide](./docs/guide/migrate-existing-spa.md) includes these entries and the HTML outlet, copied from the minimal example.
72
76
 
77
+ Deferred router data needs no additional state library. Keep footer hydration by default, or opt into early hydration with custom state available at `onShellReady`.
78
+
73
79
  ## Choose your server
74
80
 
75
81
  **Managed CLI (default).** Use `ssr-boost dev` for Express with Vite development and HMR, then `ssr-boost build` and `ssr-boost start` for production assets and SSR. The server entry is `@lomray/vite-ssr-boost/adapters/express/entry`, with hooks for requests, rendering and responses.
@@ -84,7 +90,7 @@ Add `SsrBoost()` to the Vite plugins, wire `client.ts` and `server.ts`, and repl
84
90
 
85
91
  ## Install and template quick start
86
92
 
87
- The package declares `engines.node: ">=22.12.0"`. The example uses Node 22.23.2; React Router and build tools can raise the required Node version.
93
+ See [Compatibility](#compatibility) for the package Node requirement. The example uses Node 22.23.2; React Router and build tools can raise the required Node version.
88
94
 
89
95
  Start with the [minimal template](https://github.com/Lomray-Software/vite-template/tree/example/minimal):
90
96
 
@@ -111,6 +117,8 @@ Already running this in production? Point our [free performance audit](https://a
111
117
 
112
118
  ## Compatibility
113
119
 
120
+ See the [support policy](./SUPPORT.md) for version lifetimes, response targets and breaking-change commitments, and [Upgrade from 7 to 8](./docs/guide/upgrade-v8.md) for migration instructions.
121
+
114
122
  The package is tested against the current and previous major of React, React Router and Vite, with an additional Vite 6 row. The [compatibility workflow](./.github/workflows/react-compatibility.yml) runs the full test suite and a built Worker check on Node 22.23.2 with these exact combinations:
115
123
 
116
124
  | React / React DOM | React Router | Vite |
package/SECURITY.md CHANGED
@@ -13,7 +13,7 @@ When reporting security issues, please provide the following information:
13
13
  - Steps to reproduce the vulnerability
14
14
  - Your contact information
15
15
 
16
- We take all security reports seriously and will do our best to rapidly address the issue. We are grateful for your contributions to our security efforts, and we will acknowledge your report upon resolution.
16
+ We will provide a human acknowledgment within **two business days** of receiving your security report. Business days are Monday through Friday, excluding public holidays observed by the responding maintainer. We will keep you informed while we investigate and coordinate a fix; acknowledgment does not mean resolution. See [Support policy](./SUPPORT.md) for the security maintenance windows.
17
17
 
18
18
  ## Responsible Disclosure
19
19
  We adhere to the principle of responsible disclosure. This means that if you discover a vulnerability, you agree to:
@@ -15,7 +15,7 @@ export interface IInitServerRequestOut<T = Record<string, any>> {
15
15
  shouldSkip?: boolean;
16
16
  shouldCancel?: boolean;
17
17
  }
18
- export interface IEntrypointOptions<TAppProps = Record<string, any>> extends Pick<IRenderOptions<TAppProps>, 'onRouterReady' | 'onShellReady' | 'onShellError' | 'onResponse' | 'onError' | 'getState' | 'getBody'> {
18
+ export interface IEntrypointOptions<TAppProps = Record<string, any>> extends Pick<IRenderOptions<TAppProps>, 'onRouterReady' | 'onShellReady' | 'onShellError' | 'onResponse' | 'onError' | 'getState' | 'getBody' | 'hydration' | 'nonce' | 'bootstrapScriptContent'> {
19
19
  onServerCreated?: (app: Express, serverApi: ServerApi) => Promise<void> | void;
20
20
  onServerStarted?: (app: Express, serverApi: ServerApi, server: Server) => Promise<void> | void;
21
21
  onRequest?: (req: Request, res: ExpressResponse) => Promise<IInitServerRequestOut<TAppProps>> | IInitServerRequestOut<TAppProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"entry.js","sources":["../../../src/adapters/express/entry.tsx"],"sourcesContent":[null],"names":["entry","App","routes","init","routerOptions","rest","handler","createStaticHandler","render","bind"],"mappings":"8EA4EA,SAASA,EACPC,EACAC,GACAC,KAAEA,EAAIC,cAAEA,KAAkBC,GAAyC,IAEnE,MAAMC,EAAUC,EAAoBL,EAAyBE,GAE7D,MAAO,CACLI,OAAQA,EAAOC,KAAK,KAAM,CAAEH,UAASL,QACrCE,OACAD,YACGG,EAEP"}
1
+ {"version":3,"file":"entry.js","sources":["../../../src/adapters/express/entry.tsx"],"sourcesContent":[null],"names":["entry","App","routes","init","routerOptions","rest","handler","createStaticHandler","render","bind"],"mappings":"8EA+EA,SAASA,EACPC,EACAC,GACAC,KAAEA,EAAIC,cAAEA,KAAkBC,GAAyC,IAEnE,MAAMC,EAAUC,EAAoBL,EAAyBE,GAE7D,MAAO,CACLI,OAAQA,EAAOC,KAAK,KAAM,CAAEH,UAASL,QACrCE,OACAD,YACGG,EAEP"}
@@ -26,6 +26,9 @@ export interface IRenderParams<TAppProps = Record<string, any>> {
26
26
  handler: StaticHandler;
27
27
  }
28
28
  export interface IRenderOptions<TAppProps = Record<string, any>> {
29
+ hydration?: 'early' | 'footer';
30
+ nonce?: string;
31
+ bootstrapScriptContent?: string;
29
32
  abortDelay?: number;
30
33
  getBody?: (request: ExpressRequest) => BodyInit | null | undefined;
31
34
  onRouterReady?: (params: {
@@ -61,5 +64,5 @@ export interface IShellReadyOut {
61
64
  /**
62
65
  * Render application
63
66
  */
64
- declare function render({ App, handler }: IRenderParams, config: ServerConfig, initialContext: Omit<IRequestContext, 'request'>, { onRouterReady, onShellReady, onResponse, onShellError, onError, getBody, getState, abortDelay, }: IRenderOptions): Promise<void>;
67
+ declare function render({ App, handler }: IRenderParams, config: ServerConfig, initialContext: Omit<IRequestContext, 'request'>, { onRouterReady, onShellReady, onResponse, onShellError, onError, getBody, getState, hydration, nonce, bootstrapScriptContent, abortDelay, }: IRenderOptions): Promise<void>;
65
68
  export default render;
@@ -1,2 +1,2 @@
1
- import e from"chalk";import r from"react";import t from"./create-request.js";import o from"../../constants/stream-error.js";import s from"../../core/early-hints.js";import{getHeaderEntries as n,getSetCookieHeaders as a}from"../../core/headers.js";import i from"../../core/render.js";import d from"../../node/render-to-stream.js";import c from"../../node/request-signal.js";import m from"../../node/write-early-hints.js";import p,{writeFetchHeaders as l}from"../../node/write-fetch-response.js";import u,{isDiagnosticsEnabled as h}from"../../services/diagnostics.js";import f from"../../services/ssr-manifest.js";const x=(e,r,o)=>{const s={signal:r};return o&&"GET"!==e.method&&"HEAD"!==e.method&&(s.body=o(e)??null),t(e,s)};async function y({App:t,handler:y},g,E,{onRouterReady:w,onShellReady:S,onResponse:j,onShellError:v,onError:C,getBody:R,getState:q,abortDelay:b=15e3}){const{appProps:A,html:H,req:k,res:D}=E,L=g.getLogger(),P=c(k,D);try{const c=Object.assign(E,{request:x(k,P.signal,R)}),T={appProps:A,diagnostics:h(!g.isProd)?new u(new URL(c.request.url).pathname,L):void 0,html:H,request:c.request,response:{headers:new Headers}},O=e=>(c.request=e.request,c.didError=e.didError,c.html=e.html,c.isStream=e.isStream,c.routerContext=e.routerContext,c.serverContext=e.serverContext,c),B=await i({createApp:(e,o)=>r.createElement(t,{server:{...o.appProps,req:k}},e),handler:y,renderToStream:d},T,{abortDelay:b,getState:q?({context:e})=>q({context:O(e)}):void 0,onError:({context:r,error:t})=>{const{code:s,message:n}=t;if(C?.({context:O(r),error:t}),L.info(e.red(`Stream error. Code: ${s}`)),[o.RenderAborted,o.RenderTimeout,o.RenderCancel].includes(s))return void L.info(e.dim(n));const{original:a}=t;L.error(a)},onResponse:j?({context:e,html:r,isEnd:t})=>j({context:O(e),html:r,isEnd:t}):void 0,onRouterReady:w?({context:e})=>w({context:O(e)}):void 0,onShellError:v?({context:e,error:r})=>v({context:O(e),error:r}):void 0,onShellReady:({context:e})=>{const r=O(e);((e,r)=>{if(r.headersSent||r.writableEnded)return;r.status(e.response.status??200),n(e.response.headers).forEach(([e,t])=>r.setHeader(e,t));const t=a(e.response.headers);t.length&&r.setHeader("Set-Cookie",t)})(e,D);const t=S?.({context:r});return((e,r)=>{const t=new Headers(e.response.headers);t.delete("Set-Cookie");for(const[e,o]of Object.entries(r.getHeaders()))if("set-cookie"!==e.toLowerCase()&&void 0!==o)if(Array.isArray(o))for(const r of o)t.append(e,r);else t.set(e,"number"==typeof o?String(o):o);e.response.headers=t,e.response.status=r.statusCode})(e,D),t??{}},prepare:async({context:e,executionContext:r})=>{const t=O(e),o=f.get(g);await o.prepareDevAssets(e.routerContext?.matches);const n=o.injectAssets(t);t.hasEarlyHints&&await s(r,n)},routerRequestContext:c},{onEarlyHints:e=>m(D,e)});O(T),await(async(e,r)=>{const t=r.headers.get("Location");if(t&&r.status>=300&&r.status<400&&!e.headersSent&&!e.writableEnded&&!e.destroyed)return l(e,r),await(r.body?.cancel()),void e.redirect(r.status,t);await p(e,r)})(D,B)}finally{P.dispose()}}export{y as default};
1
+ import e from"chalk";import t from"react";import r from"./create-request.js";import o from"../../constants/stream-error.js";import s from"../../core/early-hints.js";import{getHeaderEntries as n,getSetCookieHeaders as a}from"../../core/headers.js";import i from"../../core/render.js";import d from"../../node/render-to-stream.js";import c from"../../node/request-signal.js";import p from"../../node/write-early-hints.js";import m,{writeFetchHeaders as l}from"../../node/write-fetch-response.js";import u,{isDiagnosticsEnabled as h}from"../../services/diagnostics.js";import f from"../../services/ssr-manifest.js";const y=(e,t,o)=>{const s={signal:t};return o&&"GET"!==e.method&&"HEAD"!==e.method&&(s.body=o(e)??null),r(e,s)};async function x({App:r,handler:x},g,S,{onRouterReady:E,onShellReady:w,onResponse:C,onShellError:j,onError:v,getBody:R,getState:b,hydration:q,nonce:A,bootstrapScriptContent:H,abortDelay:k=15e3}){const{appProps:D,html:L,req:P,res:T}=S,O=g.getLogger(),B=c(P,T);try{const c=Object.assign(S,{request:y(P,B.signal,R)}),G={appProps:D,diagnostics:h(!g.isProd)?new u(new URL(c.request.url).pathname,O):void 0,html:L,request:c.request,response:{headers:new Headers}},U=e=>(c.request=e.request,c.didError=e.didError,c.html=e.html,c.isStream=e.isStream,c.routerContext=e.routerContext,c.serverContext=e.serverContext,c),$=await i({createApp:(e,o)=>t.createElement(r,{server:{...o.appProps,req:P}},e),handler:x,renderToStream:d},G,{abortDelay:k,hydration:q,nonce:A,bootstrapScriptContent:H,getState:b?({context:e})=>b({context:U(e)}):void 0,onError:({context:t,error:r})=>{const{code:s,message:n}=r;if(v?.({context:U(t),error:r}),O.info(e.red(`Stream error. Code: ${s}`)),[o.RenderAborted,o.RenderTimeout,o.RenderCancel].includes(s))return void O.info(e.dim(n));const{original:a}=r;O.error(a)},onResponse:C?({context:e,html:t,isEnd:r})=>C({context:U(e),html:t,isEnd:r}):void 0,onRouterReady:E?({context:e})=>E({context:U(e)}):void 0,onShellError:j?({context:e,error:t})=>j({context:U(e),error:t}):void 0,onShellReady:({context:e})=>{const t=U(e);((e,t)=>{if(t.headersSent||t.writableEnded)return;t.status(e.response.status??200),n(e.response.headers).forEach(([e,r])=>t.setHeader(e,r));const r=a(e.response.headers);r.length&&t.setHeader("Set-Cookie",r)})(e,T);const r=w?.({context:t});return((e,t)=>{const r=new Headers(e.response.headers);r.delete("Set-Cookie");for(const[e,o]of Object.entries(t.getHeaders()))if("set-cookie"!==e.toLowerCase()&&void 0!==o)if(Array.isArray(o))for(const t of o)r.append(e,t);else r.set(e,"number"==typeof o?String(o):o);e.response.headers=r,e.response.status=t.statusCode})(e,T),r??{}},prepare:async({context:e,executionContext:t})=>{const r=U(e),o=f.get(g);await o.prepareDevAssets(e.routerContext?.matches);const n=o.injectAssets(r);r.hasEarlyHints&&await s(t,n)},routerRequestContext:c},{onEarlyHints:e=>p(T,e)});U(G),await(async(e,t)=>{const r=t.headers.get("Location");if(r&&t.status>=300&&t.status<400&&!e.headersSent&&!e.writableEnded&&!e.destroyed)return l(e,t),await(t.body?.cancel()),void e.redirect(t.status,r);await m(e,t)})(T,$)}finally{B.dispose()}}export{x as default};
2
2
  //# sourceMappingURL=render.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sources":["../../../src/adapters/express/render.tsx"],"sourcesContent":[null],"names":["createRenderRequest","req","signal","getBody","options","method","body","createFetchRequest","async","render","App","handler","config","initialContext","onRouterReady","onShellReady","onResponse","onShellError","onError","getState","abortDelay","appProps","html","shellHtml","res","Logger","getLogger","requestSignal","createRequestSignal","context","Object","assign","request","coreContext","diagnostics","isDiagnosticsEnabled","isProd","Diagnostics","URL","url","pathname","undefined","response","headers","Headers","syncContext","updated","didError","isStream","routerContext","serverContext","coreRender","createApp","children","React","createElement","server","renderToStream","error","code","message","info","chalk","red","StreamError","RenderAborted","RenderTimeout","RenderCancel","includes","dim","original","isEnd","legacyContext","headersSent","writableEnded","status","getHeaderEntries","forEach","name","value","setHeader","cookies","getSetCookieHeaders","length","prepareResponse","shell","delete","entries","getHeaders","toLowerCase","Array","isArray","item","append","set","String","statusCode","syncResponse","prepare","executionContext","manifest","SsrManifest","get","prepareDevAssets","matches","hints","injectAssets","hasEarlyHints","emitEarlyHints","routerRequestContext","onEarlyHints","writeEarlyHints","location","destroyed","writeFetchHeaders","cancel","redirect","writeFetchResponse","writeResponse","dispose"],"mappings":"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"}
1
+ {"version":3,"file":"render.js","sources":["../../../src/adapters/express/render.tsx"],"sourcesContent":[null],"names":["createRenderRequest","req","signal","getBody","options","method","body","createFetchRequest","async","render","App","handler","config","initialContext","onRouterReady","onShellReady","onResponse","onShellError","onError","getState","hydration","nonce","bootstrapScriptContent","abortDelay","appProps","html","shellHtml","res","Logger","getLogger","requestSignal","createRequestSignal","context","Object","assign","request","coreContext","diagnostics","isDiagnosticsEnabled","isProd","Diagnostics","URL","url","pathname","undefined","response","headers","Headers","syncContext","updated","didError","isStream","routerContext","serverContext","coreRender","createApp","children","React","createElement","server","renderToStream","error","code","message","info","chalk","red","StreamError","RenderAborted","RenderTimeout","RenderCancel","includes","dim","original","isEnd","legacyContext","headersSent","writableEnded","status","getHeaderEntries","forEach","name","value","setHeader","cookies","getSetCookieHeaders","length","prepareResponse","shell","delete","entries","getHeaders","toLowerCase","Array","isArray","item","append","set","String","statusCode","syncResponse","prepare","executionContext","manifest","SsrManifest","get","prepareDevAssets","matches","hints","injectAssets","hasEarlyHints","emitEarlyHints","routerRequestContext","onEarlyHints","writeEarlyHints","location","destroyed","writeFetchHeaders","cancel","redirect","writeFetchResponse","writeResponse","dispose"],"mappings":"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"}
package/browser/entry.js CHANGED
@@ -1,2 +1,2 @@
1
- import e from"react";import t from"react-dom/client";import{matchRoutes as o,createBrowserRouter as n,RouterProvider as r}from"react-router";import{IS_SSR_MODE as a}from"../constants/common.js";async function i(i,c,{init:d,routerOptions:l,createRouter:m=n,rootId:u="root"}={}){const s=(()=>{const e="__staticRouterHydrationData";if(!("loading"!==document.readyState||a&&void 0!==Reflect.get(window,e)))return new Promise(t=>{const o=()=>{a&&Reflect.deleteProperty(window,e),t()};document.addEventListener("DOMContentLoaded",o,{once:!0}),a&&Object.defineProperty(window,e,{configurable:!0,enumerable:!0,get:()=>{},set:n=>{Object.defineProperty(window,e,{configurable:!0,enumerable:!0,writable:!0,value:n}),document.removeEventListener("DOMContentLoaded",o),t()}})})})(),f=o(c,window.location,l?.basename)?.filter(e=>e.route.lazy);(s||f?.length)&&await Promise.all([s,...(f??[]).map(async e=>{const{lazy:t}=e.route;if("function"==typeof t){const o=await t();o&&Object.assign(e.route,{...o,lazy:void 0})}})]);const w=m(c,l),y=document.getElementById(u),p=await(d?.({isSSRMode:a,router:w})),b=()=>e.createElement(i,{client:p},e.createElement(r,{router:w}));return a&&"1"!==y.dataset.forceSpa?t.hydrateRoot(y,e.createElement(b,null)):t.createRoot(y).render(e.createElement(b,null))}export{i as default};
1
+ import e from"react";import t from"react-dom/client";import{matchRoutes as o,createBrowserRouter as r,RouterProvider as n}from"react-router";import a from"./stream.js";import{IS_SSR_MODE as i}from"../constants/common.js";async function c(c,d,{init:s,routerOptions:l,createRouter:m=r,rootId:u="root"}={}){const f=i?a():void 0,w=(()=>{const e="__staticRouterHydrationData";if(!("loading"!==document.readyState||i&&void 0!==Reflect.get(window,e)))return new Promise(t=>{const o=()=>{i&&Reflect.deleteProperty(window,e),t()};document.addEventListener("DOMContentLoaded",o,{once:!0}),i&&Object.defineProperty(window,e,{configurable:!0,enumerable:!0,get:()=>{},set:r=>{Object.defineProperty(window,e,{configurable:!0,enumerable:!0,writable:!0,value:r}),document.removeEventListener("DOMContentLoaded",o),t()}})})})(),y=o(d,window.location,l?.basename)?.filter(e=>e.route.lazy);(w||y?.length)&&await Promise.all([w,...(y??[]).map(async e=>{const{lazy:t}=e.route;if("function"==typeof t){const o=await t();o&&Object.assign(e.route,{...o,lazy:void 0})}})]);const p=Reflect.get(window,"__staticRouterHydrationData");f&&p?.__ssrBoostStream&&Reflect.set(window,"__staticRouterHydrationData",await f.ready);const R=m(d,l),b=document.getElementById(u),g=await(s?.({isSSRMode:i,router:R})),_=()=>e.createElement(c,{client:g},e.createElement(n,{router:R}));return i&&"1"!==b.dataset.forceSpa?t.hydrateRoot(b,e.createElement(_,null)):t.createRoot(b).render(e.createElement(_,null))}export{c as default};
2
2
  //# sourceMappingURL=entry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entry.js","sources":["../../src/browser/entry.tsx"],"sourcesContent":[null],"names":["async","entry","App","routes","init","routerOptions","createRouter","createBrowserRouter","rootId","documentReady","hydrationKey","document","readyState","IS_SSR_MODE","undefined","Reflect","get","window","Promise","resolve","onReady","deleteProperty","addEventListener","once","Object","defineProperty","configurable","enumerable","set","value","writable","removeEventListener","waitForDocument","lazyMatches","matchRoutes","location","basename","filter","m","route","lazy","length","all","map","lazyResult","assign","router","root","getElementById","appProps","isSSRMode","AppComponent","React","createElement","client","RouterProvider","dataset","ReactDOM","hydrateRoot","createRoot","render"],"mappings":"kMAyEAA,eAAeC,EACbC,EACAC,GACAC,KACEA,EAAIC,cACJA,EAAaC,aACbA,EAAeC,EAAmBC,OAClCA,EAAS,QACyB,CAAA,GAEpC,MAAMC,EAtDgB,MACtB,MAAMC,EAAe,8BAErB,KAC0B,YAAxBC,SAASC,YACRC,QAAqDC,IAAtCC,QAAQC,IAAIC,OAAQP,IAKtC,OAAO,IAAIQ,QAAeC,IACxB,MAAMC,EAAU,KACVP,GACFE,QAAQM,eAAeJ,OAAQP,GAGjCS,KAGFR,SAASW,iBAAiB,mBAAoBF,EAAS,CAAEG,MAAM,IAE3DV,GACFW,OAAOC,eAAeR,OAAQP,EAAc,CAC1CgB,cAAc,EACdC,YAAY,EACZX,IAAK,OACLY,IAAMC,IACJL,OAAOC,eAAeR,OAAQP,EAAc,CAC1CgB,cAAc,EACdC,YAAY,EACZG,UAAU,EACVD,UAEFlB,SAASoB,oBAAoB,mBAAoBX,GACjDD,UAoBca,GAChBC,EAAcC,EAClB/B,EACAc,OAAOkB,SACP9B,GAAe+B,WACdC,OAAQC,GAAMA,EAAEC,MAAMC,OAIrB/B,GAAiBwB,GAAaQ,eAC1BvB,QAAQwB,IAAI,CAChBjC,MACIwB,GAAe,IAAIU,IAAI3C,MAAOsC,IAChC,MAAME,KAAEA,GAASF,EAAEC,MAEnB,GAAoB,mBAATC,EAAqB,CAC9B,MAAMI,QAAmBJ,IAErBI,GACFpB,OAAOqB,OAAOP,EAAEC,MAAO,IAClBK,EACHJ,UAAM1B,GAGZ,MAKN,MAAMgC,EAASxC,EAAaH,EAAyBE,GAC/C0C,EAAOpC,SAASqC,eAAexC,GAC/ByC,QAAkB7C,IAAO,CAAE8C,UAAWrC,EAAaiC,YAEnDK,EAAmB,IACvBC,EAAAC,cAACnD,EAAG,CAACoD,OAAQL,GACXG,EAAAC,cAACE,GAAeT,OAAQA,KAI5B,OAAKjC,GAA4C,MAA7BkC,EAAKS,QAAkB,SAIpCC,EAASC,YAAYX,EAAMK,EAAAC,cAACF,EAAY,OAHtCM,EAASE,WAAWZ,GAAMa,OAAOR,EAAAC,cAACF,EAAY,MAIzD"}
1
+ {"version":3,"file":"entry.js","sources":["../../src/browser/entry.tsx"],"sourcesContent":[null],"names":["async","entry","App","routes","init","routerOptions","createRouter","createBrowserRouter","rootId","stream","IS_SSR_MODE","receiveStream","undefined","documentReady","hydrationKey","document","readyState","Reflect","get","window","Promise","resolve","onReady","deleteProperty","addEventListener","once","Object","defineProperty","configurable","enumerable","set","value","writable","removeEventListener","waitForDocument","lazyMatches","matchRoutes","location","basename","filter","m","route","lazy","length","all","map","lazyResult","assign","hydration","__ssrBoostStream","ready","router","root","getElementById","appProps","isSSRMode","AppComponent","React","createElement","client","RouterProvider","dataset","ReactDOM","hydrateRoot","createRoot","render"],"mappings":"6NA0EAA,eAAeC,EACbC,EACAC,GACAC,KACEA,EAAIC,cACJA,EAAaC,aACbA,EAAeC,EAAmBC,OAClCA,EAAS,QACyB,CAAA,GAEpC,MAAMC,EAASC,EAAcC,SAAkBC,EACzCC,EAvDgB,MACtB,MAAMC,EAAe,8BAErB,KAC0B,YAAxBC,SAASC,YACRN,QAAqDE,IAAtCK,QAAQC,IAAIC,OAAQL,IAKtC,OAAO,IAAIM,QAAeC,IACxB,MAAMC,EAAU,KACVZ,GACFO,QAAQM,eAAeJ,OAAQL,GAGjCO,KAGFN,SAASS,iBAAiB,mBAAoBF,EAAS,CAAEG,MAAM,IAE3Df,GACFgB,OAAOC,eAAeR,OAAQL,EAAc,CAC1Cc,cAAc,EACdC,YAAY,EACZX,IAAK,OACLY,IAAMC,IACJL,OAAOC,eAAeR,OAAQL,EAAc,CAC1Cc,cAAc,EACdC,YAAY,EACZG,UAAU,EACVD,UAEFhB,SAASkB,oBAAoB,mBAAoBX,GACjDD,UAqBca,GAChBC,EAAcC,EAClBjC,EACAgB,OAAOkB,SACPhC,GAAeiC,WACdC,OAAQC,GAAMA,EAAEC,MAAMC,OAIrB7B,GAAiBsB,GAAaQ,eAC1BvB,QAAQwB,IAAI,CAChB/B,MACIsB,GAAe,IAAIU,IAAI7C,MAAOwC,IAChC,MAAME,KAAEA,GAASF,EAAEC,MAEnB,GAAoB,mBAATC,EAAqB,CAC9B,MAAMI,QAAmBJ,IAErBI,GACFpB,OAAOqB,OAAOP,EAAEC,MAAO,IAClBK,EACHJ,UAAM9B,GAGZ,MAKN,MAAMoC,EAAY/B,QAAQC,IAAIC,OAAQ,+BAGlCV,GAAUuC,GAAWC,kBACvBhC,QAAQa,IAAIX,OAAQ,oCAAqCV,EAAOyC,OAGlE,MAAMC,EAAS7C,EAAaH,EAAyBE,GAC/C+C,EAAOrC,SAASsC,eAAe7C,GAC/B8C,QAAkBlD,IAAO,CAAEmD,UAAW7C,EAAayC,YAEnDK,EAAmB,IACvBC,EAAAC,cAACxD,EAAG,CAACyD,OAAQL,GACXG,EAAAC,cAACE,GAAeT,OAAQA,KAI5B,OAAKzC,GAA4C,MAA7B0C,EAAKS,QAAkB,SAIpCC,EAASC,YAAYX,EAAMK,EAAAC,cAACF,EAAY,OAHtCM,EAASE,WAAWZ,GAAMa,OAAOR,EAAAC,cAACF,EAAY,MAIzD"}
@@ -0,0 +1,5 @@
1
+ /** Install before waiting for the document: inline frames may precede the async entry. */
2
+ declare const receiveStream: () => {
3
+ ready: Promise<unknown>;
4
+ };
5
+ export default receiveStream;
@@ -0,0 +1,2 @@
1
+ import{parse as e}from"devalue";const t=()=>{const t=window,r=t.__ssrBoostStream??=[],o=new Map;let s,c,n,i=!1,a=!1,l=!1;const m=new Promise((e,t)=>{c=e,n=t}),S=e=>{let t=o.get(e);if(!t){let r,s;const c=new Promise((e,t)=>{r=e,s=t});c.catch(()=>{}),t={promise:c,resolve:r,reject:s},o.set(e,t)}return t},d=t=>e(t,{SSRBPromise:([e])=>S(e).promise,SSRBObject:e=>Object.fromEntries(e),SSRBError:e=>{const t=Object.fromEntries(e),r=Object.assign(new Error("Streamed loader/action rejection"),t);return t.stack||delete r.stack,r},SSRBUndefined:()=>{}});return r.push=(...e)=>{for(const t of e)try{"shell"===t[0]?i=!0:"init"===t[0]?(s=d(t[1]),[,,a]=t,l=!0):S(t[1])[t[0]](d(t[2])),!l||a&&!i||c(s)}catch(e){n(e),o.forEach(t=>t.reject(e))}return 0},r.push(...r.splice(0)),m.catch(()=>{}),{ready:m}};export{t as default};
2
+ //# sourceMappingURL=stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.js","sources":["../../src/browser/stream.ts"],"sourcesContent":[null],"names":["receiveStream","target","window","queue","__ssrBoostStream","promises","Map","state","resolveReady","rejectReady","hasShell","isEarly","isInitialized","ready","Promise","resolve","reject","deferred","id","pending","get","promise","res","rej","catch","set","value","payload","parse","SSRBPromise","SSRBObject","entries","Object","fromEntries","SSRBError","data","error","assign","Error","stack","SSRBUndefined","push","frames","frame","forEach","splice"],"mappings":"gCAUA,MAAMA,EAAgB,KACpB,MAAMC,EAASC,OACTC,EAASF,EAAOG,mBAAqB,GACrCC,EAAW,IAAIC,IACrB,IAGIC,EACAC,EACAC,EALAC,GAAW,EACXC,GAAU,EACVC,GAAgB,EAIpB,MAAMC,EAAQ,IAAIC,QAAiB,CAACC,EAASC,KAC3CR,EAAeO,EACfN,EAAcO,IAIVC,EAAYC,IAChB,IAAIC,EAAUd,EAASe,IAAIF,GAE3B,IAAKC,EAAS,CACZ,IAAIJ,EACAC,EACJ,MAAMK,EAAU,IAAIP,QAAQ,CAACQ,EAAKC,KAChCR,EAAUO,EACVN,EAASO,IAGNF,EAAQG,MAAM,QACnBL,EAAU,CAAEE,UAASN,UAASC,UAC9BX,EAASoB,IAAIP,EAAIC,EACnB,CAEA,OAAOA,GAIHO,EAASC,GACbC,EAAMD,EAAS,CACbE,YAAa,EAAEX,KAAkBD,EAASC,GAAIG,QAC9CS,WAAaC,GAAiCC,OAAOC,YAAYF,GACjEG,UAAYH,IACV,MAAMI,EAAOH,OAAOC,YAAYF,GAC1BK,EAAQJ,OAAOK,OAAO,IAAIC,MAAM,oCAAqCH,GAM3E,OAJKA,EAAKI,cACDH,EAAMG,MAGRH,GAETI,cAAe,SA+BnB,OA3BArC,EAAMsC,KAAO,IAAIC,KACf,IAAK,MAAMC,KAASD,EAClB,IACmB,UAAbC,EAAM,GACRjC,GAAW,EACW,SAAbiC,EAAM,IACfpC,EAAQmB,EAAMiB,EAAM,KACpB,CAAA,CAAKhC,GAAWgC,EAChB/B,GAAgB,GAEhBK,EAAS0B,EAAM,IAAIA,EAAM,IAAIjB,EAAMiB,EAAM,MAGvC/B,GAAmBD,IAAWD,GAChCF,EAAaD,EAEjB,CAAE,MAAO6B,GACP3B,EAAY2B,GACZ/B,EAASuC,QAASzB,GAAYA,EAAQH,OAAOoB,GAC/C,CAGF,OAAO,GAETjC,EAAMsC,QAAQtC,EAAM0C,OAAO,IACtBhC,EAAMW,MAAM,QAEV,CAAEX"}
@@ -1,5 +1,4 @@
1
- /**
2
- * Stream the shell, React body and hydration footer under downstream backpressure.
3
- */
4
- declare const composeHtml: (header: string, body: ReadableStream<Uint8Array>, footer: string, abort?: (reason?: unknown) => void, onComplete?: () => void) => ReadableStream<Uint8Array>;
1
+ import type DataStream from './data-stream.js';
2
+ /** Stream shell, data frames, React bytes and footer only under downstream demand. */
3
+ declare const composeHtml: (header: string, body: ReadableStream<Uint8Array>, footer: string, abort?: (reason?: unknown) => void, onComplete?: () => void, data?: DataStream) => ReadableStream<Uint8Array>;
5
4
  export default composeHtml;
@@ -1,2 +1,2 @@
1
- const e=(e,a,r,o,t)=>{const n=new TextEncoder,c=a.getReader();let l="header";return new ReadableStream({cancel:async e=>{if(o?.(e),"footer"!==l)try{await c.cancel(e)}finally{c.releaseLock(),t?.()}},async pull(a){if("header"===l&&(l="body",e))a.enqueue(n.encode(e));else{if("body"===l){let e;try{e=await c.read()}catch(e){return o?.(e),c.releaseLock(),t?.(),void a.error(e)}if(!e.done)return void a.enqueue(e.value);l="footer",c.releaseLock(),t?.()}r&&a.enqueue(n.encode(r)),a.close()}}},{highWaterMark:0})};export{e as default};
1
+ import e from"./html-boundary.js";const n=(n,t,a,r,o,c)=>{const i=new TextEncoder,d=t.getReader();let u,l="header",f=!1,s=!1;const h=e();let y,v=!0;const w=()=>{s||(s=!0,d.releaseLock())};return new ReadableStream({cancel:async e=>{f=!0,r?.(e),c?.cancel();try{s||await d.cancel(e)}finally{w(),o?.()}},async pull(e){try{if("header"===l&&(l="body",n))return void e.enqueue(i.encode(n));for(;!f;){const n=v?c?.take():void 0;if(f)return;if(n)return void e.enqueue(i.encode(n));if(y)return v=h(y),e.enqueue(y),void(y=void 0);if("body"===l){u??=d.read();const e=await(c&&!c.isDone&&v?Promise.race([u,c.changed().then(()=>{})]):u);if(f)return;if(!e)continue;if(u=void 0,!e.done){y=e.value;continue}l="footer",v=!0,w();continue}!c||c.isDone?(a&&e.enqueue(i.encode(a)),f=!0,o?.(),e.close()):await c.changed()}}catch(n){if(f)return;f=!0,r?.(n),c?.cancel(),e.error(n);try{s||await d.cancel(n).catch(()=>{})}finally{w(),o?.()}}}},{highWaterMark:0})};export{n as default};
2
2
  //# sourceMappingURL=compose-html.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compose-html.js","sources":["../../src/core/compose-html.ts"],"sourcesContent":[null],"names":["composeHtml","header","body","footer","abort","onComplete","encoder","TextEncoder","reader","getReader","phase","ReadableStream","cancel","async","reason","releaseLock","pull","controller","enqueue","encode","chunk","read","error","done","value","close","highWaterMark"],"mappings":"AAGA,MAAMA,EAAc,CAClBC,EACAC,EACAC,EACAC,EACAC,KAEA,MAAMC,EAAU,IAAIC,YACdC,EAASN,EAAKO,YACpB,IAAIC,EAAsC,SAE1C,OAAO,IAAIC,eACT,CAIEC,OAAQC,MAAOC,IAGb,GAFAV,IAAQU,GAEM,WAAVJ,EAIJ,UACQF,EAAOI,OAAOE,EACtB,SACEN,EAAOO,cACPV,KACF,GAMF,UAAMW,CAAKC,GACT,GAAc,WAAVP,IACFA,EAAQ,OAEJT,GACFgB,EAAWC,QAAQZ,EAAQa,OAAOlB,QAJtC,CAUA,GAAc,SAAVS,EAAkB,CACpB,IAAIU,EAEJ,IACEA,QAAcZ,EAAOa,MACvB,CAAE,MAAOC,GAMP,OALAlB,IAAQkB,GACRd,EAAOO,cACPV,WACAY,EAAWK,MAAMA,EAGnB,CAEA,IAAKF,EAAMG,KAGT,YAFAN,EAAWC,QAAQE,EAAMI,OAK3Bd,EAAQ,SACRF,EAAOO,cACPV,KACF,CAEIF,GACFc,EAAWC,QAAQZ,EAAQa,OAAOhB,IAGpCc,EAAWQ,OA/BX,CAgCF,GAGF,CAAEC,cAAe"}
1
+ {"version":3,"file":"compose-html.js","sources":["../../src/core/compose-html.ts"],"sourcesContent":[null],"names":["composeHtml","header","body","footer","abort","onComplete","data","encoder","TextEncoder","reader","getReader","pendingRead","phase","isStopped","isReleased","observe","htmlBoundary","heldChunk","canInject","release","releaseLock","ReadableStream","cancel","async","reason","pull","controller","enqueue","encode","frames","take","undefined","read","chunk","isDone","Promise","race","changed","then","done","value","close","error","catch","highWaterMark"],"mappings":"kCAIA,MAAMA,EAAc,CAClBC,EACAC,EACAC,EACAC,EACAC,EACAC,KAEA,MAAMC,EAAU,IAAIC,YACdC,EAASP,EAAKQ,YACpB,IAGIC,EAHAC,EAAsC,SACtCC,GAAY,EACZC,GAAa,EAEjB,MAAMC,EAAUC,IAChB,IACIC,EADAC,GAAY,EAIhB,MAAMC,EAAU,KACTL,IACHA,GAAa,EACbL,EAAOW,gBAIX,OAAO,IAAIC,eACT,CAEEC,OAAQC,MAAOC,IACbX,GAAY,EACZT,IAAQoB,GACRlB,GAAMgB,SAEN,IACOR,SACGL,EAAOa,OAAOE,EAExB,SACEL,IACAd,KACF,GAIF,UAAMoB,CAAKC,GACT,IACE,GAAc,WAAVd,IACFA,EAAQ,OAEJX,GAGF,YAFAyB,EAAWC,QAAQpB,EAAQqB,OAAO3B,IAMtC,MAAQY,GAAW,CACjB,MAAMgB,EAASX,EAAYZ,GAAMwB,YAASC,EAE1C,GAAIlB,EACF,OAGF,GAAIgB,EAGF,YAFAH,EAAWC,QAAQpB,EAAQqB,OAAOC,IAKpC,GAAIZ,EAKF,OAJAC,EAAYH,EAAQE,GACpBS,EAAWC,QAAQV,QACnBA,OAAYc,GAKd,GAAc,SAAVnB,EAAkB,CACpBD,IAAgBF,EAAOuB,OACvB,MAAMC,QAAe3B,IAASA,EAAK4B,QAAUhB,EACzCiB,QAAQC,KAAK,CAACzB,EAAaL,EAAK+B,UAAUC,KAAK,UAC/C3B,GAEJ,GAAIE,EACF,OAGF,IAAKoB,EACH,SAKF,GAFAtB,OAAcoB,GAETE,EAAMM,KAAM,CACftB,EAAYgB,EAAMO,MAElB,QACF,CAEA5B,EAAQ,SACRM,GAAY,EACZC,IACA,QACF,EAEIb,GAASA,EAAK4B,QAKd/B,GACFuB,EAAWC,QAAQpB,EAAQqB,OAAOzB,IAGpCU,GAAY,EACZR,MACAqB,EAAWe,eAVHnC,EAAK+B,SAWf,CACF,CAAE,MAAOK,GACP,GAAI7B,EACF,OAGFA,GAAY,EACZT,IAAQsC,GACRpC,GAAMgB,SACNI,EAAWgB,MAAMA,GAEjB,IACO5B,SACGL,EAAOa,OAAOoB,GAAOC,MAAM,OAErC,SACExB,IACAd,KACF,CACF,CACF,GAEF,CAAEuC,cAAe"}
@@ -0,0 +1,50 @@
1
+ import type { StaticHandlerContext } from 'react-router';
2
+ import type Diagnostics from '../services/diagnostics.js';
3
+ interface IPending {
4
+ settled: boolean;
5
+ }
6
+ /** Preserve route response details without shipping arbitrary error properties. */
7
+ declare const errorProperties: (reason: unknown, diagnostics: boolean) => Record<string, unknown>;
8
+ /**
9
+ * Request-local promise identities and settlements. devalue encodes each frame's
10
+ * value; promise reducers keep settlement scheduling outside the value codec.
11
+ * No React bytes are read here. Nested settlements can introduce further placeholders.
12
+ */
13
+ declare class DataStream {
14
+ protected readonly diagnostics?: Diagnostics | undefined;
15
+ protected readonly nonce?: string | undefined;
16
+ readonly initial: string;
17
+ readonly done: Promise<void>;
18
+ protected resolveDone: () => void;
19
+ protected notify?: () => void;
20
+ protected change?: Promise<void>;
21
+ protected readonly identities: WeakMap<Promise<unknown>, number>;
22
+ protected readonly pending: Map<number, IPending>;
23
+ protected readonly frames: string[];
24
+ protected initialized: boolean;
25
+ protected stopped: boolean;
26
+ protected aborted: boolean;
27
+ protected nextId: number;
28
+ constructor(context: StaticHandlerContext, diagnostics?: Diagnostics | undefined, nonce?: string | undefined);
29
+ /** Use the codec's public plugin API, without depending on React Router internals. */
30
+ protected promiseId: (value: unknown) => [number] | false;
31
+ /** Encode one complete value, preserving the codec's built-in value representations. */
32
+ protected encodeValue(value: unknown): string;
33
+ /** Publish only once, and finish encoding before announcing a settlement. */
34
+ protected settle(id: number, value: unknown, rejected: boolean): void;
35
+ /** Notify a waiting pull and settle completion only after nested values were visited. */
36
+ protected wake(): void;
37
+ get isDone(): boolean;
38
+ /** Wait for data, without starting a read from the React stream. */
39
+ changed(): Promise<void>;
40
+ /** Drain completed value frames before delivering a React boundary chunk. */
41
+ take(): string;
42
+ /** Publish initialization in the selected shell/footer block to unblock hydration. */
43
+ state(isEarly: boolean): string;
44
+ /** Reject outstanding placeholders before a timeout closes the HTML response. */
45
+ abort(): void;
46
+ /** A disconnected client cannot receive scripts; detach request state from late work. */
47
+ cancel(): void;
48
+ }
49
+ export { errorProperties };
50
+ export default DataStream;
@@ -0,0 +1,2 @@
1
+ import{stringify as t}from"devalue";import{isRouteErrorResponse as e}from"react-router";import i,{streamScript as s}from"./script.js";import o from"../helpers/serialize-errors.js";const r=(t,i)=>{const s=t,o=e(t),r="DataWithResponseInit"===s?.type,n=o?t.status:s?.init?.status,a=o?t.statusText:s?.init?.statusText,c={message:s?.message??(o||r?a||`Route data error (${n??500})`:String(t)),name:s?.name??"Error"};return(o||r)&&Object.assign(c,{status:n??500,statusText:a??"",data:s?.data,internal:!1}),i&&s?.stack&&(c.stack=s.stack),c};class n{diagnostics;nonce;initial;done;resolveDone;notify;change;identities=new WeakMap;pending=new Map;frames=[];initialized=!1;stopped=!1;aborted=!1;nextId=0;constructor(t,e,i){this.diagnostics=e,this.nonce=i,e?.inspectRouterState(t),this.done=new Promise(t=>{this.resolveDone=t});try{this.initial=this.encodeValue({loaderData:t.loaderData,actionData:t.actionData,errors:o(t.errors)}),this.initialized=!0,this.wake()}catch(t){throw this.cancel(),t}}promiseId=t=>{if(t instanceof Promise){let e=this.identities.get(t);if(void 0===e){e=this.nextId++,this.identities.set(t,e),this.pending.set(e,{settled:!1});const i=e;t.then(t=>this.settle(i,t,!1),t=>this.settle(i,t,!0)),this.aborted&&this.settle(e,new Error("SSR loader/action promise aborted before it settled."),!0)}return[e]}return!1};encodeValue(i){return t(i,{SSRBPromise:this.promiseId,SSRBError:t=>(t instanceof Error||e(t))&&Object.entries(r(t,Boolean(this.diagnostics))),SSRBObject:t=>Boolean(t&&"object"==typeof t&&Object.hasOwn(t,"__proto__"))&&Object.entries(t),SSRBUndefined:t=>"function"==typeof t||"symbol"==typeof t||Boolean(t&&"object"==typeof t&&!Array.isArray(t)&&![Object.prototype,null,Date.prototype,Map.prototype,Set.prototype,RegExp.prototype,Promise.prototype,Error.prototype].includes(Object.getPrototypeOf(t)))})}settle(t,e,i){const o=this.pending.get(t);if(o&&!o.settled&&!this.stopped){o.settled=!0,i||this.diagnostics?.inspectStreamValue(e,t);try{const o=this.encodeValue(i?Object.assign(new Error("Streamed loader/action rejection"),r(e,Boolean(this.diagnostics))):e);this.frames.push(s([i?"reject":"resolve",t,o],this.nonce))}catch(e){const i=this.encodeValue(new Error(`Cannot serialize streamed value: ${String(e)}`));this.frames.push(s(["reject",t,i],this.nonce))}finally{this.pending.delete(t),this.wake()}}}wake(){this.notify?.(),this.notify=void 0,this.change=void 0,this.initialized&&!this.pending.size&&this.resolveDone()}get isDone(){return this.initialized&&!this.pending.size}changed(){return this.frames.length||this.isDone?Promise.resolve():this.change??=new Promise(t=>{this.notify=t})}take(){return this.frames.splice(0).join("")}state(t){const{initial:e}=this;return i("window.__staticRouterHydrationData = {__ssrBoostStream: true};",this.nonce,!0)+s(["init",e,t],this.nonce)}abort(){this.aborted=!0;let t=0;for(const[e,i]of this.pending)i.settled||(t++,this.settle(e,new Error("SSR loader/action promise aborted before it settled."),!0));t&&this.diagnostics?.streamAborted(t)}cancel(){this.stopped=!0,this.initialized=!0,this.pending.clear(),this.frames.length=0,this.wake()}}export{n as default,r as errorProperties};
2
+ //# sourceMappingURL=data-stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-stream.js","sources":["../../src/core/data-stream.ts"],"sourcesContent":[null],"names":["errorProperties","reason","diagnostics","value","isResponse","isRouteErrorResponse","isDataError","type","status","init","statusText","properties","message","String","name","Object","assign","data","internal","stack","DataStream","nonce","initial","done","resolveDone","notify","change","identities","WeakMap","pending","Map","frames","initialized","stopped","aborted","nextId","constructor","context","this","inspectRouterState","Promise","resolve","encodeValue","loaderData","actionData","errors","serializeErrors","wake","error","cancel","promiseId","id","get","undefined","set","settled","then","result","settle","Error","stringify","SSRBPromise","SSRBError","entries","Boolean","SSRBObject","item","hasOwn","SSRBUndefined","Array","isArray","prototype","Date","Set","RegExp","includes","getPrototypeOf","rejected","inspectStreamValue","payload","push","streamScript","delete","size","isDone","changed","length","take","splice","join","state","isEarly","script","abort","count","streamAborted","clear"],"mappings":"oLAYA,MAAMA,EAAkB,CAACC,EAAiBC,KACxC,MAAMC,EAAQF,EAQRG,EAAaC,EAAqBJ,GAClCK,EAA8B,yBAAhBH,GAAOI,KACrBC,EAASJ,EAAaH,EAAOO,OAASL,GAAOM,MAAMD,OACnDE,EAAaN,EAAaH,EAAOS,WAAaP,GAAOM,MAAMC,WAC3DC,EAAsC,CAC1CC,QACET,GAAOS,UACNR,GAAcE,EACXI,GAAc,qBAAqBF,GAAU,OAC7CK,OAAOZ,IACba,KAAMX,GAAOW,MAAQ,SAgBvB,OAbIV,GAAcE,IAChBS,OAAOC,OAAOL,EAAY,CACxBH,OAAQA,GAAU,IAClBE,WAAYA,GAAc,GAC1BO,KAAMd,GAAOc,KACbC,UAAU,IAIVhB,GAAeC,GAAOgB,QACxBR,EAAWQ,MAAQhB,EAAMgB,OAGpBR,GAQT,MAAMS,EAgBiBlB,YACAmB,MAhBLC,QACAC,KACNC,YACAC,OACAC,OACSC,WAAa,IAAIC,QACjBC,QAAU,IAAIC,IACdC,OAAmB,GAC5BC,aAAc,EACdC,SAAU,EACVC,SAAU,EACVC,OAAS,EAEnB,WAAAC,CACEC,EACmBnC,EACAmB,GADAiB,KAAApC,YAAAA,EACAoC,KAAAjB,MAAAA,EAEnBnB,GAAaqC,mBAAmBF,GAChCC,KAAKf,KAAO,IAAIiB,QAASC,IACvBH,KAAKd,YAAciB,IAErB,IACEH,KAAKhB,QAAUgB,KAAKI,YAAY,CAC9BC,WAAYN,EAAQM,WACpBC,WAAYP,EAAQO,WACpBC,OAAQC,EAAgBT,EAAQQ,UAElCP,KAAKN,aAAc,EACnBM,KAAKS,MACP,CAAE,MAAOC,GAEP,MADAV,KAAKW,SACCD,CACR,CACF,CAGUE,UAAa/C,IACrB,GAAIA,aAAiBqC,QAAS,CAC5B,IAAIW,EAAKb,KAAKX,WAAWyB,IAAIjD,GAE7B,QAAWkD,IAAPF,EAAkB,CACpBA,EAAKb,KAAKH,SACVG,KAAKX,WAAW2B,IAAInD,EAAOgD,GAC3Bb,KAAKT,QAAQyB,IAAIH,EAAI,CAAEI,SAAS,IAChC,MAAML,EAAYC,EAEbhD,EAAMqD,KACRC,GAAoBnB,KAAKoB,OAAOR,EAAWO,GAAQ,GACnDT,GAAmBV,KAAKoB,OAAOR,EAAWF,GAAO,IAGhDV,KAAKJ,SACPI,KAAKoB,OAAOP,EAAI,IAAIQ,MAAM,yDAAyD,EAEvF,CAEA,MAAO,CAACR,EACV,CAEA,OAAO,GAIC,WAAAT,CAAYvC,GACpB,OAAOyD,EAAUzD,EAAO,CACtB0D,YAAavB,KAAKY,UAClBY,UAAYd,IACTA,aAAiBW,OAAStD,EAAqB2C,KAChDjC,OAAOgD,QAAQ/D,EAAgBgD,EAAOgB,QAAQ1B,KAAKpC,eACrD+D,WAAaC,GACXF,QAAQE,GAAwB,iBAATA,GAAqBnD,OAAOoD,OAAOD,EAAM,eAChEnD,OAAOgD,QAAQG,GACjBE,cAAgBF,GACE,mBAATA,GACS,iBAATA,GACPF,QACEE,GACgB,iBAATA,IACNG,MAAMC,QAAQJ,KACd,CACCnD,OAAOwD,UACP,KACAC,KAAKD,UACLzC,IAAIyC,UACJE,IAAIF,UACJG,OAAOH,UACP/B,QAAQ+B,UACRZ,MAAMY,WACNI,SAAS5D,OAAO6D,eAAeV,MAGzC,CAGU,MAAAR,CAAOP,EAAYhD,EAAgB0E,GAC3C,MAAMhD,EAAUS,KAAKT,QAAQuB,IAAID,GAEjC,GAAKtB,IAAWA,EAAQ0B,UAAWjB,KAAKL,QAAxC,CAIAJ,EAAQ0B,SAAU,EAEbsB,GACHvC,KAAKpC,aAAa4E,mBAAmB3E,EAAOgD,GAG9C,IACE,MAAM4B,EAAUzC,KAAKI,YACnBmC,EACI9D,OAAOC,OACL,IAAI2C,MAAM,oCACV3D,EAAgBG,EAAO6D,QAAQ1B,KAAKpC,eAEtCC,GAGNmC,KAAKP,OAAOiD,KAAKC,EAAa,CAACJ,EAAW,SAAW,UAAW1B,EAAI4B,GAAUzC,KAAKjB,OACrF,CAAE,MAAO2B,GACP,MAAM+B,EAAUzC,KAAKI,YACnB,IAAIiB,MAAM,oCAAoC9C,OAAOmC,OAGvDV,KAAKP,OAAOiD,KAAKC,EAAa,CAAC,SAAU9B,EAAI4B,GAAUzC,KAAKjB,OAC9D,SACEiB,KAAKT,QAAQqD,OAAO/B,GACpBb,KAAKS,MACP,CA5BA,CA6BF,CAGU,IAAAA,GACRT,KAAKb,WACLa,KAAKb,YAAS4B,EACdf,KAAKZ,YAAS2B,EAEVf,KAAKN,cAAgBM,KAAKT,QAAQsD,MACpC7C,KAAKd,aAET,CAEA,UAAW4D,GACT,OAAO9C,KAAKN,cAAgBM,KAAKT,QAAQsD,IAC3C,CAGO,OAAAE,GACL,OAAI/C,KAAKP,OAAOuD,QAAUhD,KAAK8C,OACtB5C,QAAQC,UAGTH,KAAKZ,SAAW,IAAIc,QAASC,IACnCH,KAAKb,OAASgB,GAElB,CAGO,IAAA8C,GACL,OAAOjD,KAAKP,OAAOyD,OAAO,GAAGC,KAAK,GACpC,CAGO,KAAAC,CAAMC,GACX,MAAMrE,QAAEA,GAAYgB,KAGpB,OACEsD,EAHiB,iEAGEtD,KAAKjB,OAAO,GAAQ4D,EAAa,CAAC,OAAQ3D,EAASqE,GAAUrD,KAAKjB,MAEzF,CAGO,KAAAwE,GACLvD,KAAKJ,SAAU,EACf,IAAI4D,EAAQ,EAEZ,IAAK,MAAO3C,EAAIhD,KAAUmC,KAAKT,QACxB1B,EAAMoD,UACTuC,IACAxD,KAAKoB,OAAOP,EAAI,IAAIQ,MAAM,yDAAyD,IAInFmC,GACFxD,KAAKpC,aAAa6F,cAAcD,EAEpC,CAGO,MAAA7C,GACLX,KAAKL,SAAU,EACfK,KAAKN,aAAc,EACnBM,KAAKT,QAAQmE,QACb1D,KAAKP,OAAOuD,OAAS,EACrBhD,KAAKS,MACP"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Track tag, comment and raw-text boundaries across arbitrary React byte chunks.
3
+ * Data scripts may be inserted only after a complete tag, never in a split token
4
+ * or script/style body. This observer neither buffers HTML nor reads ahead.
5
+ */
6
+ declare const htmlBoundary: () => ((chunk: Uint8Array) => boolean);
7
+ export default htmlBoundary;
@@ -0,0 +1,2 @@
1
+ const t=()=>{let t="text",e="",r="",o="";return s=>{for(const n of s){const s=String.fromCharCode(n);"raw"===t?(e=(e+s).slice(-32),">"===s&&new RegExp(`</${o}\\s*>$`,"i").test(e)&&(t="text",e="",o="")):"comment"===t?(e=(e+s).slice(-3),"--\x3e"===e&&(t="text",e="")):"tag"===t?(e.length<32&&(e+=s),"\x3c!--"===e?t="comment":r?s===r&&(r=""):'"'===s||"'"===s?r=s:">"===s&&(o=/^<(script|style|textarea|title)(?:\s|>)/i.exec(e)?.[1]?.toLowerCase()??"",t=o?"raw":"text",e="")):"<"===s&&(t="tag",e="<")}return"text"===t&&62===s[s.length-1]}};export{t as default};
2
+ //# sourceMappingURL=html-boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-boundary.js","sources":["../../src/core/html-boundary.ts"],"sourcesContent":[null],"names":["htmlBoundary","mode","token","quote","raw","chunk","byte","char","String","fromCharCode","slice","RegExp","test","length","exec","toLowerCase"],"mappings":"AAKA,MAAMA,EAAe,KACnB,IAAIC,EAA2C,OAC3CC,EAAQ,GACRC,EAAQ,GACRC,EAAM,GAEV,OAAQC,IACN,IAAK,MAAMC,KAAQD,EAAO,CACxB,MAAME,EAAOC,OAAOC,aAAaH,GAEpB,QAATL,GACFC,GAASA,EAAQK,GAAMG,OAAM,IAEhB,MAATH,GAAgB,IAAII,OAAO,KAAKP,UAAa,KAAKQ,KAAKV,KACzDD,EAAO,OACPC,EAAQ,GACRE,EAAM,KAEU,YAATH,GACTC,GAASA,EAAQK,GAAMG,OAAM,GAEf,WAAVR,IACFD,EAAO,OACPC,EAAQ,KAEQ,QAATD,GACLC,EAAMW,OAAS,KACjBX,GAASK,GAGG,YAAVL,EACFD,EAAO,UACEE,EACLI,IAASJ,IACXA,EAAQ,IAEQ,MAATI,GAAyB,MAATA,EACzBJ,EAAQI,EACU,MAATA,IACTH,EAAM,2CAA2CU,KAAKZ,KAAS,IAAIa,eAAiB,GACpFd,EAAOG,EAAM,MAAQ,OACrBF,EAAQ,KAEQ,MAATK,IACTN,EAAO,MACPC,EAAQ,IAEZ,CAEA,MAAgB,SAATD,GAA+C,KAA5BI,EAAMA,EAAMQ,OAAS"}
package/core/render.d.ts CHANGED
@@ -29,6 +29,8 @@ export interface ISsrRequestContext<TAppProps = Record<string, any>> {
29
29
  serverContext?: IServerContext;
30
30
  }
31
31
  export interface IRenderStreamOptions {
32
+ nonce?: string;
33
+ bootstrapScriptContent?: string;
32
34
  onError: (error: unknown) => void;
33
35
  signal: AbortSignal;
34
36
  }
@@ -58,6 +60,10 @@ export interface ICoreRenderParams<TAppProps = Record<string, any>> {
58
60
  renderToStream: TRenderToStream;
59
61
  }
60
62
  export interface ICoreRenderOptions<TAppProps = Record<string, any>> {
63
+ /** Hydrate the parsed shell while deferred boundaries are still pending. */
64
+ hydration?: 'early' | 'footer';
65
+ nonce?: string;
66
+ bootstrapScriptContent?: string;
61
67
  /**
62
68
  * React rendering deadline in milliseconds, starting after router preparation.
63
69
  */
@@ -100,5 +106,5 @@ export interface ICoreRenderOptions<TAppProps = Record<string, any>> {
100
106
  /**
101
107
  * Coordinate router queries, React rendering and the final Fetch response.
102
108
  */
103
- declare const render: <TAppProps>({ createApp, handler, renderToStream }: ICoreRenderParams<TAppProps>, context: ISsrRequestContext<TAppProps>, { abortDelay, getState, onError, onResponse, onRouterReady, onShellError, onShellReady, prepare, routerRequestContext, }: ICoreRenderOptions<TAppProps>, executionContext?: ISsrExecutionContext) => Promise<Response>;
109
+ declare const render: <TAppProps>({ createApp, handler, renderToStream }: ICoreRenderParams<TAppProps>, context: ISsrRequestContext<TAppProps>, { abortDelay, getState, hydration, nonce, bootstrapScriptContent, onError, onResponse, onRouterReady, onShellError, onShellReady, prepare, routerRequestContext, }: ICoreRenderOptions<TAppProps>, executionContext?: ISsrExecutionContext) => Promise<Response>;
104
110
  export default render;
package/core/render.js CHANGED
@@ -1,2 +1,2 @@
1
- import e from"react";import{createStaticRouter as t,StaticRouterProvider as r}from"react-router";import s from"../constants/stream-error.js";import{ServerProvider as o}from"../context/server.js";import a from"./compose-html.js";import n from"./head-response.js";import{mergeResponseHeaders as c}from"./headers.js";import d from"./transform-html.js";import i from"../helpers/build-custom-state.js";import l from"../helpers/build-router-state.js";import u from"../helpers/obtain-stream-error.js";const m="text/html",h="Content-Type",p=async({createApp:p,handler:x,renderToStream:f},R,{abortDelay:C=15e3,getState:w,onError:E,onResponse:g,onRouterReady:y,onShellError:b,onShellReady:S,prepare:q,routerRequestContext:v},j)=>{const T=await x.query(R.request,{requestContext:v??R});if(T instanceof Response)return n(R.request,c(T,R.response.headers));R.routerContext=T,await(q?.({context:R,executionContext:j}));const{isStream:A=!0}=await(y?.({context:R}))??{};R.isStream=A,R.serverContext={basename:R.routerContext.basename,isServer:!0,response:null};const H=t(x.dataRoutes,R.routerContext),D=e.createElement(o,{context:R.serverContext},p(e.createElement(r,{router:H,context:R.routerContext,hydrate:!1}),R)),L=new AbortController;let k,B,I=!1;const z=()=>J(R.request.signal.reason),F=()=>clearTimeout(K),G=()=>{F(),R.request.signal.removeEventListener("abort",z)},J=e=>{I||(I=!0,k=e,G(),R.didError??=s.RenderCancel,L.abort(e),B?.abort(e))},K=setTimeout(()=>{R.didError=s.RenderTimeout,J()},C);R.request.signal.aborted?J(R.request.signal.reason):R.request.signal.addEventListener("abort",z,{once:!0});try{B=await f(D,{onError:e=>{const t=u(e);!I||t.code!==s.RenderAborted&&e!==L.signal.reason||(t.code=R.didError===s.RenderTimeout?s.RenderTimeout:s.RenderCancel);const{code:r}=t;R.didError??=r,E?.({context:R,error:t})},signal:L.signal}),I&&B.abort(k),B.allReady.then(F,F),await(A?B.shellReady:B.allReady)}catch(e){return J(e),await(B?.stream.cancel(e).catch(()=>{})),((e,t,r)=>{const s=t instanceof Error?t:new Error(String(t)),o=r?.({context:e,error:s})||"<!doctype html><p>Internal Server Error</p>",a=new Headers(e.response.headers);return a.set(h,m),new Response("HEAD"===e.request.method?null:o,{headers:a,status:500})})(R,e,b)}try{const e=R.serverContext.response;if(e&&(M=e,Boolean(M&&M.status>=300&&M.status<400&&M.headers.has("Location"))))return J(),await B.stream.cancel().catch(()=>{}),n(R.request,c(e,R.response.headers));const{header:t,footer:r,headers:s,status:o}=((e,{getState:t,onShellReady:r})=>{const s=e.serverContext.response;e.response.status=s?.status??e.response.status??e.routerContext.statusCode??200,e.response.headers.has(h)||e.response.headers.set(h,m);const o=r?.({context:e})??{},a=l(e.routerContext,e.diagnostics),n=i(t?.({context:e}),e.diagnostics),c=o.header||e.html.header,d=o.footer||e.html.footer;return e.diagnostics?.inspectShell({header:c,footer:d}),{header:c,footer:n+a+d,headers:new Headers(e.response.headers),status:e.response.status}})(R,{getState:w,onShellReady:S});if("HEAD"===R.request.method||[204,205,304].includes(o))return J(),await B.stream.cancel().catch(()=>{}),new Response(null,{headers:s,status:o});const u=a(t,B.stream,r,J,G),p=d(u,g?(e,t)=>g({context:R,html:e,isEnd:t}):void 0,R.diagnostics);return B.start(),new Response(p,{headers:s,status:o})}catch(e){throw J(e),B.stream.locked||await B.stream.cancel(e).catch(()=>{}),e}var M};export{p as default};
1
+ import e from"react";import{createStaticRouter as t,StaticRouterProvider as r}from"react-router";import o from"../constants/stream-error.js";import{ServerProvider as s}from"../context/server.js";import n from"./compose-html.js";import a from"./data-stream.js";import c from"./head-response.js";import{mergeResponseHeaders as d}from"./headers.js";import i from"./transform-html.js";import l from"../helpers/build-custom-state.js";import m from"../helpers/obtain-stream-error.js";const u="text/html",h="Content-Type",p=async({createApp:p,handler:x,renderToStream:f},w,{abortDelay:y=15e3,getState:R,hydration:S="footer",nonce:C,bootstrapScriptContent:E,onError:b,onResponse:g,onRouterReady:q,onShellError:v,onShellReady:j,prepare:T,routerRequestContext:A},B)=>{const H=await x.query(w.request,{requestContext:A??w});if(H instanceof Response)return c(w.request,d(H,w.response.headers));w.routerContext=H;const _=new a(H,w.diagnostics,C);try{await(T?.({context:w,executionContext:B}))}catch(e){throw _.cancel(),e}const{isStream:D=!0}=await(q?.({context:w}))??{};w.isStream=D,w.serverContext={basename:w.routerContext.basename,isServer:!0,response:null};const L=t(x.dataRoutes,w.routerContext),k=e.createElement(s,{context:w.serverContext},p(e.createElement(r,{router:L,context:w.routerContext,hydrate:!1}),w)),P=new AbortController;let I,$,z=!1;const F=()=>K(w.request.signal.reason),G=()=>clearTimeout(M),J=()=>{G(),w.request.signal.removeEventListener("abort",F)},K=e=>{z||(z=!0,I=e,J(),w.didError??=o.RenderCancel,_.abort(),P.abort(e),$?.abort(e))},M=setTimeout(()=>{w.didError=o.RenderTimeout,K()},y);w.request.signal.aborted?K(w.request.signal.reason):w.request.signal.addEventListener("abort",F,{once:!0});try{$=await f(k,{nonce:C,bootstrapScriptContent:"early"===S&&D?`(window.__ssrBoostStream = window.__ssrBoostStream || []).push(["shell"]);${E??""};document.currentScript?.remove();`:E,onError:e=>{const t=m(e);!z||t.code!==o.RenderAborted&&e!==P.signal.reason||(t.code=w.didError===o.RenderTimeout?o.RenderTimeout:o.RenderCancel);const{code:r}=t;w.didError??=r,b?.({context:w,error:t})},signal:P.signal}),z&&$.abort(I),Promise.all([$.allReady,_.done]).then(G,G),await(D?$.shellReady:Promise.all([$.allReady,_.done]))}catch(e){return K(e),await($?.stream.cancel(e).catch(()=>{})),((e,t,r)=>{const o=t instanceof Error?t:new Error(String(t)),s=r?.({context:e,error:o})||"<!doctype html><p>Internal Server Error</p>",n=new Headers(e.response.headers);return n.set(h,u),new Response("HEAD"===e.request.method?null:s,{headers:n,status:500})})(w,e,v)}try{const e=w.serverContext.response;if(e&&(N=e,Boolean(N&&N.status>=300&&N.status<400&&N.headers.has("Location"))))return K(),await $.stream.cancel().catch(()=>{}),c(w.request,d(e,w.response.headers));const{header:t,footer:r,headers:o,status:s}=((e,{getState:t,onShellReady:r,hydration:o,nonce:s},n)=>{const a=e.serverContext.response;e.response.status=a?.status??e.response.status??e.routerContext.statusCode??200,e.response.headers.has(h)||e.response.headers.set(h,u);const c=r?.({context:e})??{},d="early"===o&&e.isStream,i=l(t?.({context:e}),e.diagnostics,s,Boolean(d));let m=c.header||e.html.header;const p=c.footer||e.html.footer;e.diagnostics?.inspectShell({header:m,footer:p});let x=p;return d?m+=i+n.state(!0):x=i+n.state(!1)+n.take()+x,{header:m,footer:x,headers:new Headers(e.response.headers),status:e.response.status}})(w,{getState:R,onShellReady:j,hydration:S,nonce:C},_);if("HEAD"===w.request.method||[204,205,304].includes(s))return K(),await $.stream.cancel().catch(()=>{}),new Response(null,{headers:o,status:s});const a=n(t,$.stream,r,K,J,_),m=i(a,g?(e,t)=>g({context:w,html:e,isEnd:t}):void 0,w.diagnostics);return $.start(),new Response(m,{headers:o,status:s})}catch(e){throw K(e),$.stream.locked||await $.stream.cancel(e).catch(()=>{}),e}var N};export{p as default};
2
2
  //# sourceMappingURL=render.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sources":["../../src/core/render.tsx"],"sourcesContent":[null],"names":["HTML_CONTENT_TYPE","CONTENT_TYPE","render","async","createApp","handler","renderToStream","context","abortDelay","getState","onError","onResponse","onRouterReady","onShellError","onShellReady","prepare","routerRequestContext","executionContext","queried","query","request","requestContext","Response","headResponse","mergeResponseHeaders","response","headers","routerContext","isStream","serverContext","basename","isServer","router","createStaticRouter","dataRoutes","node","React","createElement","ServerProvider","StaticRouterProvider","hydrate","renderController","AbortController","abortReason","output","hasAborted","onRequestAbort","abort","signal","reason","clearAbortTimer","clearTimeout","abortTimer","cleanup","removeEventListener","didError","StreamError","RenderCancel","setTimeout","RenderTimeout","aborted","addEventListener","once","error","streamError","obtainStreamError","code","RenderAborted","allReady","then","shellReady","stream","cancel","catch","shellError","Error","String","html","Headers","set","method","status","createShellErrorResponse","serverResponse","Boolean","has","header","footer","statusCode","shell","routerState","buildRouterState","diagnostics","customState","buildCustomState","shellFooter","inspectShell","prepareHtmlResponse","includes","body","composeHtml","transformed","transformHtml","isEnd","undefined","start","locked"],"mappings":"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"}
1
+ {"version":3,"file":"render.js","sources":["../../src/core/render.tsx"],"sourcesContent":[null],"names":["HTML_CONTENT_TYPE","CONTENT_TYPE","render","async","createApp","handler","renderToStream","context","abortDelay","getState","hydration","nonce","bootstrapScriptContent","onError","onResponse","onRouterReady","onShellError","onShellReady","prepare","routerRequestContext","executionContext","queried","query","request","requestContext","Response","headResponse","mergeResponseHeaders","response","headers","routerContext","dataStream","DataStream","diagnostics","error","cancel","isStream","serverContext","basename","isServer","router","createStaticRouter","dataRoutes","node","React","createElement","ServerProvider","StaticRouterProvider","hydrate","renderController","AbortController","abortReason","output","hasAborted","onRequestAbort","abort","signal","reason","clearAbortTimer","clearTimeout","abortTimer","cleanup","removeEventListener","didError","StreamError","RenderCancel","setTimeout","RenderTimeout","aborted","addEventListener","once","streamError","obtainStreamError","code","RenderAborted","Promise","all","allReady","done","then","shellReady","stream","catch","shellError","Error","String","html","Headers","set","method","status","createShellErrorResponse","serverResponse","Boolean","has","header","footer","statusCode","shell","isEarly","customState","buildCustomState","shellFooter","inspectShell","state","take","prepareHtmlResponse","includes","body","composeHtml","transformed","transformHtml","isEnd","undefined","start","locked"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /** Escape an attribute independently of the JavaScript string escaping rules. */
2
+ declare const script: (content: string, nonce?: string, isTemporary?: boolean) => string;
3
+ /** Queue frames even when the async browser entry has not executed yet. */
4
+ declare const streamScript: (frame: unknown, nonce?: string) => string;
5
+ export { streamScript };
6
+ export default script;
package/core/script.js ADDED
@@ -0,0 +1,2 @@
1
+ import r from"../helpers/html-escape.js";const e=(r,e,s=!1)=>`<script async${void 0===e?"":` nonce="${e.replace(/[&<>"']/g,r=>`&#${r.charCodeAt(0)};`)}"`}>${r}${s?"document.currentScript?.remove();":""}<\/script>`,s=(s,t)=>e(`(window.__ssrBoostStream = window.__ssrBoostStream || []).push(${r(JSON.stringify(s))});`,t,!0);export{e as default,s as streamScript};
2
+ //# sourceMappingURL=script.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script.js","sources":["../../src/core/script.ts"],"sourcesContent":[null],"names":["script","content","nonce","isTemporary","undefined","replace","char","charCodeAt","streamScript","frame","htmlEscape","JSON","stringify"],"mappings":"yCAGA,MAAMA,EAAS,CAACC,EAAiBC,EAAgBC,GAAc,IAMtD,qBAJKC,IAAVF,EACI,GACA,WAAWA,EAAMG,QAAQ,WAAaC,GAAS,KAAKA,EAAKC,WAAW,aAEtCN,IAAUE,EAAc,oCAAsC,eAI9FK,EAAe,CAACC,EAAgBP,IACpCF,EACE,kEAAkEU,EAAWC,KAAKC,UAAUH,QAC5FP,GACA"}
@@ -1,2 +1,2 @@
1
- import*as e from"react-dom/server";const r=async()=>e.renderToReadableStream??(await(import("react-dom/server.browser"))).renderToReadableStream,a=async(e,{onError:a,signal:t})=>{const o=new AbortController;let n;const s=new Promise((e,r)=>{n=r}),l=()=>{const{reason:e}=t;o.abort(e);const{reason:r}=o.signal;n(r instanceof Error?r:new Error(String(r)))};let c;t.aborted?l():t.addEventListener("abort",l,{once:!0});try{c=await Promise.race([r().then(r=>r(e,{onError:a,signal:o.signal})),s])}catch(e){t.removeEventListener("abort",l);const r=Promise.reject(e);return r.catch(()=>{}),{allReady:r,abort:e=>o.abort(e),shellReady:r,start:()=>{},stream:new ReadableStream}}const d=()=>t.removeEventListener("abort",l);return c.allReady.then(d,d),{allReady:c.allReady,abort:e=>o.abort(e),shellReady:Promise.resolve(),start:()=>{},stream:c}};export{a as default};
1
+ import*as e from"react-dom/server";const r=async()=>e.renderToReadableStream??(await(import("react-dom/server.browser"))).renderToReadableStream,t=async(e,{onError:t,signal:a,nonce:o,bootstrapScriptContent:n})=>{const s=new AbortController;let l;const c=new Promise((e,r)=>{l=r}),i=()=>{const{reason:e}=a;s.abort(e);const{reason:r}=s.signal;l(r instanceof Error?r:new Error(String(r)))};let d;a.aborted?i():a.addEventListener("abort",i,{once:!0});try{d=await Promise.race([r().then(r=>r(e,{onError:t,signal:s.signal,nonce:o,bootstrapScriptContent:n})),c])}catch(e){a.removeEventListener("abort",i);const r=Promise.reject(e);return r.catch(()=>{}),{allReady:r,abort:e=>s.abort(e),shellReady:r,start:()=>{},stream:new ReadableStream}}const b=()=>a.removeEventListener("abort",i);return d.allReady.then(b,b),{allReady:d.allReady,abort:e=>s.abort(e),shellReady:Promise.resolve(),start:()=>{},stream:d}};export{t as default};
2
2
  //# sourceMappingURL=render-to-stream.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"render-to-stream.js","sources":["../../src/edge/render-to-stream.ts"],"sourcesContent":[null],"names":["getRenderer","async","ReactDOMServer","renderToReadableStream","renderToStream","node","onError","signal","controller","AbortController","rejectPending","pendingAbort","Promise","_","reject","abort","reason","signalReason","Error","String","stream","aborted","addEventListener","once","race","then","error","removeEventListener","shellError","catch","allReady","shellReady","start","ReadableStream","removeAbortListener","resolve"],"mappings":"mCAMA,MAAMA,EAAcC,SAClBC,EAAeC,sCACD,8BAA6BA,uBAKvCC,EAAkCH,MAAOI,GAAQC,UAASC,aAC9D,MAAMC,EAAa,IAAIC,gBACvB,IAAIC,EAKJ,MAAMC,EAAe,IAAIC,QAAe,CAACC,EAAGC,KAC1CJ,EAAgBI,IAMZC,EAAQ,KACZ,MAAQC,OAAQC,GAAiBV,EAEjCC,EAAWO,MAAME,GAEjB,MAAMD,OAAEA,GAAWR,EAAWD,OAE9BG,EAAcM,aAAkBE,MAAQF,EAAS,IAAIE,MAAMC,OAAOH,MASpE,IAAII,EANAb,EAAOc,QACTN,IAEAR,EAAOe,iBAAiB,QAASP,EAAO,CAAEQ,MAAM,IAKlD,IACEH,QAAeR,QAAQY,KAAK,CAC1BxB,IAAcyB,KAAMtB,GAClBA,EAAuBE,EAAM,CAAEC,UAASC,OAAQC,EAAWD,UAE7DI,GAEJ,CAAE,MAAOe,GACPnB,EAAOoB,oBAAoB,QAASZ,GACpC,MAAMa,EAAahB,QAAQE,OAAOY,GAIlC,OAFKE,EAAWC,MAAM,QAEf,CACLC,SAAUF,EAKVb,MAAQC,GAAWR,EAAWO,MAAMC,GACpCe,WAAYH,EAKZI,MAAO,OACPZ,OAAQ,IAAIa,eAEhB,CAKA,MAAMC,EAAsB,IAAY3B,EAAOoB,oBAAoB,QAASZ,GAI5E,OAFKK,EAAOU,SAASL,KAAKS,EAAqBA,GAExC,CACLJ,SAAUV,EAAOU,SAKjBf,MAAQC,GAAWR,EAAWO,MAAMC,GACpCe,WAAYnB,QAAQuB,UAKpBH,MAAO,OACPZ"}
1
+ {"version":3,"file":"render-to-stream.js","sources":["../../src/edge/render-to-stream.ts"],"sourcesContent":[null],"names":["getRenderer","async","ReactDOMServer","renderToReadableStream","renderToStream","node","onError","signal","nonce","bootstrapScriptContent","controller","AbortController","rejectPending","pendingAbort","Promise","_","reject","abort","reason","signalReason","Error","String","stream","aborted","addEventListener","once","race","then","error","removeEventListener","shellError","catch","allReady","shellReady","start","ReadableStream","removeAbortListener","resolve"],"mappings":"mCAMA,MAAMA,EAAcC,SAClBC,EAAeC,sCACD,8BAA6BA,uBAKvCC,EAAkCH,MACtCI,GACEC,UAASC,SAAQC,QAAOC,6BAE1B,MAAMC,EAAa,IAAIC,gBACvB,IAAIC,EAKJ,MAAMC,EAAe,IAAIC,QAAe,CAACC,EAAGC,KAC1CJ,EAAgBI,IAMZC,EAAQ,KACZ,MAAQC,OAAQC,GAAiBZ,EAEjCG,EAAWO,MAAME,GAEjB,MAAMD,OAAEA,GAAWR,EAAWH,OAE9BK,EAAcM,aAAkBE,MAAQF,EAAS,IAAIE,MAAMC,OAAOH,MASpE,IAAII,EANAf,EAAOgB,QACTN,IAEAV,EAAOiB,iBAAiB,QAASP,EAAO,CAAEQ,MAAM,IAKlD,IACEH,QAAeR,QAAQY,KAAK,CAC1B1B,IAAc2B,KAAMxB,GAClBA,EAAuBE,EAAM,CAC3BC,UACAC,OAAQG,EAAWH,OACnBC,QACAC,4BAGJI,GAEJ,CAAE,MAAOe,GACPrB,EAAOsB,oBAAoB,QAASZ,GACpC,MAAMa,EAAahB,QAAQE,OAAOY,GAIlC,OAFKE,EAAWC,MAAM,QAEf,CACLC,SAAUF,EAKVb,MAAQC,GAAWR,EAAWO,MAAMC,GACpCe,WAAYH,EAKZI,MAAO,OACPZ,OAAQ,IAAIa,eAEhB,CAKA,MAAMC,EAAsB,IAAY7B,EAAOsB,oBAAoB,QAASZ,GAI5E,OAFKK,EAAOU,SAASL,KAAKS,EAAqBA,GAExC,CACLJ,SAAUV,EAAOU,SAKjBf,MAAQC,GAAWR,EAAWO,MAAMC,GACpCe,WAAYnB,QAAQuB,UAKpBH,MAAO,OACPZ"}
@@ -2,5 +2,5 @@ import type Diagnostics from '../services/diagnostics.js';
2
2
  /**
3
3
  * Build custom state
4
4
  */
5
- declare function buildCustomState(initState?: Record<string, Record<string, any>> | void, diagnostics?: Diagnostics): string;
5
+ declare function buildCustomState(initState?: Record<string, Record<string, any>> | void, diagnostics?: Diagnostics, nonce?: string, isTemporary?: boolean): string;
6
6
  export default buildCustomState;
@@ -1,2 +1,2 @@
1
- import t from"./html-escape.js";function e(e,r){r?.inspectState(e);return Object.entries(e??{}).map(([e,r])=>{if(!e||!r||!Object.keys(r||{}).length)return"";const i=t(JSON.stringify(JSON.stringify(r)));return`<script async>window${/^[A-Za-z_$][\w$]*$/.test(e)?`.${e}`:`[${t(JSON.stringify(e))}]`} = JSON.parse(${i});<\/script>`}).join("").trim()}export{e as default};
1
+ import t from"../core/script.js";import r from"./html-escape.js";function e(e,i,n,s=!1){i?.inspectState(e);return Object.entries(e??{}).map(([e,i])=>{if(!e||!i||!Object.keys(i||{}).length)return"";const o=r(JSON.stringify(JSON.stringify(i))),c=/^[A-Za-z_$][\w$]*$/.test(e)?`.${e}`:`[${r(JSON.stringify(e))}]`;return t(`window${c} = JSON.parse(${o});`,n,s)}).join("").trim()}export{e as default};
2
2
  //# sourceMappingURL=build-custom-state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-custom-state.js","sources":["../../src/helpers/build-custom-state.ts"],"sourcesContent":[null],"names":["buildCustomState","initState","diagnostics","inspectState","Object","entries","map","key","state","keys","length","json","htmlEscape","JSON","stringify","test","join","trim"],"mappings":"gCAMA,SAASA,EACPC,EACAC,GAEAA,GAAaC,aAAaF,GAe1B,OAbqBG,OAAOC,QAAQJ,GAAa,CAAA,GAAIK,IAAI,EAAEC,EAAKC,MAC9D,IAAKD,IAAQC,IAAUJ,OAAOK,KAAKD,GAAS,IAAIE,OAC9C,MAAO,GAGT,MAAMC,EAAOC,EAAWC,KAAKC,UAAUD,KAAKC,UAAUN,KAKtD,MAAO,uBAJU,qBAAqBO,KAAKR,GACvC,IAAIA,IACJ,IAAIK,EAAWC,KAAKC,UAAUP,uBAEqBI,kBAGrCK,KAAK,IAAIC,MAC/B"}
1
+ {"version":3,"file":"build-custom-state.js","sources":["../../src/helpers/build-custom-state.ts"],"sourcesContent":[null],"names":["buildCustomState","initState","diagnostics","nonce","isTemporary","inspectState","Object","entries","map","key","state","keys","length","json","htmlEscape","JSON","stringify","property","test","script","join","trim"],"mappings":"iEAOA,SAASA,EACPC,EACAC,EACAC,EACAC,GAAc,GAEdF,GAAaG,aAAaJ,GAe1B,OAbqBK,OAAOC,QAAQN,GAAa,CAAA,GAAIO,IAAI,EAAEC,EAAKC,MAC9D,IAAKD,IAAQC,IAAUJ,OAAOK,KAAKD,GAAS,IAAIE,OAC9C,MAAO,GAGT,MAAMC,EAAOC,EAAWC,KAAKC,UAAUD,KAAKC,UAAUN,KAChDO,EAAW,qBAAqBC,KAAKT,GACvC,IAAIA,IACJ,IAAIK,EAAWC,KAAKC,UAAUP,OAElC,OAAOU,EAAO,SAASF,kBAAyBJ,MAAUV,EAAOC,KAG/CgB,KAAK,IAAIC,MAC/B"}
@@ -3,5 +3,5 @@ import type Diagnostics from '../services/diagnostics.js';
3
3
  /**
4
4
  * Build router state
5
5
  */
6
- declare function buildRouterState(context: StaticHandlerContext, diagnostics?: Diagnostics): string;
6
+ declare function buildRouterState(context: StaticHandlerContext, diagnostics?: Diagnostics, nonce?: string): string;
7
7
  export default buildRouterState;
@@ -1,2 +1,2 @@
1
- import r from"./html-escape.js";import t from"./serialize-errors.js";function a(a,o){o?.inspectRouterState(a);const{loaderData:e,actionData:i,errors:s}=a,n={loaderData:e,actionData:i,errors:t(s)};return`<script async>window.__staticRouterHydrationData = JSON.parse(${r(JSON.stringify(JSON.stringify(n)))});<\/script>`}export{a as default};
1
+ import r from"../core/script.js";import t from"./html-escape.js";import a from"./serialize-errors.js";function o(o,e,i){e?.inspectRouterState(o);const{loaderData:s,actionData:n,errors:c}=o,p={loaderData:s,actionData:n,errors:a(c)},f=t(JSON.stringify(JSON.stringify(p)));return r(`window.__staticRouterHydrationData = JSON.parse(${f});`,i)}export{o as default};
2
2
  //# sourceMappingURL=build-router-state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-router-state.js","sources":["../../src/helpers/build-router-state.ts"],"sourcesContent":[null],"names":["buildRouterState","context","diagnostics","inspectRouterState","loaderData","actionData","errors","routerState","serializeErrors","htmlEscape","JSON","stringify"],"mappings":"qEAQA,SAASA,EAAiBC,EAA+BC,GACvDA,GAAaC,mBAAmBF,GAEhC,MAAMG,WAAEA,EAAUC,WAAEA,EAAUC,OAAEA,GAAWL,EACrCM,EAAc,CAClBH,aACAC,aACAC,OAAQE,EAAgBF,IAI1B,MAAO,iEAFMG,EAAWC,KAAKC,UAAUD,KAAKC,UAAUJ,kBAGxD"}
1
+ {"version":3,"file":"build-router-state.js","sources":["../../src/helpers/build-router-state.ts"],"sourcesContent":[null],"names":["buildRouterState","context","diagnostics","nonce","inspectRouterState","loaderData","actionData","errors","routerState","serializeErrors","json","htmlEscape","JSON","stringify","script"],"mappings":"sGASA,SAASA,EACPC,EACAC,EACAC,GAEAD,GAAaE,mBAAmBH,GAEhC,MAAMI,WAAEA,EAAUC,WAAEA,EAAUC,OAAEA,GAAWN,EACrCO,EAAc,CAClBH,aACAC,aACAC,OAAQE,EAAgBF,IAEpBG,EAAOC,EAAWC,KAAKC,UAAUD,KAAKC,UAAUL,KAEtD,OAAOM,EAAO,mDAAmDJ,MAAUP,EAC7E"}
@@ -1,2 +1,2 @@
1
- import{PassThrough as r,Readable as e}from"node:stream";import{renderToPipeableStream as t}from"react-dom/server";const o=(o,n)=>{const a=new r,s=e.toWeb(a,{strategy:{highWaterMark:a.readableHighWaterMark,size:r=>r.byteLength}});let i,l,c,d;const g=new Promise((r,e)=>{i=e,c=r}),h=new Promise((r,e)=>{l=e,d=r});g.catch(()=>{}),h.catch(()=>{});let m=!1,b=!1;const E=t(o,{onAllReady:c,onError:n.onError,onShellError:r=>{const e=r instanceof Error?r:new Error(String(r));m=!0,i(e),l(e)},onShellReady:()=>{m=!0,d()}}),f=r=>{if(!b){if(b=!0,!m){m=!0;const e=r instanceof Error?r:new Error("string"==typeof r?r:"Render aborted");l(e),i(e)}E.abort(r)}},y=()=>f(n.signal.reason),p=()=>n.signal.removeEventListener("abort",y);n.signal.aborted?y():n.signal.addEventListener("abort",y,{once:!0}),g.then(p,p);let w=!1;return{allReady:g,abort:f,shellReady:h,start:()=>{w||(w=!0,E.pipe(a))},stream:s}};export{o as default};
1
+ import{PassThrough as r,Readable as e}from"node:stream";import{renderToPipeableStream as t}from"react-dom/server";const o=(o,n)=>{const a=new r,s=e.toWeb(a,{strategy:{highWaterMark:a.readableHighWaterMark,size:r=>r.byteLength}});let i,l,c,d;const b=new Promise((r,e)=>{i=e,c=r}),g=new Promise((r,e)=>{l=e,d=r});b.catch(()=>{}),g.catch(()=>{});let h=!1,m=!1;const p=t(o,{nonce:n.nonce,bootstrapScriptContent:n.bootstrapScriptContent,onAllReady:c,onError:n.onError,onShellError:r=>{const e=r instanceof Error?r:new Error(String(r));h=!0,i(e),l(e)},onShellReady:()=>{h=!0,d()}}),E=r=>{if(!m){if(m=!0,!h){h=!0;const e=r instanceof Error?r:new Error("string"==typeof r?r:"Render aborted");l(e),i(e)}p.abort(r)}},f=()=>E(n.signal.reason),y=()=>n.signal.removeEventListener("abort",f);n.signal.aborted?f():n.signal.addEventListener("abort",f,{once:!0}),b.then(y,y);let w=!1;return{allReady:b,abort:E,shellReady:g,start:()=>{w||(w=!0,p.pipe(a))},stream:s}};export{o as default};
2
2
  //# sourceMappingURL=render-to-stream.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"render-to-stream.js","sources":["../../src/node/render-to-stream.ts"],"sourcesContent":[null],"names":["renderToStream","node","options","destination","PassThrough","stream","Readable","toWeb","strategy","highWaterMark","readableHighWaterMark","size","chunk","byteLength","rejectAll","rejectShell","resolveAll","resolveShell","allReady","Promise","resolve","reject","shellReady","catch","hasShellSettled","hasAborted","rendered","renderToPipeableStream","onAllReady","onError","onShellError","error","shellError","Error","String","onShellReady","abort","reason","onAbort","signal","cleanup","removeEventListener","aborted","addEventListener","once","then","hasStarted","start","pipe"],"mappings":"kHAOA,MAAMA,EAAkC,CAACC,EAAMC,KAC7C,MAAMC,EAAc,IAAIC,EAClBC,EAASC,EAASC,MAAMJ,EAAa,CACzCK,SAAU,CACRC,cAAeN,EAAYO,sBAK3BC,KAAOC,GAAsBA,EAAMC,cAGvC,IAAIC,EACAC,EACAC,EACAC,EAKJ,MAAMC,EAAW,IAAIC,QAAc,CAACC,EAASC,KAC3CP,EAAYO,EACZL,EAAaI,IAMTE,EAAa,IAAIH,QAAc,CAACC,EAASC,KAC7CN,EAAcM,EACdJ,EAAeG,IAGZF,EAASK,MAAM,QACfD,EAAWC,MAAM,QAEtB,IAAIC,GAAkB,EAClBC,GAAa,EACjB,MAAMC,EAAWC,EAAuB1B,EAAM,CAC5C2B,WAAYZ,EACZa,QAAS3B,EAAQ2B,QAKjBC,aAAeC,IACb,MAAMC,EAAaD,aAAiBE,MAAQF,EAAQ,IAAIE,MAAMC,OAAOH,IAErEP,GAAkB,EAClBV,EAAUkB,GACVjB,EAAYiB,IAMdG,aAAc,KACZX,GAAkB,EAClBP,OAOEmB,EAASC,IACb,IAAIZ,EAAJ,CASA,GALAA,GAAa,GAKRD,EAAiB,CACpBA,GAAkB,EAClB,MACMO,EAAQM,aAAkBJ,MAAQI,EAAS,IAAIJ,MADnB,iBAAXI,EAAsBA,EAAS,kBAGtDtB,EAAYgB,GACZjB,EAAUiB,EACZ,CAEAL,EAASU,MAAMC,EAhBf,GAsBIC,EAAU,IAAYF,EAAMlC,EAAQqC,OAAOF,QAK3CG,EAAU,IAAYtC,EAAQqC,OAAOE,oBAAoB,QAASH,GAEpEpC,EAAQqC,OAAOG,QACjBJ,IAEApC,EAAQqC,OAAOI,iBAAiB,QAASL,EAAS,CAAEM,MAAM,IAGvD1B,EAAS2B,KAAKL,EAASA,GAC5B,IAAIM,GAAa,EAEjB,MAAO,CACL5B,WACAkB,QACAd,aAKAyB,MAAO,KACAD,IACHA,GAAa,EACbpB,EAASsB,KAAK7C,KAGlBE"}
1
+ {"version":3,"file":"render-to-stream.js","sources":["../../src/node/render-to-stream.ts"],"sourcesContent":[null],"names":["renderToStream","node","options","destination","PassThrough","stream","Readable","toWeb","strategy","highWaterMark","readableHighWaterMark","size","chunk","byteLength","rejectAll","rejectShell","resolveAll","resolveShell","allReady","Promise","resolve","reject","shellReady","catch","hasShellSettled","hasAborted","rendered","renderToPipeableStream","nonce","bootstrapScriptContent","onAllReady","onError","onShellError","error","shellError","Error","String","onShellReady","abort","reason","onAbort","signal","cleanup","removeEventListener","aborted","addEventListener","once","then","hasStarted","start","pipe"],"mappings":"kHAOA,MAAMA,EAAkC,CAACC,EAAMC,KAC7C,MAAMC,EAAc,IAAIC,EAClBC,EAASC,EAASC,MAAMJ,EAAa,CACzCK,SAAU,CACRC,cAAeN,EAAYO,sBAK3BC,KAAOC,GAAsBA,EAAMC,cAGvC,IAAIC,EACAC,EACAC,EACAC,EAKJ,MAAMC,EAAW,IAAIC,QAAc,CAACC,EAASC,KAC3CP,EAAYO,EACZL,EAAaI,IAMTE,EAAa,IAAIH,QAAc,CAACC,EAASC,KAC7CN,EAAcM,EACdJ,EAAeG,IAGZF,EAASK,MAAM,QACfD,EAAWC,MAAM,QAEtB,IAAIC,GAAkB,EAClBC,GAAa,EACjB,MAAMC,EAAWC,EAAuB1B,EAAM,CAC5C2B,MAAO1B,EAAQ0B,MACfC,uBAAwB3B,EAAQ2B,uBAChCC,WAAYd,EACZe,QAAS7B,EAAQ6B,QAKjBC,aAAeC,IACb,MAAMC,EAAaD,aAAiBE,MAAQF,EAAQ,IAAIE,MAAMC,OAAOH,IAErET,GAAkB,EAClBV,EAAUoB,GACVnB,EAAYmB,IAMdG,aAAc,KACZb,GAAkB,EAClBP,OAOEqB,EAASC,IACb,IAAId,EAAJ,CASA,GALAA,GAAa,GAKRD,EAAiB,CACpBA,GAAkB,EAClB,MACMS,EAAQM,aAAkBJ,MAAQI,EAAS,IAAIJ,MADnB,iBAAXI,EAAsBA,EAAS,kBAGtDxB,EAAYkB,GACZnB,EAAUmB,EACZ,CAEAP,EAASY,MAAMC,EAhBf,GAsBIC,EAAU,IAAYF,EAAMpC,EAAQuC,OAAOF,QAK3CG,EAAU,IAAYxC,EAAQuC,OAAOE,oBAAoB,QAASH,GAEpEtC,EAAQuC,OAAOG,QACjBJ,IAEAtC,EAAQuC,OAAOI,iBAAiB,QAASL,EAAS,CAAEM,MAAM,IAGvD5B,EAAS6B,KAAKL,EAASA,GAC5B,IAAIM,GAAa,EAEjB,MAAO,CACL9B,WACAoB,QACAhB,aAKA2B,MAAO,KACAD,IACHA,GAAa,EACbtB,EAASwB,KAAK/C,KAGlBE"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lomray/vite-ssr-boost",
3
- "version": "8.2.0",
4
- "description": "Vite plugin for create awesome SSR or SPA applications on React.",
3
+ "version": "8.3.0-beta.1",
4
+ "description": "SSR and streaming for existing Vite + React Router apps in Data mode, without Framework mode",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  "./node/production": {
@@ -32,7 +32,12 @@
32
32
  "vite",
33
33
  "plugin",
34
34
  "react",
35
- "ssr"
35
+ "ssr",
36
+ "react-router",
37
+ "server-side-rendering",
38
+ "data-router",
39
+ "streaming",
40
+ "spa"
36
41
  ],
37
42
  "publishConfig": {
38
43
  "access": "public"
@@ -51,7 +56,7 @@
51
56
  "build": "rollup -c",
52
57
  "build:watch": "rollup -c -w",
53
58
  "docs:dev": "vitepress dev docs",
54
- "docs:build": "vitepress build docs",
59
+ "docs:build": "vitepress build docs && node scripts/build-llms.mjs",
55
60
  "docs:preview": "vitepress preview docs",
56
61
  "release": "npm run build && cd lib && npm publish",
57
62
  "lint:check": "eslint . --max-warnings=0",
@@ -63,11 +68,13 @@
63
68
  "test:edge:packed": "node scripts/test-packed-edge.mjs",
64
69
  "test:bun": "bun scripts/test-bun.mjs",
65
70
  "test:template": "npm run build && node scripts/test-template.mjs",
66
- "test:coverage": "vitest run --coverage"
71
+ "test:coverage": "vitest run --coverage",
72
+ "test:browser": "playwright test --config playwright.config.mjs"
67
73
  },
68
74
  "dependencies": {
69
75
  "chalk": "^6.0.0",
70
76
  "commander": "^15.0.0",
77
+ "devalue": "^5.9.2",
71
78
  "hoist-non-react-statics": "^3.3.2",
72
79
  "json5": "^2.2.3"
73
80
  },
@@ -85,6 +92,7 @@
85
92
  "@lomray/eslint-config": "^7.0.0",
86
93
  "@lomray/eslint-config-react": "^7.0.0",
87
94
  "@lomray/prettier-config": "^3.0.0",
95
+ "@playwright/test": "^1.63.0",
88
96
  "@rollup/plugin-terser": "^1.0.0",
89
97
  "@rollup/plugin-typescript": "^12.3.0",
90
98
  "@testing-library/react": "^16.3.3",
@@ -1,6 +1,6 @@
1
1
  import type { StaticHandlerContext } from 'react-router';
2
2
  import Logger from './logger.js';
3
- type TDiagnosticCode = 'SSR_BOOST_LOADER_NOT_SERIALIZABLE' | 'SSR_BOOST_STATE_NOT_SERIALIZABLE' | 'SSR_BOOST_OUTLET_MISSING' | 'SSR_BOOST_HYDRATION_STATE_MISSING' | 'SSR_BOOST_DUPLICATE_OUTPUT' | 'SSR_BOOST_ONRESPONSE_INVALID_RETURN';
3
+ type TDiagnosticCode = 'SSR_BOOST_LOADER_NOT_SERIALIZABLE' | 'SSR_BOOST_STREAM_PROMISE_ABORTED' | 'SSR_BOOST_STATE_NOT_SERIALIZABLE' | 'SSR_BOOST_OUTLET_MISSING' | 'SSR_BOOST_HYDRATION_STATE_MISSING' | 'SSR_BOOST_DUPLICATE_OUTPUT' | 'SSR_BOOST_ONRESPONSE_INVALID_RETURN';
4
4
  interface ISerializationIssue {
5
5
  path: string;
6
6
  reason: string;
@@ -18,9 +18,10 @@ declare const formatDiagnostic: (code: TDiagnosticCode, sentence: string) => str
18
18
  */
19
19
  declare const splitHtmlShell: (html: string, file: string, outlet?: string) => [string, string];
20
20
  /**
21
- * Find values JSON cannot preserve, descending only into plain objects and arrays.
21
+ * Custom state uses JSON. Router state also supports promises, Date, RegExp, bigint,
22
+ * Map and Set through the stream codec; functions, symbols, classes and cycles warn.
22
23
  */
23
- declare const walkSerializable: (value: unknown, report: (issue: ISerializationIssue) => void, path?: string, ancestors?: Set<object>) => void;
24
+ declare const walkSerializable: (value: unknown, report: (issue: ISerializationIssue) => void, path?: string, ancestors?: Set<object>, streamed?: boolean) => void;
24
25
  /**
25
26
  * Inspect one development response while allowing every chunk to stream immediately.
26
27
  */
@@ -44,6 +45,10 @@ declare class Diagnostics {
44
45
  * Include React Router's route id and the full loader/action key path.
45
46
  */
46
47
  inspectRouterState({ loaderData, actionData }: StaticHandlerContext): void;
48
+ /** Report the request's pending loader/action promises at the render deadline. */
49
+ streamAborted(count: number): void;
50
+ /** Inspect streamed resolutions with the same supported value matrix as initial data. */
51
+ inspectStreamValue(value: unknown, id: number): void;
47
52
  /**
48
53
  * Check custom state before the serializer can omit or coerce it.
49
54
  */
@@ -1,2 +1,2 @@
1
- import t from"./logger.js";const e="\x3c!--ssr-outlet--\x3e",o="window.__staticRouterHydrationData",s=Symbol.for("@lomray/vite-ssr-boost/diagnostics"),r=globalThis,n=t=>{const e="undefined"==typeof process?void 0:process.env;return"0"===e?.SSR_BOOST_DIAGNOSTICS||"1"===e?.SSR_BOOST_DIAGNOSTICS?"1"===e.SSR_BOOST_DIAGNOSTICS:t??"production"!==e?.NODE_ENV},i=(t,e)=>`[ssr-boost] ${t}: ${e} See https://lomray-software.github.io/vite-ssr-boost/reference/diagnostics#${t.toLowerCase()}`,a=(t,o,s=e)=>{const r=t.split(s);if(!s||2!==r.length)throw new Error(i("SSR_BOOST_OUTLET_MISSING",`Invalid HTML shell in ${JSON.stringify(o)}: expected exactly one non-empty outlet ${JSON.stringify(s)}.`));return r},S=t=>{if(null===t)return"null";if("object"!=typeof t){return{bigint:"BigInt",symbol:"Symbol"}[typeof t]??typeof t}const e=Object.getPrototypeOf(t),o=e?.constructor?.name;return"string"==typeof o&&o?o:"object"},c=(t,e,o="$",s=new Set)=>{const r=typeof t;if("function"===r||"bigint"===r||"symbol"===r)return void e({path:o,reason:`${S(t)} is not JSON-serializable`});if(null===t||"object"!==r)return;const n=t,i=Object.getPrototypeOf(n);if(i!==Object.prototype&&null!==i&&(!Array.isArray(n)||i!==Array.prototype)){const t=S(n);return void e({path:o,reason:"Date"===t?"Date hydrates as a string":`${t} is not JSON-serializable`})}if(s.has(n))e({path:o,reason:"a circular reference is not JSON-serializable"});else{s.add(n);for(const[t,r]of Object.entries(n)){const i=Array.isArray(n)&&/^(0|[1-9]\d*)$/.test(t)?`[${t}]`:/^[A-Za-z_$][\w$]*$/.test(t)?`.${t}`:`[${JSON.stringify(t)}]`;c(r,e,o+i,s)}s.delete(n)}};class l{route;logger;chunks=[];constructor(e,o=new t){this.route=e,this.logger=o}warn(t,e){const o=i(t,e),n=r[s]??=new Set;n.has(o)||(n.add(o),this.logger.warn(o,{}))}inspectShell({header:t,footer:o}){("string"!=typeof t||"string"!=typeof o||t.includes(e)||o.includes(e))&&this.warn("SSR_BOOST_OUTLET_MISSING",`HTML shell for route ${JSON.stringify(this.route)} must supply both header and footer around exactly one ${e} outlet, with no outlet left in either half.`)}inspectRouterState({loaderData:t,actionData:e}){for(const[o,s]of Object.entries({loaderData:t,actionData:e}))for(const[t,e]of Object.entries(s??{}))c(e,({path:e,reason:o})=>this.warn("SSR_BOOST_LOADER_NOT_SERIALIZABLE",`Route ${JSON.stringify(t)} at ${e}: ${o}.`),`${o}[${JSON.stringify(t)}]`)}inspectState(t){c(t,({path:t,reason:e})=>this.warn("SSR_BOOST_STATE_NOT_SERIALIZABLE",`getState for route ${JSON.stringify(this.route)} at ${t}: ${e}.`))}inspectOnResponse(t){void 0!==t&&"string"!=typeof t&&this.warn("SSR_BOOST_ONRESPONSE_INVALID_RETURN",`onResponse for route ${JSON.stringify(this.route)} returned ${S(t)}; return a string or undefined.`)}append(t){this.chunks.push(t)}complete(){const t=this.chunks.join("");this.chunks=[];const e=new Map,s=t=>{e.set(t,(e.get(t)??0)+1)},r=t.replace(/<!--[\s\S]*?-->/g,"").replace(/(<(script|style|textarea|title)\b(?:[^"'<>]|"[^"]*"|'[^']*')*>)([\s\S]*?)<\/\2\s*>/gi,(t,e,r,n)=>{if("script"===r.toLowerCase()){/\bwindow\.__staticRouterHydrationData\s*=/.test(n)&&s(o);for(const t of n.matchAll(/\$RC\s*\(\s*(["'])(B:[^"']+)\1/g))s(`$RC("${t[2]}")`)}return e});for(const t of r.matchAll(/<([a-z][\w:-]*)\b((?:[^"'<>]|"[^"]*"|'[^']*')*)>/gi)){const e=t[1].toLowerCase();"html"!==e&&"head"!==e||s(`<${e}>`);for(const e of t[2].matchAll(/([^\s=]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/g)){const t=e[2]??e[3]??e[4];"id"===e[1].toLowerCase()&&/^(S|B):/.test(t)&&s(`id="${t}"`)}}e.has(o)||this.warn("SSR_BOOST_HYDRATION_STATE_MISSING",`Completed response for route ${JSON.stringify(this.route)} has no ${o} script; preserve the hydration footer in onResponse.`);for(const[t,o]of e)o>1&&this.warn("SSR_BOOST_DUPLICATE_OUTPUT",`Completed response for route ${JSON.stringify(this.route)} repeats ${t}; onResponse must return undefined to keep a chunk and '' to withhold one.`)}}export{l as default,i as formatDiagnostic,n as isDiagnosticsEnabled,a as splitHtmlShell,c as walkSerializable};
1
+ import t from"./logger.js";const e="\x3c!--ssr-outlet--\x3e",o="window.__staticRouterHydrationData",r=Symbol.for("@lomray/vite-ssr-boost/diagnostics"),s=globalThis,n=t=>{const e="undefined"==typeof process?void 0:process.env;return"0"===e?.SSR_BOOST_DIAGNOSTICS||"1"===e?.SSR_BOOST_DIAGNOSTICS?"1"===e.SSR_BOOST_DIAGNOSTICS:t??"production"!==e?.NODE_ENV},i=(t,e)=>`[ssr-boost] ${t}: ${e} See https://lomray-software.github.io/vite-ssr-boost/reference/diagnostics#${t.toLowerCase()}`,a=(t,o,r=e)=>{const s=t.split(r);if(!r||2!==s.length)throw new Error(i("SSR_BOOST_OUTLET_MISSING",`Invalid HTML shell in ${JSON.stringify(o)}: expected exactly one non-empty outlet ${JSON.stringify(r)}.`));return s},S=t=>{if(null===t)return"null";if("object"!=typeof t){return{bigint:"BigInt",symbol:"Symbol"}[typeof t]??typeof t}const e=Object.getPrototypeOf(t),o=e?.constructor?.name;return"string"==typeof o&&o?o:"object"},c=(t,e,o="$",r=new Set,s=!1)=>{const n=typeof t;if(s&&(t instanceof Promise||t instanceof Date||t instanceof RegExp||"bigint"===n))return;if("function"===n||"bigint"===n||"symbol"===n)return void e({path:o,reason:`${S(t)} is not JSON-serializable`});if(null===t||"object"!==n)return;const i=t,a=Object.getPrototypeOf(i);if(!(s&&(i instanceof Map||i instanceof Set)||a===Object.prototype||null===a||Array.isArray(i)&&a===Array.prototype)){const t=S(i);return void e({path:o,reason:"Date"===t?"Date hydrates as a string":`${t} is not JSON-serializable`})}if(r.has(i))return void e({path:o,reason:"a circular reference is not JSON-serializable"});r.add(i);const f=s&&i instanceof Map?[...i].flatMap(([t,e],o)=>[[`${o}.key`,t],[`${o}.value`,e]]):s&&i instanceof Set?[...i].map((t,e)=>[String(e),t]):Object.entries(i);for(const[t,n]of f){const a=Array.isArray(i)&&/^(0|[1-9]\d*)$/.test(t)?`[${t}]`:/^[A-Za-z_$][\w$]*$/.test(t)?`.${t}`:`[${JSON.stringify(t)}]`;c(n,e,o+a,r,s)}r.delete(i)};class f{route;logger;chunks=[];constructor(e,o=new t){this.route=e,this.logger=o}warn(t,e){const o=i(t,e),n=s[r]??=new Set;n.has(o)||(n.add(o),this.logger.warn(o,{}))}inspectShell({header:t,footer:o}){("string"!=typeof t||"string"!=typeof o||t.includes(e)||o.includes(e))&&this.warn("SSR_BOOST_OUTLET_MISSING",`HTML shell for route ${JSON.stringify(this.route)} must supply both header and footer around exactly one ${e} outlet, with no outlet left in either half.`)}inspectRouterState({loaderData:t,actionData:e}){for(const[o,r]of Object.entries({loaderData:t,actionData:e}))for(const[t,e]of Object.entries(r??{}))c(e,({path:e,reason:o})=>this.warn("SSR_BOOST_LOADER_NOT_SERIALIZABLE",`Route ${JSON.stringify(t)} at ${e}: ${o}.`),`${o}[${JSON.stringify(t)}]`,new Set,!0)}streamAborted(t){this.warn("SSR_BOOST_STREAM_PROMISE_ABORTED",`Route ${JSON.stringify(this.route)} aborted with ${t} pending loader/action promise(s); the browser receives a rejection when connected.`)}inspectStreamValue(t,e){c(t,({path:t,reason:e})=>this.warn("SSR_BOOST_LOADER_NOT_SERIALIZABLE",`Route ${JSON.stringify(this.route)} at ${t}: ${e}.`),`promise[${e}]`,new Set,!0)}inspectState(t){c(t,({path:t,reason:e})=>this.warn("SSR_BOOST_STATE_NOT_SERIALIZABLE",`getState for route ${JSON.stringify(this.route)} at ${t}: ${e}.`))}inspectOnResponse(t){void 0!==t&&"string"!=typeof t&&this.warn("SSR_BOOST_ONRESPONSE_INVALID_RETURN",`onResponse for route ${JSON.stringify(this.route)} returned ${S(t)}; return a string or undefined.`)}append(t){this.chunks.push(t)}complete(){const t=this.chunks.join("");this.chunks=[];const e=new Map,r=t=>{e.set(t,(e.get(t)??0)+1)},s=t.replace(/<!--[\s\S]*?-->/g,"").replace(/(<(script|style|textarea|title)\b(?:[^"'<>]|"[^"]*"|'[^']*')*>)([\s\S]*?)<\/\2\s*>/gi,(t,e,s,n)=>{if("script"===s.toLowerCase()){/\bwindow\.__staticRouterHydrationData\s*=/.test(n)&&r(o);for(const t of n.matchAll(/\$RC\s*\(\s*(["'])(B:[^"']+)\1/g))r(`$RC("${t[2]}")`)}return e});for(const t of s.matchAll(/<([a-z][\w:-]*)\b((?:[^"'<>]|"[^"]*"|'[^']*')*)>/gi)){const e=t[1].toLowerCase();"html"!==e&&"head"!==e||r(`<${e}>`);for(const e of t[2].matchAll(/([^\s=]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/g)){const t=e[2]??e[3]??e[4];"id"===e[1].toLowerCase()&&/^(S|B):/.test(t)&&r(`id="${t}"`)}}e.has(o)||this.warn("SSR_BOOST_HYDRATION_STATE_MISSING",`Completed response for route ${JSON.stringify(this.route)} has no ${o} script; preserve the hydration footer in onResponse.`);for(const[t,o]of e)o>1&&this.warn("SSR_BOOST_DUPLICATE_OUTPUT",`Completed response for route ${JSON.stringify(this.route)} repeats ${t}; onResponse must return undefined to keep a chunk and '' to withhold one.`)}}export{f as default,i as formatDiagnostic,n as isDiagnosticsEnabled,a as splitHtmlShell,c as walkSerializable};
2
2
  //# sourceMappingURL=diagnostics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostics.js","sources":["../../src/services/diagnostics.ts"],"sourcesContent":[null],"names":["OUTLET","HYDRATION","warnedKey","Symbol","for","registry","globalThis","isDiagnosticsEnabled","enabled","env","process","undefined","SSR_BOOST_DIAGNOSTICS","NODE_ENV","formatDiagnostic","code","sentence","toLowerCase","splitHtmlShell","html","file","outlet","parts","split","length","Error","JSON","stringify","valueType","value","bigint","symbol","prototype","Object","getPrototypeOf","name","constructor","walkSerializable","report","path","ancestors","Set","type","reason","object","Array","isArray","has","add","key","child","entries","suffix","test","delete","Diagnostics","route","logger","chunks","Logger","this","warn","detail","message","warned","inspectShell","header","footer","includes","inspectRouterState","loaderData","actionData","kind","data","inspectState","state","inspectOnResponse","append","push","complete","join","markers","Map","count","marker","set","get","markup","replace","_tag","opening","content","match","matchAll","attribute","total"],"mappings":"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"}
1
+ {"version":3,"file":"diagnostics.js","sources":["../../src/services/diagnostics.ts"],"sourcesContent":[null],"names":["OUTLET","HYDRATION","warnedKey","Symbol","for","registry","globalThis","isDiagnosticsEnabled","enabled","env","process","undefined","SSR_BOOST_DIAGNOSTICS","NODE_ENV","formatDiagnostic","code","sentence","toLowerCase","splitHtmlShell","html","file","outlet","parts","split","length","Error","JSON","stringify","valueType","value","bigint","symbol","prototype","Object","getPrototypeOf","name","constructor","walkSerializable","report","path","ancestors","Set","streamed","type","Promise","Date","RegExp","reason","object","Map","Array","isArray","has","add","entries","flatMap","key","child","index","map","String","suffix","test","delete","Diagnostics","route","logger","chunks","Logger","this","warn","detail","message","warned","inspectShell","header","footer","includes","inspectRouterState","loaderData","actionData","kind","data","streamAborted","count","inspectStreamValue","id","inspectState","state","inspectOnResponse","append","push","complete","join","markers","marker","set","get","markup","replace","_tag","opening","content","match","matchAll","attribute","total"],"mappings":"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"}