@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.
- package/README.md +2 -0
- package/adapters/express/entry.d.ts +4 -3
- package/adapters/express/entry.js +1 -1
- package/adapters/express/entry.js.map +1 -1
- package/adapters/express/render.d.ts +12 -2
- package/adapters/express/render.js +1 -1
- package/adapters/express/render.js.map +1 -1
- package/adapters/express/server.js +1 -1
- package/adapters/express/server.js.map +1 -1
- package/cli/doctor.js +1 -1
- package/cli/doctor.js.map +1 -1
- package/cloudflare.js +1 -1
- package/cloudflare.js.map +1 -1
- package/core/admission.d.ts +53 -0
- package/core/admission.js +2 -0
- package/core/admission.js.map +1 -0
- package/core/handler-runtime.d.ts +39 -0
- package/core/handler-runtime.js +2 -0
- package/core/handler-runtime.js.map +1 -0
- package/core/handler.d.ts +7 -6
- package/core/handler.js +1 -1
- package/core/handler.js.map +1 -1
- package/core/not-found.d.ts +46 -0
- package/core/not-found.js +2 -0
- package/core/not-found.js.map +1 -0
- package/core/render.d.ts +10 -0
- package/core/render.js +1 -1
- package/core/render.js.map +1 -1
- package/core/request-guard.d.ts +78 -0
- package/core/request-guard.js +2 -0
- package/core/request-guard.js.map +1 -0
- package/core/request-target.d.ts +3 -0
- package/core/request-target.js +2 -0
- package/core/request-target.js.map +1 -0
- package/core/ssr-policy.d.ts +6 -2
- package/core/ssr-policy.js +1 -1
- package/core/ssr-policy.js.map +1 -1
- package/node/create-request.js +1 -1
- package/node/create-request.js.map +1 -1
- package/package.json +1 -1
- package/services/request-timeline.d.ts +1 -1
- package/services/request-timeline.js.map +1 -1
- package/testing/create-handler.js +1 -1
- 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
|
|
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","
|
|
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
|
|
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","
|
|
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
|
|
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","
|
|
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
|
|
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
|
|
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":"
|
|
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
|
|
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
|
|
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
|
package/core/handler.js.map
CHANGED
|
@@ -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","
|
|
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{
|
|
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
|
package/core/render.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sources":["../../src/core/render.tsx"],"sourcesContent":[null],"names":["HTML_CONTENT_TYPE","CONTENT_TYPE","
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"request-target.js","sources":["../../src/core/request-target.ts"],"sourcesContent":[null],"names":["requestTargets","WeakMap"],"mappings":"AACA,MAAMA,EAAiB,IAAIC"}
|
package/core/ssr-policy.d.ts
CHANGED
|
@@ -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.
|
package/core/ssr-policy.js
CHANGED
|
@@ -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
|
|
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
|
package/core/ssr-policy.js.map
CHANGED
|
@@ -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":"qHA6BA,MAAMA,EAAiB,CAACC,EAA0BC,KAChD,GAAgB,KAAZD,EACF,MAAM,IAAIE,MAAM,uCAGlB,MAAMC,EACe,iBAAZH,EACHI,EAAaJ,GAASG,OACtB,IAAIE,OAAOL,EAAQM,OAAQN,EAAQO,OAEzC,MAAO,CACLP,UACAC,UAKAO,KAAOC,IACLN,EAAOO,UAAY,EAEZP,EAAOK,KAAKC,MAQnBE,EAAa,CACjBC,EACAC,EAAS,KAETD,EAAOE,QAAQ,EAAGC,KAAIC,KAAMC,EAAWC,eACrC,MAAMF,GACHC,GAAWE,WAAW,KAAOF,EAAY,GAAGJ,KAAUI,GAAa,MACjEG,QAAQ,OAAQ,KAChBA,QAAQ,MAAO,KAAO,IAE3B,MAAO,CAAC,CAAEL,KAAIC,WAAWL,EAAWO,GAAY,GAAIF,MAMxD,MAAMK,EAIYC,OAKAC,SAKGC,SAKAC,KAKAC,KAKAC,OAKArB,OAKAsB,MAKTC,cAAe,EAKzB,WAAAC,EACEL,KAAEA,EAAO,MAAKb,OAAEA,EAAS,GAAEc,KAAEA,EAAO,MAAKC,OAAEA,GAAuB,GAClEI,EAA0C,GAC1CR,EAAW,IACXS,GAAyB,oBAAZC,aAA0BC,EAAYD,QAAQD,IAAIG,uBAa/D,GAXAC,KAAKb,SAAWA,EAChBa,KAAKV,KAAOA,EAKZU,KAAKR,MAAQjB,EAAWoB,GAAYM,IAAKC,IAAK,IACzCA,EACHtB,KAAM,GAAGO,EAASH,QAAQ,MAAO,MAAMkB,EAAMtB,eAGnCkB,IAARF,EAAmB,CACrB,MAAMO,EAASP,EACZQ,MAAM,KACNH,IAAKI,GAAUA,EAAMC,QACrBC,OAAOC,SAEVR,KAAKX,KAAQc,EAAOM,OAEhBN,EAAOO,KAAML,IAAWA,EAAMtB,WAAW,MACvC,UACA,UAHF,MAQJiB,KAAKZ,SAAWe,EAAOF,IAAKI,IAC1B,MAAMM,EAAaN,EAAMtB,WAAW,KAEpC,OAAOpB,EAAegD,EAAaN,EAAMO,MAAM,GAAKP,EAAOM,KAE7DX,KAAK9B,OAAS,sBAChB,MACE8B,KAAKX,KAAOA,EACZW,KAAKZ,SACM,QAATC,EAAiB,GAAKb,EAAOyB,IAAKrC,GAAYD,EAAeC,EAAkB,YAATyB,IACxEW,KAAKT,OAASA,EACdS,KAAK9B,OAAS,SAGhB8B,KAAKd,OAAuB,QAAdc,KAAKX,MAAkBmB,QAAQR,KAAKT,OACpD,CAKO,MAAAsB,
|
|
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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"}
|
package/node/create-request.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"./create-headers.js";const
|
|
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":"
|
|
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,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":"
|
|
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
|
|
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","
|
|
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"}
|