@lomray/vite-ssr-boost 8.4.7-beta.1 → 8.5.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 (44) hide show
  1. package/README.md +2 -0
  2. package/adapters/express/entry.d.ts +4 -3
  3. package/adapters/express/entry.js +1 -1
  4. package/adapters/express/entry.js.map +1 -1
  5. package/adapters/express/render.d.ts +12 -2
  6. package/adapters/express/render.js +1 -1
  7. package/adapters/express/render.js.map +1 -1
  8. package/adapters/express/server.js +1 -1
  9. package/adapters/express/server.js.map +1 -1
  10. package/cli/doctor.js +1 -1
  11. package/cli/doctor.js.map +1 -1
  12. package/cloudflare.js +1 -1
  13. package/cloudflare.js.map +1 -1
  14. package/core/admission.d.ts +53 -0
  15. package/core/admission.js +2 -0
  16. package/core/admission.js.map +1 -0
  17. package/core/handler-runtime.d.ts +39 -0
  18. package/core/handler-runtime.js +2 -0
  19. package/core/handler-runtime.js.map +1 -0
  20. package/core/handler.d.ts +7 -6
  21. package/core/handler.js +1 -1
  22. package/core/handler.js.map +1 -1
  23. package/core/not-found.d.ts +46 -0
  24. package/core/not-found.js +2 -0
  25. package/core/not-found.js.map +1 -0
  26. package/core/render.d.ts +10 -0
  27. package/core/render.js +1 -1
  28. package/core/render.js.map +1 -1
  29. package/core/request-guard.d.ts +78 -0
  30. package/core/request-guard.js +2 -0
  31. package/core/request-guard.js.map +1 -0
  32. package/core/request-target.d.ts +3 -0
  33. package/core/request-target.js +2 -0
  34. package/core/request-target.js.map +1 -0
  35. package/core/ssr-policy.d.ts +6 -2
  36. package/core/ssr-policy.js +1 -1
  37. package/core/ssr-policy.js.map +1 -1
  38. package/node/create-request.js +1 -1
  39. package/node/create-request.js.map +1 -1
  40. package/package.json +1 -1
  41. package/services/request-timeline.d.ts +1 -1
  42. package/services/request-timeline.js.map +1 -1
  43. package/testing/create-handler.js +1 -1
  44. package/testing/create-handler.js.map +1 -1
package/README.md CHANGED
@@ -84,6 +84,8 @@ Deferred router data needs no additional state library. Keep footer hydration by
84
84
 
85
85
  **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.
86
86
 
87
+ **Request protection.** The default-on [request guard](./docs/api/request-guard.md) validates document methods and targets before hooks, with configurable 404 modes and optional SSR concurrency limits.
88
+
87
89
  **Fetch handler.** Import `createHandler` from `@lomray/vite-ssr-boost/core/handler` and connect it through `adapters/node`, `adapters/express`, `adapters/fastify`, `adapters/hono` or `adapters/edge`. Your transport owns the development server, static assets and route-asset injection; follow [Runtime adapters](./docs/guide/runtime-adapters.md) when you need this control.
88
90
 
89
91
  Both paths are measured weekly in the public [ssr-benchmarks](https://github.com/Lomray-Software/ssr-benchmarks) repository: the same application on vite-ssr-boost, React Router Framework mode, Vike, TanStack Start and Next.js, and a runtime matrix that serves the boost build through Express, `node:http`, Fastify, Hono and Bun. See [Benchmarks](./docs/reference/benchmarks.md) for what is measured and how to reproduce it.
@@ -6,6 +6,7 @@ import { createStaticHandler } from 'react-router';
6
6
  import type { ServeStaticOptions } from 'serve-static';
7
7
  import type { Logger } from 'vite';
8
8
  import type { IRenderOptions, TRender } from './render.js';
9
+ import type { IHandlerRuntimeOptions } from '../../core/handler-runtime.js';
9
10
  import type { ISsrPolicy } from '../../core/ssr-policy.js';
10
11
  import type { TRouteObject } from '../../interfaces/route-object.js';
11
12
  import type ServerApi from '../../services/server-api.js';
@@ -42,8 +43,7 @@ export interface IAppServerProps<T = Record<string, any>> {
42
43
  server: T;
43
44
  }
44
45
  export type TApp<T> = FC<PropsWithChildren<Record<string, any> & IAppServerProps<T>>>;
45
- export interface IEntryServerOptions<TAppProps = Record<string, any>> extends Pick<IPrepareRenderOut, 'loggerProd' | 'loggerDev' | 'middlewares'> {
46
- ssr?: ISsrPolicy;
46
+ export interface IEntryServerOptions<TAppProps = Record<string, any>> extends Omit<IHandlerRuntimeOptions, 'basename'>, Pick<IPrepareRenderOut, 'loggerProd' | 'loggerDev' | 'middlewares'> {
47
47
  abortDelay?: number;
48
48
  init?: (params: {
49
49
  config: ServerConfig;
@@ -53,6 +53,7 @@ export interface IEntryServerOptions<TAppProps = Record<string, any>> extends Pi
53
53
  /**
54
54
  * Render server side application
55
55
  */
56
- declare function entry<TAppProps>(App: TApp<TAppProps>, routes: TRouteObject[], { init, routerOptions, ssr, ...rest }?: IEntryServerOptions<TAppProps>): IPrepareRenderOut<TAppProps>;
56
+ declare function entry<TAppProps>(App: TApp<TAppProps>, routes: TRouteObject[], { init, routerOptions, ssr, requestGuard, notFound, admission, ...rest }?: IEntryServerOptions<TAppProps>): IPrepareRenderOut<TAppProps>;
57
57
  export default entry;
58
58
  export type { ISsrPolicy };
59
+ export type { IAdmissionOptions, IAdmissionEvent, IRequestGuardOptions, IRequestGuardDecisionContext, TRequestGuardReason, TNotFoundOptions, ICachedNotFoundOptions, } from '../../core/handler.js';
@@ -1,2 +1,2 @@
1
- import{createStaticHandler as r}from"react-router";import e from"./render.js";import o from"../../core/spa-shell.js";import t from"../../core/ssr-policy.js";function s(s,n,{init:i,routerOptions:p,ssr:a,...l}={}){const m=r(n,p),u=new t(a,m.dataRoutes,p?.basename),c=o();return{render:e.bind(null,{handler:m,App:s,policy:u,spaShell:c}),init:i,routes:n,...l}}export{s as default};
1
+ import{createStaticHandler as r}from"react-router";import e from"./render.js";import n from"../../core/handler-runtime.js";function t(t,o,{init:s,routerOptions:i,ssr:u,requestGuard:a,notFound:d,admission:m,...p}={}){const f=r(o,i),l=new n(f.dataRoutes,{ssr:u,requestGuard:a,notFound:d,admission:m,basename:i?.basename});return{render:e.bind(null,{handler:f,App:t,runtime:l}),init:s,routes:o,...p}}export{t as default};
2
2
  //# sourceMappingURL=entry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entry.js","sources":["../../../src/adapters/express/entry.tsx"],"sourcesContent":[null],"names":["entry","App","routes","init","routerOptions","ssr","rest","handler","createStaticHandler","policy","SsrPolicy","dataRoutes","basename","spaShell","createSpaShell","render","bind"],"mappings":"6JAsFA,SAASA,EACPC,EACAC,GACAC,KAAEA,EAAIC,cAAEA,EAAaC,IAAEA,KAAQC,GAAyC,IAExE,MAAMC,EAAUC,EAAoBN,EAAyBE,GACvDK,EAAS,IAAIC,EAAUL,EAAKE,EAAQI,WAAYP,GAAeQ,UAC/DC,EAAWC,IAEjB,MAAO,CACLC,OAAQA,EAAOC,KAAK,KAAM,CAAET,UAASN,MAAKQ,SAAQI,aAClDV,OACAD,YACGI,EAEP"}
1
+ {"version":3,"file":"entry.js","sources":["../../../src/adapters/express/entry.tsx"],"sourcesContent":[null],"names":["entry","App","routes","init","routerOptions","ssr","requestGuard","notFound","admission","rest","handler","createStaticHandler","runtime","HandlerRuntime","dataRoutes","basename","render","bind"],"mappings":"2HAqFA,SAASA,EACPC,EACAC,GACAC,KACEA,EAAIC,cACJA,EAAaC,IACbA,EAAGC,aACHA,EAAYC,SACZA,EAAQC,UACRA,KACGC,GAC+B,CAAA,GAEpC,MAAMC,EAAUC,EAAoBT,EAAyBE,GACvDQ,EAAU,IAAIC,EAAeH,EAAQI,WAAY,CACrDT,MACAC,eACAC,WACAC,YACAO,SAAUX,GAAeW,WAG3B,MAAO,CACLC,OAAQA,EAAOC,KAAK,KAAM,CAAEP,UAAST,MAAKW,YAC1CT,OACAD,YACGO,EAEP"}
@@ -1,8 +1,10 @@
1
1
  import type { Request as ExpressRequest, Response as ExpressResponse } from 'express';
2
2
  import type { RouterState, StaticHandlerContext, StaticHandler } from 'react-router';
3
- import type { TApp } from './entry.js';
3
+ import type { TApp, IEntrypointOptions } from './entry.js';
4
4
  import StreamError from '../../constants/stream-error.js';
5
5
  import type { IServerContext } from '../../context/server.js';
6
+ import type { IHtmlShell } from '../../core/handler.js';
7
+ import type HandlerRuntime from '../../core/handler-runtime.js';
6
8
  import type { ICoreRenderOptions, ISsrRequestContext } from '../../core/render.js';
7
9
  import type createSpaShell from '../../core/spa-shell.js';
8
10
  import type SsrPolicy from '../../core/ssr-policy.js';
@@ -32,11 +34,19 @@ export interface IRequestContext<TAppProps = Record<any, any>> {
32
34
  export type TRender<TAppProps = Record<any, any>> = (config: ServerConfig, context: Omit<IRequestContext<TAppProps>, 'request' | 'response'>, options: IRenderOptions) => Promise<void>;
33
35
  export interface IRenderParams<TAppProps = Record<string, any>> {
34
36
  App: TApp<TAppProps>;
37
+ /** Startup state shared across legacy transport hook closures. */
38
+ runtime?: HandlerRuntime;
35
39
  handler: StaticHandler;
36
40
  policy?: SsrPolicy;
37
41
  spaShell?: ReturnType<typeof createSpaShell>;
38
42
  }
39
43
  export interface IRenderOptions<TAppProps = Record<string, any>> extends Pick<ICoreRenderOptions<TAppProps>, 'documentHeaders' | 'sessionCookie' | 'protectPrivate'> {
44
+ /** Initialize legacy request props after the Fetch guard. */
45
+ onRequest?: IEntrypointOptions<TAppProps>['onRequest'];
46
+ /** Continue middleware when the request hook explicitly skips SSR. */
47
+ onSkip?: () => void;
48
+ /** Defer template loading until after request validation. */
49
+ getHtml?: () => IHtmlShell | Promise<IHtmlShell>;
40
50
  hydration?: 'early' | 'footer';
41
51
  nonce?: string;
42
52
  bootstrapScriptContent?: string;
@@ -75,5 +85,5 @@ export interface IShellReadyOut {
75
85
  /**
76
86
  * Render application
77
87
  */
78
- declare function render({ App, handler, policy, spaShell }: IRenderParams, config: ServerConfig, initialContext: Omit<IRequestContext, 'request' | 'response'>, { onRouterReady, onShellReady, onResponse, onShellError, onError, getBody, getState, hydration, nonce, bootstrapScriptContent, documentHeaders, sessionCookie, protectPrivate, abortDelay, }: IRenderOptions): Promise<void>;
88
+ declare function render({ App, handler, policy, spaShell, runtime }: IRenderParams, config: ServerConfig, initialContext: Omit<IRequestContext, 'request' | 'response'>, { onRequest, onSkip, getHtml, onRouterReady, onShellReady, onResponse, onShellError, onError, getBody, getState, hydration, nonce, bootstrapScriptContent, documentHeaders, sessionCookie, protectPrivate, abortDelay, }: IRenderOptions): Promise<void>;
79
89
  export default render;
@@ -1,2 +1,2 @@
1
- import e from"chalk";import r from"react";import t from"./create-request.js";import s from"./route-assets.js";import o from"../../constants/stream-error.js";import n from"../../core/early-hints.js";import{getSetCookieHeaders as a,getHeaderEntries as i}from"../../core/headers.js";import d from"../../core/render.js";import c from"../../node/render-to-stream.js";import p from"../../node/request-signal.js";import l from"../../node/write-early-hints.js";import m,{writeFetchHeaders as h}from"../../node/write-fetch-response.js";import u,{isDiagnosticsEnabled as f}from"../../services/diagnostics.js";const y=(e,r,t)=>{if(t&&!r.headersSent&&!r.writableEnded){e.response.status!==t.status&&r.status(e.response.status??200);const s=new Set([...t.headers.keys(),...e.response.headers.keys()]);for(const o of s)e.response.headers.get(o)!==t.headers.get(o)&&(e.response.headers.has(o)?r.setHeader(o,"set-cookie"===o?a(e.response.headers):e.response.headers.get(o)):r.removeHeader(o))}const s=new Headers(e.response.headers);s.delete("Set-Cookie");for(const[e,t]of Object.entries(r.getHeaders()))if("set-cookie"!==e.toLowerCase()&&void 0!==t)if(Array.isArray(t))for(const r of t)s.append(e,r);else s.set(e,"number"==typeof t?String(t):t);e.response.headers=s,e.response.status=r.statusCode};async function g({App:g,handler:S,policy:w,spaShell:b},j,v,{onRouterReady:E,onShellReady:R,onResponse:H,onShellError:C,onError:x,getBody:k,getState:q,hydration:A,nonce:P,bootstrapScriptContent:L,documentHeaders:D,sessionCookie:O,protectPrivate:T,abortDelay:B=15e3}){const{req:G,res:U}=v,$=j.getLogger(),z=p(G,U);try{const p=((e,r,s)=>{const o={signal:r};return s&&"GET"!==e.method&&"HEAD"!==e.method&&(o.body=s(e)??null),t(e,o)})(G,z.signal,k),F=Object.assign(v,{request:p,response:{headers:new Headers},diagnostics:f(!j.isProd)?new u(new URL(p.url).pathname,$):void 0});if(!j.isProd&&F.diagnostics){const{diagnostics:e}=F;for(const r of["req","res"]){let t=F[r];Object.defineProperty(F,r,{configurable:!0,enumerable:!0,get:()=>(e.deprecatedReqRes(),t),set:e=>{t=e}})}}const{response:I}=F;y(F,U),200===I.status&&(I.status=void 0);const J=await d({createApp:(e,t)=>r.createElement(g,{server:{...t.appProps,req:G}},e),handler:S,policy:w,spaShell:b,renderToStream:c},F,{abortDelay:B,hydration:A,nonce:P,bootstrapScriptContent:L,documentHeaders:D,sessionCookie:O,protectPrivate:T,getState:q?()=>q({context:F}):void 0,onError:({error:r})=>{const{code:t,message:s}=r;if(x?.({context:F,error:r}),$.info(e.red(`Stream error. Code: ${t}`)),[o.RenderAborted,o.RenderTimeout,o.RenderCancel].includes(t))return void $.info(e.dim(s));const{original:n}=r;$.error(n)},onResponse:H?({html:e,isEnd:r})=>H({context:F,html:e,isEnd:r}):void 0,onRouterReady:E?()=>E({context:F}):void 0,onShellError:C?({error:e})=>C({context:F,error:e}):void 0,onShellReady:()=>{((e,r)=>{if(r.headersSent||r.writableEnded)return;r.status(e.response.status??200),i(e.response.headers).forEach(([e,t])=>r.setHeader(e,t));const t=a(e.response.headers);t.length&&r.setHeader("Set-Cookie",t)})(F,U);const{response:e}=F,{headers:r,status:t}=e,s=R?{headers:new Headers(r),status:t}:void 0,o=R?.({context:F});return y(F,U,s),o??{}},prepare:async({executionContext:e})=>{const{matches:r,isSpa:t,hasEarlyHints:o}=F,a=(await s(j,r,t)).injectAssets(F,Boolean(o));o&&await n(e,a)},routerRequestContext:F},{onEarlyHints:e=>l(U,e)});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 h(e,r),await(r.body?.cancel()),void e.redirect(r.status,t);await m(e,r)})(U,J)}finally{z.dispose()}}export{g as default};
1
+ import e from"chalk";import s from"react";import t from"./create-request.js";import r from"./route-assets.js";import o from"../../constants/stream-error.js";import n from"../../core/early-hints.js";import a from"../../core/handler.js";import{getHeaderEntries as i,getSetCookieHeaders as d}from"../../core/headers.js";import c from"../../node/render-to-stream.js";import p from"../../node/request-signal.js";import l from"../../node/write-early-hints.js";import h,{writeFetchHeaders as u}from"../../node/write-fetch-response.js";import m,{isDiagnosticsEnabled as f}from"../../services/diagnostics.js";const y=(e,s,t)=>{if(t&&!s.headersSent&&!s.writableEnded){e.response.status!==t.status&&s.status(e.response.status??200);const r=new Set([...t.headers.keys(),...e.response.headers.keys()]);for(const o of r)e.response.headers.get(o)!==t.headers.get(o)&&(e.response.headers.has(o)?s.setHeader(o,"set-cookie"===o?d(e.response.headers):e.response.headers.get(o)):s.removeHeader(o))}const r=new Headers(e.response.headers);r.delete("Set-Cookie");for(const[e,t]of Object.entries(s.getHeaders()))if("set-cookie"!==e.toLowerCase()&&void 0!==t)if(Array.isArray(t))for(const s of t)r.append(e,s);else r.set(e,"number"==typeof t?String(t):t);e.response.headers=r,e.response.status=s.statusCode};async function g({App:g,handler:S,policy:w,spaShell:E,runtime:b},H,j,{onRequest:R,onSkip:v,getHtml:C,onRouterReady:k,onShellReady:q,onResponse:x,onShellError:P,onError:A,getBody:O,getState:L,hydration:D,nonce:T,bootstrapScriptContent:B,documentHeaders:G,sessionCookie:U,protectPrivate:$,abortDelay:z=15e3}){const{req:F,res:I}=j,J=H.getLogger(),K=p(F,I);try{const p=((e,s,r)=>{const o={signal:s};return r&&"GET"!==e.method&&"HEAD"!==e.method&&(o.body=r(e)??null),t(e,o)})(F,K.signal,O);let M,N=F,Q=!0;const V=a({createApp:(e,t)=>s.createElement(g,{server:{...t.appProps,req:N}},e),handler:S,requestContext:j,policy:w,spaShell:E,renderToStream:c},{onRequest:async({request:e})=>{e!==p&&(N=Object.assign(Object.create(F),{headers:Object.fromEntries(e.headers),method:e.method,cookies:{},signedCookies:{}}));const{appProps:s,hasEarlyHints:t,shouldSkip:r,shouldCancel:o}=await(R?.(N,I))??{};if(r||o||I.writableEnded||I.headersSent)return Q=!1,r&&v?.(),new Response(null,{status:204});j.hasEarlyHints=t??j.hasEarlyHints;const n={response:{headers:new Headers,status:void 0}};return y(n,I),{appProps:s??j.appProps,headers:n.response.headers,status:200===n.response.status?void 0:n.response.status}},getHtml:C??(()=>j.html),onContext:({context:e})=>{if(M=Object.assign(e,{req:N,res:I,hasEarlyHints:j.hasEarlyHints}),M.diagnostics=f(!H.isProd)?new m(new URL(e.request.url).pathname,J):void 0,!H.isProd&&M.diagnostics){const{diagnostics:e}=M;for(const s of["req","res"]){let t=M[s];Object.defineProperty(M,s,{configurable:!0,enumerable:!0,get:()=>(e.deprecatedReqRes(),t),set:e=>{t=e}})}}},routerRequestContext:j,abortDelay:z,hydration:D,nonce:T,bootstrapScriptContent:B,documentHeaders:G,sessionCookie:U,protectPrivate:$,getState:L?()=>L({context:M}):void 0,onError:({error:s})=>{const{code:t,message:r}=s;if(A?.({context:M,error:s}),J.info(e.red(`Stream error. Code: ${t}`)),[o.RenderAborted,o.RenderTimeout,o.RenderCancel].includes(t))return void J.info(e.dim(r));const{original:n}=s;J.error(n)},onResponse:x?({html:e,isEnd:s})=>x({context:M,html:e,isEnd:s}):void 0,onRouterReady:k?()=>k({context:M}):void 0,onShellError:P?({error:e})=>P({context:M,error:e}):void 0,onShellReady:()=>{((e,s)=>{if(s.headersSent||s.writableEnded)return;s.status(e.response.status??200),i(e.response.headers).forEach(([e,t])=>s.setHeader(e,t));const t=d(e.response.headers);t.length&&s.setHeader("Set-Cookie",t)})(M,I);const{response:e}=M,{headers:s,status:t}=e,r=q?{headers:new Headers(s),status:t}:void 0,o=q?.({context:M});return y(M,I,r),o??{}},prepare:async({executionContext:e})=>{const{matches:s,isSpa:t,hasEarlyHints:o}=M,a=(await r(H,s,t)).injectAssets(M,Boolean(o));o&&await n(e,a)}},b),W=await V(p,{onEarlyHints:e=>l(I,e)});Q?await(async(e,s)=>{const t=s.headers.get("Location");if(t&&s.status>=300&&s.status<400&&!e.headersSent&&!e.writableEnded&&!e.destroyed)return u(e,s),await(s.body?.cancel()),void e.redirect(s.status,t);await h(e,s)})(I,W):await(W.body?.cancel())}finally{K.dispose()}}export{g 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":["syncResponse","context","res","previous","headersSent","writableEnded","response","status","names","Set","headers","keys","name","get","has","setHeader","getSetCookieHeaders","removeHeader","Headers","delete","value","Object","entries","getHeaders","toLowerCase","undefined","Array","isArray","item","append","set","String","statusCode","async","render","App","handler","policy","spaShell","config","initialContext","onRouterReady","onShellReady","onResponse","onShellError","onError","getBody","getState","hydration","nonce","bootstrapScriptContent","documentHeaders","sessionCookie","protectPrivate","abortDelay","req","Logger","getLogger","requestSignal","createRequestSignal","request","signal","options","method","body","createFetchRequest","createRenderRequest","assign","diagnostics","isDiagnosticsEnabled","isProd","Diagnostics","URL","url","pathname","defineProperty","configurable","enumerable","deprecatedReqRes","next","initialResponse","coreRender","createApp","children","updated","React","createElement","server","appProps","renderToStream","error","code","message","info","chalk","red","StreamError","RenderAborted","RenderTimeout","RenderCancel","includes","dim","original","html","isEnd","getHeaderEntries","forEach","cookies","length","prepareResponse","shellResponse","shell","prepare","executionContext","matches","isSpa","hasEarlyHints","hints","getRouteAssets","injectAssets","Boolean","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":["syncResponse","context","res","previous","headersSent","writableEnded","response","status","names","Set","headers","keys","name","get","has","setHeader","getSetCookieHeaders","removeHeader","Headers","delete","value","Object","entries","getHeaders","toLowerCase","undefined","Array","isArray","item","append","set","String","statusCode","async","render","App","handler","policy","spaShell","runtime","config","initialContext","onRequest","onSkip","getHtml","onRouterReady","onShellReady","onResponse","onShellError","onError","getBody","getState","hydration","nonce","bootstrapScriptContent","documentHeaders","sessionCookie","protectPrivate","abortDelay","req","Logger","getLogger","requestSignal","createRequestSignal","request","signal","options","method","body","createFetchRequest","createRenderRequest","legacyRequest","shouldWrite","fetch","createHandler","createApp","children","updated","React","createElement","server","appProps","requestContext","renderToStream","renderRequest","assign","create","fromEntries","cookies","signedCookies","hasEarlyHints","shouldSkip","shouldCancel","Response","metadata","html","onContext","diagnostics","isDiagnosticsEnabled","isProd","Diagnostics","URL","url","pathname","defineProperty","configurable","enumerable","deprecatedReqRes","next","routerRequestContext","error","code","message","info","chalk","red","StreamError","RenderAborted","RenderTimeout","RenderCancel","includes","dim","original","isEnd","getHeaderEntries","forEach","length","prepareResponse","shellResponse","shell","prepare","executionContext","matches","isSpa","hints","getRouteAssets","injectAssets","Boolean","emitEarlyHints","onEarlyHints","writeEarlyHints","location","destroyed","writeFetchHeaders","cancel","redirect","writeFetchResponse","writeResponse","dispose"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import e from"node:http";import r from"node:https";import t from"node:path";import s from"compression";import o from"express";import i from"./prepare-server.js";import a from"./static-files.js";import n from"../../helpers/print-server-info.js";import p from"../../services/server-api.js";async function d(d){const c=o().disable("x-powered-by");d.isProd&&c.set("env","production");const m=new p;d.setApp(c);const l=i.init(d,m);if(!d.isProd){const e=await(await(import("vite"))).createServer({server:{middlewareMode:!0,watch:{usePolling:!0,interval:100}},appType:"custom",mode:d.mode});c.use(e.middlewares),d.setVite(e)}const{isSPA:f}=d.getParams();if(f||await l.onAppCreated(),d.isProd){const{root:e,publicDir:r}=d.getParams(),{compression:i,expressStatic:n}=l.getMiddlewaresConfig();if(i&&c.use(s(i)),f||c.use((e,r,t)=>{"/index.html"!==e.url||m.hasAccessIndexHtml()||(e.url="/index-not-found.html"),t()}),n){const{basename:s,...i}=n;c.use(s,(f?o.static:a)(t.resolve(`${e}/${r}`),{...i,index:!!f&&void 0}))}}return f?c.use(/(.*)/,(e,r,t)=>{(async()=>{try{const t=(await l.loadHtml(e)).join("");r.send(t)}catch(e){d.getLogger().error(`Failed to handle request: ${e?.message}`,{error:e}),t(e)}})()}):c.use(/(.*)/,(e,r,t)=>{(async()=>{try{const[{render:s,onRequest:o,...i},a]=await Promise.all([l.loadEntrypoint(),l.loadHtml(e)]),{appProps:n,hasEarlyHints:p,shouldSkip:c,shouldCancel:m}=(o?await o(e,r):void 0)??{},[f,u]=a;if(m||r.writableEnded||r.headersSent)return;if(c)return t();const h={req:e,res:r,hasEarlyHints:p,appProps:n??{},html:{header:f,footer:u}};await s(d,h,i)}catch(e){d.getLogger().error(`Failed to handle request: ${e?.message}`,{error:e}),t(e)}})()}),{run:({version:t,isPrintInfo:s=!0}={})=>{const{port:o,host:i}=d.getParams(),a=Boolean(d.getVite()?.config?.server?.https);d.isHost&&!d.isProd&&(d.getVite().config.server.host=i);const p=(a?r.createServer(d.getVite().config.server.https,c):e.createServer(c)).listen(o,i,()=>{l.onServerStarted?.(c,m,p),s&&n(d,{version:t,server:p})});return p},app:c}}export{d as default};
1
+ import e from"node:http";import r from"node:https";import t from"node:path";import o from"compression";import s from"express";import i from"./prepare-server.js";import n from"./static-files.js";import a from"../../helpers/print-server-info.js";import p from"../../services/server-api.js";async function c(c){const d=s().disable("x-powered-by");c.isProd&&d.set("env","production");const m=new p;c.setApp(d);const l=i.init(c,m);if(!c.isProd){const e=await(await(import("vite"))).createServer({server:{middlewareMode:!0,watch:{usePolling:!0,interval:100}},appType:"custom",mode:c.mode});d.use(e.middlewares),c.setVite(e)}const{isSPA:f}=c.getParams();if(f||await l.onAppCreated(),c.isProd){const{root:e,publicDir:r}=c.getParams(),{compression:i,expressStatic:a}=l.getMiddlewaresConfig();if(i&&d.use(o(i)),f||d.use((e,r,t)=>{"/index.html"!==e.url||m.hasAccessIndexHtml()||(e.url="/index-not-found.html"),t()}),a){const{basename:o,...i}=a;d.use(o,(f?s.static:n)(t.resolve(`${e}/${r}`),{...i,index:!!f&&void 0}))}}return f?d.use(/(.*)/,(e,r,t)=>{(async()=>{try{const t=(await l.loadHtml(e)).join("");r.send(t)}catch(e){c.getLogger().error(`Failed to handle request: ${e?.message}`,{error:e}),t(e)}})()}):d.use(/(.*)/,(e,r,t)=>{(async()=>{try{const{render:o,onRequest:s,...i}=await l.loadEntrypoint(),n={req:e,res:r,appProps:{},html:{header:"",footer:""}};await o(c,n,{...i,onRequest:s,onSkip:t,getHtml:async()=>{const[r,t]=await l.loadHtml(e);return{header:r,footer:t}}})}catch(e){c.getLogger().error(`Failed to handle request: ${e?.message}`,{error:e}),t(e)}})()}),{run:({version:t,isPrintInfo:o=!0}={})=>{const{port:s,host:i}=c.getParams(),n=Boolean(c.getVite()?.config?.server?.https);c.isHost&&!c.isProd&&(c.getVite().config.server.host=i);const p=(n?r.createServer(c.getVite().config.server.https,d):e.createServer(d)).listen(s,i,()=>{l.onServerStarted?.(d,m,p),o&&a(c,{version:t,server:p})});return p},app:d}}export{c as default};
2
2
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sources":["../../../src/adapters/express/server.ts"],"sourcesContent":[null],"names":["async","createServer","config","app","express","disable","isProd","set","serverApi","ServerApi","setApp","prepareServer","PrepareServer","init","vite","server","middlewareMode","watch","usePolling","interval","appType","mode","use","middlewares","setVite","isSPA","getParams","onAppCreated","root","publicDir","compression","compressionConfig","expressStatic","getMiddlewaresConfig","req","_","next","url","hasAccessIndexHtml","basename","expressStaticOpts","static","staticFiles","path","resolve","index","undefined","res","html","loadHtml","join","send","e","getLogger","error","message","render","onRequest","renderParams","clientHtml","Promise","all","loadEntrypoint","appProps","hasEarlyHints","shouldSkip","shouldCancel","header","footer","writableEnded","headersSent","renderInput","run","version","isPrintInfo","port","host","isHTTPS","Boolean","getVite","https","isHost","http","listen","onServerStarted","printServerInfo"],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sources":["../../../src/adapters/express/server.ts"],"sourcesContent":[null],"names":["async","createServer","config","app","express","disable","isProd","set","serverApi","ServerApi","setApp","prepareServer","PrepareServer","init","vite","server","middlewareMode","watch","usePolling","interval","appType","mode","use","middlewares","setVite","isSPA","getParams","onAppCreated","root","publicDir","compression","compressionConfig","expressStatic","getMiddlewaresConfig","req","_","next","url","hasAccessIndexHtml","basename","expressStaticOpts","static","staticFiles","path","resolve","index","undefined","res","html","loadHtml","join","send","e","getLogger","error","message","render","onRequest","renderParams","loadEntrypoint","renderInput","appProps","header","footer","onSkip","getHtml","run","version","isPrintInfo","port","host","isHTTPS","Boolean","getVite","https","isHost","http","listen","onServerStarted","printServerInfo"],"mappings":"gSAsBAA,eAAeC,EAAaC,GAC1B,MAAMC,EAAMC,IAAUC,QAAQ,gBAE1BH,EAAOI,QACTH,EAAII,IAAI,MAAO,cAGjB,MAAMC,EAAY,IAAIC,EAEtBP,EAAOQ,OAAOP,GAEd,MAAMQ,EAAgBC,EAAcC,KAAKX,EAAQM,GAEjD,IAAKN,EAAOI,OAAQ,CAMlB,MAAMQ,qBACS,UACbb,aAAa,CACbc,OAAQ,CACNC,gBAAgB,EAChBC,MAAO,CAKLC,YAAY,EACZC,SAAU,MAGdC,QAAS,SACTC,KAAMnB,EAAOmB,OAMflB,EAAImB,IAAIR,EAAKS,aAEbrB,EAAOsB,QAAQV,EACjB,CAEA,MAAMW,MAAEA,GAAUvB,EAAOwB,YAMzB,GAJKD,SACGd,EAAcgB,eAGlBzB,EAAOI,OAAQ,CACjB,MAAMsB,KAAEA,EAAIC,UAAEA,GAAc3B,EAAOwB,aAC3BI,YAAaC,EAAiBC,cAAEA,GAAkBrB,EAAcsB,uBAmBxE,GAjBIF,GACF5B,EAAImB,IAAIQ,EAAYC,IAGjBN,GAIHtB,EAAImB,IAAI,CAACY,EAAKC,EAAGC,KACC,gBAAZF,EAAIG,KAA0B7B,EAAU8B,uBAC1CJ,EAAIG,IAAM,yBAGZD,MAIAJ,EAAe,CACjB,MAAMO,SAAEA,KAAaC,GAAsBR,EAE3C7B,EAAImB,IACFiB,GACCd,EAAQrB,EAAQqC,OAASC,GAAaC,EAAKC,QAAQ,GAAGhB,KAAQC,KAAc,IACxEW,EACHK,QAAOpB,QAAQqB,IAGrB,CACF,CAwDA,OAnDKrB,EAmCHtB,EAAImB,IAAI,OAAQ,CAACY,EAAKa,EAAKX,KACpB,WACH,IACE,MAAMY,SAAcrC,EAAcsC,SAASf,IAAMgB,KAAK,IAEtDH,EAAII,KAAKH,EACX,CAAE,MAAOI,GACPlD,EACGmD,YACAC,MAAM,6BAA8BF,GAAaG,UAAW,CAAED,MAAOF,IACxEhB,EAAKgB,EACP,CACD,EAXI,KAnCPjD,EAAImB,IAAI,OAAQ,CAACY,EAAKa,EAAKX,KACpB,WACH,IACE,MAAMoB,OAAEA,EAAMC,UAAEA,KAAcC,SAAuB/C,EAAcgD,iBAC7DC,EAAsC,CAC1C1B,MACAa,MACAc,SAAU,CAAA,EACVb,KAAM,CAAEc,OAAQ,GAAIC,OAAQ,WAGxBP,EAAOtD,EAAQ0D,EAAa,IAC7BF,EACHD,YACAO,OAAQ5B,EAER6B,QAASjE,UACP,MAAO8D,EAAQC,SAAgBpD,EAAcsC,SAASf,GAEtD,MAAO,CAAE4B,SAAQC,YAGvB,CAAE,MAAOX,GACPlD,EACGmD,YACAC,MAAM,6BAA8BF,GAAaG,UAAW,CAAED,MAAOF,IACxEhB,EAAKgB,EACP,CACD,EA3BI,KAiDF,CAILc,IAAK,EAAGC,UAASC,eAAc,GAAS,CAAA,KACtC,MAAMC,KAAEA,EAAIC,KAAEA,GAASpE,EAAOwB,YACxB6C,EAAUC,QAAQtE,EAAOuE,WAAWvE,QAAQa,QAAQ2D,OAKtDxE,EAAOyE,SAAWzE,EAAOI,SAC3BJ,EAAOuE,UAAWvE,OAAOa,OAAOuD,KAAOA,GAGzC,MAAMvD,GACJwD,EACIG,EAAMzE,aAAaC,EAAOuE,UAAWvE,OAAOa,OAAO2D,MAAQvE,GAC3DyE,EAAK3E,aAAaE,IACtB0E,OAAOR,EAAMC,EAAM,KACd3D,EAAcmE,kBAAkB3E,EAAKK,EAAWO,GAEhDqD,GAIAW,EAAgB7E,EAAQ,CAAEiE,UAASpD,aAG1C,OAAOA,GAETZ,MAEJ"}
package/cli/doctor.js CHANGED
@@ -1,2 +1,2 @@
1
- import e from"node:fs";import{createRequire as t}from"node:module";import r from"node:path";import s from"semver";import o from"./diagnostic-codes.js";import{libraryPackage as n,stringValue as i,readPackage as a,readConfig as c,readHtml as d,objectProperty as l}from"./project.js";import p from"../constants/plugin-name.js";import u from"../services/parse-routes.js";import m from"../services/server-config.js";import f from"../services/source-files.js";const h=[{react:"18.2.0",router:"7.18.3",vite:"6.4.3"},{react:"19.2.8",router:"7.18.3",vite:"7.3.6"},{react:"19.2.8",router:"8.3.1",vite:"8.2.2"}],g="package.json",v=(t,s)=>{for(let o=t;;o=r.dirname(o)){const t=r.join(o,"node_modules",s);if(e.existsSync(r.join(t,g)))return e.realpathSync(t);if(o===r.dirname(o))return}},b=t=>{const s={react:new Set,"react-dom":new Set},o=new Set,n=(e,t)=>{for(const i of t){const t=v(e,i);if(!t||o.has(t))continue;o.add(t),"react"!==i&&"react-dom"!==i||s[i].add(t);const{dependencies:c,peerDependencies:d}=a(r.join(t,g));n(t,Object.keys({...c,...d}))}},{dependencies:i,devDependencies:c}=a(r.join(t,g));return n(e.realpathSync(t),Object.keys({...i,...c})),{react:[...s.react],"react-dom":[...s["react-dom"]]}},y=(e,t="")=>e.flatMap(e=>{const r=[t,String(e.index)].filter(Boolean).join("-");return[{id:e.id??r,path:e.path??null},...y(e.children,r)]}),$=(v={})=>{const $=r.resolve(v.root??process.cwd()),w=[],j={node:process.versions.node},x={versions:j,adapter:null,routes:[],checks:w,diagnosticCodes:[]},k=(e,t,r,s=!1)=>{try{w.push({name:e,status:"ok",message:r(),fix:t,...s?{info:s}:{}})}catch(r){w.push({name:e,status:"error",message:r.message,fix:t,...s?{info:s}:{}})}};let S={};k("package","Run doctor in the app directory or set --root.",()=>(S=a(r.join($,g)),"package.json is readable"));const R=t(r.join($,g)),E=[p,"react","react-dom","react-router","vite"],O=n(),D={[p]:O.engines.node},M={app:S.peerDependencies??{}};for(const e of E)k(`version:${e}`,`Install ${e} at a version satisfying the installed packages’ peer ranges.`,()=>{const t=a(R.resolve(`${e}/package.json`)),r=s.valid(t.version);if(M[e]=t.peerDependencies??(e===p?O.peerDependencies??{}:{}),j[e]=r,!r)throw new Error(`${e} has no valid installed version`);return t.engines?.node&&(D[e]=t.engines.node),`${e} ${r}`}),j[e]??=null;for(const e of w.filter(e=>e.name.startsWith("version:")&&"ok"===e.status)){const t=e.name.slice(8),r=Object.entries(M).flatMap(([e,r])=>r[t]&&!s.satisfies(j[t],r[t])?[`${e} requires ${t}: ${r[t]}`]:[]);r.length&&(e.status="error",e.message+=`; ${r.join("; ")}`)}const N=e=>Number(j.react===e.react&&j["react-dom"]===e.react)+Number(j["react-router"]===e.router)+Number(j.vite===e.vite),F=(e,t)=>{const r=s.parse(e),o=s.parse(t);return r?1e6*Math.abs(r.major-o.major)+1e3*Math.abs(r.minor-o.minor)+Math.abs(r.patch-o.patch):Number.MAX_SAFE_INTEGER},[A]=[...h].sort((e,t)=>N(t)-N(e)||F(j.react,e.react)-F(j.react,t.react)||F(j["react-dom"],e.react)-F(j["react-dom"],t.react)||F(j["react-router"],e.router)-F(j["react-router"],t.router)||F(j.vite,e.vite)-F(j.vite,t.vite)),C=`React ${j.react??"missing"}${j["react-dom"]!==j.react?` (React DOM ${j["react-dom"]??"missing"})`:""} + Router ${j["react-router"]??"missing"} + Vite ${j.vite??"missing"}`,z=3===N(A);w.push({name:"compatibility",status:z?"ok":"warn",message:z?`${C} is a tested row`:`${C} is not a tested row; closest: React ${A.react} + Router ${A.router} + Vite ${A.vite}`,fix:`Use React and React DOM ${A.react}, React Router ${A.router}, and Vite ${A.vite} for a tested combination.`}),k("node","Use a Node version satisfying the package and app engines (CI uses 22.23.2).",()=>{S.engines?.node&&(D.app=S.engines.node);const e=Object.entries(D).filter(([,e])=>!s.satisfies(process.versions.node,e));if(e.length)throw new Error(`Node ${process.versions.node} does not satisfy ${e.map(([e,t])=>`${e}: ${t}`).join(", ")}`);return`Node ${process.versions.node} satisfies engines`}),k("react-copies","Align React and React DOM versions across dependencies and workspace packages, then dedupe with your package manager (npm dedupe, pnpm dedupe, yarn dedupe).",()=>{const e=b($),t=[...e.react,...e["react-dom"]],s=`React copies: ${e.react.length}; React DOM copies: ${e["react-dom"].length} (${t.map(e=>r.relative($,e)).join(", ")||"none installed"})`;if(1===e.react.length&&1===e["react-dom"].length)return"One physical copy each of React and React DOM";const o=(e=>{try{const t=l(c(e).node,"resolve"),r="ObjectExpression"===t?.type?l(t,"dedupe"):void 0;return"ArrayExpression"===r?.type?r.elements.flatMap(e=>i(e??void 0)??[]):[]}catch{return[]}})($);if(!e.react.length||!e["react-dom"].length||!["react","react-dom"].every(e=>o.includes(e)))throw new Error(s);return`${s}; resolve.dedupe keeps one copy of each in the bundle`});const V=w[w.length-1];let I;V.message.includes("resolve.dedupe")&&(V.status="warn"),k("vite-plugin","Add SsrBoost() from @lomray/vite-ssr-boost/plugin to Vite plugins.",()=>{if(I=c($),!I.plugin)throw new Error("Vite plugins do not contain the imported SsrBoost() plugin");return"SsrBoost() is in the Vite plugins"});const B=I?.viteRoot??(e.existsSync(r.join($,"index.html"))?$:r.join($,"src")),J=r.resolve(B,i(I?.option("indexFile"))??"index.html"),U=i(I?.option("clientFile"))??"client.ts",_=i(I?.option("serverFile"))??"server.ts";k("html-module",'Keep one local <script type="module" src="..."> pointing to the configured clientFile.',()=>{const e=d(J);if(1!==e.entries.length)throw new Error(`${r.relative($,J)}: expected one module script, found ${e.entries.length}`);const t=e.attribute(e.entries[0],"src");if(!t||/^(?:\w+:|\/\/)/.test(t)||r.resolve(t.startsWith("/")?B:r.dirname(J),t.replace(/^\//,""))!==r.resolve(B,U))throw new Error(`${r.relative($,J)}: module script does not match clientFile`);return"Module script matches the browser entry"}),k("html-outlet","Place exactly one \x3c!--ssr-outlet--\x3e inside the root element.",()=>{const e=d(J);if(1!==e.outlets)throw new Error(`${r.relative($,J)}: expected one \x3c!--ssr-outlet--\x3e, found ${e.outlets}`);return"Exactly one SSR outlet"});const W=new f(I?.aliases);for(const[e,t,s]of[["browser",U,"browser/entry"],["server",_,"adapters/express/entry"]])k(`${e}-entry`,`Create the ${e} entry and import ${p}/${s}.`,()=>{if(!W.read(r.resolve(B,t)).ast.program.body.filter(e=>"ImportDeclaration"===e.type).some(e=>e.source.value.replace(/\.js$/,"")===`${p}/${s}`))throw new Error(`${t}: missing library ${s} import`);return"server"===e&&(x.adapter="express"),`${t} imports ${s}`});k("routes","Use statically analyzable route objects; follow the file and line in the parser error.",()=>(x.routes=y(new u(m.init({},{root:B,clientFile:U}),I?.aliases).parse(!0)),`${x.routes.length} route IDs resolved`)),k("scripts",'Add scripts that run "ssr-boost dev", "ssr-boost build" and "ssr-boost start"; any script names work.',()=>{const e=Object.values(S.scripts??{}),t=["dev","build","start"].filter(t=>!e.some(e=>new RegExp(`(?:^|\\s)ssr-boost\\s+${t}(?:\\s|$)`).test(e)));if(t.length)throw new Error(`Scripts missing ssr-boost commands: ${t.join(", ")}`);return"Development, build, and SSR start scripts use ssr-boost"}),k("robots","Review public/robots.txt for your deployment; use build --unlock-robots only when intended.",()=>{const t=i(I?l(I.node,"publicDir"):void 0)??"public",s=r.resolve(B,t,"robots.txt");return e.existsSync(s)?/^Disallow:\s*\/\s*$/im.test(e.readFileSync(s,"utf8"))?"robots.txt blocks crawling at / (report only)":"robots.txt contains a custom/allow policy (report only)":"No robots.txt policy (report only)"},!0),k("size-budget","Add a size:check or test:size script with an application bundle budget.",()=>Object.keys(S.scripts??{}).some(e=>/(?:^|:)size(?::|$)/.test(e))?"Size budget script present":"No size budget script (informational)",!0);const q=I?l(I.node,"build"):void 0,G="ObjectExpression"===q?.type?i(l(q,"outDir")):void 0,K=r.resolve(B,G??"dist","ssr-boost-diagnostics.json");if(e.existsSync(K))try{const t=JSON.parse(e.readFileSync(K,"utf8")),r=t&&"object"==typeof t?Reflect.get(t,"codes"):void 0;x.diagnosticCodes=Array.isArray(r)?o.filter(e=>r.includes(e)):[]}catch{}return x},w=e=>({schemaVersion:1,versions:e.versions,adapter:e.adapter,routes:e.routes,checks:e.checks.map(({name:e,status:t,fix:r,info:s})=>({name:e,status:t,fix:r,...s?{info:s}:{}})),diagnosticCodes:e.diagnosticCodes}),j=(t={})=>{const s=$(t);if(t.bundle)try{e.writeFileSync(r.resolve(t.root??process.cwd(),t.bundle),`${JSON.stringify(w(s),null,2)}\n`)}catch{s.checks.push({name:"bundle",status:"error",message:"Cannot write the support bundle.",fix:"Choose a writable file in an existing directory for --bundle."})}t.json?console.info(JSON.stringify(s,null,2)):console.table(s.checks.map(({status:e,name:t,message:r,fix:s})=>({status:e,check:t,message:r,fix:s}))),process.exitCode=s.checks.some(e=>"error"===e.status)?1:0};export{h as TESTED_MATRIX,j as default,$ as inspectProject,b as reactCopies,w as supportBundle};
1
+ import e from"node:fs";import{createRequire as t}from"node:module";import s from"node:path";import r from"semver";import o from"./diagnostic-codes.js";import{libraryPackage as n,stringValue as i,readPackage as a,readConfig as c,readHtml as d,objectProperty as l}from"./project.js";import p from"../constants/plugin-name.js";import{resolveSsrMaxConcurrency as u}from"../core/admission.js";import m from"../services/parse-routes.js";import f from"../services/server-config.js";import h from"../services/source-files.js";const v=[{react:"18.2.0",router:"7.18.3",vite:"6.4.3"},{react:"19.2.8",router:"7.18.3",vite:"7.3.6"},{react:"19.2.8",router:"8.3.1",vite:"8.2.2"}],g="package.json",b=(t,r)=>{for(let o=t;;o=s.dirname(o)){const t=s.join(o,"node_modules",r);if(e.existsSync(s.join(t,g)))return e.realpathSync(t);if(o===s.dirname(o))return}},y=t=>{const r={react:new Set,"react-dom":new Set},o=new Set,n=(e,t)=>{for(const i of t){const t=b(e,i);if(!t||o.has(t))continue;o.add(t),"react"!==i&&"react-dom"!==i||r[i].add(t);const{dependencies:c,peerDependencies:d}=a(s.join(t,g));n(t,Object.keys({...c,...d}))}},{dependencies:i,devDependencies:c}=a(s.join(t,g));return n(e.realpathSync(t),Object.keys({...i,...c})),{react:[...r.react],"react-dom":[...r["react-dom"]]}},$=(e,t="")=>e.flatMap(e=>{const s=[t,String(e.index)].filter(Boolean).join("-");return[{id:e.id??s,path:e.path??null},...$(e.children,s)]}),w=(b={})=>{const w=s.resolve(b.root??process.cwd()),j=[],R={node:process.versions.node},S={versions:R,adapter:null,routes:[],checks:j,diagnosticCodes:[]},x=(e,t,s,r=!1)=>{try{j.push({name:e,status:"ok",message:s(),fix:t,...r?{info:r}:{}})}catch(s){j.push({name:e,status:"error",message:s.message,fix:t,...r?{info:r}:{}})}};let k={};x("package","Run doctor in the app directory or set --root.",()=>(k=a(s.join(w,g)),"package.json is readable"));const C=t(s.join(w,g)),N=[p,"react","react-dom","react-router","vite"],E=n(),O={[p]:E.engines.node},M={app:k.peerDependencies??{}};for(const e of N)x(`version:${e}`,`Install ${e} at a version satisfying the installed packages’ peer ranges.`,()=>{const t=a(C.resolve(`${e}/package.json`)),s=r.valid(t.version);if(M[e]=t.peerDependencies??(e===p?E.peerDependencies??{}:{}),R[e]=s,!s)throw new Error(`${e} has no valid installed version`);return t.engines?.node&&(O[e]=t.engines.node),`${e} ${s}`}),R[e]??=null;for(const e of j.filter(e=>e.name.startsWith("version:")&&"ok"===e.status)){const t=e.name.slice(8),s=Object.entries(M).flatMap(([e,s])=>s[t]&&!r.satisfies(R[t],s[t])?[`${e} requires ${t}: ${s[t]}`]:[]);s.length&&(e.status="error",e.message+=`; ${s.join("; ")}`)}const D=e=>Number(R.react===e.react&&R["react-dom"]===e.react)+Number(R["react-router"]===e.router)+Number(R.vite===e.vite),A=(e,t)=>{const s=r.parse(e),o=r.parse(t);return s?1e6*Math.abs(s.major-o.major)+1e3*Math.abs(s.minor-o.minor)+Math.abs(s.patch-o.patch):Number.MAX_SAFE_INTEGER},[_]=[...v].sort((e,t)=>D(t)-D(e)||A(R.react,e.react)-A(R.react,t.react)||A(R["react-dom"],e.react)-A(R["react-dom"],t.react)||A(R["react-router"],e.router)-A(R["react-router"],t.router)||A(R.vite,e.vite)-A(R.vite,t.vite)),F=`React ${R.react??"missing"}${R["react-dom"]!==R.react?` (React DOM ${R["react-dom"]??"missing"})`:""} + Router ${R["react-router"]??"missing"} + Vite ${R.vite??"missing"}`,U=3===D(_);j.push({name:"compatibility",status:U?"ok":"warn",message:U?`${F} is a tested row`:`${F} is not a tested row; closest: React ${_.react} + Router ${_.router} + Vite ${_.vite}`,fix:`Use React and React DOM ${_.react}, React Router ${_.router}, and Vite ${_.vite} for a tested combination.`}),x("node","Use a Node version satisfying the package and app engines (CI uses 22.23.2).",()=>{k.engines?.node&&(O.app=k.engines.node);const e=Object.entries(O).filter(([,e])=>!r.satisfies(process.versions.node,e));if(e.length)throw new Error(`Node ${process.versions.node} does not satisfy ${e.map(([e,t])=>`${e}: ${t}`).join(", ")}`);return`Node ${process.versions.node} satisfies engines`}),x("react-copies","Align React and React DOM versions across dependencies and workspace packages, then dedupe with your package manager (npm dedupe, pnpm dedupe, yarn dedupe).",()=>{const e=y(w),t=[...e.react,...e["react-dom"]],r=`React copies: ${e.react.length}; React DOM copies: ${e["react-dom"].length} (${t.map(e=>s.relative(w,e)).join(", ")||"none installed"})`;if(1===e.react.length&&1===e["react-dom"].length)return"One physical copy each of React and React DOM";const o=(e=>{try{const t=l(c(e).node,"resolve"),s="ObjectExpression"===t?.type?l(t,"dedupe"):void 0;return"ArrayExpression"===s?.type?s.elements.flatMap(e=>i(e??void 0)??[]):[]}catch{return[]}})(w);if(!e.react.length||!e["react-dom"].length||!["react","react-dom"].every(e=>o.includes(e)))throw new Error(r);return`${r}; resolve.dedupe keeps one copy of each in the bundle`});const z=j[j.length-1];let V;z.message.includes("resolve.dedupe")&&(z.status="warn"),x("vite-plugin","Add SsrBoost() from @lomray/vite-ssr-boost/plugin to Vite plugins.",()=>{if(V=c(w),!V.plugin)throw new Error("Vite plugins do not contain the imported SsrBoost() plugin");return"SsrBoost() is in the Vite plugins"});const X=V?.viteRoot??(e.existsSync(s.join(w,"index.html"))?w:s.join(w,"src")),I=s.resolve(X,i(V?.option("indexFile"))??"index.html"),Y=i(V?.option("clientFile"))??"client.ts",B=i(V?.option("serverFile"))??"server.ts";x("html-module",'Keep one local <script type="module" src="..."> pointing to the configured clientFile.',()=>{const e=d(I);if(1!==e.entries.length)throw new Error(`${s.relative(w,I)}: expected one module script, found ${e.entries.length}`);const t=e.attribute(e.entries[0],"src");if(!t||/^(?:\w+:|\/\/)/.test(t)||s.resolve(t.startsWith("/")?X:s.dirname(I),t.replace(/^\//,""))!==s.resolve(X,Y))throw new Error(`${s.relative(w,I)}: module script does not match clientFile`);return"Module script matches the browser entry"}),x("html-outlet","Place exactly one \x3c!--ssr-outlet--\x3e inside the root element.",()=>{const e=d(I);if(1!==e.outlets)throw new Error(`${s.relative(w,I)}: expected one \x3c!--ssr-outlet--\x3e, found ${e.outlets}`);return"Exactly one SSR outlet"});const J=new h(V?.aliases);for(const[e,t,r]of[["browser",Y,"browser/entry"],["server",B,"adapters/express/entry"]])x(`${e}-entry`,`Create the ${e} entry and import ${p}/${r}.`,()=>{if(!J.read(s.resolve(X,t)).ast.program.body.filter(e=>"ImportDeclaration"===e.type).some(e=>e.source.value.replace(/\.js$/,"")===`${p}/${r}`))throw new Error(`${t}: missing library ${r} import`);return"server"===e&&(S.adapter="express"),`${t} imports ${r}`});x("routes","Use statically analyzable route objects; follow the file and line in the parser error.",()=>(S.routes=$(new m(f.init({},{root:X,clientFile:Y}),V?.aliases).parse(!0)),`${S.routes.length} route IDs resolved`)),x("scripts",'Add scripts that run "ssr-boost dev", "ssr-boost build" and "ssr-boost start"; any script names work.',()=>{const e=Object.values(k.scripts??{}),t=["dev","build","start"].filter(t=>!e.some(e=>new RegExp(`(?:^|\\s)ssr-boost\\s+${t}(?:\\s|$)`).test(e)));if(t.length)throw new Error(`Scripts missing ssr-boost commands: ${t.join(", ")}`);return"Development, build, and SSR start scripts use ssr-boost"}),x("robots","Review public/robots.txt for your deployment; use build --unlock-robots only when intended.",()=>{const t=i(V?l(V.node,"publicDir"):void 0)??"public",r=s.resolve(X,t,"robots.txt");return e.existsSync(r)?/^Disallow:\s*\/\s*$/im.test(e.readFileSync(r,"utf8"))?"robots.txt blocks crawling at / (report only)":"robots.txt contains a custom/allow policy (report only)":"No robots.txt policy (report only)"},!0),x("ssr-admission","Set SSR_MAX_CONCURRENCY to a positive safe integer to bound concurrent SSR renders.",()=>{const e=process.env.SSR_MAX_CONCURRENCY;return void 0===e?"SSR_MAX_CONCURRENCY is not set (admission environment override disabled)":void 0===u(e)?"SSR_MAX_CONCURRENCY is set but invalid (override ignored)":"SSR_MAX_CONCURRENCY is set and valid"},!0),x("size-budget","Add a size:check or test:size script with an application bundle budget.",()=>Object.keys(k.scripts??{}).some(e=>/(?:^|:)size(?::|$)/.test(e))?"Size budget script present":"No size budget script (informational)",!0);const W=V?l(V.node,"build"):void 0,q="ObjectExpression"===W?.type?i(l(W,"outDir")):void 0,G=s.resolve(X,q??"dist","ssr-boost-diagnostics.json");if(e.existsSync(G))try{const t=JSON.parse(e.readFileSync(G,"utf8")),s=t&&"object"==typeof t?Reflect.get(t,"codes"):void 0;S.diagnosticCodes=Array.isArray(s)?o.filter(e=>s.includes(e)):[]}catch{}return S},j=e=>({schemaVersion:1,versions:e.versions,adapter:e.adapter,routes:e.routes,checks:e.checks.map(({name:e,status:t,fix:s,info:r})=>({name:e,status:t,fix:s,...r?{info:r}:{}})),diagnosticCodes:e.diagnosticCodes}),R=(t={})=>{const r=w(t);if(t.bundle)try{e.writeFileSync(s.resolve(t.root??process.cwd(),t.bundle),`${JSON.stringify(j(r),null,2)}\n`)}catch{r.checks.push({name:"bundle",status:"error",message:"Cannot write the support bundle.",fix:"Choose a writable file in an existing directory for --bundle."})}t.json?console.info(JSON.stringify(r,null,2)):console.table(r.checks.map(({status:e,name:t,message:s,fix:r})=>({status:e,check:t,message:s,fix:r}))),process.exitCode=r.checks.some(e=>"error"===e.status)?1:0};export{v as TESTED_MATRIX,R as default,w as inspectProject,y as reactCopies,j as supportBundle};
2
2
  //# sourceMappingURL=doctor.js.map
package/cli/doctor.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sources":["../../src/cli/doctor.ts"],"sourcesContent":[null],"names":["TESTED_MATRIX","react","router","vite","PACKAGE_FILE","packageDirectory","from","name","directory","path","dirname","candidate","join","fs","existsSync","realpathSync","reactCopies","root","copies","Set","visited","visit","names","location","has","add","dependencies","peerDependencies","readPackage","Object","keys","devDependencies","routeDetails","routes","parent","flatMap","route","position","String","index","filter","Boolean","id","children","inspectProject","options","resolve","process","cwd","checks","versions","node","report","adapter","diagnosticCodes","check","fix","inspect","info","push","status","message","error","pkg","require","createRequire","packages","PLUGIN_NAME","ownPackage","libraryPackage","engines","peers","app","metadata","version","semver","valid","Error","item","row","startsWith","slice","failures","entries","dependant","ranges","satisfies","length","matches","Number","distance","installed","tested","parse","target","Math","abs","major","minor","patch","MAX_SAFE_INTEGER","closest","sort","left","right","trio","isTested","range","map","locations","summary","relative","dedupe","objectProperty","readConfig","type","undefined","elements","element","stringValue","viteDedupe","every","includes","copiesCheck","config","plugin","viteRoot","indexFile","option","clientFile","serverFile","html","readHtml","src","attribute","test","replace","outlets","sources","SourceFiles","aliases","kind","file","expected","read","ast","program","body","some","source","value","ParseRoutes","ServerConfig","init","scripts","values","missing","command","RegExp","publicDir","readFileSync","build","outDir","diagnosticsFile","recorded","JSON","codes","Reflect","get","Array","isArray","DIAGNOSTIC_CODES","code","supportBundle","schemaVersion","runDoctor","bundle","writeFileSync","stringify","json","console","table","exitCode"],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sources":["../../src/cli/doctor.ts"],"sourcesContent":[null],"names":["TESTED_MATRIX","react","router","vite","PACKAGE_FILE","packageDirectory","from","name","directory","path","dirname","candidate","join","fs","existsSync","realpathSync","reactCopies","root","copies","Set","visited","visit","names","location","has","add","dependencies","peerDependencies","readPackage","Object","keys","devDependencies","routeDetails","routes","parent","flatMap","route","position","String","index","filter","Boolean","id","children","inspectProject","options","resolve","process","cwd","checks","versions","node","report","adapter","diagnosticCodes","check","fix","inspect","info","push","status","message","error","pkg","require","createRequire","packages","PLUGIN_NAME","ownPackage","libraryPackage","engines","peers","app","metadata","version","semver","valid","Error","item","row","startsWith","slice","failures","entries","dependant","ranges","satisfies","length","matches","Number","distance","installed","tested","parse","target","Math","abs","major","minor","patch","MAX_SAFE_INTEGER","closest","sort","left","right","trio","isTested","range","map","locations","summary","relative","dedupe","objectProperty","readConfig","type","undefined","elements","element","stringValue","viteDedupe","every","includes","copiesCheck","config","plugin","viteRoot","indexFile","option","clientFile","serverFile","html","readHtml","src","attribute","test","replace","outlets","sources","SourceFiles","aliases","kind","file","expected","read","ast","program","body","some","source","value","ParseRoutes","ServerConfig","init","scripts","values","missing","command","RegExp","publicDir","readFileSync","env","SSR_MAX_CONCURRENCY","resolveSsrMaxConcurrency","build","outDir","diagnosticsFile","recorded","JSON","codes","Reflect","get","Array","isArray","DIAGNOSTIC_CODES","code","supportBundle","schemaVersion","runDoctor","bundle","writeFileSync","stringify","json","console","table","exitCode"],"mappings":"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"}
package/cloudflare.js CHANGED
@@ -1,2 +1,2 @@
1
- import{createElement as e}from"react";import{createStaticHandler as t}from"react-router";import s from"./core/handler.js";import r from"./core/head-response.js";import o from"./edge/render-to-stream.js";import{splitHtmlShell as n}from"./services/diagnostics.js";import a from"./services/route-asset-preparer.js";import i from"./services/route-assets-memory.js";const c="Cache-Control",d=new WeakMap,m=(e,t)=>{const s=Reflect.get(e,t);if(!s||"function"!=typeof s.fetch)throw new Error(`[ssr-boost] Missing Workers assets binding "${t}".`);return s},l=async(e,t="/index.html",s="ASSETS",r="\x3c!--ssr-outlet--\x3e")=>{const o=m(e,s);let a=d.get(o);a||(a=new Map,d.set(o,a));const i=JSON.stringify([t,r]);let c=a.get(i);return c||(c=(async()=>{const e=await o.fetch(new Request(new URL(t,"https://assets.local"))),{ok:s,body:a,status:i}=e;if(!s)throw await(a?.cancel()),new Error(`[ssr-boost] Failed to load "${t}" from assets: ${i}.`);const[c,d]=n(await e.text(),t,r);return()=>({header:c,footer:d})})(),a.set(i,c),c.catch(()=>a.delete(i))),c},p=({routes:d,App:l,manifest:p,getHtml:u,indexHtml:f,routerOptions:w,onRequest:h,onRouterReady:g,onShellReady:x,prepare:y,assets:R="ASSETS",modulePreload:S=!1,outlet:b="\x3c!--ssr-outlet--\x3e",...v})=>{const E=t(d,w),A=a(new i(p,S)),j=void 0===f?void 0:n(f,"indexHtml",b);return async(t,n,a)=>{const{url:i,method:d,headers:p}=t,{pathname:f}=new URL(i);if(!1!==R&&["GET","HEAD"].includes(d)&&"/"!==f&&"/index.html"!==f){const e=await m(n,R).fetch(t),{status:s,ok:o,headers:a,body:i,statusText:d}=e;if(404!==s){if((o||304===s)&&/\/assets\/[^/]+-[\w-]{8,}\.[^/]+$/.test(f)){const e=new Headers(a);return e.set(c,"public, max-age=31536000, immutable"),r(t,new Response(i,{status:s,statusText:d,headers:e}))}return r(t,e)}await(i?.cancel())}const w={platform:{env:n,ctx:a},waitUntil:a.waitUntil.bind(a)};return s({handler:E,createApp:(t,s)=>e(l,{server:s.appProps},t),renderToStream:o},{diagnostics:!1,...v,getHtml:()=>u?u(t,n,a):{header:j[0],footer:j[1]},onRequest:h?()=>h({request:t,executionContext:w}):void 0,prepare:async e=>{await A(e),await(y?.(e))},onShellReady:e=>{const{context:t}=e,{isStream:s,response:r}=t,{headers:o}=r;return s&&!o.has("Content-Encoding")&&(o.set("Content-Encoding","identity"),o.get(c)?.includes("no-transform")||o.append(c,"no-transform")),x?.(e)??{}},onRouterReady:async e=>({isStream:!/bot|crawler|spider|slurp|bingpreview/i.test(p.get("User-Agent")??""),...await(g?.(e))})})(t,w)}};export{i as RouteAssets,p as createWorkerHandler,l as getHtmlFromAssets};
1
+ import{createElement as e}from"react";import{createStaticHandler as t}from"react-router";import s from"./core/handler.js";import r from"./core/handler-runtime.js";import o from"./core/head-response.js";import n from"./edge/render-to-stream.js";import{splitHtmlShell as a}from"./services/diagnostics.js";import i from"./services/route-asset-preparer.js";import c from"./services/route-assets-memory.js";const d="Cache-Control",m=new WeakMap,u=(e,t)=>{const s=Reflect.get(e,t);if(!s||"function"!=typeof s.fetch)throw new Error(`[ssr-boost] Missing Workers assets binding "${t}".`);return s},l=async(e,t="/index.html",s="ASSETS",r="\x3c!--ssr-outlet--\x3e")=>{const o=u(e,s);let n=m.get(o);n||(n=new Map,m.set(o,n));const i=JSON.stringify([t,r]);let c=n.get(i);return c||(c=(async()=>{const e=await o.fetch(new Request(new URL(t,"https://assets.local"))),{ok:s,body:n,status:i}=e;if(!s)throw await(n?.cancel()),new Error(`[ssr-boost] Failed to load "${t}" from assets: ${i}.`);const[c,d]=a(await e.text(),t,r);return()=>({header:c,footer:d})})(),n.set(i,c),c.catch(()=>n.delete(i))),c},p=({routes:m,App:l,manifest:p,getHtml:f,indexHtml:w,routerOptions:h,onRequest:g,onRouterReady:x,onShellReady:y,prepare:R,assets:b="ASSETS",modulePreload:S=!1,outlet:v="\x3c!--ssr-outlet--\x3e",...E})=>{const j=t(m,h),A=new r(j.dataRoutes,{...E,basename:h?.basename??E.basename}),H=i(new c(p,S)),T=void 0===w?void 0:a(w,"indexHtml",v);return async(t,r,a)=>{const{url:i,method:c,headers:m}=t,{pathname:p}=new URL(i);if(!1!==b&&["GET","HEAD"].includes(c)&&"/"!==p&&"/index.html"!==p){const e=await u(r,b).fetch(t),{status:s,ok:n,headers:a,body:i,statusText:c}=e;if(404!==s){if((n||304===s)&&/\/assets\/[^/]+-[\w-]{8,}\.[^/]+$/.test(p)){const e=new Headers(a);return e.set(d,"public, max-age=31536000, immutable"),o(t,new Response(i,{status:s,statusText:c,headers:e}))}return o(t,e)}await(i?.cancel())}const w={platform:{env:r,ctx:a},waitUntil:a.waitUntil.bind(a)};return s({handler:j,createApp:(t,s)=>e(l,{server:s.appProps},t),renderToStream:n},{diagnostics:!1,...E,getHtml:e=>f?f(e,r,a):{header:T[0],footer:T[1]},onRequest:g?({request:e})=>g({request:e,executionContext:w}):void 0,prepare:async e=>{await H(e),await(R?.(e))},onShellReady:e=>{const{context:t}=e,{isStream:s,response:r}=t,{headers:o}=r;return s&&!o.has("Content-Encoding")&&(o.set("Content-Encoding","identity"),o.get(d)?.includes("no-transform")||o.append(d,"no-transform")),y?.(e)??{}},onRouterReady:async e=>({isStream:!/bot|crawler|spider|slurp|bingpreview/i.test(m.get("User-Agent")??""),...await(x?.(e))})},A)(t,w)}};export{c as RouteAssets,p as createWorkerHandler,l as getHtmlFromAssets};
2
2
  //# sourceMappingURL=cloudflare.js.map
package/cloudflare.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cloudflare.js","sources":["../src/cloudflare.ts"],"sourcesContent":[null],"names":["CACHE_CONTROL","htmlCache","WeakMap","getAssetsBinding","env","name","binding","Reflect","get","fetch","Error","getHtmlFromAssets","async","indexPath","bindingName","outlet","cache","Map","set","key","JSON","stringify","pending","response","Request","URL","ok","isOk","body","status","cancel","header","footer","splitHtmlShell","text","catch","delete","createWorkerHandler","routes","App","manifest","getHtml","indexHtml","routerOptions","onRequest","onRouterReady","onShellReady","prepare","assets","modulePreload","options","handler","createStaticHandler","prepareAssets","createAssetPreparer","RouteAssets","shell","undefined","request","ctx","url","method","headers","requestHeaders","pathname","includes","responseHeaders","statusText","test","Headers","headResponse","Response","executionContext","platform","waitUntil","bind","createHandler","createApp","children","context","createElement","server","appProps","renderToStream","diagnostics","params","isStream","has","append","render"],"mappings":"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"}
1
+ {"version":3,"file":"cloudflare.js","sources":["../src/cloudflare.ts"],"sourcesContent":[null],"names":["CACHE_CONTROL","htmlCache","WeakMap","getAssetsBinding","env","name","binding","Reflect","get","fetch","Error","getHtmlFromAssets","async","indexPath","bindingName","outlet","cache","Map","set","key","JSON","stringify","pending","response","Request","URL","ok","isOk","body","status","cancel","header","footer","splitHtmlShell","text","catch","delete","createWorkerHandler","routes","App","manifest","getHtml","indexHtml","routerOptions","onRequest","onRouterReady","onShellReady","prepare","assets","modulePreload","options","handler","createStaticHandler","runtime","HandlerRuntime","dataRoutes","basename","prepareAssets","createAssetPreparer","RouteAssets","shell","undefined","request","ctx","url","method","headers","requestHeaders","pathname","includes","responseHeaders","statusText","test","Headers","headResponse","Response","executionContext","platform","waitUntil","bind","createHandler","createApp","children","context","createElement","server","appProps","renderToStream","diagnostics","renderRequest","params","isStream","has","append","render"],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ export interface IAdmissionEvent {
2
+ /** Admission or terminal render outcome. */
3
+ outcome: 'admitted' | 'rejected' | 'finish' | 'abort' | 'error';
4
+ /** Slots still occupied after this event. */
5
+ active: number;
6
+ /** Elapsed monotonic time for a terminal outcome. */
7
+ durationMs?: number;
8
+ }
9
+ export type TAdmissionOverload = 'reject' | 'spa' | Response | ((request: Request) => Response | Promise<Response>);
10
+ export interface IAdmissionOptions {
11
+ /** Positive safe integer; a valid SSR_MAX_CONCURRENCY overrides this value. */
12
+ maxConcurrency?: number;
13
+ /** Respond immediately at capacity. Default: reject. */
14
+ overload?: TAdmissionOverload;
15
+ /** Best-effort lifecycle observation. */
16
+ onEvent?: (event: IAdmissionEvent) => void;
17
+ }
18
+ export interface IAdmissionSlot {
19
+ /** Release exactly once, including races between abort and stream completion. */
20
+ release: (outcome: 'finish' | 'abort' | 'error') => void;
21
+ /** Observe the final response stream under consumer backpressure. */
22
+ response: (response: Response) => Response;
23
+ }
24
+ /** Invalid or absent environment values leave admission disabled. */
25
+ export declare const resolveSsrMaxConcurrency: (value?: string) => number | undefined;
26
+ /** Read process defensively; Workers may have no process or env object. */
27
+ export declare const readSsrMaxConcurrency: () => number | undefined;
28
+ /** Bound real React renders without a queue or work on the disabled path. */
29
+ declare class Admission {
30
+ /** Maximum simultaneously occupied slots. */
31
+ protected readonly limit: number;
32
+ /** Startup overload behavior and observation hook. */
33
+ protected readonly options: IAdmissionOptions;
34
+ /** Currently occupied render slots. */
35
+ protected activeCount: number;
36
+ /** Snapshot the concurrency limit and overload policy at startup. */
37
+ constructor(
38
+ /** Maximum simultaneously occupied slots. */
39
+ limit: number,
40
+ /** Startup overload behavior and observation hook. */
41
+ options?: IAdmissionOptions);
42
+ /** Expose occupancy for diagnostics and tests. */
43
+ get activeRequests(): number;
44
+ /** Select the immediate overload response. */
45
+ get overload(): TAdmissionOverload;
46
+ /** Acquire immediately before React starts, without queuing excess work. */
47
+ tryAcquire(signal?: AbortSignal): IAdmissionSlot | undefined;
48
+ /** Minimal overload response, including HEAD semantics. */
49
+ reject(request: Request): Promise<Response>;
50
+ /** Instrumentation must not interrupt rendering or release. */
51
+ protected emit(event: IAdmissionEvent): void;
52
+ }
53
+ export default Admission;
@@ -0,0 +1,2 @@
1
+ const e=e=>{const t=Number(e);return Number.isSafeInteger(t)&&t>0?t:void 0},t=()=>{try{return e(globalThis.process?.env?.SSR_MAX_CONCURRENCY)}catch{return}};class r{limit;options;activeCount=0;constructor(e,t={}){if(this.limit=e,this.options=t,!Number.isSafeInteger(e)||e<=0)throw new Error("SSR concurrency limit must be a positive integer.")}get activeRequests(){return this.activeCount}get overload(){return this.options.overload??"reject"}tryAcquire(e){if(this.activeCount>=this.limit)return void this.emit({outcome:"rejected",active:this.activeCount});const t=performance.now();let r=!1;this.activeCount+=1,this.emit({outcome:"admitted",active:this.activeCount});const o=o=>{r||(r=!0,e?.removeEventListener("abort",n),this.activeCount-=1,this.emit({outcome:o,active:this.activeCount,durationMs:performance.now()-t}))},n=()=>o("abort");return e?.aborted?n():e?.addEventListener("abort",n,{once:!0}),{release:o,response:e=>{if(!e.body)return o("finish"),e;const t=e.body.getReader();let r=!1;const n=new ReadableStream({cancel:async e=>{r=!0,o("abort");try{await t.cancel(e)}finally{t.releaseLock()}},pull:async e=>{try{const{done:n,value:i}=await t.read();if(r)return;n?(r=!0,t.releaseLock(),o("finish"),e.close()):e.enqueue(i)}catch(n){r||(r=!0,t.releaseLock(),o("error"),e.error(n))}}},{highWaterMark:0});return new Response(n,e)}}}async reject(e){const{overload:t}=this,r=new Headers({"Content-Type":"text/plain; charset=utf-8","Cache-Control":"private, no-store","Retry-After":"1"});let o="Service Unavailable";if("function"==typeof t||t instanceof Response){const n=("function"==typeof t?await t(e):t).clone();n.headers.forEach((e,t)=>r.set(t,e)),r.set("Cache-Control","private, no-store"),o=await n.arrayBuffer()}return new Response("HEAD"===e.method?null:o,{status:503,headers:r})}emit(e){try{this.options.onEvent?.(e)}catch{}}}export{r as default,t as readSsrMaxConcurrency,e as resolveSsrMaxConcurrency};
2
+ //# sourceMappingURL=admission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admission.js","sources":["../../src/core/admission.ts"],"sourcesContent":[null],"names":["resolveSsrMaxConcurrency","value","parsed","Number","isSafeInteger","undefined","readSsrMaxConcurrency","globalThis","process","env","SSR_MAX_CONCURRENCY","Admission","limit","options","activeCount","constructor","this","Error","activeRequests","overload","tryAcquire","signal","emit","outcome","active","started","performance","now","isReleased","release","removeEventListener","onAbort","durationMs","aborted","addEventListener","once","response","body","reader","getReader","isStopped","ReadableStream","cancel","async","reason","releaseLock","pull","controller","done","isDone","read","close","enqueue","error","highWaterMark","Response","reject","request","headers","Headers","custom","clone","forEach","name","set","arrayBuffer","method","status","event","onEvent"],"mappings":"AA6BO,MAAMA,EAA4BC,IACvC,MAAMC,EAASC,OAAOF,GAEtB,OAAOE,OAAOC,cAAcF,IAAWA,EAAS,EAAIA,OAASG,GAIlDC,EAAwB,KACnC,IACE,OAAON,EAAyBO,WAAWC,SAASC,KAAKC,oBAC3D,CAAE,MACA,MACF,GAIF,MAAMC,EAOiBC,MAEAC,QAPXC,YAAc,EAGxB,WAAAC,CAEqBH,EAEAC,EAA6B,CAAA,GAEhD,GAJmBG,KAAAJ,MAAAA,EAEAI,KAAAH,QAAAA,GAEdV,OAAOC,cAAcQ,IAAUA,GAAS,EAC3C,MAAM,IAAIK,MAAM,oDAEpB,CAGA,kBAAWC,GACT,OAAOF,KAAKF,WACd,CAGA,YAAWK,GACT,OAAOH,KAAKH,QAAQM,UAAY,QAClC,CAGO,UAAAC,CAAWC,GAChB,GAAIL,KAAKF,aAAeE,KAAKJ,MAG3B,YAFAI,KAAKM,KAAK,CAAEC,QAAS,WAAYC,OAAQR,KAAKF,cAKhD,MAAMW,EAAUC,YAAYC,MAC5B,IAAIC,GAAa,EAEjBZ,KAAKF,aAAe,EACpBE,KAAKM,KAAK,CAAEC,QAAS,WAAYC,OAAQR,KAAKF,cAG9C,MAAMe,EAAsCN,IACtCK,IAIJA,GAAa,EACbP,GAAQS,oBAAoB,QAASC,GACrCf,KAAKF,aAAe,EACpBE,KAAKM,KAAK,CAAEC,UAASC,OAAQR,KAAKF,YAAakB,WAAYN,YAAYC,MAAQF,MAI3EM,EAAU,IAAYF,EAAQ,SAQpC,OANIR,GAAQY,QACVF,IAEAV,GAAQa,iBAAiB,QAASH,EAAS,CAAEI,MAAM,IAG9C,CACLN,UAEAO,SAAWA,IACT,IAAKA,EAASC,KAGZ,OAFAR,EAAQ,UAEDO,EAGT,MAAME,EAASF,EAASC,KAAKE,YAC7B,IAAIC,GAAY,EAChB,MAAMH,EAAO,IAAII,eACf,CAEEC,OAAQC,MAAOC,IACbJ,GAAY,EACZX,EAAQ,SAER,UACQS,EAAOI,OAAOE,EACtB,SACEN,EAAOO,aACT,GAGFC,KAAMH,MAAOI,IACX,IACE,MAAQC,KAAMC,EAAMhD,MAAEA,SAAgBqC,EAAOY,OAE7C,GAAIV,EACF,OAGES,GACFT,GAAY,EACZF,EAAOO,cACPhB,EAAQ,UACRkB,EAAWI,SAEXJ,EAAWK,QAAQnD,EAEvB,CAAE,MAAOoD,GACFb,IACHA,GAAY,EACZF,EAAOO,cACPhB,EAAQ,SACRkB,EAAWM,MAAMA,GAErB,IAGJ,CAAEC,cAAe,IAGnB,OAAO,IAAIC,SAASlB,EAAMD,IAGhC,CAGO,YAAMoB,CAAOC,GAClB,MAAMtC,SAAEA,GAAaH,KACf0C,EAAU,IAAIC,QAAQ,CAC1B,eAAgB,4BAChB,gBAAiB,oBACjB,cAAe,MAEjB,IAAItB,EAAwB,sBAG5B,GAAwB,mBAAblB,GAA2BA,aAAoBoC,SAAU,CAClE,MAAMK,GAA8B,mBAAbzC,QAAgCA,EAASsC,GAAWtC,GAAU0C,QAErFD,EAAOF,QAAQI,QAAQ,CAAC7D,EAAO8D,IAASL,EAAQM,IAAID,EAAM9D,IAC1DyD,EAAQM,IAAI,gBAAiB,qBAC7B3B,QAAauB,EAAOK,aACtB,CAEA,OAAO,IAAIV,SAA4B,SAAnBE,EAAQS,OAAoB,KAAO7B,EAAM,CAAE8B,OAAQ,IAAKT,WAC9E,CAGU,IAAApC,CAAK8C,GACb,IACEpD,KAAKH,QAAQwD,UAAUD,EACzB,CAAE,MAEF,CACF"}
@@ -0,0 +1,39 @@
1
+ import type { StaticHandler } from 'react-router';
2
+ import Admission from './admission.js';
3
+ import type { IAdmissionOptions } from './admission.js';
4
+ import NotFoundCache from './not-found.js';
5
+ import type { TNotFoundOptions } from './not-found.js';
6
+ import RequestGuard from './request-guard.js';
7
+ import type { IRequestGuardOptions } from './request-guard.js';
8
+ import SsrPolicy from './ssr-policy.js';
9
+ import type { ISsrPolicy } from './ssr-policy.js';
10
+ export interface IHandlerRuntimeOptions {
11
+ /** Default-on document request validation; false preserves the previous pipeline. */
12
+ requestGuard?: IRequestGuardOptions | false;
13
+ /** Missing-route document behavior. Default: render. */
14
+ notFound?: TNotFoundOptions;
15
+ /** Optional real-render concurrency limit. */
16
+ admission?: IAdmissionOptions;
17
+ /** Route rendering policy. */
18
+ ssr?: ISsrPolicy;
19
+ /** Must match createStaticHandler's basename. */
20
+ basename?: string;
21
+ }
22
+ /** Shared startup state for adapters whose per-request hooks capture transport metadata. */
23
+ declare class HandlerRuntime {
24
+ /** Default-on request validation. */
25
+ readonly guard?: RequestGuard;
26
+ /** Optional bounded anonymous 404 cache. */
27
+ readonly cache?: NotFoundCache;
28
+ /** Absent entirely when no valid limit is configured. */
29
+ readonly admission?: Admission;
30
+ /** Compiled policy and bot handling. */
31
+ readonly policy: SsrPolicy;
32
+ /** Reuse the current document template's SPA shell. */
33
+ readonly spaShell: (html: import("./handler.js").IHtmlShell) => import("./handler.js").IHtmlShell;
34
+ /** Selected 404 behavior. */
35
+ readonly notFound: TNotFoundOptions;
36
+ /** Snapshot environment and application options once per handler/entry. */
37
+ constructor(dataRoutes: StaticHandler['dataRoutes'], { requestGuard, notFound, admission, ssr, basename }?: IHandlerRuntimeOptions);
38
+ }
39
+ export default HandlerRuntime;
@@ -0,0 +1,2 @@
1
+ import o,{readSsrMaxConcurrency as s}from"./admission.js";import e from"./not-found.js";import n from"./request-guard.js";import r from"./spa-shell.js";import i from"./ssr-policy.js";class t{guard;cache;admission;policy;spaShell=r();notFound;constructor(r,{requestGuard:t,notFound:a="render",admission:c,ssr:d,basename:m}={}){this.policy=new i(d,r,m),this.notFound=a;const p=s()??c?.maxConcurrency;!1!==t&&(this.guard=new n(r,t,m),"cached"!==a&&("object"!=typeof a||a instanceof Response)||(this.cache=new e("cached"===a?void 0:a))),void 0!==p&&(this.admission=new o(p,c))}}export{t as default};
2
+ //# sourceMappingURL=handler-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler-runtime.js","sources":["../../src/core/handler-runtime.ts"],"sourcesContent":[null],"names":["HandlerRuntime","guard","cache","admission","policy","spaShell","createSpaShell","notFound","constructor","dataRoutes","requestGuard","ssr","basename","this","SsrPolicy","limit","readSsrMaxConcurrency","maxConcurrency","RequestGuard","Response","NotFoundCache","undefined","Admission"],"mappings":"uLAyBA,MAAMA,EAEYC,MAEAC,MAEAC,UAEAC,OAEAC,SAAWC,IAEXC,SAGhB,WAAAC,CACEC,GACAC,aAAEA,EAAYH,SAAEA,EAAW,SAAQJ,UAAEA,EAASQ,IAAEA,EAAGC,SAAEA,GAAqC,IAE1FC,KAAKT,OAAS,IAAIU,EAAUH,EAAKF,EAAYG,GAC7CC,KAAKN,SAAWA,EAChB,MAAMQ,EAAQC,KAA2Bb,GAAWc,gBAE/B,IAAjBP,IACFG,KAAKZ,MAAQ,IAAIiB,EAAaT,EAAYC,EAAcE,GAGzC,WAAbL,IACqB,iBAAbA,GAA2BA,aAAoBY,YAEvDN,KAAKX,MAAQ,IAAIkB,EAA2B,WAAbb,OAAwBc,EAAYd,UAIzDc,IAAVN,IACFF,KAAKV,UAAY,IAAImB,EAAUP,EAAOZ,GAE1C"}
package/core/handler.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import HandlerRuntime from './handler-runtime.js';
2
+ import type { IHandlerRuntimeOptions } from './handler-runtime.js';
1
3
  import type { ICoreRenderOptions, ICoreRenderParams, ISsrRequestContext } from './render.js';
2
4
  import type { ISsrPolicy } from './ssr-policy.js';
3
5
  import type { ISsrExecutionContext, TSsrHandler } from './types.js';
@@ -10,11 +12,7 @@ interface IRequestInit<TAppProps> {
10
12
  headers?: HeadersInit;
11
13
  status?: number;
12
14
  }
13
- interface ICreateHandlerOptions<TAppProps> extends ICoreRenderOptions<TAppProps> {
14
- /** Select SSR or the SPA shell before running route loaders. */
15
- ssr?: ISsrPolicy;
16
- /** Must match the basename passed to createStaticHandler. */
17
- basename?: string;
15
+ interface ICreateHandlerOptions<TAppProps> extends ICoreRenderOptions<TAppProps>, IHandlerRuntimeOptions {
18
16
  /**
19
17
  * Development checks; defaults to NODE_ENV !== 'production', overridden by SSR_BOOST_DIAGNOSTICS.
20
18
  */
@@ -38,6 +36,9 @@ interface ICreateHandlerOptions<TAppProps> extends ICoreRenderOptions<TAppProps>
38
36
  /**
39
37
  * Create isolated request state and allow request hooks to bypass rendering.
40
38
  */
41
- declare const createHandler: <TAppProps = Record<string, any>>(params: ICoreRenderParams<TAppProps>, { diagnostics, getHtml, onContext, onRequest, ssr, basename, ...options }: ICreateHandlerOptions<TAppProps>) => TSsrHandler;
39
+ declare const createHandler: <TAppProps = Record<string, any>>(params: ICoreRenderParams<TAppProps>, { diagnostics, getHtml, onContext, onRequest, ssr, basename, requestGuard, notFound, admission, ...options }: ICreateHandlerOptions<TAppProps>, runtime?: HandlerRuntime) => TSsrHandler;
42
40
  export type { ICreateHandlerOptions, IHtmlShell, IRequestInit, ISsrPolicy };
43
41
  export default createHandler;
42
+ export type { IAdmissionOptions, IAdmissionEvent, TAdmissionOverload } from './admission.js';
43
+ export type { IRequestGuardOptions, IRequestGuardDecisionContext, TRequestGuardReason, } from './request-guard.js';
44
+ export type { TNotFoundOptions, ICachedNotFoundOptions } from './not-found.js';
package/core/handler.js CHANGED
@@ -1,2 +1,2 @@
1
- import{hasCookie as e}from"./document-headers.js";import s from"./head-response.js";import t from"./render.js";import o from"./spa-shell.js";import r from"./ssr-policy.js";import n,{isDiagnosticsEnabled as a}from"../services/diagnostics.js";import{createTimeline as i}from"../services/request-timeline.js";const c=(c,{diagnostics:p,getHtml:m,onContext:d,onRequest:l,ssr:u,basename:h,...f})=>{const w=new r(u,c.handler.dataRoutes,h),j=o();return async(o,r)=>{const u=a(p),h=i(o,u);try{const a=l?await l({executionContext:r,request:o}):void 0,i=a instanceof Response,p=i?void 0:a,x={appProps:p?.appProps??{},diagnostics:u?new n(new URL(o.url).pathname):void 0,executionContext:r,html:i?{header:"",footer:""}:await m(o),request:o,response:{headers:new Headers(p?.headers),status:p?.status},...h?{timeline:h}:{}};if(d?.({context:x}),i){const{sessionCookie:t}=f;x.diagnostics?.inspectCachePolicy(a.headers,Boolean(t&&e(o,t)));const r=await s(o,a);return h?.response(r)??r}return await t({...c,policy:w,spaShell:j},x,f,r)}catch(e){throw h?.abort(e),h?.end(),e}}};export{c as default};
1
+ import e,{hasCookie as s}from"./document-headers.js";import o from"./handler-runtime.js";import t from"./head-response.js";import n from"./render.js";import r,{isDiagnosticsEnabled as a}from"../services/diagnostics.js";import{createTimeline as i}from"../services/request-timeline.js";const d=(d,{diagnostics:c,getHtml:u,onContext:p,onRequest:m,ssr:h,basename:l,requestGuard:f,notFound:C,admission:w,...x},v=new o(d.handler.dataRoutes,{ssr:h,basename:l,requestGuard:f,notFound:C,admission:w}))=>{const{guard:y,cache:H}=v,g=d.policy??v.policy,q=d.spaShell??v.spaShell;return async(o,h)=>{const l=a(c),f=i(o,l);try{const a=await(y?.handle(o));if(a?.reason&&f?.record("guard.reject",{reason:a.reason}),a?.response)return f?.response(a.response)??a.response;const i=a?.notFound,c=v.notFound;if(i&&(c instanceof Response||"function"==typeof c)){const s=("function"==typeof c?await c(o):c).clone(),t=new Headers(s.headers);t.set("Cache-Control","private, no-store"),"HEAD"===o.method&&s.body?.cancel().catch(()=>{});const n=new Response("HEAD"===o.method?null:s.body,{status:404,headers:x.documentHeaders?e(x.documentHeaders,x)({request:o,response:{headers:t}}):t});return f?.response(n)??n}const C=async(e,o=!1)=>{const C=m?await m({executionContext:h,request:e}):void 0,w=C instanceof Response,y=w?void 0:C,H=Object.assign(d.requestContext??{},{appProps:y?.appProps??{},diagnostics:l?new r(new URL(e.url).pathname):void 0,executionContext:h,html:w?{header:"",footer:""}:await u(e),request:e,matches:a?.matches,notFound:i?o?"cached":"spa"===c?"spa":"render":void 0,response:{headers:new Headers(y?.headers),status:y?.status},...!o&&f?{timeline:f}:{}});if(i&&H.response.headers.set("Cache-Control","private, no-store"),p?.({context:H}),w){const{sessionCookie:o}=x;H.diagnostics?.inspectCachePolicy(C.headers,Boolean(o&&s(e,o)));const n=await t(e,C);return{response:H.timeline?.response(n)??n,isCacheable:!1}}return{response:await n({...d,policy:g,spaShell:q,admission:v.admission},H,o?{...x,documentHeaders:void 0}:x,h),isCacheable:!H.didError&&404===H.routerContext?.statusCode,routerContext:H.routerContext}};if(i&&H&&void 0===x.nonce){const s=await H.get(o,e=>C(e,!0),x.documentHeaders?(s,t)=>e(x.documentHeaders,x)({request:o,routerContext:t,response:{headers:s}}):void 0);return f?.response(s)??s}return(await C(o)).response}catch(e){throw f?.abort(e),f?.end(),e}}};export{d as default};
2
2
  //# sourceMappingURL=handler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sources":["../../src/core/handler.ts"],"sourcesContent":[null],"names":["createHandler","params","diagnostics","getHtml","onContext","onRequest","ssr","basename","options","policy","SsrPolicy","handler","dataRoutes","spaShell","createSpaShell","async","request","executionContext","isEnabled","isDiagnosticsEnabled","timeline","createTimeline","requestInit","undefined","isBypass","Response","metadata","context","appProps","Diagnostics","URL","url","pathname","html","header","footer","response","headers","Headers","status","sessionCookie","inspectCachePolicy","Boolean","hasCookie","headResponse","render","error","abort","end"],"mappings":"kTAsDA,MAAMA,EAAgB,CACpBC,GAEEC,cACAC,UACAC,YACAC,YACAC,MACAC,cACGC,MAGL,MAAMC,EAAS,IAAIC,EAAUJ,EAAKL,EAAOU,QAAQC,WAAYL,GACvDM,EAAWC,IAKjB,OAAOC,MAAOC,EAASC,KACrB,MAAMC,EAAYC,EAAqBjB,GACjCkB,EAAWC,EAAeL,EAASE,GAEzC,IACE,MAAMI,EAAcjB,QAAkBA,EAAU,CAAEY,mBAAkBD,iBAAaO,EAC3EC,EAAWF,aAAuBG,SAClCC,EAAWF,OAAWD,EAAYD,EAClCK,EAAyC,CAC7CC,SAAWF,GAAUE,UAAY,GACjC1B,YAAagB,EAAY,IAAIW,EAAY,IAAIC,IAAId,EAAQe,KAAKC,eAAYT,EAC1EN,mBACAgB,KAAMT,EAAW,CAAEU,OAAQ,GAAIC,OAAQ,UAAahC,EAAQa,GAC5DA,UACAoB,SAAU,CACRC,QAAS,IAAIC,QAAQZ,GAAUW,SAC/BE,OAAQb,GAAUa,WAEhBnB,EAAW,CAAEA,YAAa,IAKhC,GAFAhB,IAAY,CAAEuB,YAEVH,EAAU,CACZ,MAAMgB,cAAEA,GAAkBhC,EAE1BmB,EAAQzB,aAAauC,mBACnBnB,EAAYe,QACZK,QAAQF,GAAiBG,EAAU3B,EAASwB,KAG9C,MAAMJ,QAAiBQ,EAAa5B,EAASM,GAE7C,OAAOF,GAAUgB,SAASA,IAAaA,CACzC,CAEA,aAAaS,EAAO,IAAK5C,EAAQQ,SAAQI,YAAYc,EAASnB,EAASS,EACzE,CAAE,MAAO6B,GAGP,MAFA1B,GAAU2B,MAAMD,GAChB1B,GAAU4B,MACJF,CACR"}
1
+ {"version":3,"file":"handler.js","sources":["../../src/core/handler.ts"],"sourcesContent":[null],"names":["createHandler","params","diagnostics","getHtml","onContext","onRequest","ssr","basename","requestGuard","notFound","admission","options","runtime","HandlerRuntime","handler","dataRoutes","guard","cache","policy","spaShell","async","request","executionContext","isEnabled","isDiagnosticsEnabled","timeline","createTimeline","guarded","handle","reason","record","response","isMissing","mode","Response","custom","clone","headers","Headers","set","method","body","cancel","catch","status","documentHeaders","execute","renderRequest","isCached","requestInit","undefined","isBypass","metadata","context","Object","assign","requestContext","appProps","Diagnostics","URL","url","pathname","html","header","footer","matches","sessionCookie","inspectCachePolicy","Boolean","hasCookie","headResponse","isCacheable","render","didError","routerContext","statusCode","nonce","get","anonymous","error","abort","end"],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { StaticHandlerContext } from 'react-router';
2
+ export interface ICachedNotFoundOptions {
3
+ /** Buffer and retain runtime-rendered router 404 documents. */
4
+ mode: 'cached';
5
+ /** Partition anonymous documents. Default: one shared key. */
6
+ key?: (request: Request) => string;
7
+ /** Maximum retained documents, evicted least recently used first. Default: 16. */
8
+ maxEntries?: number;
9
+ }
10
+ export type TNotFoundOptions = 'render' | 'spa' | 'cached' | ICachedNotFoundOptions | Response | ((request: Request) => Response | Promise<Response>);
11
+ interface ICachedDocument {
12
+ /** Buffered bytes avoid retained streams or shared response bodies. */
13
+ html: string;
14
+ /** Anonymous response metadata. */
15
+ headers: Headers;
16
+ /** Preserve failures without storing them. */
17
+ status: number;
18
+ /** Anonymous router metadata for per-request document rules. */
19
+ routerContext?: StaticHandlerContext;
20
+ }
21
+ export interface INotFoundRenderResult {
22
+ /** Response from the anonymous render. */
23
+ response: Response;
24
+ /** Router/render failures must never populate the cache. */
25
+ isCacheable: boolean;
26
+ /** Router metadata used by document header rules on cache hits. */
27
+ routerContext?: StaticHandlerContext;
28
+ }
29
+ /** Process-lifetime LRU with one in-flight render per application key. */
30
+ declare class NotFoundCache {
31
+ /** Cache partitioning and bounded retention. */
32
+ protected readonly options: ICachedNotFoundOptions;
33
+ /** Retain only completed successful 404 documents. */
34
+ protected readonly entries: Map<string, ICachedDocument>;
35
+ /** Share cold renders without sharing consumable Response bodies. */
36
+ protected readonly pending: Map<string, Promise<ICachedDocument>>;
37
+ /** Validate cache bounds at startup. */
38
+ constructor(
39
+ /** Cache partitioning and bounded retention. */
40
+ options?: ICachedNotFoundOptions);
41
+ /** Render with no credentials; HEAD can warm the same complete document as GET. */
42
+ get(request: Request, render: (anonymous: Request) => Promise<INotFoundRenderResult>, prepareHeaders?: (headers: Headers, routerContext?: StaticHandlerContext) => Headers): Promise<Response>;
43
+ /** Buffer first; a thrown render or read never leaves a poisoned cache entry. */
44
+ protected render(key: string, request: Request, render: (anonymous: Request) => Promise<INotFoundRenderResult>): Promise<ICachedDocument>;
45
+ }
46
+ export default NotFoundCache;
@@ -0,0 +1,2 @@
1
+ class e{options;entries=new Map;pending=new Map;constructor(e={mode:"cached"}){this.options=e;const{maxEntries:t=16}=e;if(!Number.isSafeInteger(t)||t<=0)throw new Error("404 cache maxEntries must be a positive integer.")}async get(e,t,s){const n=this.options.key?.(e)??"";let i=this.entries.get(n);if(i)this.entries.delete(n),this.entries.set(n,i);else{let s=this.pending.get(n);if(!s){const i=new Headers(e.headers);i.delete("Cookie"),i.delete("Authorization"),i.delete("Content-Length");const r=new Request(e.url,{headers:i,method:"GET"});s=this.render(n,r,t),this.pending.set(n,s)}i=await s}return new Response("HEAD"===e.method||[204,205,304].includes(i.status)?null:i.html,{headers:s?.(i.headers,i.routerContext)??i.headers,status:i.status})}async render(e,t,s){try{const{response:n,isCacheable:i,routerContext:r}=await s(t),o=new Headers(n.headers);o.delete("Set-Cookie");const a={html:await n.text(),headers:o,status:n.status,routerContext:r};if(i&&404===n.status)for(this.entries.set(e,a);this.entries.size>(this.options.maxEntries??16);){const[e]=this.entries.keys();this.entries.delete(e)}return a}finally{this.pending.delete(e)}}}export{e as default};
2
+ //# sourceMappingURL=not-found.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"not-found.js","sources":["../../src/core/not-found.ts"],"sourcesContent":[null],"names":["NotFoundCache","options","entries","Map","pending","constructor","mode","this","maxEntries","Number","isSafeInteger","Error","get","request","render","prepareHeaders","key","document","delete","set","headers","Headers","anonymous","Request","url","method","Response","includes","status","html","routerContext","response","isCacheable","text","size","oldest","keys"],"mappings":"AAwCA,MAAMA,EAUiBC,QARFC,QAAU,IAAIC,IAGdC,QAAU,IAAID,IAGjC,WAAAE,CAEqBJ,EAAkC,CAAEK,KAAM,WAA1CC,KAAAN,QAAAA,EAEnB,MAAMO,WAAEA,EAAa,IAAOP,EAE5B,IAAKQ,OAAOC,cAAcF,IAAeA,GAAc,EACrD,MAAM,IAAIG,MAAM,mDAEpB,CAGO,SAAMC,CACXC,EACAC,EACAC,GAEA,MAAMC,EAAMT,KAAKN,QAAQe,MAAMH,IAAY,GAC3C,IAAII,EAAWV,KAAKL,QAAQU,IAAII,GAEhC,GAAIC,EACFV,KAAKL,QAAQgB,OAAOF,GACpBT,KAAKL,QAAQiB,IAAIH,EAAKC,OACjB,CACL,IAAIb,EAAUG,KAAKH,QAAQQ,IAAII,GAE/B,IAAKZ,EAAS,CACZ,MAAMgB,EAAU,IAAIC,QAAQR,EAAQO,SAEpCA,EAAQF,OAAO,UACfE,EAAQF,OAAO,iBACfE,EAAQF,OAAO,kBACf,MAAMI,EAAY,IAAIC,QAAQV,EAAQW,IAAK,CAAEJ,UAASK,OAAQ,QAE9DrB,EAAUG,KAAKO,OAAOE,EAAKM,EAAWR,GACtCP,KAAKH,QAAQe,IAAIH,EAAKZ,EACxB,CAEAa,QAAiBb,CACnB,CAEA,OAAO,IAAIsB,SACU,SAAnBb,EAAQY,QAAqB,CAAC,IAAK,IAAK,KAAKE,SAASV,EAASW,QAAU,KAAOX,EAASY,KACzF,CACET,QAASL,IAAiBE,EAASG,QAASH,EAASa,gBAAkBb,EAASG,QAChFQ,OAAQX,EAASW,QAGvB,CAGU,YAAMd,CACdE,EACAH,EACAC,GAEA,IACE,MAAMiB,SAAEA,EAAQC,YAAEA,EAAWF,cAAEA,SAAwBhB,EAAOD,GACxDO,EAAU,IAAIC,QAAQU,EAASX,SAGrCA,EAAQF,OAAO,cAEf,MAAMD,EAAW,CACfY,WAAYE,EAASE,OACrBb,UACAQ,OAAQG,EAASH,OACjBE,iBAGF,GAAIE,GAAmC,MAApBD,EAASH,OAG1B,IAFArB,KAAKL,QAAQiB,IAAIH,EAAKC,GAEfV,KAAKL,QAAQgC,MAAQ3B,KAAKN,QAAQO,YAAc,KAAK,CAC1D,MAAO2B,GAAU5B,KAAKL,QAAQkC,OAE9B7B,KAAKL,QAAQgB,OAAOiB,EACtB,CAGF,OAAOlB,CACT,SACEV,KAAKH,QAAQc,OAAOF,EACtB,CACF"}
package/core/render.d.ts CHANGED
@@ -2,6 +2,8 @@ import type { ReactNode } from 'react';
2
2
  import type { RouterState, StaticHandler, StaticHandlerContext } from 'react-router';
3
3
  import StreamError from '../constants/stream-error.js';
4
4
  import type { IServerContext } from '../context/server.js';
5
+ import type Admission from './admission.js';
6
+ import type { IAdmissionSlot } from './admission.js';
5
7
  import type { IDocumentHeaderRule, IDocumentHeadersOptions } from './document-headers.js';
6
8
  import type createSpaShell from './spa-shell.js';
7
9
  import type SsrPolicy from './ssr-policy.js';
@@ -24,6 +26,10 @@ export interface ISsrRequestContext<TAppProps = Record<string, any>> {
24
26
  };
25
27
  isStream?: boolean;
26
28
  isSpa?: boolean;
29
+ /** Guard-selected 404 rendering mode. */
30
+ notFound?: 'render' | 'spa' | 'cached';
31
+ /** Active render slot, absent when admission is disabled. */
32
+ admissionSlot?: IAdmissionSlot;
27
33
  /** Structural route matches are available to prepare even when loaders are skipped. */
28
34
  matches?: RouterState['matches'];
29
35
  request: Request;
@@ -64,9 +70,13 @@ export interface IRenderStream {
64
70
  }
65
71
  export type TRenderToStream = (node: ReactNode, options: IRenderStreamOptions) => IRenderStream | Promise<IRenderStream>;
66
72
  export interface ICoreRenderParams<TAppProps = Record<string, any>> {
73
+ /** Adapter-owned state; only provide when constructing a handler for one request. */
74
+ requestContext?: ISsrRequestContext<TAppProps>;
67
75
  createApp: (children: ReactNode, context: ISsrRequestContext<TAppProps>) => ReactNode;
68
76
  handler: StaticHandler;
69
77
  renderToStream: TRenderToStream;
78
+ /** Shared render admission controller, created only when enabled. */
79
+ admission?: Admission;
70
80
  policy?: SsrPolicy;
71
81
  spaShell?: ReturnType<typeof createSpaShell>;
72
82
  }
package/core/render.js CHANGED
@@ -1,2 +1,2 @@
1
- import e from"react";import{matchRoutes as t,createStaticRouter as r,StaticRouterProvider as o}from"react-router";import s from"../constants/stream-error.js";import{ServerProvider as a}from"../context/server.js";import n from"./compose-html.js";import i from"./data-stream.js";import c,{hasCookie as d}from"./document-headers.js";import l from"./head-response.js";import{mergeResponseHeaders as m}from"./headers.js";import h from"./transform-html.js";import u from"../helpers/build-custom-state.js";import p from"../helpers/build-router-state.js";import C from"../helpers/obtain-stream-error.js";import{createTimeline as f}from"../services/request-timeline.js";const w="text/html",x="Content-Type",y=async({createApp:d,handler:f,renderToStream:y,policy:R,spaShell:S},v,{abortDelay:b=15e3,getState:g,hydration:q="footer",nonce:E,bootstrapScriptContent:j,onError:k,onResponse:H,onRouterReady:P,onShellError:T,onShellReady:A,prepare:B,routerRequestContext:D,documentHeaders:L,sessionCookie:_,protectPrivate:$},I)=>{const O=R?.select(v.request,v.diagnostics)??"ssr";if(R?.active&&!v.response.headers.has("Cache-Control")&&v.response.headers.set("Cache-Control","no-store"),"spa"===O)return v.isSpa=!0,v.isStream=!1,v.matches=t(f.dataRoutes,new URL(v.request.url),R?.basename)??[],v.html=S(v.html),B&&await B({context:v,executionContext:I}),L&&(v.response.headers=c(L,{sessionCookie:_,protectPrivate:$})(v)),v.response.status=200,v.response.headers.set(x,"text/html; charset=utf-8"),new Response("HEAD"===v.request.method?null:v.html.header+v.html.footer,{headers:v.response.headers,status:200});const U=await f.query(v.request,{requestContext:D??v});if(v.timeline?.record("router.query"),U instanceof Response)return l(v.request,m(U,v.response.headers));v.routerContext=U,v.matches=U.matches;const{loaderData:z,actionData:F,errors:G}=U,J=Object.keys(z).length>0||null!==F||null!==G,K="early"===q||J?new i(U,v.diagnostics,E,v.timeline):void 0;try{B&&await B({context:v,executionContext:I}),v.timeline?.record("prepare")}catch(e){throw K?.cancel(),e}const{isStream:M=!0}=(P?await P({context:v}):void 0)??{};v.isStream=M,v.serverContext={basename:v.routerContext.basename,isServer:!0,response:null};const N=r(f.dataRoutes,v.routerContext),Q=e.createElement(a,{context:v.serverContext},d(e.createElement(o,{router:N,context:v.routerContext,hydrate:!1}),v)),V=new AbortController;let W,X,Y=!1;const Z=()=>re(v.request.signal.reason),ee=()=>clearTimeout(oe),te=()=>{ee(),v.request.signal.removeEventListener("abort",Z)},re=e=>{Y||(Y=!0,W=e,v.timeline?.abort(e),te(),v.didError??=s.RenderCancel,K?.abort(),V.abort(e),X?.abort(e))},oe=setTimeout(()=>{v.didError=s.RenderTimeout,v.timeline?.abort(new Error(`SSR render timed out after ${b}ms`)),re()},b);v.request.signal.aborted?re(v.request.signal.reason):v.request.signal.addEventListener("abort",Z,{once:!0});try{X=await y(Q,{nonce:E,bootstrapScriptContent:"early"===q&&M?`(window.__ssrBoostStream = window.__ssrBoostStream || []).push(["shell"]);${j??""};document.currentScript?.remove();`:j,onError:e=>{const t=C(e);!Y||t.code!==s.RenderAborted&&e!==V.signal.reason||(t.code=v.didError===s.RenderTimeout?s.RenderTimeout:s.RenderCancel);const{code:r}=t;v.didError??=r,k?.({context:v,error:t})},signal:V.signal}),Y&&X.abort(W),Promise.all([X.allReady,K?.done]).then(ee,ee),await X.shellReady,v.timeline?.record("shell.ready"),M||await Promise.all([X.allReady,K?.done])}catch(e){return re(e),await(X?.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>",a=new Headers(e.response.headers);return a.set(x,w),new Response("HEAD"===e.request.method?null:s,{headers:a,status:500})})(v,e,T)}try{const e=v.serverContext.response;if(e&&(se=e,Boolean(se&&se.status>=300&&se.status<400&&se.headers.has("Location"))))return re(),await X.stream.cancel().catch(()=>{}),l(v.request,m(e,v.response.headers));const{header:t,footer:r,headers:o,status:s}=((e,{getState:t,onShellReady:r,hydration:o,nonce:s,documentHeaders:a,sessionCookie:n,protectPrivate:i},d)=>{const l=e.serverContext.response;e.response.status=l?.status??e.response.status??e.routerContext.statusCode??200,e.response.headers.has(x)||e.response.headers.set(x,w);const m=r?.({context:e})??{},h="early"===o&&e.isStream,C=u(t?.({context:e}),e.diagnostics,s,Boolean(h));let f=m.header||e.html.header;const y=m.footer||e.html.footer;e.diagnostics?.inspectShell({header:f,footer:y});let R=y;h?f+=C+d.state(!0):R=C+(d?d.state(!1)+d.take():p(e.routerContext,void 0,s))+R;return a&&(e.response.headers=c(a,{sessionCookie:n,protectPrivate:i})(e)),{header:f,footer:R,headers:new Headers(e.response.headers),status:e.response.status}})(v,{getState:g,onShellReady:A,hydration:q,nonce:E,documentHeaders:L,sessionCookie:_,protectPrivate:$},K);if("HEAD"===v.request.method||[204,205,304].includes(s))return re(),await X.stream.cancel().catch(()=>{}),new Response(null,{headers:o,status:s});const a=n(t,X.stream,r,re,te,K,v.timeline,"early"===q&&M),i=h(a,H?(e,t)=>H({context:v,html:e,isEnd:t}):void 0,v.diagnostics);return X.start(),new Response(i,{headers:o,status:s})}catch(e){throw re(e),X.stream.locked||await X.stream.cancel(e).catch(()=>{}),e}var se},R=async(e,t,r,o)=>{const s=t.timeline??f(t.request,Boolean(t.diagnostics));s&&(t.timeline=s);try{const a=await y(e,t,r,o),{sessionCookie:n}=r;return t.diagnostics?.inspectCachePolicy(a.headers,Boolean(n&&d(t.request,n))),s?.response(a)??a}catch(e){throw s?.abort(e),s?.end(),e}};export{R as default};
1
+ import e from"react";import{createStaticRouter as t,StaticRouterProvider as r,matchRoutes as s}from"react-router";import o from"../constants/stream-error.js";import{ServerProvider as a}from"../context/server.js";import n from"./compose-html.js";import i from"./data-stream.js";import l,{hasCookie as d}from"./document-headers.js";import c from"./head-response.js";import{mergeResponseHeaders as m}from"./headers.js";import h from"./transform-html.js";import u from"../helpers/build-custom-state.js";import p from"../helpers/build-router-state.js";import S from"../helpers/obtain-stream-error.js";import{createTimeline as y}from"../services/request-timeline.js";const f="text/html",C="Content-Type",w="Cache-Control",x="private, no-store",v=async({handler:e,policy:t,spaShell:r},o,{prepare:a,documentHeaders:n,sessionCookie:i,protectPrivate:d},c,m=200,h=!1)=>(o.isSpa=!0,o.isStream=!1,o.matches??=s(e.dataRoutes,new URL(o.request.url),t?.basename)??[],o.html=r(o.html),o.response.status=m,a&&!h&&await a({context:o,executionContext:c}),o.notFound&&o.response.headers.set(w,x),n&&(o.response.headers=l(n,{sessionCookie:i,protectPrivate:d})(o)),o.response.headers.set(C,"text/html; charset=utf-8"),new Response("HEAD"===o.request.method?null:o.html.header+o.html.footer,{headers:o.response.headers,status:m})),R=async({createApp:s,handler:d,renderToStream:y,policy:R,spaShell:b,admission:q},g,{abortDelay:E=15e3,getState:j,hydration:k="footer",nonce:H,bootstrapScriptContent:P,onError:B,onResponse:A,onRouterReady:F,onShellError:T,onShellReady:D,prepare:L,routerRequestContext:_,documentHeaders:$,sessionCookie:I,protectPrivate:O},U)=>{const z="cached"===g.notFound?"ssr":"spa"===g.notFound?R?.shouldRenderBot(g.request)?"ssr":"spa":R?.select(g.request,g.diagnostics,g.matches)??"ssr";if(R?.active&&!g.response.headers.has(w)&&g.response.headers.set(w,"no-store"),"spa"===z)return v({handler:d,policy:R,spaShell:b},g,{prepare:L,documentHeaders:$,sessionCookie:I,protectPrivate:O},U,g.notFound?404:200);if(q&&(g.admissionSlot=q.tryAcquire(g.request.signal),!g.admissionSlot))return"spa"!==q.overload||R?.isBot(g.request)?q.reject(g.request):(g.response.headers.set(w,x),v({handler:d,policy:R,spaShell:b},g,{prepare:L,documentHeaders:$,sessionCookie:I,protectPrivate:O},U));let G;try{G=await d.query(g.request,{requestContext:_??g})}catch(e){throw g.admissionSlot?.release("error"),e}if(g.timeline?.record("router.query"),G instanceof Response)return g.admissionSlot?.release("finish"),c(g.request,m(G,g.response.headers));g.routerContext=G,g.matches=G.matches;const{loaderData:J,actionData:K,errors:M}=G,N=Object.keys(J).length>0||null!==K||null!==M,Q="early"===k||N?new i(G,g.diagnostics,H,g.timeline):void 0;try{L&&await L({context:g,executionContext:U}),g.timeline?.record("prepare")}catch(e){throw Q?.cancel(),g.admissionSlot?.release("error"),e}let V;try{V=F?await F({context:g}):void 0}catch(e){throw Q?.cancel(),g.admissionSlot?.release("error"),e}const W="cached"!==g.notFound&&(V?.isStream??!0);g.isStream=W,g.serverContext={basename:g.routerContext.basename,isServer:!0,response:null};const X=t(d.dataRoutes,g.routerContext),Y=e.createElement(a,{context:g.serverContext},s(e.createElement(r,{router:X,context:g.routerContext,hydrate:!1}),g)),Z=new AbortController;let ee,te,re=!1;const se=()=>{g.admissionSlot?.release("abort"),ne(g.request.signal.reason)},oe=()=>clearTimeout(ie),ae=()=>{oe(),g.request.signal.removeEventListener("abort",se)},ne=e=>{re||(re=!0,ee=e,g.timeline?.abort(e),ae(),g.didError??=o.RenderCancel,Q?.abort(),Z.abort(e),te?.abort(e))},ie=setTimeout(()=>{g.admissionSlot?.release("error"),g.didError=o.RenderTimeout,g.timeline?.abort(new Error(`SSR render timed out after ${E}ms`)),ne()},E);g.request.signal.aborted?se():g.request.signal.addEventListener("abort",se,{once:!0});try{te=await y(Y,{nonce:H,bootstrapScriptContent:"early"===k&&W?`(window.__ssrBoostStream = window.__ssrBoostStream || []).push(["shell"]);${P??""};document.currentScript?.remove();`:P,onError:e=>{const t=S(e);!re||t.code!==o.RenderAborted&&e!==Z.signal.reason||(t.code=g.didError===o.RenderTimeout?o.RenderTimeout:o.RenderCancel);const{code:r}=t;g.didError??=r,g.admissionSlot?.release(re?"abort":"error"),B?.({context:g,error:t})},signal:Z.signal}),re&&te.abort(ee),Promise.all([te.allReady,Q?.done]).then(oe,oe),await te.shellReady,g.timeline?.record("shell.ready"),g.isStream||await Promise.all([te.allReady,Q?.done])}catch(e){return g.admissionSlot?.release("error"),ne(e),await(te?.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(C,f),new Response("HEAD"===e.request.method?null:o,{headers:a,status:500})})(g,e,T)}try{const e=g.serverContext.response;if(e&&(le=e,Boolean(le&&le.status>=300&&le.status<400&&le.headers.has("Location"))))return g.admissionSlot?.release("finish"),ne(),await te.stream.cancel().catch(()=>{}),c(g.request,m(e,g.response.headers));const{header:t,footer:r,headers:s,status:o}=((e,{getState:t,onShellReady:r,hydration:s,nonce:o,documentHeaders:a,sessionCookie:n,protectPrivate:i},d)=>{const c=e.serverContext.response;e.response.status=c?.status??e.response.status??e.routerContext.statusCode??200,e.response.headers.has(C)||e.response.headers.set(C,f);const m=r?.({context:e})??{};e.notFound&&(e.response.headers.set(w,x),e.response.status<500&&(e.response.status=404));const h="early"===s&&e.isStream,S=u(t?.({context:e}),e.diagnostics,o,Boolean(h));let y=m.header||e.html.header;const v=m.footer||e.html.footer;e.diagnostics?.inspectShell({header:y,footer:v});let R=v;h?y+=S+d.state(!0):R=S+(d?d.state(!1)+d.take():p(e.routerContext,void 0,o))+R;return a&&(e.response.headers=l(a,{sessionCookie:n,protectPrivate:i})(e)),{header:y,footer:R,headers:new Headers(e.response.headers),status:e.response.status}})(g,{getState:j,onShellReady:D,hydration:k,nonce:H,documentHeaders:$,sessionCookie:I,protectPrivate:O},Q);if("HEAD"===g.request.method||[204,205,304].includes(o))return g.admissionSlot?.release("finish"),ne(),await te.stream.cancel().catch(()=>{}),new Response(null,{headers:s,status:o});const a=n(t,te.stream,r,ne,ae,Q,g.timeline,"early"===k&&W),i=h(a,A?(e,t)=>A({context:g,html:e,isEnd:t}):void 0,g.diagnostics);return te.start(),new Response(i,{headers:s,status:o})}catch(e){throw g.admissionSlot?.release("error"),ne(e),te.stream.locked||await te.stream.cancel(e).catch(()=>{}),e}var le},b=async(e,t,r,s)=>{const o=t.timeline??("cached"===t.notFound?void 0:y(t.request,Boolean(t.diagnostics)));o&&(t.timeline=o);try{const a=await R(e,t,r,s),{sessionCookie:n}=r;t.diagnostics?.inspectCachePolicy(a.headers,Boolean(n&&d(t.request,n)));const i=t.admissionSlot?.response(a)??a;return o?.response(i)??i}catch(e){throw t.admissionSlot?.release("error"),o?.abort(e),o?.end(),e}};export{b 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","renderResponse","async","createApp","handler","renderToStream","policy","spaShell","context","abortDelay","getState","hydration","nonce","bootstrapScriptContent","onError","onResponse","onRouterReady","onShellError","onShellReady","prepare","routerRequestContext","documentHeaders","rules","sessionCookie","protectPrivate","executionContext","mode","select","request","diagnostics","active","response","headers","has","set","isSpa","isStream","matches","matchRoutes","dataRoutes","URL","url","basename","html","status","Response","method","header","footer","queried","query","requestContext","timeline","record","headResponse","mergeResponseHeaders","routerContext","loaderData","actionData","errors","hasRouterData","Object","keys","length","dataStream","DataStream","undefined","error","cancel","serverContext","isServer","router","createStaticRouter","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","Error","aborted","addEventListener","once","streamError","obtainStreamError","code","RenderAborted","Promise","all","allReady","done","then","shellReady","stream","catch","shellError","String","Headers","createShellErrorResponse","serverResponse","Boolean","statusCode","shell","isEarly","customState","buildCustomState","shellFooter","inspectShell","state","take","buildRouterState","prepareHtmlResponse","includes","body","composeHtml","transformed","transformHtml","isEnd","start","locked","render","params","options","createTimeline","inspectCachePolicy","hasCookie","end"],"mappings":"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"}
1
+ {"version":3,"file":"render.js","sources":["../../src/core/render.tsx"],"sourcesContent":[null],"names":["HTML_CONTENT_TYPE","CONTENT_TYPE","CACHE_CONTROL","PRIVATE_NO_STORE","renderSpa","async","handler","policy","spaShell","context","prepare","documentHeaders","rules","sessionCookie","protectPrivate","executionContext","status","isPrepared","isSpa","isStream","matches","matchRoutes","dataRoutes","URL","request","url","basename","html","response","notFound","headers","set","Response","method","header","footer","renderResponse","createApp","renderToStream","admission","abortDelay","getState","hydration","nonce","bootstrapScriptContent","onError","onResponse","onRouterReady","onShellError","onShellReady","routerRequestContext","mode","shouldRenderBot","select","diagnostics","active","has","admissionSlot","tryAcquire","signal","overload","isBot","reject","queried","query","requestContext","error","release","timeline","record","headResponse","mergeResponseHeaders","routerContext","loaderData","actionData","errors","hasRouterData","Object","keys","length","dataStream","DataStream","undefined","cancel","routerReady","serverContext","isServer","router","createStaticRouter","node","React","createElement","ServerProvider","StaticRouterProvider","hydrate","renderController","AbortController","abortReason","output","hasAborted","onRequestAbort","abort","reason","clearAbortTimer","clearTimeout","abortTimer","cleanup","removeEventListener","didError","StreamError","RenderCancel","setTimeout","RenderTimeout","Error","aborted","addEventListener","once","streamError","obtainStreamError","code","RenderAborted","Promise","all","allReady","done","then","shellReady","stream","catch","shellError","String","Headers","createShellErrorResponse","serverResponse","Boolean","statusCode","shell","isEarly","customState","buildCustomState","shellFooter","inspectShell","state","take","buildRouterState","prepareHtmlResponse","includes","body","composeHtml","transformed","transformHtml","isEnd","start","locked","render","params","options","createTimeline","inspectCachePolicy","hasCookie","admittedResponse","end"],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import type { RouterState, StaticHandler } from 'react-router';
2
+ export type TRequestGuardReason = 'method' | 'target-too-large' | 'malformed-target' | 'blocked-extension' | 'route' | 'decide';
3
+ export interface IRequestGuardDecisionContext {
4
+ /** Original Fetch request. */
5
+ request: Request;
6
+ /** Parsed document URL. */
7
+ url: URL;
8
+ /** Structural matches, without executing loaders. */
9
+ matches: RouterState['matches'];
10
+ }
11
+ export interface IRequestGuardOptions {
12
+ /** Allowed document methods. Default: GET, HEAD, POST. */
13
+ methods?: string[];
14
+ /** Maximum UTF-8 bytes in pathname plus search. Default: 8192. */
15
+ maxTargetBytes?: number;
16
+ /** Maximum UTF-8 bytes in the pathname. Default: 2048. */
17
+ maxPathBytes?: number;
18
+ /** Maximum UTF-8 bytes in the query, excluding ?. Default: 6144. */
19
+ maxQueryBytes?: number;
20
+ /** Maximum nonempty path segments. Default: 32. */
21
+ maxSegments?: number;
22
+ /** Maximum UTF-8 bytes per segment. Default: 1024. */
23
+ maxSegmentBytes?: number;
24
+ /** Reject encoded delimiters, including a second decoding pass. Default: allow. */
25
+ encodedDelimiters?: 'allow' | 'reject';
26
+ /** Override script-extension probes; strings are literal extensions without a dot. */
27
+ blockedExtensions?: RegExp | string[] | false;
28
+ /** Block dotfile segments, except /.well-known/*. Default: true. */
29
+ blockDotfiles?: boolean;
30
+ /** Override a matched request after built-in checks. */
31
+ decide?: (context: IRequestGuardDecisionContext) => 'allow' | 'notFound' | Response | undefined | Promise<'allow' | 'notFound' | Response | undefined>;
32
+ /** Observe rejections without affecting their response. */
33
+ onReject?: (event: {
34
+ request: Request;
35
+ reason: TRequestGuardReason;
36
+ status: number;
37
+ }) => void;
38
+ }
39
+ export interface IRequestGuardResult {
40
+ /** Matches are shared with policy and SPA preparation. */
41
+ matches: RouterState['matches'];
42
+ /** A terminal response skips request initialization. */
43
+ response?: Response;
44
+ /** Missing routes continue through the configured 404 mode. */
45
+ notFound?: boolean;
46
+ /** Low-cardinality rejection classification. */
47
+ reason?: TRequestGuardReason;
48
+ }
49
+ /** Validate document targets before application hooks, route policy or loaders run. */
50
+ declare class RequestGuard {
51
+ /** Mounted data routes, without running loaders. */
52
+ protected readonly routes: StaticHandler['dataRoutes'];
53
+ /** Match the router mount point. */
54
+ protected readonly basename: string;
55
+ /** Snapshot methods and bounds at handler creation. */
56
+ protected readonly options: Required<Omit<IRequestGuardOptions, 'decide' | 'onReject'>> & Pick<IRequestGuardOptions, 'decide' | 'onReject'>;
57
+ /** Clone expressions so application lastIndex is never mutated. */
58
+ protected readonly extensions: RegExp | Set<string> | false;
59
+ /** Retain the mounted data routes and basename. */
60
+ constructor(
61
+ /** Mounted data routes, without running loaders. */
62
+ routes?: StaticHandler['dataRoutes'], options?: IRequestGuardOptions,
63
+ /** Match the router mount point. */
64
+ basename?: string);
65
+ /** First rejection wins; HEAD follows the normal rendering pipeline when allowed. */
66
+ handle(request: Request): Promise<IRequestGuardResult>;
67
+ /** Check raw and decoded shapes, retaining encoded slash compatibility by default. */
68
+ protected decode(pathname: string): string | undefined;
69
+ /** Enforce path depth, bytes and unambiguous traversal semantics. */
70
+ protected hasValidShape(pathname: string): boolean;
71
+ /** Keep well-known resource routes accessible while blocking dotfiles and script probes. */
72
+ protected isBlocked(pathname: string): boolean;
73
+ /** Produce short, private guard responses without a HEAD body. */
74
+ protected reject(request: Request, reason: TRequestGuardReason, status: number, body: string, headers?: HeadersInit): IRequestGuardResult;
75
+ /** Observability hooks must never change request handling. */
76
+ protected notify(request: Request, reason: TRequestGuardReason, status: number): void;
77
+ }
78
+ export default RequestGuard;
@@ -0,0 +1,2 @@
1
+ import{matchRoutes as e}from"react-router";import t from"./head-response.js";import s from"./request-target.js";const o=/\.(?:php\d*|phtml|phar|asp|aspx|jsp|jspx|cgi|cfm|cfml|action|do|faces|shtml)\/?$/i,n=/%(?:2f|5c|23|3f)/i,i=new TextEncoder;class a{routes;basename;options;extensions;constructor(e=[],t={},s="/"){this.routes=e,this.basename=s,this.options={...t,methods:t.methods??["GET","HEAD","POST"],maxTargetBytes:t.maxTargetBytes??8192,maxPathBytes:t.maxPathBytes??2048,maxQueryBytes:t.maxQueryBytes??6144,maxSegments:t.maxSegments??32,maxSegmentBytes:t.maxSegmentBytes??1024,encodedDelimiters:t.encodedDelimiters??"allow",blockedExtensions:t.blockedExtensions??o,blockDotfiles:t.blockDotfiles??!0},this.options.methods=[...this.options.methods];const{blockedExtensions:n}=this.options;this.extensions=Array.isArray(n)?new Set(n.map(e=>e.replace(/^\./,"").toLowerCase())):n&&new RegExp(n.source,n.flags)}async handle(o){const{methods:n,maxTargetBytes:a,maxPathBytes:r,maxQueryBytes:c,decide:h}=this.options;if(!n.includes(o.method))return this.reject(o,"method",405,"Method Not Allowed",{Allow:n.join(", ")});let d;const l=s.get(o)??o.url.replace(/^[a-z][a-z\d+.-]*:\/\/[^/\\?#]*/i,"");try{d=new URL(o.url)}catch{return this.reject(o,"malformed-target",400,"Bad Request")}const{pathname:m,search:u}=d,p=m+u,x=l.split(/[?#]/,1)[0]||"/";if(i.encode(p).length>a||i.encode(m).length>r||i.encode(u.slice(1)).length>c)return this.reject(o,"target-too-large",414,"URI Too Long");const f=this.decode(m);if(!f||!this.decode(x)||l.includes("#"))return this.reject(o,"malformed-target",400,"Bad Request");if(this.isBlocked(f))return this.reject(o,"blocked-extension",404,"Not Found");const y=e(this.routes,d,this.basename)??[];if(!y.length)return/\.[a-z0-9]{1,8}$/i.test(f.replace(/\/$/,""))?this.reject(o,"route",404,"Not Found"):(this.notify(o,"route",404),{matches:y,notFound:!0,reason:"route"});const g=await(h?.({request:o,url:d,matches:y}));return g instanceof Response?(this.notify(o,"decide",g.status),{matches:y,response:await t(o,g),reason:"decide"}):"notFound"===g?(this.notify(o,"decide",404),{matches:y,notFound:!0,reason:"decide"}):{matches:y}}decode(e){const{encodedDelimiters:t}=this.options;try{const s=decodeURIComponent(e);if("reject"===t&&(n.test(e)||n.test(s))||!this.hasValidShape(e)||!this.hasValidShape(s))return;return s}catch{return}}hasValidShape(e){const{maxSegments:t,maxSegmentBytes:s}=this.options,o=e.split("/").filter(Boolean);return e.startsWith("/")&&!/[\u0000-\u001f\u007f\\]/.test(e)&&!e.includes("//")&&o.length<=t&&o.every(e=>"."!==e&&".."!==e&&i.encode(e).length<=s)}isBlocked(e){return!(!this.options.blockDotfiles||e.startsWith("/.well-known/")||!e.split("/").some(e=>e.startsWith(".")))||(this.extensions instanceof RegExp?(this.extensions.lastIndex=0,this.extensions.test(e)):Boolean(this.extensions&&this.extensions.has(e.replace(/\/$/,"").split(".").pop().toLowerCase())))}reject(e,t,s,o,n){return this.notify(e,t,s),{matches:[],reason:t,response:new Response("HEAD"===e.method?null:o,{status:s,headers:{"Content-Type":"text/plain; charset=utf-8","Cache-Control":"private, no-store",...n}})}}notify(e,t,s){try{this.options.onReject?.({request:e,reason:t,status:s})}catch{}}}export{a as default};
2
+ //# sourceMappingURL=request-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-guard.js","sources":["../../src/core/request-guard.ts"],"sourcesContent":[null],"names":["SCRIPT_EXTENSION","ENCODED_DELIMITER","encoder","TextEncoder","RequestGuard","routes","basename","options","extensions","constructor","this","methods","maxTargetBytes","maxPathBytes","maxQueryBytes","maxSegments","maxSegmentBytes","encodedDelimiters","blockedExtensions","blockDotfiles","Array","isArray","Set","map","extension","replace","toLowerCase","RegExp","source","flags","handle","request","decide","includes","method","reject","Allow","join","url","raw","requestTargets","get","URL","pathname","search","target","rawPath","split","encode","length","slice","decoded","decode","isBlocked","matches","matchRoutes","test","notify","notFound","reason","decision","Response","status","response","headResponse","decodeURIComponent","hasValidShape","segments","filter","Boolean","startsWith","every","segment","some","lastIndex","has","pop","body","headers","onReject"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Preserve adapter targets before Fetch/WHATWG normalization, without retaining requests. */
2
+ declare const requestTargets: WeakMap<Request, string>;
3
+ export default requestTargets;
@@ -0,0 +1,2 @@
1
+ const a=new WeakMap;export{a as default};
2
+ //# sourceMappingURL=request-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-target.js","sources":["../../src/core/request-target.ts"],"sourcesContent":[null],"names":["requestTargets","WeakMap"],"mappings":"AACA,MAAMA,EAAiB,IAAIC"}
@@ -1,4 +1,4 @@
1
- import type { StaticHandler } from 'react-router';
1
+ import type { RouterState, StaticHandler } from 'react-router';
2
2
  import type Diagnostics from '../services/diagnostics.js';
3
3
  type TRenderMode = 'ssr' | 'spa';
4
4
  interface ISsrPolicy {
@@ -73,7 +73,11 @@ declare class SsrPolicy {
73
73
  /**
74
74
  * Crawler protection wins over both runtime decisions and environment rollback rules.
75
75
  */
76
- select(request: Request, diagnostics?: Diagnostics): TRenderMode;
76
+ select(request: Request, diagnostics?: Diagnostics, matches?: RouterState['matches']): TRenderMode;
77
+ /** Reuse crawler detection for 404 and overload fallbacks, even with all-route SSR. */
78
+ isBot(request: Request): boolean;
79
+ /** Keep crawlers on SSR when the configured bot policy requires it. */
80
+ shouldRenderBot(request: Request): boolean;
77
81
  /**
78
82
  * Explain typos using declared paths, including concrete URLs for dynamic route ids.
79
83
  * A global 404 catch-all must not hide a misspelled policy.
@@ -1,2 +1,2 @@
1
- import{isbot as t}from"isbot";import{pathToRegexp as e}from"path-to-regexp";import{matchPath as s}from"react-router";const i=(t,s)=>{if(""===t)throw new Error("SSR route patterns cannot be empty.");const i="string"==typeof t?e(t).regexp:new RegExp(t.source,t.flags);return{pattern:t,exclude:s,test:t=>(i.lastIndex=0,i.test(t))}},r=(t,e="")=>t.flatMap(({id:t,path:s,children:i})=>{const a=(s?.startsWith("/")?s:`${e}/${s??""}`).replace(/\/+/g,"/").replace(/\/$/,"")||"/";return[{id:t,path:a},...r(i??[],a)]});class a{active;basename;patterns;mode;bots;decide;source;paths;hasInspected=!1;constructor({mode:t="all",routes:e=[],bots:s="ssr",decide:a}={},o=[],n="/",c=("undefined"==typeof process?void 0:process.env.SSR_BOOST_SSR_ROUTES)){if(this.basename=n,this.bots=s,this.paths=r(o).map(t=>({...t,path:`${n.replace(/\/$/,"")}${t.path}`})),void 0!==c){const t=c.split(",").map(t=>t.trim()).filter(Boolean);this.mode=t.length?t.some(t=>!t.startsWith("!"))?"include":"exclude":"all",this.patterns=t.map(t=>{const e=t.startsWith("!");return i(e?t.slice(1):t,e)}),this.source="SSR_BOOST_SSR_ROUTES"}else this.mode=t,this.patterns="all"===t?[]:e.map(e=>i(e,"exclude"===t)),this.decide=a,this.source="config";this.active="all"!==this.mode||Boolean(this.decide)}select(e,i){if(!this.active)return"ssr";this.inspect(i);const{url:r,headers:a}=e,o=new URL(r),n=t(a.get("user-agent")),c=this.patterns.filter(({test:t})=>t(o.pathname)),p=c.find(({exclude:t})=>t);let h=p||"include"===this.mode&&!c.length?"spa":"ssr",d=`${this.source} ${this.mode}`;if(n&&"ssr"===this.bots)h="ssr",d="bots: ssr";else{const t=this.decide?.({request:e,url:o,isBot:n});void 0!==t&&(h=t,d="config decide")}const l=p?.pattern??c[0]?.pattern??[...this.paths].reverse().find(({path:t})=>s(t,o.pathname))?.path??"(unmatched URL)";return i?.policyDecision(String(l),h,d),h}inspect(t){if(t&&!this.hasInspected){this.hasInspected=!0;for(const{pattern:e,test:i}of this.patterns){this.paths.some(({path:t})=>"/*"!==t&&(i(t)||"string"==typeof e&&Boolean(s(t,e))))||t.policyUnmatched(String(e))}}}}export{a as default};
1
+ import{isbot as t}from"isbot";import{pathToRegexp as e}from"path-to-regexp";import{matchPath as s}from"react-router";const i=(t,s)=>{if(""===t)throw new Error("SSR route patterns cannot be empty.");const i="string"==typeof t?e(t).regexp:new RegExp(t.source,t.flags);return{pattern:t,exclude:s,test:t=>(i.lastIndex=0,i.test(t))}},r=(t,e="")=>t.flatMap(({id:t,path:s,children:i})=>{const o=(s?.startsWith("/")?s:`${e}/${s??""}`).replace(/\/+/g,"/").replace(/\/$/,"")||"/";return[{id:t,path:o},...r(i??[],o)]});class o{active;basename;patterns;mode;bots;decide;source;paths;hasInspected=!1;constructor({mode:t="all",routes:e=[],bots:s="ssr",decide:o}={},a=[],n="/",h=("undefined"==typeof process?void 0:process.env.SSR_BOOST_SSR_ROUTES)){if(this.basename=n,this.bots=s,this.paths=r(a).map(t=>({...t,path:`${n.replace(/\/$/,"")}${t.path}`})),void 0!==h){const t=h.split(",").map(t=>t.trim()).filter(Boolean);this.mode=t.length?t.some(t=>!t.startsWith("!"))?"include":"exclude":"all",this.patterns=t.map(t=>{const e=t.startsWith("!");return i(e?t.slice(1):t,e)}),this.source="SSR_BOOST_SSR_ROUTES"}else this.mode=t,this.patterns="all"===t?[]:e.map(e=>i(e,"exclude"===t)),this.decide=o,this.source="config";this.active="all"!==this.mode||Boolean(this.decide)}select(e,i,r){if(!this.active)return"ssr";this.inspect(i);const{url:o,headers:a}=e,n=new URL(o),h=t(a.get("user-agent")),p=this.patterns.filter(({test:t})=>t(n.pathname)),c=p.find(({exclude:t})=>t);let d=c||"include"===this.mode&&!p.length?"spa":"ssr",l=`${this.source} ${this.mode}`;if(h&&"ssr"===this.bots)d="ssr",l="bots: ssr";else{const t=this.decide?.({request:e,url:n,isBot:h});void 0!==t&&(d=t,l="config decide")}const u=c?.pattern??p[0]?.pattern??(r?.length?this.paths.find(({id:t})=>t===r[r.length-1].route.id)?.path:void 0)??[...this.paths].reverse().find(({path:t})=>s(t,n.pathname))?.path??"(unmatched URL)";return i?.policyDecision(String(u),d,l),d}isBot(e){return t(e.headers.get("user-agent"))}shouldRenderBot(t){return"ssr"===this.bots&&this.isBot(t)}inspect(t){if(t&&!this.hasInspected){this.hasInspected=!0;for(const{pattern:e,test:i}of this.patterns){this.paths.some(({path:t})=>"/*"!==t&&(i(t)||"string"==typeof e&&Boolean(s(t,e))))||t.policyUnmatched(String(e))}}}}export{o as default};
2
2
  //# sourceMappingURL=ssr-policy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-policy.js","sources":["../../src/core/ssr-policy.ts"],"sourcesContent":[null],"names":["compilePattern","pattern","exclude","Error","regexp","pathToRegexp","RegExp","source","flags","test","pathname","lastIndex","routePaths","routes","parent","flatMap","id","path","routePath","children","startsWith","replace","SsrPolicy","active","basename","patterns","mode","bots","decide","paths","hasInspected","constructor","dataRoutes","env","process","undefined","SSR_BOOST_SSR_ROUTES","this","map","route","values","split","value","trim","filter","Boolean","length","some","isExcluded","slice","select","request","diagnostics","inspect","url","requestUrl","headers","URL","isBot","isbot","get","matched","excluded","find","decision","reverse","matchPath","policyDecision","String","policyUnmatched"],"mappings":"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"}
1
+ {"version":3,"file":"ssr-policy.js","sources":["../../src/core/ssr-policy.ts"],"sourcesContent":[null],"names":["compilePattern","pattern","exclude","Error","regexp","pathToRegexp","RegExp","source","flags","test","pathname","lastIndex","routePaths","routes","parent","flatMap","id","path","routePath","children","startsWith","replace","SsrPolicy","active","basename","patterns","mode","bots","decide","paths","hasInspected","constructor","dataRoutes","env","process","undefined","SSR_BOOST_SSR_ROUTES","this","map","route","values","split","value","trim","filter","Boolean","length","some","isExcluded","slice","select","request","diagnostics","matches","inspect","url","requestUrl","headers","URL","isBot","isbot","get","matched","excluded","find","decision","reverse","matchPath","policyDecision","String","shouldRenderBot","policyUnmatched"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import e from"./create-headers.js";const t=(t,o={})=>{const{body:n,origin:r,signal:s}=o,d=e(t.headers),a=t.socket&&"encrypted"in t.socket&&t.socket.encrypted?"https":"http",h=t.headers[":authority"],i=d.get("host")??("string"==typeof h?h:null),l=new URL(r??`${a}://${i}`).origin,c=o.url??t.url??"/",p=new URL(c.startsWith("/")?l+c:c,l),y={headers:d,method:t.method,signal:s};return"GET"!==t.method&&"HEAD"!==t.method&&("body"in o?(d.delete("Content-Length"),n instanceof FormData&&d.delete("Content-Type"),y.body=n):y.body=t,y.duplex="half"),new Request(p,y)};export{t as default};
1
+ import e from"../core/request-target.js";import t from"./create-headers.js";const o=(o,r={})=>{const{body:n,origin:s,signal:d}=r,a=t(o.headers),h=o.socket&&"encrypted"in o.socket&&o.socket.encrypted?"https":"http",i=o.headers[":authority"],c=a.get("host")??("string"==typeof i?i:null),l=new URL(s??`${h}://${c}`).origin,p=r.url??o.url??"/",m=new URL(p.startsWith("/")?l+p:p,l),u={headers:a,method:o.method,signal:d};"GET"!==o.method&&"HEAD"!==o.method&&("body"in r?(a.delete("Content-Length"),n instanceof FormData&&a.delete("Content-Type"),u.body=n):u.body=o,u.duplex="half");const y=new Request(m,u);return e.set(y,p),y};export{o as default};
2
2
  //# sourceMappingURL=create-request.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-request.js","sources":["../../src/node/create-request.ts"],"sourcesContent":[null],"names":["createRequest","req","options","body","origin","signal","headers","createHeaders","protocol","socket","encrypted","authority","host","get","requestOrigin","URL","target","url","startsWith","init","method","delete","FormData","duplex","Request"],"mappings":"mCAaA,MAAMA,EAAgB,CAACC,EAAuBC,EAAiC,MAC7E,MAAMC,KAAEA,EAAIC,OAAEA,EAAMC,OAAEA,GAAWH,EAC3BI,EAAUC,EAAcN,EAAIK,SAC5BE,EACJP,EAAIQ,QAAU,cAAeR,EAAIQ,QAAUR,EAAIQ,OAAOC,UAAY,QAAU,OACxEC,EAAYV,EAAIK,QAAQ,cACxBM,EAAON,EAAQO,IAAI,UAAiC,iBAAdF,EAAyBA,EAAY,MAC3EG,EAAgB,IAAIC,IAAIX,GAAU,GAAGI,OAAcI,KAAQR,OAC3DY,EAASd,EAAQe,KAAOhB,EAAIgB,KAAO,IAKnCA,EAAM,IAAIF,IAAIC,EAAOE,WAAW,KAAOJ,EAAgBE,EAASA,EAAQF,GACxEK,EAA0C,CAC9Cb,UACAc,OAAQnB,EAAImB,OACZf,UAsBF,MAnBmB,QAAfJ,EAAImB,QAAmC,SAAfnB,EAAImB,SAC1B,SAAUlB,GACZI,EAAQe,OAAO,kBAEXlB,aAAgBmB,UAIlBhB,EAAQe,OAAO,gBAGjBF,EAAKhB,KAAOA,GAEZgB,EAAKhB,KAAOF,EAGdkB,EAAKI,OAAS,QAGT,IAAIC,QAAQP,EAAKE"}
1
+ {"version":3,"file":"create-request.js","sources":["../../src/node/create-request.ts"],"sourcesContent":[null],"names":["createRequest","req","options","body","origin","signal","headers","createHeaders","protocol","socket","encrypted","authority","host","get","requestOrigin","URL","target","url","startsWith","init","method","delete","FormData","duplex","request","Request","requestTargets","set"],"mappings":"4EAcA,MAAMA,EAAgB,CAACC,EAAuBC,EAAiC,MAC7E,MAAMC,KAAEA,EAAIC,OAAEA,EAAMC,OAAEA,GAAWH,EAC3BI,EAAUC,EAAcN,EAAIK,SAC5BE,EACJP,EAAIQ,QAAU,cAAeR,EAAIQ,QAAUR,EAAIQ,OAAOC,UAAY,QAAU,OACxEC,EAAYV,EAAIK,QAAQ,cACxBM,EAAON,EAAQO,IAAI,UAAiC,iBAAdF,EAAyBA,EAAY,MAC3EG,EAAgB,IAAIC,IAAIX,GAAU,GAAGI,OAAcI,KAAQR,OAC3DY,EAASd,EAAQe,KAAOhB,EAAIgB,KAAO,IAKnCA,EAAM,IAAIF,IAAIC,EAAOE,WAAW,KAAOJ,EAAgBE,EAASA,EAAQF,GACxEK,EAA0C,CAC9Cb,UACAc,OAAQnB,EAAImB,OACZf,UAGiB,QAAfJ,EAAImB,QAAmC,SAAfnB,EAAImB,SAC1B,SAAUlB,GACZI,EAAQe,OAAO,kBAEXlB,aAAgBmB,UAIlBhB,EAAQe,OAAO,gBAGjBF,EAAKhB,KAAOA,GAEZgB,EAAKhB,KAAOF,EAGdkB,EAAKI,OAAS,QAGhB,MAAMC,EAAU,IAAIC,QAAQR,EAAKE,GAIjC,OAFAO,EAAeC,IAAIH,EAASR,GAErBQ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lomray/vite-ssr-boost",
3
- "version": "8.4.7-beta.1",
3
+ "version": "8.5.0-beta.1",
4
4
  "description": "SSR and streaming for existing Vite + React Router apps in Data mode, without Framework mode",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,4 +1,4 @@
1
- type TRequestStage = 'router.query' | 'prepare' | 'shell.ready' | 'state.emitted' | 'stream.resolve' | 'stream.reject' | 'body.end' | 'response.end' | 'abort';
1
+ type TRequestStage = 'guard.reject' | 'router.query' | 'prepare' | 'shell.ready' | 'state.emitted' | 'stream.resolve' | 'stream.reject' | 'body.end' | 'response.end' | 'abort';
2
2
  interface ITimelineEvent {
3
3
  stage: TRequestStage;
4
4
  /** Milliseconds since the request timeline started. */
@@ -1 +1 @@
1
- {"version":3,"file":"request-timeline.js","sources":["../../src/services/request-timeline.ts"],"sourcesContent":[null],"names":["describeReason","reason","Error","message","JSON","stringify","RequestTimeline","request","events","started","performance","now","ended","aborted","constructor","this","signal","onAbort","addEventListener","once","record","stage","detail","push","at","abort","end","removeEventListener","process","env","SSR_BOOST_TIMELINE","NODE_ENV","console","info","type","method","path","URL","url","pathname","timeline","response","body","responseBody","reader","getReader","isStopped","finish","releaseLock","ReadableStream","cancel","async","pull","controller","done","isDone","value","read","close","enqueue","error","highWaterMark","Response","createTimeline","diagnostics","undefined"],"mappings":"AAsBA,MAAMA,EAAkBC,IACtB,GAAIA,aAAkBC,MACpB,OAAOD,EAAOE,QAGhB,GAAsB,iBAAXF,EACT,OAAOA,EAGT,IACE,OAAOG,KAAKC,UAAUJ,IAAW,kBACnC,CAAE,MACA,MAAO,6BACT,GAIF,MAAMK,EA4BiBC,QAxBLC,OAA2B,GAK3BC,QAAUC,YAAYC,MAK5BC,OAAQ,EAKRC,SAAU,EAKpB,WAAAC,CAIqBP,GAAAQ,KAAAR,QAAAA,EAEnB,MAAMS,OAAEA,GAAWT,EAEfS,EAAOH,QACTE,KAAKE,UAELD,EAAOE,iBAAiB,QAASH,KAAKE,QAAS,CAAEE,MAAM,GAE3D,CAGO,MAAAC,CAAOC,EAAsBC,GAC7BP,KAAKH,OACRG,KAAKP,OAAOe,KAAK,CAAEF,QAAOG,GAAId,YAAYC,MAAQI,KAAKN,WAAYa,GAEvE,CAKO,KAAAG,CAAMxB,GACNc,KAAKF,UACRE,KAAKF,SAAU,EACfE,KAAKK,OAAO,QAAS,CAAEnB,OAAQD,EAAeC,KAElD,CAGO,GAAAyB,GACDX,KAAKH,QAITG,KAAKK,OAAO,gBACZL,KAAKH,OAAQ,EACbG,KAAKR,QAAQS,OAAOW,oBAAoB,QAASZ,KAAKE,SAGjC,oBAAZW,SAC4B,MAAnCA,QAAQC,IAAIC,oBACa,eAAzBF,QAAQC,IAAIE,UAEZC,QAAQC,KACN7B,KAAKC,UAAU,CACb6B,KAAM,qBACNC,OAAQpB,KAAKR,QAAQ4B,OACrBC,KAAM,IAAIC,IAAItB,KAAKR,QAAQ+B,KAAKC,SAChCC,SAAUzB,KAAKP,UAIvB,CAGO,QAAAiC,CAASA,GACd,MAAQC,KAAMC,GAAiBF,EAE/B,IAAKE,EAGH,OAFA5B,KAAKW,MAEEe,EAGT,MAAMG,EAASD,EAAaE,YAC5B,IAAIC,GAAY,EAKhB,MAAMC,EAAS,KACbD,GAAY,EACZF,EAAOI,cACPjC,KAAKW,OAEDgB,EAAO,IAAIO,eACf,CAIEC,OAAQC,MAAOlD,IACb6C,GAAY,EACZ/B,KAAKU,MAAMxB,GAEX,UACQ2C,EAAOM,OAAOjD,EACtB,SACE8C,GACF,GAMFK,KAAMD,MAAOE,IACX,IACE,MAAQC,KAAMC,EAAMC,MAAEA,SAAgBZ,EAAOa,OAE7C,GAAIX,EACF,OAGES,GACFR,IACAM,EAAWK,SAEXL,EAAWM,QAAQH,EAEvB,CAAE,MAAOI,GACFd,IACH/B,KAAKU,MAAMmC,GACXb,IACAM,EAAWO,MAAMA,GAErB,IAGJ,CAAEC,cAAe,IAGnB,OAAO,IAAIC,SAASpB,EAAMD,EAC5B,CAKUxB,QAAU,IAAYF,KAAKU,MAAMV,KAAKR,QAAQS,OAAOf,QAIjE,MAAM8D,EAAiB,CAACxD,EAAkByD,IACxCA,GAAmC,oBAAZpC,SAA8D,MAAnCA,QAAQC,IAAIC,mBAC1D,IAAIxB,EAAgBC,QACpB0D"}
1
+ {"version":3,"file":"request-timeline.js","sources":["../../src/services/request-timeline.ts"],"sourcesContent":[null],"names":["describeReason","reason","Error","message","JSON","stringify","RequestTimeline","request","events","started","performance","now","ended","aborted","constructor","this","signal","onAbort","addEventListener","once","record","stage","detail","push","at","abort","end","removeEventListener","process","env","SSR_BOOST_TIMELINE","NODE_ENV","console","info","type","method","path","URL","url","pathname","timeline","response","body","responseBody","reader","getReader","isStopped","finish","releaseLock","ReadableStream","cancel","async","pull","controller","done","isDone","value","read","close","enqueue","error","highWaterMark","Response","createTimeline","diagnostics","undefined"],"mappings":"AAuBA,MAAMA,EAAkBC,IACtB,GAAIA,aAAkBC,MACpB,OAAOD,EAAOE,QAGhB,GAAsB,iBAAXF,EACT,OAAOA,EAGT,IACE,OAAOG,KAAKC,UAAUJ,IAAW,kBACnC,CAAE,MACA,MAAO,6BACT,GAIF,MAAMK,EA4BiBC,QAxBLC,OAA2B,GAK3BC,QAAUC,YAAYC,MAK5BC,OAAQ,EAKRC,SAAU,EAKpB,WAAAC,CAIqBP,GAAAQ,KAAAR,QAAAA,EAEnB,MAAMS,OAAEA,GAAWT,EAEfS,EAAOH,QACTE,KAAKE,UAELD,EAAOE,iBAAiB,QAASH,KAAKE,QAAS,CAAEE,MAAM,GAE3D,CAGO,MAAAC,CAAOC,EAAsBC,GAC7BP,KAAKH,OACRG,KAAKP,OAAOe,KAAK,CAAEF,QAAOG,GAAId,YAAYC,MAAQI,KAAKN,WAAYa,GAEvE,CAKO,KAAAG,CAAMxB,GACNc,KAAKF,UACRE,KAAKF,SAAU,EACfE,KAAKK,OAAO,QAAS,CAAEnB,OAAQD,EAAeC,KAElD,CAGO,GAAAyB,GACDX,KAAKH,QAITG,KAAKK,OAAO,gBACZL,KAAKH,OAAQ,EACbG,KAAKR,QAAQS,OAAOW,oBAAoB,QAASZ,KAAKE,SAGjC,oBAAZW,SAC4B,MAAnCA,QAAQC,IAAIC,oBACa,eAAzBF,QAAQC,IAAIE,UAEZC,QAAQC,KACN7B,KAAKC,UAAU,CACb6B,KAAM,qBACNC,OAAQpB,KAAKR,QAAQ4B,OACrBC,KAAM,IAAIC,IAAItB,KAAKR,QAAQ+B,KAAKC,SAChCC,SAAUzB,KAAKP,UAIvB,CAGO,QAAAiC,CAASA,GACd,MAAQC,KAAMC,GAAiBF,EAE/B,IAAKE,EAGH,OAFA5B,KAAKW,MAEEe,EAGT,MAAMG,EAASD,EAAaE,YAC5B,IAAIC,GAAY,EAKhB,MAAMC,EAAS,KACbD,GAAY,EACZF,EAAOI,cACPjC,KAAKW,OAEDgB,EAAO,IAAIO,eACf,CAIEC,OAAQC,MAAOlD,IACb6C,GAAY,EACZ/B,KAAKU,MAAMxB,GAEX,UACQ2C,EAAOM,OAAOjD,EACtB,SACE8C,GACF,GAMFK,KAAMD,MAAOE,IACX,IACE,MAAQC,KAAMC,EAAMC,MAAEA,SAAgBZ,EAAOa,OAE7C,GAAIX,EACF,OAGES,GACFR,IACAM,EAAWK,SAEXL,EAAWM,QAAQH,EAEvB,CAAE,MAAOI,GACFd,IACH/B,KAAKU,MAAMmC,GACXb,IACAM,EAAWO,MAAMA,GAErB,IAGJ,CAAEC,cAAe,IAGnB,OAAO,IAAIC,SAASpB,EAAMD,EAC5B,CAKUxB,QAAU,IAAYF,KAAKU,MAAMV,KAAKR,QAAQS,OAAOf,QAIjE,MAAM8D,EAAiB,CAACxD,EAAkByD,IACxCA,GAAmC,oBAAZpC,SAA8D,MAAnCA,QAAQC,IAAIC,mBAC1D,IAAIxB,EAAgBC,QACpB0D"}
@@ -1,2 +1,2 @@
1
- import e from"react";import{createStaticHandler as t}from"react-router";import r from"../core/handler.js";import{TEST_ORIGIN as o}from"./requests.js";import n from"./response.js";const i={header:'<!doctype html><html><head></head><body><div id="root">',footer:'</div><script type="module">/* test browser entry */<\/script></body></html>'},a=(a,s)=>({routes:m,App:c,shell:l=i,routerOptions:d,renderToStream:u=a,signal:p,timeout:f,onContext:h,onRouterReady:b,...w})=>{const y=t(m,d);let g;const v=async()=>"indexFile"in l?(g??=s(l),(await g)()):{...l};return{fetch:async(t,{isStream:i,timeout:a=f,signal:s,...m}={})=>{const l=performance.now(),d=new AbortController,g=[d.signal,p,s,t instanceof Request?t.signal:void 0].filter(e=>Boolean(e)),R=AbortSignal.any(g),S=new Request("string"==typeof t?new URL(t,o):t,{...m,signal:R});let x,E,A;const T=new Promise((e,t)=>{A=t}),C=()=>A(R.reason),j=()=>{clearTimeout(x),R.removeEventListener("abort",C)};if(R.addEventListener("abort",C,{once:!0}),void 0!==a){if(!Number.isFinite(a)||a<0)throw j(),new RangeError("timeout must be a finite, non-negative number of milliseconds.");x=setTimeout(()=>d.abort(new DOMException(`SSR test timed out after ${a}ms`,"TimeoutError")),a)}try{R.throwIfAborted();const t=r({handler:y,renderToStream:u,createApp:(t,r)=>c?e.createElement(c,{server:r.appProps},t):t},{...w,getHtml:v,onContext:e=>{({timeline:E}=e.context),h?.(e)},onRouterReady:async e=>{const t=await(b?.(e));return void 0===i?t??{}:{...t,isStream:i}}})(S);t.then(e=>{if(R.aborted)return e.body?.cancel(R.reason)}).catch(()=>{});const o=await Promise.race([t,T]);return new n(o,{started:l,timeline:E,signal:R,onComplete:j})}catch(e){throw j(),E?.abort(e),E?.end(),e}}}};export{a as default};
1
+ import e from"react";import{createStaticHandler as t}from"react-router";import o from"../core/handler.js";import{TEST_ORIGIN as r}from"./requests.js";import n from"./response.js";const a={header:'<!doctype html><html><head></head><body><div id="root">',footer:'</div><script type="module">/* test browser entry */<\/script></body></html>'},s=(s,i)=>({routes:m,App:c,shell:l=a,routerOptions:d,renderToStream:u=s,signal:p,timeout:f,onContext:b,onRouterReady:h,...w})=>{const y=t(m,d);let g;const v=new WeakMap,x=o({handler:y,renderToStream:u,createApp:(t,o)=>c?e.createElement(c,{server:o.appProps},t):t},{...w,basename:d?.basename??w.basename,getHtml:async()=>"indexFile"in l?(g??=i(l),(await g)()):{...l},onContext:e=>{v.get(e.context.request)?.onContext(e.context),b?.(e)},onRouterReady:async e=>{const t=await(h?.(e)),o=v.get(e.context.request)?.isStream;return void 0===o?t??{}:{...t,isStream:o}}});return{fetch:async(e,{isStream:t,timeout:o=f,signal:a,...s}={})=>{const i=performance.now(),m=new AbortController,c=[m.signal,p,a,e instanceof Request?e.signal:void 0].filter(e=>Boolean(e)),l=AbortSignal.any(c),d=new Request("string"==typeof e?new URL(e,r):e,{...s,signal:l});let u,b,h;const w=new Promise((e,t)=>{h=t}),y=()=>h(l.reason),g=()=>{clearTimeout(u),l.removeEventListener("abort",y)};if(l.addEventListener("abort",y,{once:!0}),void 0!==o){if(!Number.isFinite(o)||o<0)throw g(),new RangeError("timeout must be a finite, non-negative number of milliseconds.");u=setTimeout(()=>m.abort(new DOMException(`SSR test timed out after ${o}ms`,"TimeoutError")),o)}try{l.throwIfAborted(),v.set(d,{isStream:t,onContext:e=>{({timeline:b}=e)}});const e=x(d);e.then(e=>{if(l.aborted)return e.body?.cancel(l.reason)}).catch(()=>{});const o=await Promise.race([e,w]);return new n(o,{started:i,timeline:b,signal:l,onComplete:g})}catch(e){throw g(),b?.abort(e),b?.end(),e}}}};export{s as default};
2
2
  //# sourceMappingURL=create-handler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-handler.js","sources":["../../src/testing/create-handler.tsx"],"sourcesContent":[null],"names":["DEFAULT_SHELL","header","footer","testHandlerFactory","renderer","loadShell","routes","App","shell","routerOptions","renderToStream","signal","defaultSignal","timeout","defaultTimeout","onContext","onRouterReady","options","handler","createStaticHandler","fileShell","getHtml","async","fetch","input","isStream","init","started","performance","now","controller","AbortController","signals","Request","undefined","filter","item","Boolean","combined","AbortSignal","any","request","URL","TEST_ORIGIN","timer","timeline","rejectAbort","aborted","Promise","_","reject","onAbort","reason","cleanup","clearTimeout","removeEventListener","addEventListener","once","Number","isFinite","RangeError","setTimeout","abort","DOMException","throwIfAborted","pending","createHandler","createApp","children","context","React","createElement","server","appProps","params","result","then","response","body","cancel","catch","race","TestResponse","onComplete","error","end"],"mappings":"mLAyCA,MAAMA,EAA4B,CAChCC,OAAQ,0DACRC,OAAQ,gFAIJC,EACJ,CAACC,EAA2BC,IAC5B,EACEC,SACAC,MACAC,QAAQR,EACRS,gBACAC,iBAAiBN,EACjBO,OAAQC,EACRC,QAASC,EACTC,YACAC,mBACGC,MAEH,MAAMC,EAAUC,EAAoBb,EAAyBG,GAC7D,IAAIW,EAKJ,MAAMC,EAAUC,SACV,cAAed,GACjBY,IAAcf,EAAUG,UAEVY,MAGT,IAAKZ,GAGd,MAAO,CAILe,MAAOD,MAAOE,GAASC,WAAUZ,UAAUC,EAAgBH,YAAWe,GAAS,MAC7E,MAAMC,EAAUC,YAAYC,MACtBC,EAAa,IAAIC,gBACjBC,EAAU,CACdF,EAAWnB,OACXC,EACAD,EACAa,aAAiBS,QAAUT,EAAMb,YAASuB,GAC1CC,OAAQC,GAA8BC,QAAQD,IAC1CE,EAAWC,YAAYC,IAAIR,GAC3BS,EAAU,IAAIR,QACD,iBAAVT,EAAqB,IAAIkB,IAAIlB,EAAOmB,GAAenB,EAC1D,IACKE,EACHf,OAAQ2B,IAGZ,IAAIM,EACAC,EACAC,EAKJ,MAAMC,EAAU,IAAIC,QAAe,CAACC,EAAGC,KACrCJ,EAAcI,IAMVC,EAAU,IAAYL,EAAYR,EAASc,QAK3CC,EAAU,KACdC,aAAaV,GACbN,EAASiB,oBAAoB,QAASJ,IAKxC,GAFAb,EAASkB,iBAAiB,QAASL,EAAS,CAAEM,MAAM,SAEpCvB,IAAZrB,EAAuB,CACzB,IAAK6C,OAAOC,SAAS9C,IAAYA,EAAU,EAEzC,MADAwC,IACM,IAAIO,WAAW,kEAMvBhB,EAAQiB,WACN,IACE/B,EAAWgC,MACT,IAAIC,aAAa,4BAA4BlD,MAAa,iBAE9DA,EAEJ,CAEA,IACEyB,EAAS0B,iBACT,MAiCMC,EAjCQC,EACZ,CACEhD,UACAR,iBAKAyD,UAAW,CAACC,EAAUC,IACpB9D,EAAM+D,EAAAC,cAAChE,EAAG,CAACiE,OAAQH,EAAQI,UAAWL,GAAkBA,GAE5D,IACKnD,EACHI,UAKAN,UAAY2D,MACP7B,YAAa6B,EAAOL,SACvBtD,IAAY2D,IAMd1D,cAAeM,MAAOoD,IACpB,MAAMC,QAAe3D,IAAgB0D,IAErC,YAAoBxC,IAAbT,EAA0BkD,GAAU,CAAA,EAAM,IAAKA,EAAQlD,cAIpDF,CAAMkB,GAKjBwB,EACFW,KAAMC,IACL,GAAIvC,EAASS,QACX,OAAO8B,EAASC,MAAMC,OAAOzC,EAASc,UAKzC4B,MAAM,QAET,MAAMH,QAAiB7B,QAAQiC,KAAK,CAAChB,EAASlB,IAE9C,OAAO,IAAImC,EAAaL,EAAU,CAChClD,UACAkB,WACAlC,OAAQ2B,EACR6C,WAAY9B,GAEhB,CAAE,MAAO+B,GAIP,MAHA/B,IACAR,GAAUiB,MAAMsB,GAChBvC,GAAUwC,MACJD,CACR"}
1
+ {"version":3,"file":"create-handler.js","sources":["../../src/testing/create-handler.tsx"],"sourcesContent":[null],"names":["DEFAULT_SHELL","header","footer","testHandlerFactory","renderer","loadShell","routes","App","shell","routerOptions","renderToStream","signal","defaultSignal","timeout","defaultTimeout","onContext","onRouterReady","options","handler","createStaticHandler","fileShell","requestOptions","WeakMap","fetch","createHandler","createApp","children","context","React","createElement","server","appProps","basename","getHtml","async","params","get","request","result","isStream","undefined","input","init","started","performance","now","controller","AbortController","signals","Request","filter","item","Boolean","combined","AbortSignal","any","URL","TEST_ORIGIN","timer","timeline","rejectAbort","aborted","Promise","_","reject","onAbort","reason","cleanup","clearTimeout","removeEventListener","addEventListener","once","Number","isFinite","RangeError","setTimeout","abort","DOMException","throwIfAborted","set","pending","then","response","body","cancel","catch","race","TestResponse","onComplete","error","end"],"mappings":"mLAyCA,MAAMA,EAA4B,CAChCC,OAAQ,0DACRC,OAAQ,gFAIJC,EACJ,CAACC,EAA2BC,IAC5B,EACEC,SACAC,MACAC,QAAQR,EACRS,gBACAC,iBAAiBN,EACjBO,OAAQC,EACRC,QAASC,EACTC,YACAC,mBACGC,MAEH,MAAMC,EAAUC,EAAoBb,EAAyBG,GAC7D,IAAIW,EAKJ,MAUMC,EAAiB,IAAIC,QAQrBC,EAAQC,EACZ,CACEN,UACAR,iBAKAe,UAAW,CAACC,EAAUC,IACpBpB,EAAMqB,EAAAC,cAACtB,EAAG,CAACuB,OAAQH,EAAQI,UAAWL,GAAkBA,GAE5D,IACKT,EACHe,SAAUvB,GAAeuB,UAAYf,EAAQe,SAC7CC,QAhCYC,SACV,cAAe1B,GACjBY,IAAcf,EAAUG,UAEVY,MAGT,IAAKZ,GA8BVO,UAAYoB,IACVd,EAAee,IAAID,EAAOR,QAAQU,UAAUtB,UAAUoB,EAAOR,SAC7DZ,IAAYoB,IAMdnB,cAAekB,MAAOC,IACpB,MAAMG,QAAetB,IAAgBmB,IAE/BI,EAAWlB,EAAee,IAAID,EAAOR,QAAQU,UAAUE,SAE7D,YAAoBC,IAAbD,EAA0BD,GAAU,CAAA,EAAM,IAAKA,EAAQC,eAKpE,MAAO,CAILhB,MAAOW,MAAOO,GAASF,WAAU1B,UAAUC,EAAgBH,YAAW+B,GAAS,MAC7E,MAAMC,EAAUC,YAAYC,MACtBC,EAAa,IAAIC,gBACjBC,EAAU,CACdF,EAAWnC,OACXC,EACAD,EACA8B,aAAiBQ,QAAUR,EAAM9B,YAAS6B,GAC1CU,OAAQC,GAA8BC,QAAQD,IAC1CE,EAAWC,YAAYC,IAAIP,GAC3BX,EAAU,IAAIY,QACD,iBAAVR,EAAqB,IAAIe,IAAIf,EAAOgB,GAAehB,EAC1D,IACKC,EACH/B,OAAQ0C,IAGZ,IAAIK,EACAC,EACAC,EAKJ,MAAMC,EAAU,IAAIC,QAAe,CAACC,EAAGC,KACrCJ,EAAcI,IAMVC,EAAU,IAAYL,EAAYP,EAASa,QAK3CC,EAAU,KACdC,aAAaV,GACbL,EAASgB,oBAAoB,QAASJ,IAKxC,GAFAZ,EAASiB,iBAAiB,QAASL,EAAS,CAAEM,MAAM,SAEpC/B,IAAZ3B,EAAuB,CACzB,IAAK2D,OAAOC,SAAS5D,IAAYA,EAAU,EAEzC,MADAsD,IACM,IAAIO,WAAW,kEAMvBhB,EAAQiB,WACN,IACE7B,EAAW8B,MACT,IAAIC,aAAa,4BAA4BhE,MAAa,iBAE9DA,EAEJ,CAEA,IACEwC,EAASyB,iBACTzD,EAAe0D,IAAI1C,EAAS,CAC1BE,WAEAxB,UAAYY,MACPgC,YAAahC,MAGpB,MAAMqD,EAAUzD,EAAMc,GAKjB2C,EACFC,KAAMC,IACL,GAAI7B,EAASQ,QACX,OAAOqB,EAASC,MAAMC,OAAO/B,EAASa,UAKzCmB,MAAM,QAET,MAAMH,QAAiBpB,QAAQwB,KAAK,CAACN,EAASnB,IAE9C,OAAO,IAAI0B,EAAaL,EAAU,CAChCvC,UACAgB,WACAhD,OAAQ0C,EACRmC,WAAYrB,GAEhB,CAAE,MAAOsB,GAIP,MAHAtB,IACAR,GAAUiB,MAAMa,GAChB9B,GAAU+B,MACJD,CACR"}