@lomray/vite-ssr-boost 8.4.0-beta.1 → 8.4.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +2 -0
  2. package/adapters/express/entry.d.ts +4 -1
  3. package/adapters/express/entry.js +1 -1
  4. package/adapters/express/entry.js.map +1 -1
  5. package/adapters/express/render.d.ts +9 -2
  6. package/adapters/express/render.js +1 -1
  7. package/adapters/express/render.js.map +1 -1
  8. package/adapters/express/server.js +1 -1
  9. package/adapters/express/server.js.map +1 -1
  10. package/browser/entry.js +1 -1
  11. package/browser/entry.js.map +1 -1
  12. package/core/compose-html.d.ts +2 -1
  13. package/core/compose-html.js +1 -1
  14. package/core/compose-html.js.map +1 -1
  15. package/core/data-stream.d.ts +3 -1
  16. package/core/data-stream.js +1 -1
  17. package/core/data-stream.js.map +1 -1
  18. package/core/handler.d.ts +12 -3
  19. package/core/handler.js +1 -1
  20. package/core/handler.js.map +1 -1
  21. package/core/render.d.ts +11 -2
  22. package/core/render.js +1 -1
  23. package/core/render.js.map +1 -1
  24. package/core/spa-html.d.ts +6 -0
  25. package/core/spa-html.js +2 -0
  26. package/core/spa-html.js.map +1 -0
  27. package/core/spa-shell.d.ts +7 -0
  28. package/core/spa-shell.js +2 -0
  29. package/core/spa-shell.js.map +1 -0
  30. package/core/ssr-policy.d.ts +51 -0
  31. package/core/ssr-policy.js +2 -0
  32. package/core/ssr-policy.js.map +1 -0
  33. package/package.json +31 -1
  34. package/plugins/create-spa-index.js +1 -1
  35. package/plugins/create-spa-index.js.map +1 -1
  36. package/services/diagnostics.d.ts +11 -3
  37. package/services/diagnostics.js +1 -1
  38. package/services/diagnostics.js.map +1 -1
  39. package/services/request-timeline.d.ts +30 -0
  40. package/services/request-timeline.js +2 -0
  41. package/services/request-timeline.js.map +1 -0
  42. package/services/route-assets.d.ts +4 -2
  43. package/services/route-assets.js +1 -1
  44. package/services/route-assets.js.map +1 -1
  45. package/services/ssr-manifest.d.ts +7 -3
  46. package/services/ssr-manifest.js +1 -1
  47. package/services/ssr-manifest.js.map +1 -1
  48. package/testing/browser-observer.d.ts +30 -0
  49. package/testing/browser-observer.js +2 -0
  50. package/testing/browser-observer.js.map +1 -0
  51. package/testing/create-handler.d.ts +32 -0
  52. package/testing/create-handler.js +2 -0
  53. package/testing/create-handler.js.map +1 -0
  54. package/testing/deferred.d.ts +9 -0
  55. package/testing/deferred.js +2 -0
  56. package/testing/deferred.js.map +1 -0
  57. package/testing/edge.d.ts +9 -0
  58. package/testing/edge.js +2 -0
  59. package/testing/edge.js.map +1 -0
  60. package/testing/parse-response.d.ts +12 -0
  61. package/testing/parse-response.js +2 -0
  62. package/testing/parse-response.js.map +1 -0
  63. package/testing/playwright.d.ts +17 -0
  64. package/testing/playwright.js +2 -0
  65. package/testing/playwright.js.map +1 -0
  66. package/testing/requests.d.ts +6 -0
  67. package/testing/requests.js +2 -0
  68. package/testing/requests.js.map +1 -0
  69. package/testing/response.d.ts +46 -0
  70. package/testing/response.js +2 -0
  71. package/testing/response.js.map +1 -0
  72. package/testing.d.ts +9 -0
  73. package/testing.js +2 -0
  74. package/testing.js.map +1 -0
@@ -0,0 +1,7 @@
1
+ import type { IHtmlShell } from './handler.js';
2
+ /**
3
+ * Cache generation for the current template, returning isolated mutable request shells.
4
+ * Compare the source so development edits and request-specific getHtml values stay fresh.
5
+ */
6
+ declare const createSpaShell: () => ((html: IHtmlShell) => IHtmlShell);
7
+ export default createSpaShell;
@@ -0,0 +1,2 @@
1
+ import e from"./spa-html.js";const r=()=>{let r,o;return t=>(r?.header===t.header&&r?.footer===t.footer||(r={...t},o={header:e(t.header),footer:t.footer}),{...o})};export{r as default};
2
+ //# sourceMappingURL=spa-shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spa-shell.js","sources":["../../src/core/spa-shell.ts"],"sourcesContent":[null],"names":["createSpaShell","source","shell","html","header","footer","createSpaHtml"],"mappings":"6BAOA,MAAMA,EAAiB,KACrB,IAAIC,EACAC,EAEJ,OAAQC,IACFF,GAAQG,SAAWD,EAAKC,QAAUH,GAAQI,SAAWF,EAAKE,SAC5DJ,EAAS,IAAKE,GACdD,EAAQ,CAAEE,OAAQE,EAAcH,EAAKC,QAASC,OAAQF,EAAKE,SAGtD,IAAKH"}
@@ -0,0 +1,51 @@
1
+ import type { StaticHandler } from 'react-router';
2
+ import type Diagnostics from '../services/diagnostics.js';
3
+ type TRenderMode = 'ssr' | 'spa';
4
+ interface ISsrPolicy {
5
+ mode?: 'all' | 'include' | 'exclude';
6
+ routes?: (string | RegExp)[];
7
+ bots?: 'ssr' | 'policy';
8
+ decide?: (params: {
9
+ request: Request;
10
+ url: URL;
11
+ isBot: boolean;
12
+ }) => TRenderMode | undefined;
13
+ }
14
+ interface IPolicyPattern {
15
+ pattern: string | RegExp;
16
+ exclude: boolean;
17
+ test: (pathname: string) => boolean;
18
+ }
19
+ /**
20
+ * Collect URL paths alongside their route ids without resolving lazy modules or loaders.
21
+ */
22
+ declare const routePaths: (routes: StaticHandler["dataRoutes"], parent?: string) => {
23
+ id: string;
24
+ path: string;
25
+ }[];
26
+ /**
27
+ * Snapshot environment policy when the application entry/handler is created at startup.
28
+ */
29
+ declare class SsrPolicy {
30
+ readonly active: boolean;
31
+ readonly basename: string;
32
+ protected readonly patterns: IPolicyPattern[];
33
+ protected readonly mode: NonNullable<ISsrPolicy['mode']>;
34
+ protected readonly bots: NonNullable<ISsrPolicy['bots']>;
35
+ protected readonly decide?: ISsrPolicy['decide'];
36
+ protected readonly source: string;
37
+ protected readonly paths: ReturnType<typeof routePaths>;
38
+ protected hasInspected: boolean;
39
+ constructor({ mode, routes, bots, decide }?: ISsrPolicy, dataRoutes?: StaticHandler['dataRoutes'], basename?: string, env?: string | undefined);
40
+ /**
41
+ * Explain typos using declared paths, including concrete URLs for dynamic route ids.
42
+ * A global 404 catch-all must not hide a misspelled policy.
43
+ */
44
+ protected inspect(diagnostics?: Diagnostics): void;
45
+ /**
46
+ * Crawler protection wins over both runtime decisions and environment rollback rules.
47
+ */
48
+ select(request: Request, diagnostics?: Diagnostics): TRenderMode;
49
+ }
50
+ export type { ISsrPolicy, TRenderMode };
51
+ export default SsrPolicy;
@@ -0,0 +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(t=>{const s=(t.path?.startsWith("/")?t.path:`${e}/${t.path??""}`).replace(/\/+/g,"/").replace(/\/$/,"")||"/";return[{id:t.id,path:s},...r(t.children??[],s)]});class a{active;basename;patterns;mode;bots;decide;source;paths;hasInspected=!1;constructor({mode:t="all",routes:e=[],bots:s="ssr",decide:a}={},o=[],n="/",p=("undefined"==typeof process?void 0:process.env.SSR_BOOST_SSR_ROUTES)){if(this.basename=n,this.bots=s,this.paths=r(o).map(t=>({...t,path:`${n.replace(/\/$/,"")}${t.path}`})),void 0!==p){const t=p.split(",").map(t=>t.trim()).filter(Boolean);this.mode=t.length?t.some(t=>!t.startsWith("!"))?"include":"exclude":"all",this.patterns=t.map(t=>{const e=t.startsWith("!");return i(e?t.slice(1):t,e)}),this.source="SSR_BOOST_SSR_ROUTES"}else this.mode=t,this.patterns="all"===t?[]:e.map(e=>i(e,"exclude"===t)),this.decide=a,this.source="config";this.active="all"!==this.mode||Boolean(this.decide)}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))}}}select(e,i){if(!this.active)return"ssr";this.inspect(i);const r=new URL(e.url),a=t(e.headers.get("user-agent")),o=this.patterns.filter(({test:t})=>t(r.pathname)),n=o.find(({exclude:t})=>t);let p=n||"include"===this.mode&&!o.length?"spa":"ssr",h=`${this.source} ${this.mode}`;if(a&&"ssr"===this.bots)p="ssr",h="bots: ssr";else{const t=this.decide?.({request:e,url:r,isBot:a});void 0!==t&&(p=t,h="config decide")}const c=n?.pattern??o[0]?.pattern??[...this.paths].reverse().find(({path:t})=>s(t,r.pathname))?.path??"(unmatched URL)";return i?.policyDecision(String(c),p,h),p}}export{a as default};
2
+ //# sourceMappingURL=ssr-policy.js.map
@@ -0,0 +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","route","path","startsWith","replace","id","children","SsrPolicy","active","basename","patterns","mode","bots","decide","paths","hasInspected","constructor","dataRoutes","env","process","undefined","SSR_BOOST_SSR_ROUTES","this","map","values","split","value","trim","filter","Boolean","length","some","isExcluded","slice","inspect","diagnostics","matchPath","policyUnmatched","String","select","request","url","URL","isBot","isbot","headers","get","matched","excluded","find","decision","reverse","policyDecision"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lomray/vite-ssr-boost",
3
- "version": "8.4.0-beta.1",
3
+ "version": "8.4.0-beta.3",
4
4
  "description": "SSR and streaming for existing Vite + React Router apps in Data mode, without Framework mode",
5
5
  "type": "module",
6
6
  "exports": {
@@ -25,6 +25,30 @@
25
25
  "./*": {
26
26
  "types": "./*.d.ts",
27
27
  "default": "./*.js"
28
+ },
29
+ "./testing": {
30
+ "types": "./testing.d.ts",
31
+ "workerd": "./testing/edge.js",
32
+ "worker": "./testing/edge.js",
33
+ "edge-light": "./testing/edge.js",
34
+ "browser": "./testing/edge.js",
35
+ "default": "./testing.js"
36
+ },
37
+ "./testing.js": {
38
+ "types": "./testing.d.ts",
39
+ "workerd": "./testing/edge.js",
40
+ "worker": "./testing/edge.js",
41
+ "edge-light": "./testing/edge.js",
42
+ "browser": "./testing/edge.js",
43
+ "default": "./testing.js"
44
+ },
45
+ "./testing/playwright": {
46
+ "types": "./testing/playwright.d.ts",
47
+ "default": "./testing/playwright.js"
48
+ },
49
+ "./testing/playwright.js": {
50
+ "types": "./testing/playwright.d.ts",
51
+ "default": "./testing/playwright.js"
28
52
  }
29
53
  },
30
54
  "keywords": [
@@ -77,8 +101,10 @@
77
101
  "devalue": "^5.9.2",
78
102
  "diff": "^9.0.0",
79
103
  "hoist-non-react-statics": "^3.3.2",
104
+ "isbot": "^5.2.2",
80
105
  "json5": "^2.2.3",
81
106
  "parse5": "^8.0.1",
107
+ "path-to-regexp": "^8.4.2",
82
108
  "semver": "^7.8.5"
83
109
  },
84
110
  "optionalDependencies": {
@@ -144,6 +170,7 @@
144
170
  "@babel/parser": ">=7.23.0",
145
171
  "@babel/traverse": ">=7.23.0",
146
172
  "@babel/types": ">=7.23.0",
173
+ "@playwright/test": ">=1.40.0",
147
174
  "@types/compression": ">=1.7.5",
148
175
  "@types/express": ">=4.17.21",
149
176
  "@types/serve-static": ">=1.15.5",
@@ -161,6 +188,9 @@
161
188
  },
162
189
  "@types/serve-static": {
163
190
  "optional": true
191
+ },
192
+ "@playwright/test": {
193
+ "optional": true
164
194
  }
165
195
  },
166
196
  "overrides": {
@@ -1,2 +1,2 @@
1
- import e from"../constants/plugin-name.js";import{getCurrentEntrypointName as t}from"./handle-custom-entrypoint.js";const n=`${e}-create-spa-entrypoint`;function o(e={}){const{filename:o="index-spa.html",rootId:a="root"}=e;let r="";return{name:n,enforce:"post",apply:(e,{command:n,isSsrBuild:o})=>"build"===n&&!o&&!t(),transformIndexHtml:e=>(r=e.replace(`id="${a}"`,`id="${a}" data-force-spa="1"`),e),generateBundle(){r&&this.emitFile({type:"asset",fileName:o,source:r})}}}export{o as default};
1
+ import t from"../constants/plugin-name.js";import e from"../core/spa-html.js";import{getCurrentEntrypointName as o}from"./handle-custom-entrypoint.js";const n=`${t}-create-spa-entrypoint`;function r(t={}){const{filename:r="index-spa.html",rootId:s="root"}=t;let m="";return{name:n,enforce:"post",apply:(t,{command:e,isSsrBuild:n})=>"build"===e&&!n&&!o(),transformIndexHtml:t=>(m=e(t,s),t),generateBundle(){m&&this.emitFile({type:"asset",fileName:r,source:m})}}}export{r as default};
2
2
  //# sourceMappingURL=create-spa-index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-spa-index.js","sources":["../../src/plugins/create-spa-index.ts"],"sourcesContent":[null],"names":["pluginName","PLUGIN_NAME","ViteCreateSPAIndexPlugin","options","filename","rootId","spaHtml","name","enforce","apply","_","command","isSsrBuild","getCurrentEntrypointName","transformIndexHtml","html","replace","generateBundle","this","emitFile","type","fileName","source"],"mappings":"oHASA,MAAMA,EAAa,GAAGC,0BAStB,SAASC,EAAyBC,EAA0B,IAC1D,MAAMC,SAAEA,EAAW,iBAAgBC,OAAEA,EAAS,QAAWF,EACzD,IAAIG,EAAU,GAEd,MAAO,CACLC,KAAMP,EACNQ,QAAS,OAITC,MAAK,CAACC,GAAGC,QAAEA,EAAOC,WAAEA,KACC,UAAZD,IAAwBC,IAAeC,IAEhDC,mBAAmBC,IACjBT,EAAUS,EAAKC,QAAQ,OAAOX,KAAW,OAAOA,yBAEzCU,GAET,cAAAE,GACOX,GAILY,KAAKC,SAAS,CACZC,KAAM,QACNC,SAAUjB,EACVkB,OAAQhB,GAEZ,EAEJ"}
1
+ {"version":3,"file":"create-spa-index.js","sources":["../../src/plugins/create-spa-index.ts"],"sourcesContent":[null],"names":["pluginName","PLUGIN_NAME","ViteCreateSPAIndexPlugin","options","filename","rootId","spaHtml","name","enforce","apply","_","command","isSsrBuild","getCurrentEntrypointName","transformIndexHtml","html","createSpaHtml","generateBundle","this","emitFile","type","fileName","source"],"mappings":"uJAUA,MAAMA,EAAa,GAAGC,0BAStB,SAASC,EAAyBC,EAA0B,IAC1D,MAAMC,SAAEA,EAAW,iBAAgBC,OAAEA,EAAS,QAAWF,EACzD,IAAIG,EAAU,GAEd,MAAO,CACLC,KAAMP,EACNQ,QAAS,OAITC,MAAK,CAACC,GAAGC,QAAEA,EAAOC,WAAEA,KACC,UAAZD,IAAwBC,IAAeC,IAEhDC,mBAAmBC,IACjBT,EAAUU,EAAcD,EAAMV,GAEvBU,GAET,cAAAE,GACOX,GAILY,KAAKC,SAAS,CACZC,KAAM,QACNC,SAAUjB,EACVkB,OAAQhB,GAEZ,EAEJ"}
@@ -1,6 +1,6 @@
1
1
  import type { StaticHandlerContext } from 'react-router';
2
2
  import Logger from './logger.js';
3
- type TDiagnosticCode = 'SSR_BOOST_CACHE_PRIVATE_LEAK' | 'SSR_BOOST_DEPRECATED_REQ_RES' | 'SSR_BOOST_LOADER_NOT_SERIALIZABLE' | 'SSR_BOOST_STREAM_PROMISE_ABORTED' | 'SSR_BOOST_STATE_NOT_SERIALIZABLE' | 'SSR_BOOST_OUTLET_MISSING' | 'SSR_BOOST_HYDRATION_STATE_MISSING' | 'SSR_BOOST_DUPLICATE_OUTPUT' | 'SSR_BOOST_ONRESPONSE_INVALID_RETURN';
3
+ type TDiagnosticCode = 'SSR_BOOST_CACHE_PRIVATE_LEAK' | 'SSR_BOOST_DEPRECATED_REQ_RES' | 'SSR_BOOST_SSR_POLICY' | 'SSR_BOOST_SSR_POLICY_UNMATCHED' | 'SSR_BOOST_LOADER_NOT_SERIALIZABLE' | 'SSR_BOOST_STREAM_PROMISE_ABORTED' | 'SSR_BOOST_STATE_NOT_SERIALIZABLE' | 'SSR_BOOST_OUTLET_MISSING' | 'SSR_BOOST_HYDRATION_STATE_MISSING' | 'SSR_BOOST_DUPLICATE_OUTPUT' | 'SSR_BOOST_ONRESPONSE_INVALID_RETURN';
4
4
  interface ISerializationIssue {
5
5
  path: string;
6
6
  reason: string;
@@ -27,15 +27,23 @@ declare const walkSerializable: (value: unknown, report: (issue: ISerializationI
27
27
  */
28
28
  declare class Diagnostics {
29
29
  protected readonly route: string;
30
- protected readonly logger: Pick<Logger, 'warn'>;
30
+ protected readonly logger: Pick<Logger, 'warn'> & Partial<Pick<Logger, 'info'>>;
31
31
  protected chunks: string[];
32
- constructor(route: string, logger?: Pick<Logger, 'warn'>);
32
+ constructor(route: string, logger?: Pick<Logger, 'warn'> & Partial<Pick<Logger, 'info'>>);
33
33
  /**
34
34
  * Emit each concrete message once per process, including across handler instances.
35
35
  */
36
36
  protected warn(code: TDiagnosticCode, detail: string): void;
37
37
  /** Warn once for either legacy Express field, regardless of route or hook. */
38
38
  deprecatedReqRes(): void;
39
+ /**
40
+ * Report policy choices without logging concrete parameter, cookie or query values.
41
+ */
42
+ policyDecision(pattern: string, mode: string, source: string): void;
43
+ /**
44
+ * Warn once for a configured pattern with no corresponding route id.
45
+ */
46
+ policyUnmatched(pattern: string): void;
39
47
  /**
40
48
  * A split Fetch shell has one insertion boundary and must not retain raw outlets.
41
49
  */
@@ -1,2 +1,2 @@
1
- import t from"./logger.js";const e="\x3c!--ssr-outlet--\x3e",o="window.__staticRouterHydrationData",s=Symbol.for("@lomray/vite-ssr-boost/diagnostics"),r=globalThis,n=t=>{const e="undefined"==typeof process?void 0:process.env;return"0"===e?.SSR_BOOST_DIAGNOSTICS||"1"===e?.SSR_BOOST_DIAGNOSTICS?"1"===e.SSR_BOOST_DIAGNOSTICS:t??"production"!==e?.NODE_ENV},i=(t,e)=>`[ssr-boost] ${t}: ${e} See https://lomray-software.github.io/vite-ssr-boost/reference/diagnostics#${t.toLowerCase()}`,a=(t,o,s=e)=>{const r=t.split(s);if(!s||2!==r.length)throw new Error(i("SSR_BOOST_OUTLET_MISSING",`Invalid HTML shell in ${JSON.stringify(o)}: expected exactly one non-empty outlet ${JSON.stringify(s)}.`));return r},c=t=>{if(null===t)return"null";if("object"!=typeof t){return{bigint:"BigInt",symbol:"Symbol"}[typeof t]??typeof t}const e=Object.getPrototypeOf(t),o=e?.constructor?.name;return"string"==typeof o&&o?o:"object"},S=(t,e,o="$",s=new Set,r=!1)=>{const n=typeof t;if(r&&(t instanceof Promise||t instanceof Date||t instanceof RegExp||"bigint"===n))return;if("function"===n||"bigint"===n||"symbol"===n)return void e({path:o,reason:`${c(t)} is not JSON-serializable`});if(null===t||"object"!==n)return;const i=t,a=Object.getPrototypeOf(i);if(!(r&&(i instanceof Map||i instanceof Set)||a===Object.prototype||null===a||Array.isArray(i)&&a===Array.prototype)){const t=c(i);return void e({path:o,reason:"Date"===t?"Date hydrates as a string":`${t} is not JSON-serializable`})}if(s.has(i))return void e({path:o,reason:"a circular reference is not JSON-serializable"});s.add(i);const f=r&&i instanceof Map?[...i].flatMap(([t,e],o)=>[[`${o}.key`,t],[`${o}.value`,e]]):r&&i instanceof Set?[...i].map((t,e)=>[String(e),t]):Object.entries(i);for(const[t,n]of f){const a=Array.isArray(i)&&/^(0|[1-9]\d*)$/.test(t)?`[${t}]`:/^[A-Za-z_$][\w$]*$/.test(t)?`.${t}`:`[${JSON.stringify(t)}]`;S(n,e,o+a,s,r)}s.delete(i)};class f{route;logger;chunks=[];constructor(e,o=new t){this.route=e,this.logger=o}warn(t,e){const o=i(t,e),n=r[s]??=new Set;n.has(o)||(n.add(o),this.logger.warn(o,{}))}deprecatedReqRes(){this.warn("SSR_BOOST_DEPRECATED_REQ_RES","context.req and context.res are deprecated in 8.x and planned for removal in 9.0; use context.request, context.response.headers/context.response.status and React Router HTTP helpers such as redirect().")}inspectShell({header:t,footer:o}){("string"!=typeof t||"string"!=typeof o||t.includes(e)||o.includes(e))&&this.warn("SSR_BOOST_OUTLET_MISSING",`HTML shell for route ${JSON.stringify(this.route)} must supply both header and footer around exactly one ${e} outlet, with no outlet left in either half.`)}inspectCachePolicy(t,e){/(?:^|,)\s*public\s*(?:,|$)/i.test(t.get("Cache-Control")??"")&&(t.has("Set-Cookie")||e)&&this.warn("SSR_BOOST_CACHE_PRIVATE_LEAK",`Response for route ${JSON.stringify(this.route)} is public with Set-Cookie or a session cookie. Use private, no-store and bypass the shared cache for authenticated requests.`)}inspectRouterState({loaderData:t,actionData:e}){for(const[o,s]of Object.entries({loaderData:t,actionData:e}))for(const[t,e]of Object.entries(s??{}))S(e,({path:e,reason:o})=>this.warn("SSR_BOOST_LOADER_NOT_SERIALIZABLE",`Route ${JSON.stringify(t)} at ${e}: ${o}.`),`${o}[${JSON.stringify(t)}]`,new Set,!0)}streamAborted(t){this.warn("SSR_BOOST_STREAM_PROMISE_ABORTED",`Route ${JSON.stringify(this.route)} aborted with ${t} pending loader/action promise(s); the browser receives a rejection when connected.`)}inspectStreamValue(t,e){S(t,({path:t,reason:e})=>this.warn("SSR_BOOST_LOADER_NOT_SERIALIZABLE",`Route ${JSON.stringify(this.route)} at ${t}: ${e}.`),`promise[${e}]`,new Set,!0)}inspectState(t){S(t,({path:t,reason:e})=>this.warn("SSR_BOOST_STATE_NOT_SERIALIZABLE",`getState for route ${JSON.stringify(this.route)} at ${t}: ${e}.`))}inspectOnResponse(t){void 0!==t&&"string"!=typeof t&&this.warn("SSR_BOOST_ONRESPONSE_INVALID_RETURN",`onResponse for route ${JSON.stringify(this.route)} returned ${c(t)}; return a string or undefined.`)}append(t){this.chunks.push(t)}complete(){const t=this.chunks.join("");this.chunks=[];const e=new Map,s=t=>{e.set(t,(e.get(t)??0)+1)},r=t.replace(/<!--[\s\S]*?-->/g,"").replace(/(<(script|style|textarea|title)\b(?:[^"'<>]|"[^"]*"|'[^']*')*>)([\s\S]*?)<\/\2\s*>/gi,(t,e,r,n)=>{if("script"===r.toLowerCase()){/\bwindow\.__staticRouterHydrationData\s*=/.test(n)&&s(o);for(const t of n.matchAll(/\$RC\s*\(\s*(["'])(B:[^"']+)\1/g))s(`$RC("${t[2]}")`)}return e});for(const t of r.matchAll(/<([a-z][\w:-]*)\b((?:[^"'<>]|"[^"]*"|'[^']*')*)>/gi)){const e=t[1].toLowerCase();"html"!==e&&"head"!==e||s(`<${e}>`);for(const e of t[2].matchAll(/([^\s=]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/g)){const t=e[2]??e[3]??e[4];"id"===e[1].toLowerCase()&&/^(S|B):/.test(t)&&s(`id="${t}"`)}}e.has(o)||this.warn("SSR_BOOST_HYDRATION_STATE_MISSING",`Completed response for route ${JSON.stringify(this.route)} has no ${o} script; preserve the hydration footer in onResponse.`);for(const[t,o]of e)o>1&&this.warn("SSR_BOOST_DUPLICATE_OUTPUT",`Completed response for route ${JSON.stringify(this.route)} repeats ${t}; onResponse must return undefined to keep a chunk and '' to withhold one.`)}}export{f as default,i as formatDiagnostic,n as isDiagnosticsEnabled,a as splitHtmlShell,S as walkSerializable};
1
+ import t from"./logger.js";const e="\x3c!--ssr-outlet--\x3e",o="window.__staticRouterHydrationData",s=Symbol.for("@lomray/vite-ssr-boost/diagnostics"),r=globalThis,n=t=>{const e="undefined"==typeof process?void 0:process.env;return"0"===e?.SSR_BOOST_DIAGNOSTICS||"1"===e?.SSR_BOOST_DIAGNOSTICS?"1"===e.SSR_BOOST_DIAGNOSTICS:t??"production"!==e?.NODE_ENV},i=(t,e)=>`[ssr-boost] ${t}: ${e} See https://lomray-software.github.io/vite-ssr-boost/reference/diagnostics#${t.toLowerCase()}`,a=(t,o,s=e)=>{const r=t.split(s);if(!s||2!==r.length)throw new Error(i("SSR_BOOST_OUTLET_MISSING",`Invalid HTML shell in ${JSON.stringify(o)}: expected exactly one non-empty outlet ${JSON.stringify(s)}.`));return r},c=t=>{if(null===t)return"null";if("object"!=typeof t){return{bigint:"BigInt",symbol:"Symbol"}[typeof t]??typeof t}const e=Object.getPrototypeOf(t),o=e?.constructor?.name;return"string"==typeof o&&o?o:"object"},S=(t,e,o="$",s=new Set,r=!1)=>{const n=typeof t;if(r&&(t instanceof Promise||t instanceof Date||t instanceof RegExp||"bigint"===n))return;if("function"===n||"bigint"===n||"symbol"===n)return void e({path:o,reason:`${c(t)} is not JSON-serializable`});if(null===t||"object"!==n)return;const i=t,a=Object.getPrototypeOf(i);if(!(r&&(i instanceof Map||i instanceof Set)||a===Object.prototype||null===a||Array.isArray(i)&&a===Array.prototype)){const t=c(i);return void e({path:o,reason:"Date"===t?"Date hydrates as a string":`${t} is not JSON-serializable`})}if(s.has(i))return void e({path:o,reason:"a circular reference is not JSON-serializable"});s.add(i);const h=r&&i instanceof Map?[...i].flatMap(([t,e],o)=>[[`${o}.key`,t],[`${o}.value`,e]]):r&&i instanceof Set?[...i].map((t,e)=>[String(e),t]):Object.entries(i);for(const[t,n]of h){const a=Array.isArray(i)&&/^(0|[1-9]\d*)$/.test(t)?`[${t}]`:/^[A-Za-z_$][\w$]*$/.test(t)?`.${t}`:`[${JSON.stringify(t)}]`;S(n,e,o+a,s,r)}s.delete(i)};class h{route;logger;chunks=[];constructor(e,o=new t){this.route=e,this.logger=o}warn(t,e){const o=i(t,e),n=r[s]??=new Set;n.has(o)||(n.add(o),this.logger.warn(o,{}))}deprecatedReqRes(){this.warn("SSR_BOOST_DEPRECATED_REQ_RES","context.req and context.res are deprecated in 8.x and planned for removal in 9.0; use context.request, context.response.headers/context.response.status and React Router HTTP helpers such as redirect().")}policyDecision(t,e,o){const n=i("SSR_BOOST_SSR_POLICY",`Pattern ${JSON.stringify(t)} selects ${e} via ${o}.`),a=r[s]??=new Set;a.has(n)||(a.add(n),this.logger.info?.(n,{}))}policyUnmatched(t){this.warn("SSR_BOOST_SSR_POLICY_UNMATCHED",`Pattern ${JSON.stringify(t)} matches no known route id; check its URL path and router basename.`)}inspectShell({header:t,footer:o}){("string"!=typeof t||"string"!=typeof o||t.includes(e)||o.includes(e))&&this.warn("SSR_BOOST_OUTLET_MISSING",`HTML shell for route ${JSON.stringify(this.route)} must supply both header and footer around exactly one ${e} outlet, with no outlet left in either half.`)}inspectCachePolicy(t,e){/(?:^|,)\s*public\s*(?:,|$)/i.test(t.get("Cache-Control")??"")&&(t.has("Set-Cookie")||e)&&this.warn("SSR_BOOST_CACHE_PRIVATE_LEAK",`Response for route ${JSON.stringify(this.route)} is public with Set-Cookie or a session cookie. Use private, no-store and bypass the shared cache for authenticated requests.`)}inspectRouterState({loaderData:t,actionData:e}){for(const[o,s]of Object.entries({loaderData:t,actionData:e}))for(const[t,e]of Object.entries(s??{}))S(e,({path:e,reason:o})=>this.warn("SSR_BOOST_LOADER_NOT_SERIALIZABLE",`Route ${JSON.stringify(t)} at ${e}: ${o}.`),`${o}[${JSON.stringify(t)}]`,new Set,!0)}streamAborted(t){this.warn("SSR_BOOST_STREAM_PROMISE_ABORTED",`Route ${JSON.stringify(this.route)} aborted with ${t} pending loader/action promise(s); the browser receives a rejection when connected.`)}inspectStreamValue(t,e){S(t,({path:t,reason:e})=>this.warn("SSR_BOOST_LOADER_NOT_SERIALIZABLE",`Route ${JSON.stringify(this.route)} at ${t}: ${e}.`),`promise[${e}]`,new Set,!0)}inspectState(t){S(t,({path:t,reason:e})=>this.warn("SSR_BOOST_STATE_NOT_SERIALIZABLE",`getState for route ${JSON.stringify(this.route)} at ${t}: ${e}.`))}inspectOnResponse(t){void 0!==t&&"string"!=typeof t&&this.warn("SSR_BOOST_ONRESPONSE_INVALID_RETURN",`onResponse for route ${JSON.stringify(this.route)} returned ${c(t)}; return a string or undefined.`)}append(t){this.chunks.push(t)}complete(){const t=this.chunks.join("");this.chunks=[];const e=new Map,s=t=>{e.set(t,(e.get(t)??0)+1)},r=t.replace(/<!--[\s\S]*?-->/g,"").replace(/(<(script|style|textarea|title)\b(?:[^"'<>]|"[^"]*"|'[^']*')*>)([\s\S]*?)<\/\2\s*>/gi,(t,e,r,n)=>{if("script"===r.toLowerCase()){/\bwindow\.__staticRouterHydrationData\s*=/.test(n)&&s(o);for(const t of n.matchAll(/\$RC\s*\(\s*(["'])(B:[^"']+)\1/g))s(`$RC("${t[2]}")`)}return e});for(const t of r.matchAll(/<([a-z][\w:-]*)\b((?:[^"'<>]|"[^"]*"|'[^']*')*)>/gi)){const e=t[1].toLowerCase();"html"!==e&&"head"!==e||s(`<${e}>`);for(const e of t[2].matchAll(/([^\s=]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/g)){const t=e[2]??e[3]??e[4];"id"===e[1].toLowerCase()&&/^(S|B):/.test(t)&&s(`id="${t}"`)}}e.has(o)||this.warn("SSR_BOOST_HYDRATION_STATE_MISSING",`Completed response for route ${JSON.stringify(this.route)} has no ${o} script; preserve the hydration footer in onResponse.`);for(const[t,o]of e)o>1&&this.warn("SSR_BOOST_DUPLICATE_OUTPUT",`Completed response for route ${JSON.stringify(this.route)} repeats ${t}; onResponse must return undefined to keep a chunk and '' to withhold one.`)}}export{h as default,i as formatDiagnostic,n as isDiagnosticsEnabled,a as splitHtmlShell,S as walkSerializable};
2
2
  //# sourceMappingURL=diagnostics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostics.js","sources":["../../src/services/diagnostics.ts"],"sourcesContent":[null],"names":["OUTLET","HYDRATION","warnedKey","Symbol","for","registry","globalThis","isDiagnosticsEnabled","enabled","env","process","undefined","SSR_BOOST_DIAGNOSTICS","NODE_ENV","formatDiagnostic","code","sentence","toLowerCase","splitHtmlShell","html","file","outlet","parts","split","length","Error","JSON","stringify","valueType","value","bigint","symbol","prototype","Object","getPrototypeOf","name","constructor","walkSerializable","report","path","ancestors","Set","streamed","type","Promise","Date","RegExp","reason","object","Map","Array","isArray","has","add","entries","flatMap","key","child","index","map","String","suffix","test","delete","Diagnostics","route","logger","chunks","Logger","this","warn","detail","message","warned","deprecatedReqRes","inspectShell","header","footer","includes","inspectCachePolicy","headers","hasSessionCookie","get","inspectRouterState","loaderData","actionData","kind","data","streamAborted","count","inspectStreamValue","id","inspectState","state","inspectOnResponse","append","push","complete","join","markers","marker","set","markup","replace","_tag","opening","content","match","matchAll","attribute","total"],"mappings":"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"}
1
+ {"version":3,"file":"diagnostics.js","sources":["../../src/services/diagnostics.ts"],"sourcesContent":[null],"names":["OUTLET","HYDRATION","warnedKey","Symbol","for","registry","globalThis","isDiagnosticsEnabled","enabled","env","process","undefined","SSR_BOOST_DIAGNOSTICS","NODE_ENV","formatDiagnostic","code","sentence","toLowerCase","splitHtmlShell","html","file","outlet","parts","split","length","Error","JSON","stringify","valueType","value","bigint","symbol","prototype","Object","getPrototypeOf","name","constructor","walkSerializable","report","path","ancestors","Set","streamed","type","Promise","Date","RegExp","reason","object","Map","Array","isArray","has","add","entries","flatMap","key","child","index","map","String","suffix","test","delete","Diagnostics","route","logger","chunks","Logger","this","warn","detail","message","warned","deprecatedReqRes","policyDecision","pattern","mode","source","reported","info","policyUnmatched","inspectShell","header","footer","includes","inspectCachePolicy","headers","hasSessionCookie","get","inspectRouterState","loaderData","actionData","kind","data","streamAborted","count","inspectStreamValue","id","inspectState","state","inspectOnResponse","append","push","complete","join","markers","marker","set","markup","replace","_tag","opening","content","match","matchAll","attribute","total"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ type TRequestStage = 'router.query' | 'prepare' | 'shell.ready' | 'state.emitted' | 'stream.resolve' | 'stream.reject' | 'body.end' | 'response.end' | 'abort';
2
+ interface ITimelineEvent {
3
+ stage: TRequestStage;
4
+ at: number;
5
+ id?: number;
6
+ placement?: 'early' | 'footer';
7
+ reason?: string;
8
+ }
9
+ /** Request-local observations; never constructed on the disabled path. */
10
+ declare class RequestTimeline {
11
+ protected readonly request: Request;
12
+ readonly events: ITimelineEvent[];
13
+ readonly started: number;
14
+ protected ended: boolean;
15
+ protected aborted: boolean;
16
+ constructor(request: Request);
17
+ protected onAbort: () => void;
18
+ /** Offsets mark completion/emission, not the beginning of a stage. */
19
+ record(stage: TRequestStage, detail?: Omit<ITimelineEvent, 'stage' | 'at'>): void;
20
+ abort(reason?: unknown): void;
21
+ /** Emit one JSON line only when explicitly requested in development. */
22
+ end(): void;
23
+ /** Observe final transformed bytes without reading ahead of the consumer. */
24
+ response(response: Response): Response;
25
+ }
26
+ /** Keep the constructor, event array and clock reads behind the enablement check. */
27
+ declare const createTimeline: (request: Request, diagnostics: boolean) => RequestTimeline | undefined;
28
+ export { createTimeline };
29
+ export type { ITimelineEvent, TRequestStage };
30
+ export default RequestTimeline;
@@ -0,0 +1,2 @@
1
+ const e=e=>{if(e instanceof Error)return e.message;if("string"==typeof e)return e;try{return JSON.stringify(e)??"Render cancelled"}catch{return"Unserializable abort reason"}};class t{request;events=[];started=performance.now();ended=!1;aborted=!1;constructor(e){this.request=e,e.signal.aborted?this.onAbort():e.signal.addEventListener("abort",this.onAbort,{once:!0})}onAbort=()=>this.abort(this.request.signal.reason);record(e,t){this.ended||this.events.push({stage:e,at:performance.now()-this.started,...t})}abort(t){this.aborted||(this.aborted=!0,this.record("abort",{reason:e(t)}))}end(){this.ended||(this.record("response.end"),this.ended=!0,this.request.signal.removeEventListener("abort",this.onAbort),"undefined"!=typeof process&&"1"===process.env.SSR_BOOST_TIMELINE&&"production"!==process.env.NODE_ENV&&console.info(JSON.stringify({type:"SSR_BOOST_TIMELINE",method:this.request.method,path:new URL(this.request.url).pathname,timeline:this.events})))}response(e){if(!e.body)return this.end(),e;const t=e.body.getReader();let r=!1;const s=()=>{r=!0,t.releaseLock(),this.end()},n=new ReadableStream({cancel:async e=>{r=!0,this.abort(e);try{await t.cancel(e)}finally{s()}},pull:async e=>{try{const n=await t.read();if(r)return;n.done?(s(),e.close()):e.enqueue(n.value)}catch(t){r||(this.abort(t),s(),e.error(t))}}},{highWaterMark:0});return new Response(n,e)}}const r=(e,r)=>r||"undefined"!=typeof process&&"1"===process.env.SSR_BOOST_TIMELINE?new t(e):void 0;export{r as createTimeline,t as default};
2
+ //# sourceMappingURL=request-timeline.js.map
@@ -0,0 +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","abort","record","stage","detail","push","at","end","removeEventListener","process","env","SSR_BOOST_TIMELINE","NODE_ENV","console","info","type","method","path","URL","url","pathname","timeline","response","body","reader","getReader","isStopped","finish","releaseLock","ReadableStream","cancel","async","pull","controller","chunk","read","done","close","enqueue","value","error","highWaterMark","Response","createTimeline","diagnostics","undefined"],"mappings":"AAoBA,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,EAMkCC,QALtBC,OAA2B,GAC3BC,QAAUC,YAAYC,MAC5BC,OAAQ,EACRC,SAAU,EAEpB,WAAAC,CAAsCP,GAAAQ,KAAAR,QAAAA,EAChCA,EAAQS,OAAOH,QACjBE,KAAKE,UAELV,EAAQS,OAAOE,iBAAiB,QAASH,KAAKE,QAAS,CAAEE,MAAM,GAEnE,CAEUF,QAAU,IAAYF,KAAKK,MAAML,KAAKR,QAAQS,OAAOf,QAGxD,MAAAoB,CAAOC,EAAsBC,GAC7BR,KAAKH,OACRG,KAAKP,OAAOgB,KAAK,CAAEF,QAAOG,GAAIf,YAAYC,MAAQI,KAAKN,WAAYc,GAEvE,CAEO,KAAAH,CAAMnB,GACNc,KAAKF,UACRE,KAAKF,SAAU,EACfE,KAAKM,OAAO,QAAS,CAAEpB,OAAQD,EAAeC,KAElD,CAGO,GAAAyB,GACDX,KAAKH,QAITG,KAAKM,OAAO,gBACZN,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,IAAKA,EAASC,KAGZ,OAFA3B,KAAKW,MAEEe,EAGT,MAAME,EAASF,EAASC,KAAKE,YAC7B,IAAIC,GAAY,EAChB,MAAMC,EAAS,KACbD,GAAY,EACZF,EAAOI,cACPhC,KAAKW,OAEDgB,EAAO,IAAIM,eACf,CACEC,OAAQC,MAAOjD,IACb4C,GAAY,EACZ9B,KAAKK,MAAMnB,GAEX,UACQ0C,EAAOM,OAAOhD,EACtB,SACE6C,GACF,GAEFK,KAAMD,MAAOE,IACX,IACE,MAAMC,QAAcV,EAAOW,OAE3B,GAAIT,EACF,OAGEQ,EAAME,MACRT,IACAM,EAAWI,SAEXJ,EAAWK,QAAQJ,EAAMK,MAE7B,CAAE,MAAOC,GACFd,IACH9B,KAAKK,MAAMuC,GACXb,IACAM,EAAWO,MAAMA,GAErB,IAGJ,CAAEC,cAAe,IAGnB,OAAO,IAAIC,SAASnB,EAAMD,EAC5B,EAIF,MAAMqB,EAAiB,CAACvD,EAAkBwD,IACxCA,GAAmC,oBAAZnC,SAA8D,MAAnCA,QAAQC,IAAIC,mBAC1D,IAAIxB,EAAgBC,QACpByD"}
@@ -21,6 +21,8 @@ interface IInjectAssetsContext {
21
21
  header: string;
22
22
  };
23
23
  routerContext?: StaticHandlerContext;
24
+ matches?: RouterState['matches'];
25
+ isSpa?: boolean;
24
26
  }
25
27
  /**
26
28
  * Load and inject route assets with an independent cache for one build.
@@ -49,7 +51,7 @@ declare class RouteAssets {
49
51
  /**
50
52
  * Get route assets
51
53
  */
52
- protected getAssets(routes?: RouterState['matches']): IAsset[];
54
+ protected getAssets(routes?: RouterState['matches'], _isSpa?: boolean): IAsset[];
53
55
  /**
54
56
  * Build preload hints without depending on a particular HTTP transport.
55
57
  */
@@ -57,7 +59,7 @@ declare class RouteAssets {
57
59
  /**
58
60
  * Inject route assets to head html
59
61
  */
60
- injectAssets({ routerContext, html }: IInjectAssetsContext): Headers;
62
+ injectAssets({ routerContext, matches, html, isSpa }: IInjectAssetsContext): Headers;
61
63
  }
62
64
  export { AssetType };
63
65
  export type { IAsset, TAssets };
@@ -1,2 +1,2 @@
1
- import e from"node:fs";import t from"node:path";var s;!function(e){e.style="style",e.script="script",e.image="image",e.font="font"}(s||(s={}));class r{outputDir;modulePreload;routesAssets=null;constructor(e,s=!1){this.outputDir=t.resolve(e),this.modulePreload=s}get isDev(){return!1}getAssetsManifestFile(){return t.join(this.outputDir,"server","assets-manifest.json")}loadAssetsManifest(){if(null!==this.routesAssets)return this.routesAssets;const t=this.getAssetsManifestFile();return e.existsSync(t)?(this.routesAssets=JSON.parse(e.readFileSync(t,{encoding:"utf-8"})),this.routesAssets):{}}sortAssets(e){return e.sort((e,t)=>e.weight===t.weight?Number(e.isNested)-Number(t.isNested):e.weight-t.weight)}getAssets(e){const t=e?.map(({route:e})=>e.id).filter(Boolean)??[];if(!t.length)return[];const s=this.loadAssetsManifest();return this.sortAssets(t.map(e=>s[e]).flat().filter(Boolean))}getEarlyHints(e){const t=new Headers;return e.forEach(({type:e,url:s})=>{e&&["style","script"].includes(e)&&t.append("Link",`<${s}>; rel=preload; as=${e}`)}),t}injectAssets({routerContext:e,html:t}){const r=this.getAssets(e?.matches),i=r.map(({type:e,url:t,isPreload:r,content:i=""})=>{switch(e){case s.style:return this.isDev?`<style data-vite-dev-id="${t}">${i}</style>`:`<link rel="stylesheet" href="${t}">`;case s.script:return r?this.modulePreload?`<link rel="modulepreload" as="script" crossorigin href="${t}">`:null:`<script async type="module" crossorigin src="${t}"><\/script>`}return null}).filter(Boolean);return t.header=t.header.replace("</head>",`${i.join("\n")}</head>`),this.getEarlyHints(r)}}export{s as AssetType,r as default};
1
+ import e from"node:fs";import s from"node:path";var t;!function(e){e.style="style",e.script="script",e.image="image",e.font="font"}(t||(t={}));class r{outputDir;modulePreload;routesAssets=null;constructor(e,t=!1){this.outputDir=s.resolve(e),this.modulePreload=t}get isDev(){return!1}getAssetsManifestFile(){return s.join(this.outputDir,"server","assets-manifest.json")}loadAssetsManifest(){if(null!==this.routesAssets)return this.routesAssets;const s=this.getAssetsManifestFile();return e.existsSync(s)?(this.routesAssets=JSON.parse(e.readFileSync(s,{encoding:"utf-8"})),this.routesAssets):{}}sortAssets(e){return e.sort((e,s)=>e.weight===s.weight?Number(e.isNested)-Number(s.isNested):e.weight-s.weight)}getAssets(e,s){const t=e?.map(({route:e})=>e.id).filter(Boolean)??[];if(!t.length)return[];const r=this.loadAssetsManifest();return this.sortAssets(t.map(e=>r[e]).flat().filter(Boolean))}getEarlyHints(e){const s=new Headers;return e.forEach(({type:e,url:t})=>{e&&["style","script"].includes(e)&&s.append("Link",`<${t}>; rel=preload; as=${e}`)}),s}injectAssets({routerContext:e,matches:s,html:r,isSpa:i}){const o=this.getAssets(s??e?.matches,i),n=o.map(({type:e,url:s,isPreload:r,content:o=""})=>{switch(e){case t.style:return this.isDev?`<style data-vite-dev-id="${s}">${o}</style>`:`<link rel="stylesheet" href="${s}">`;case t.script:return r?this.modulePreload||i?`<link rel="modulepreload" as="script" crossorigin href="${s}">`:null:`<script async type="module" crossorigin src="${s}"><\/script>`}return null}).filter(Boolean);return r.header=r.header.replace("</head>",`${n.join("\n")}</head>`),this.getEarlyHints(o)}}export{t as AssetType,r as default};
2
2
  //# sourceMappingURL=route-assets.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"route-assets.js","sources":["../../src/services/route-assets.ts"],"sourcesContent":[null],"names":["AssetType","RouteAssets","outputDir","modulePreload","routesAssets","constructor","buildDir","this","path","resolve","isDev","getAssetsManifestFile","join","loadAssetsManifest","manifestFile","fs","existsSync","JSON","parse","readFileSync","encoding","sortAssets","assets","sort","a","b","weight","Number","isNested","getAssets","routes","routeIds","map","route","id","filter","Boolean","length","routeId","flat","getEarlyHints","headers","Headers","forEach","type","url","includes","append","injectAssets","routerContext","html","matches","htmlAssets","isPreload","content","style","script","header","replace"],"mappings":"gDAIA,IAAKA,GAAL,SAAKA,GACHA,EAAA,MAAA,QACAA,EAAA,OAAA,SACAA,EAAA,MAAA,QACAA,EAAA,KAAA,MACD,CALD,CAAKA,IAAAA,EAAS,CAAA,IA4Bd,MAAMC,EACeC,UAEAC,cAETC,aAAgD,KAE1D,WAAAC,CAAYC,EAAkBH,GAAgB,GAC5CI,KAAKL,UAAYM,EAAKC,QAAQH,GAC9BC,KAAKJ,cAAgBA,CACvB,CAKA,SAAcO,GACZ,OAAO,CACT,CAKU,qBAAAC,GACR,OAAOH,EAAKI,KAAKL,KAAKL,UAAW,SAAU,uBAC7C,CAKU,kBAAAW,GACR,GAA0B,OAAtBN,KAAKH,aACP,OAAOG,KAAKH,aAGd,MAAMU,EAAeP,KAAKI,wBAE1B,OAAKI,EAAGC,WAAWF,IAInBP,KAAKH,aAAea,KAAKC,MAAMH,EAAGI,aAAaL,EAAc,CAAEM,SAAU,WAKlEb,KAAKH,cARH,CAAA,CASX,CAKU,UAAAiB,CAAWC,GACnB,OAAOA,EAAOC,KAAK,CAACC,EAAGC,IACrBD,EAAEE,SAAWD,EAAEC,OAASC,OAAOH,EAAEI,UAAYD,OAAOF,EAAEG,UAAYJ,EAAEE,OAASD,EAAEC,OAEnF,CAKU,SAAAG,CAAUC,GAClB,MAAMC,EAAWD,GAAQE,IAAI,EAAGC,WAAYA,EAAMC,IAAIC,OAAOC,UAAY,GAEzE,IAAKL,EAASM,OACZ,MAAO,GAGT,MAAMjC,EAAeG,KAAKM,qBAE1B,OAAON,KAAKc,WACVU,EACGC,IAAKM,GAAYlC,EAAakC,IAC9BC,OACAJ,OAAOC,SAEd,CAKO,aAAAI,CAAclB,GACnB,MAAMmB,EAAU,IAAIC,QAUpB,OARApB,EAAOqB,QAAQ,EAAGC,OAAMC,UACjBD,GAAS,CAAC,QAAS,UAAUE,SAASF,IAI3CH,EAAQM,OAAO,OAAQ,IAAIF,uBAAyBD,OAG/CH,CACT,CAKO,YAAAO,EAAaC,cAAEA,EAAaC,KAAEA,IACnC,MAAM5B,EAASf,KAAKsB,UAAUoB,GAAeE,SACvCC,EAAa9B,EAChBU,IAAI,EAAGY,OAAMC,MAAKQ,YAAWC,UAAU,OACtC,OAAQV,GACN,KAAK5C,EAAUuD,MACb,OAAOhD,KAAKG,MACR,4BAA4BmC,MAAQS,YACpC,gCAAgCT,MAEtC,KAAK7C,EAAUwD,OACb,OAAOH,EACH9C,KAAKJ,cAEH,2DAA2D0C,MAC3D,KACF,gDAAgDA,gBAGxD,OAAO,OAERV,OAAOC,SAIV,OAFAc,EAAKO,OAASP,EAAKO,OAAOC,QAAQ,UAAW,GAAGN,EAAWxC,KAAK,gBAEzDL,KAAKiC,cAAclB,EAC5B"}
1
+ {"version":3,"file":"route-assets.js","sources":["../../src/services/route-assets.ts"],"sourcesContent":[null],"names":["AssetType","RouteAssets","outputDir","modulePreload","routesAssets","constructor","buildDir","this","path","resolve","isDev","getAssetsManifestFile","join","loadAssetsManifest","manifestFile","fs","existsSync","JSON","parse","readFileSync","encoding","sortAssets","assets","sort","a","b","weight","Number","isNested","getAssets","routes","_isSpa","routeIds","map","route","id","filter","Boolean","length","routeId","flat","getEarlyHints","headers","Headers","forEach","type","url","includes","append","injectAssets","routerContext","matches","html","isSpa","htmlAssets","isPreload","content","style","script","header","replace"],"mappings":"gDAIA,IAAKA,GAAL,SAAKA,GACHA,EAAA,MAAA,QACAA,EAAA,OAAA,SACAA,EAAA,MAAA,QACAA,EAAA,KAAA,MACD,CALD,CAAKA,IAAAA,EAAS,CAAA,IA8Bd,MAAMC,EACeC,UAEAC,cAETC,aAAgD,KAE1D,WAAAC,CAAYC,EAAkBH,GAAgB,GAC5CI,KAAKL,UAAYM,EAAKC,QAAQH,GAC9BC,KAAKJ,cAAgBA,CACvB,CAKA,SAAcO,GACZ,OAAO,CACT,CAKU,qBAAAC,GACR,OAAOH,EAAKI,KAAKL,KAAKL,UAAW,SAAU,uBAC7C,CAKU,kBAAAW,GACR,GAA0B,OAAtBN,KAAKH,aACP,OAAOG,KAAKH,aAGd,MAAMU,EAAeP,KAAKI,wBAE1B,OAAKI,EAAGC,WAAWF,IAInBP,KAAKH,aAAea,KAAKC,MAAMH,EAAGI,aAAaL,EAAc,CAAEM,SAAU,WAKlEb,KAAKH,cARH,CAAA,CASX,CAKU,UAAAiB,CAAWC,GACnB,OAAOA,EAAOC,KAAK,CAACC,EAAGC,IACrBD,EAAEE,SAAWD,EAAEC,OAASC,OAAOH,EAAEI,UAAYD,OAAOF,EAAEG,UAAYJ,EAAEE,OAASD,EAAEC,OAEnF,CAOU,SAAAG,CAAUC,EAAiCC,GACnD,MAAMC,EAAWF,GAAQG,IAAI,EAAGC,WAAYA,EAAMC,IAAIC,OAAOC,UAAY,GAEzE,IAAKL,EAASM,OACZ,MAAO,GAGT,MAAMlC,EAAeG,KAAKM,qBAE1B,OAAON,KAAKc,WACVW,EACGC,IAAKM,GAAYnC,EAAamC,IAC9BC,OACAJ,OAAOC,SAEd,CAKO,aAAAI,CAAcnB,GACnB,MAAMoB,EAAU,IAAIC,QAUpB,OARArB,EAAOsB,QAAQ,EAAGC,OAAMC,UACjBD,GAAS,CAAC,QAAS,UAAUE,SAASF,IAI3CH,EAAQM,OAAO,OAAQ,IAAIF,uBAAyBD,OAG/CH,CACT,CAKO,YAAAO,EAAaC,cAAEA,EAAaC,QAAEA,EAAOC,KAAEA,EAAIC,MAAEA,IAClD,MAAM/B,EAASf,KAAKsB,UAAUsB,GAAWD,GAAeC,QAASE,GAC3DC,EAAahC,EAChBW,IAAI,EAAGY,OAAMC,MAAKS,YAAWC,UAAU,OACtC,OAAQX,GACN,KAAK7C,EAAUyD,MACb,OAAOlD,KAAKG,MACR,4BAA4BoC,MAAQU,YACpC,gCAAgCV,MAEtC,KAAK9C,EAAU0D,OACb,OAAOH,EACHhD,KAAKJ,eAAiBkD,EAEpB,2DAA2DP,MAC3D,KACF,gDAAgDA,gBAGxD,OAAO,OAERV,OAAOC,SAIV,OAFAe,EAAKO,OAASP,EAAKO,OAAOC,QAAQ,UAAW,GAAGN,EAAW1C,KAAK,gBAEzDL,KAAKkC,cAAcnB,EAC5B"}
@@ -99,7 +99,11 @@ declare class SsrManifest extends RouteAssets {
99
99
  /**
100
100
  * Get route assets from Vite in development or the built manifest in production.
101
101
  */
102
- protected getAssets(routes?: RouterState['matches']): IAsset[];
102
+ protected getAssets(routes?: RouterState['matches'], isSpa?: boolean): IAsset[];
103
+ /**
104
+ * Resolve structural route metadata without importing the server's lazy component.
105
+ */
106
+ protected getDevRouteIds(routes?: RouterState['matches']): string[];
103
107
  /**
104
108
  * Get development route assets
105
109
  */
@@ -107,11 +111,11 @@ declare class SsrManifest extends RouteAssets {
107
111
  /**
108
112
  * Compile SSR graph styles before the browser has populated the client graph.
109
113
  */
110
- prepareDevAssets(routes?: RouterState['matches']): Promise<void>;
114
+ prepareDevAssets(routes?: RouterState['matches'], isSpa?: boolean): Promise<void>;
111
115
  /**
112
116
  * Collect development assets from the current server and client module graphs.
113
117
  */
114
- protected getAssetsDev(routes?: RouterState['matches']): IAsset[];
118
+ protected getAssetsDev(routes?: RouterState['matches'], isSpa?: boolean): IAsset[];
115
119
  /**
116
120
  * Get module assets
117
121
  */
@@ -1,2 +1,2 @@
1
- import e from"node:fs";import s from"node:path";import t from"chalk";import i from"./parse-routes.js";import r from"./path-normalize.js";import o,{AssetType as a}from"./route-assets.js";class n extends o{static instance=null;config;pathNormalize;root;buildDir;manifestName="manifest.json";viteAliases;basename;renderBuiltUrl;constructor(e,{buildDir:t,viteAliases:i,basename:o,renderBuiltUrl:a}={}){super(s.resolve(e.getParams().root,t||""),e.isModulePreload),this.config=e,this.root=e.getParams().root,this.buildDir=t,this.viteAliases=i??e.getVite()?.config?.resolve.alias,this.pathNormalize=new r(e,i),this.basename=o,this.renderBuiltUrl=a}static get(e,s={}){return null===n.instance&&(n.instance=new n(e,s)),n.instance}get isDev(){return Boolean(this.config.getVite())}getOutDir(){return s.resolve(this.root,this.buildDir||"")}getAssetsManifestFile(){return`${this.getOutDir()}/server/assets-manifest.json`}loadClientManifest(){const t=s.resolve(this.root,`${this.buildDir||""}/client/.vite`),i=`${t}/${this.manifestName}`;if(!e.existsSync(i))return{};const r=JSON.parse(e.readFileSync(i,{encoding:"utf-8"}));return e.rmSync(i),0===e.readdirSync(t).length&&e.rmSync(t,{recursive:!0}),r}getRoutesTreeIds(e,s){const t={};return e.forEach(e=>{const i=[s,String(e.index)].filter(Boolean).join("-"),r=e.id??i;e.import&&(t[r]=this.pathNormalize.getAppPath(e.import)),e.children.length>0&&Object.assign(t,this.getRoutesTreeIds(e.children,i))}),t}getRouteAssets(e,t,i=!1){const r=[...t?.assets??[],...t?.css??[],t?.file].reduce((e,r)=>{if(r){const o=this.getAssetType(r),a=t.isEntry&&t.file===r;if(o){const t=s.posix.normalize(`${this.basename}/${r}`),n=this.renderBuiltUrl?.(t,{type:"asset",ssr:!0,hostId:"",hostType:t.split(".").at(-1)?.toLowerCase()});e[r]={url:"string"==typeof n?n:t,weight:a?1.9:this.getAssetWeight(r),type:o,isNested:i,isPreload:!a}}}return e},{});return t?.imports?.length&&t.imports.forEach(s=>{const t=e[s];t&&Object.assign(r,this.getRouteAssets(e,t,!0))}),r}buildRoutesManifest(){const s=this.loadClientManifest(),t=new i(this.config,this.viteAliases),r=this.getRoutesTreeIds(t.parse()),o=this.pathNormalize.getImportPostfix(),a={};Object.entries(r).forEach(([e,t])=>{const i=o.find(e=>void 0!==s[`${t}${e}`]),r=s[`${t}${i||""}`];a[e]=this.sortAssets(Object.values(this.getRouteAssets(s,r)))}),e.writeFileSync(this.getAssetsManifestFile(),JSON.stringify(a,null,2),{encoding:"utf-8"})}getAssets(e){return this.isDev?this.getAssetsDev(e):super.getAssets(e)}getDevModules(e){const t=e?.map(({route:e})=>this.pathNormalize.getAppPath(e?.pathId,!0)).filter(Boolean)??[],i=this.pathNormalize.getImportPostfix(),r=this.config.getPluginConfig(),o=[r?.clientFile??"client.ts",r?.serverFile??"server.ts"].map(e=>s.resolve(this.root,e)),a=[];return[...o,...t].forEach(e=>{for(const s of i){const t=this.config.getVite()?.moduleGraph.getModuleById(`${e}${s}`);if(t){a.push(t);break}}}),a}async prepareDevAssets(e){const s=this.config.getVite();if(!s)return;const t=new Set,i=async e=>{t.has(e.url)||(t.add(e.url),e.file&&/\.(?:css|less|s[ac]ss|styl(?:us)?|pcss|postcss)$/.test(e.file)&&await s.transformRequest(e.url),await Promise.all([...e.importedModules].map(i)))};await Promise.all(this.getDevModules(e).map(i))}getAssetsDev(e){const s=Object.assign({},...this.getDevModules(e).map(e=>this.getModuleAssets(e)));return Object.values(s)}getModuleAssets(e,s=new Set){const i=e?.importedModules??e?.clientImportedModules;if(!i?.size||s.has(e.file))return{};let r={};return s.add(e.file),i.forEach(e=>{const{file:i,transformResult:o}=e,n=i?.split(".").at(-1);if(i&&n&&["css","scss","sass","less","styl","stylus","pcss","postcss"].includes(n)){const e=o?.code.match(/__vite__css\s+=\s+"(?<css>.+)"/)?.groups?.css;if(e)try{r[i]={type:a.style,url:i,weight:this.getAssetWeight(i),content:JSON.parse(`{"style": "${e}"}`).style,isNested:Boolean(s.size),isPreload:!1}}catch{console.warn(t.yellowBright("Failed to parse style: ",i))}}else r={...r,...this.getModuleAssets(e,s)}}),r}getAssetWeight(e){switch(this.getAssetType(e)){case a.style:return 1;case a.script:return 2;default:return 3}}getAssetType(e){const s=e.split(".").at(-1)?.toLowerCase();switch(s){case"css":case"scss":return a.style;case"js":return a.script;case"svg":case"jpg":case"jpeg":case"png":case"webp":case"gif":case"ico":return a.image;case"ttf":case"otf":case"woff":case"woff2":return a.font;default:return null}}}export{n as default};
1
+ import e from"node:fs";import t from"node:path";import s from"chalk";import i from"./parse-routes.js";import r from"./path-normalize.js";import o,{AssetType as a}from"./route-assets.js";class n extends o{static instance=null;config;pathNormalize;root;buildDir;manifestName="manifest.json";viteAliases;basename;renderBuiltUrl;constructor(e,{buildDir:s,viteAliases:i,basename:o,renderBuiltUrl:a}={}){super(t.resolve(e.getParams().root,s||""),e.isModulePreload),this.config=e,this.root=e.getParams().root,this.buildDir=s,this.viteAliases=i??e.getVite()?.config?.resolve.alias,this.pathNormalize=new r(e,i),this.basename=o,this.renderBuiltUrl=a}static get(e,t={}){return null===n.instance&&(n.instance=new n(e,t)),n.instance}get isDev(){return Boolean(this.config.getVite())}getOutDir(){return t.resolve(this.root,this.buildDir||"")}getAssetsManifestFile(){return`${this.getOutDir()}/server/assets-manifest.json`}loadClientManifest(){const s=t.resolve(this.root,`${this.buildDir||""}/client/.vite`),i=`${s}/${this.manifestName}`;if(!e.existsSync(i))return{};const r=JSON.parse(e.readFileSync(i,{encoding:"utf-8"}));return e.rmSync(i),0===e.readdirSync(s).length&&e.rmSync(s,{recursive:!0}),r}getRoutesTreeIds(e,t){const s={};return e.forEach(e=>{const i=[t,String(e.index)].filter(Boolean).join("-"),r=e.id??i;e.import&&(s[r]=this.pathNormalize.getAppPath(e.import)),e.children.length>0&&Object.assign(s,this.getRoutesTreeIds(e.children,i))}),s}getRouteAssets(e,s,i=!1){const r=[...s?.assets??[],...s?.css??[],s?.file].reduce((e,r)=>{if(r){const o=this.getAssetType(r),a=s.isEntry&&s.file===r;if(o){const s=t.posix.normalize(`${this.basename}/${r}`),n=this.renderBuiltUrl?.(s,{type:"asset",ssr:!0,hostId:"",hostType:s.split(".").at(-1)?.toLowerCase()});e[r]={url:"string"==typeof n?n:s,weight:a?1.9:this.getAssetWeight(r),type:o,isNested:i,isPreload:!a}}}return e},{});return s?.imports?.length&&s.imports.forEach(t=>{const s=e[t];s&&Object.assign(r,this.getRouteAssets(e,s,!0))}),r}buildRoutesManifest(){const t=this.loadClientManifest(),s=new i(this.config,this.viteAliases),r=this.getRoutesTreeIds(s.parse()),o=this.pathNormalize.getImportPostfix(),a={};Object.entries(r).forEach(([e,s])=>{const i=o.find(e=>void 0!==t[`${s}${e}`]),r=t[`${s}${i||""}`];a[e]=this.sortAssets(Object.values(this.getRouteAssets(t,r)))}),e.writeFileSync(this.getAssetsManifestFile(),JSON.stringify(a,null,2),{encoding:"utf-8"})}getAssets(e,t){return this.isDev?this.getAssetsDev(e,t):super.getAssets(e)}getDevRouteIds(e){return e?.map(({route:e})=>this.pathNormalize.getAppPath(e?.pathId,!0)).filter(Boolean)??[]}getDevModules(e){const s=this.getDevRouteIds(e),i=this.pathNormalize.getImportPostfix(),r=this.config.getPluginConfig(),o=[r?.clientFile??"client.ts",r?.serverFile??"server.ts"].map(e=>t.resolve(this.root,e)),a=[];return[...o,...s].forEach(e=>{for(const t of i){const s=this.config.getVite()?.moduleGraph.getModuleById(`${e}${t}`);if(s){a.push(s);break}}}),a}async prepareDevAssets(e,t=!1){const s=this.config.getVite();if(!s)return;t&&await Promise.all(this.getDevRouteIds(e).map(async e=>{const t=this.pathNormalize.findAppFile(e);t&&await s.transformRequest(`/@fs/${t}`)}));const i=new Set,r=async e=>{i.has(e.url)||(i.add(e.url),e.file&&/\.(?:css|less|s[ac]ss|styl(?:us)?|pcss|postcss)$/.test(e.file)&&await s.transformRequest(e.url),await Promise.all([...e.importedModules].map(r)))};await Promise.all(this.getDevModules(e).map(r))}getAssetsDev(e,t=!1){const s=Object.assign({},...this.getDevModules(e).map(e=>this.getModuleAssets(e))),i=t?this.getDevRouteIds(e).flatMap(e=>{const t=this.pathNormalize.getImportPostfix().map(t=>this.config.getVite()?.moduleGraph.getModuleById(`${e}${t}`)).find(Boolean);return t?[{type:a.script,url:t.url,weight:2,isNested:!1,isPreload:!0}]:[]}):[];return[...Object.values(s),...i]}getModuleAssets(e,t=new Set){const i=e?.importedModules??e?.clientImportedModules;if(!i?.size||t.has(e.file))return{};let r={};return t.add(e.file),i.forEach(e=>{const{file:i,transformResult:o}=e,n=i?.split(".").at(-1);if(i&&n&&["css","scss","sass","less","styl","stylus","pcss","postcss"].includes(n)){const e=o?.code.match(/__vite__css\s+=\s+"(?<css>.+)"/)?.groups?.css;if(e)try{r[i]={type:a.style,url:i,weight:this.getAssetWeight(i),content:JSON.parse(`{"style": "${e}"}`).style,isNested:Boolean(t.size),isPreload:!1}}catch{console.warn(s.yellowBright("Failed to parse style: ",i))}}else r={...r,...this.getModuleAssets(e,t)}}),r}getAssetWeight(e){switch(this.getAssetType(e)){case a.style:return 1;case a.script:return 2;default:return 3}}getAssetType(e){const t=e.split(".").at(-1)?.toLowerCase();switch(t){case"css":case"scss":return a.style;case"js":return a.script;case"svg":case"jpg":case"jpeg":case"png":case"webp":case"gif":case"ico":return a.image;case"ttf":case"otf":case"woff":case"woff2":return a.font;default:return null}}}export{n as default};
2
2
  //# sourceMappingURL=ssr-manifest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-manifest.js","sources":["../../src/services/ssr-manifest.ts"],"sourcesContent":[null],"names":["SsrManifest","RouteAssets","static","config","pathNormalize","root","buildDir","manifestName","viteAliases","basename","renderBuiltUrl","constructor","super","path","resolve","getParams","isModulePreload","this","getVite","alias","PathNormalize","get","params","instance","isDev","Boolean","getOutDir","getAssetsManifestFile","loadClientManifest","clientManifestDir","clientSsrManifest","fs","existsSync","result","JSON","parse","readFileSync","encoding","rmSync","readdirSync","length","recursive","getRoutesTreeIds","routes","index","forEach","route","position","String","filter","join","routeId","id","import","getAppPath","children","Object","assign","getRouteAssets","manifest","module","isNested","assets","css","file","reduce","res","asset","type","getAssetType","isEntry","filename","posix","normalize","modifiedFilename","ssr","hostId","hostType","split","at","toLowerCase","url","weight","getAssetWeight","isPreload","imports","nestedAsset","nestedModule","buildRoutesManifest","routesService","ParseRoutes","routesPaths","postfixes","getImportPostfix","entries","routePath","routePostfix","find","postfix","undefined","routeMeta","sortAssets","values","writeFileSync","stringify","getAssets","getAssetsDev","getDevModules","routeIds","map","pathId","pluginConfig","getPluginConfig","rootIds","clientFile","serverFile","modules","moduleId","ext","moduleGraph","getModuleById","push","prepareDevAssets","vite","visited","Set","visit","async","has","add","test","transformRequest","Promise","all","importedModules","getModuleAssets","skipModules","clientImportedModules","size","subModule","transformResult","includes","code","match","groups","AssetType","style","content","console","warn","chalk","yellowBright","script","image","font"],"mappings":"0LAiCA,MAAMA,UAAoBC,EAIdC,gBAAsC,KAK7BC,OAKAC,cAKAC,KAKAC,SAKAC,aAAe,gBAKfC,YAKAC,SAKAC,eAKnB,WAAAC,CACER,GACAG,SAAEA,EAAQE,YAAEA,EAAWC,SAAEA,EAAQC,eAAEA,GAAuC,IAE1EE,MAAMC,EAAKC,QAAQX,EAAOY,YAAYV,KAAMC,GAAY,IAAKH,EAAOa,iBAEpEC,KAAKd,OAASA,EACdc,KAAKZ,KAAOF,EAAOY,YAAYV,KAC/BY,KAAKX,SAAWA,EAChBW,KAAKT,YAAcA,GAAeL,EAAOe,WAAWf,QAAQW,QAAQK,MACpEF,KAAKb,cAAgB,IAAIgB,EAAcjB,EAAQK,GAC/CS,KAAKR,SAAWA,EAChBQ,KAAKP,eAAiBA,CACxB,CAKO,UAAOW,CAAIlB,EAAsBmB,EAA6B,IAKnE,OAJ6B,OAAzBtB,EAAYuB,WACdvB,EAAYuB,SAAW,IAAIvB,EAAYG,EAAQmB,IAG1CtB,EAAYuB,QACrB,CAKA,SAAcC,GACZ,OAAOC,QAAQR,KAAKd,OAAOe,UAC7B,CAKU,SAAAQ,GACR,OAAOb,EAAKC,QAAQG,KAAKZ,KAAMY,KAAKX,UAAY,GAClD,CAKU,qBAAAqB,GACR,MAAO,GAAGV,KAAKS,yCACjB,CAKU,kBAAAE,GACR,MAAMC,EAAoBhB,EAAKC,QAAQG,KAAKZ,KAAM,GAAGY,KAAKX,UAAY,mBAChEwB,EAAoB,GAAGD,KAAqBZ,KAAKV,eAEvD,IAAKwB,EAAGC,WAAWF,GACjB,MAAO,CAAA,EAGT,MAAMG,EAASC,KAAKC,MAClBJ,EAAGK,aAAaN,EAAmB,CAAEO,SAAU,WAUjD,OAPAN,EAAGO,OAAOR,GAGuC,IAA7CC,EAAGQ,YAAYV,GAAmBW,QACpCT,EAAGO,OAAOT,EAAmB,CAAEY,WAAW,IAGrCR,CACT,CAKU,gBAAAS,CACRC,EACAC,GAEA,MAAMX,EAA6C,CAAA,EAenD,OAbAU,EAAOE,QAASC,IACd,MAAMC,EAAW,CAACH,EAAOI,OAAOF,EAAMF,QAAQK,OAAOxB,SAASyB,KAAK,KAC7DC,EAAUL,EAAMM,IAAML,EAExBD,EAAMO,SACRpB,EAAOkB,GAAWlC,KAAKb,cAAckD,WAAWR,EAAMO,SAGpDP,EAAMS,SAASf,OAAS,GAC1BgB,OAAOC,OAAOxB,EAAQhB,KAAKyB,iBAAiBI,EAAMS,SAAUR,MAIzDd,CACT,CAKU,cAAAyB,CACRC,EACAC,EACAC,GAAW,GAEX,MAEMC,EAFa,IAAKF,GAAQE,QAAU,MAASF,GAAQG,KAAO,GAAKH,GAAQI,MAErDC,OACxB,CAACC,EAAKC,KACJ,GAAIA,EAAO,CACT,MAAMC,EAAOnD,KAAKoD,aAAaF,GACzBG,EAAUV,EAAOU,SAAWV,EAAOI,OAASG,EAGlD,GAAIC,EAAM,CACR,MAAMG,EAAW1D,EAAK2D,MAAMC,UAAU,GAAGxD,KAAKR,YAAY0D,KACpDO,EAAmBzD,KAAKP,iBAAiB6D,EAAU,CACvDH,KAAM,QACNO,KAAK,EACLC,OAAQ,GACRC,SAAUN,EAASO,MAAM,KAAKC,IAAG,IAAKC,gBAGxCd,EAAIC,GAAS,CACXc,IAAiC,iBAArBP,EAAgCA,EAAmBH,EAC/DW,OAAQZ,EAAU,IAAMrD,KAAKkE,eAAehB,GAC5CC,OACAP,WACAuB,WAAYd,EAEhB,CACF,CAEA,OAAOJ,GAET,CAAA,GAcF,OAVIN,GAAQyB,SAAS7C,QACnBoB,EAAOyB,QAAQxC,QAASyC,IACtB,MAAMC,EAAe5B,EAAS2B,GAE1BC,GACF/B,OAAOC,OAAOK,EAAQ7C,KAAKyC,eAAeC,EAAU4B,GAAc,MAKjEzB,CACT,CAKO,mBAAA0B,GACL,MAAM7B,EAAW1C,KAAKW,qBAChB6D,EAAgB,IAAIC,EAAYzE,KAAKd,OAAQc,KAAKT,aAClDmF,EAAc1E,KAAKyB,iBAAiB+C,EAActD,SAElDyD,EAAY3E,KAAKb,cAAcyF,mBAC/B5D,EAAmC,CAAA,EAGzCuB,OAAOsC,QAAQH,GAAa9C,QAAQ,EAAEM,EAAS4C,MAC7C,MAAMC,EAAeJ,EAAUK,KAAMC,QAGLC,IAAvBxC,EAFU,GAAGoC,IAAYG,MAK5BE,EAAYzC,EADA,GAAGoC,IAAYC,GAAgB,MAGjD/D,EAAOkB,GAAWlC,KAAKoF,WAAW7C,OAAO8C,OAAOrF,KAAKyC,eAAeC,EAAUyC,OAGhFrE,EAAGwE,cAActF,KAAKU,wBAAyBO,KAAKsE,UAAUvE,EAAQ,KAAM,GAAI,CAC9EI,SAAU,SAEd,CAKU,SAAAoE,CAAU9D,GAClB,OAAO1B,KAAKO,MAAQP,KAAKyF,aAAa/D,GAAU/B,MAAM6F,UAAU9D,EAClE,CAKU,aAAAgE,CAAchE,GACtB,MAAMiE,EACHjE,GACGkE,IAAI,EAAG/D,WAAY7B,KAAKb,cAAckD,WAAYR,GAAuBgE,QAAQ,IAClF7D,OAAOxB,UAAyB,GAE/BmE,EAAY3E,KAAKb,cAAcyF,mBAC/BkB,EAAe9F,KAAKd,OAAO6G,kBAC3BC,EAAU,CACdF,GAAcG,YAAc,YAC5BH,GAAcI,YAAc,aAC5BN,IAAK7C,GAASnD,EAAKC,QAAQG,KAAKZ,KAAM2D,IAClCoD,EAAwB,GAa9B,MAXA,IAAIH,KAAYL,GAAU/D,QAASwE,IACjC,IAAK,MAAMC,KAAO1B,EAAW,CAC3B,MAAMhC,EAAS3C,KAAKd,OAAOe,WAAWqG,YAAYC,cAAc,GAAGH,IAAWC,KAE9E,GAAI1D,EAAQ,CACVwD,EAAQK,KAAK7D,GACb,KACF,CACF,IAGKwD,CACT,CAKO,sBAAMM,CAAiB/E,GAC5B,MAAMgF,EAAO1G,KAAKd,OAAOe,UAEzB,IAAKyG,EACH,OAGF,MAAMC,EAAU,IAAIC,IAKdC,EAAQC,MAAOnE,IACfgE,EAAQI,IAAIpE,EAAOqB,OAIvB2C,EAAQK,IAAIrE,EAAOqB,KAEfrB,EAAOI,MAAQ,mDAAmDkE,KAAKtE,EAAOI,aAC1E2D,EAAKQ,iBAAiBvE,EAAOqB,WAG/BmD,QAAQC,IAAI,IAAIzE,EAAO0E,iBAAiBzB,IAAIiB,YAG9CM,QAAQC,IAAIpH,KAAK0F,cAAchE,GAAQkE,IAAIiB,GACnD,CAKU,YAAApB,CAAa/D,GACrB,MAAMmB,EAASN,OAAOC,OACpB,CAAA,KACGxC,KAAK0F,cAAchE,GAAQkE,IAAKjD,GAAW3C,KAAKsH,gBAAgB3E,KAGrE,OAAOJ,OAAO8C,OAAOxC,EACvB,CAKU,eAAAyE,CAAgB3E,EAAqB4E,EAA2B,IAAIX,KAC5E,MAAMxC,EAAUzB,GAAQ0E,iBAAmB1E,GAAQ6E,sBAEnD,IAAKpD,GAASqD,MAAQF,EAAYR,IAAIpE,EAAQI,MAC5C,MAAO,CAAA,EAGT,IAAIF,EAAkB,CAAA,EAsCtB,OApCA0E,EAAYP,IAAIrE,EAAQI,MAExBqB,EAAQxC,QAAS8F,IACf,MAAM3E,KAAEA,EAAI4E,gBAAEA,GAAoBD,EAC5BrB,EAAMtD,GAAMc,MAAM,KAAKC,OAE7B,GACEf,GACAsD,GACA,CAAC,MAAO,OAAQ,OAAQ,OAAQ,OAAQ,SAAU,OAAQ,WAAWuB,SAASvB,GAC9E,CAEA,MAAMwB,EAAOF,GAAiBE,KAAKC,MAAM,mCAAmCC,QAAQjF,IAEpF,GAAI+E,EACF,IACEhF,EAAOE,GAAQ,CACbI,KAAM6E,EAAUC,MAChBjE,IAAKjB,EACLkB,OAAQjE,KAAKkE,eAAenB,GAC5BmF,QAAUjH,KAAKC,MAAM,cAAc2G,OAAgCI,MACnErF,SAAUpC,QAAQ+G,EAAYE,MAC9BtD,WAAW,EAEf,CAAE,MACAgE,QAAQC,KAAKC,EAAMC,aAAa,0BAA2BvF,GAC7D,CAEJ,MACEF,EAAS,IACJA,KACA7C,KAAKsH,gBAAgBI,EAAWH,MAKlC1E,CACT,CAKU,cAAAqB,CAAehB,GAGvB,OAFalD,KAAKoD,aAAaF,IAG7B,KAAK8E,EAAUC,MACb,OAAO,EAET,KAAKD,EAAUO,OACb,OAAO,EAET,QACE,OAAO,EAEb,CAKU,YAAAnF,CAAaF,GACrB,MAAMmD,EAAMnD,EAAMW,MAAM,KAAKC,IAAG,IAAKC,cAErC,OAAQsC,GACN,IAAK,MACL,IAAK,OACH,OAAO2B,EAAUC,MAEnB,IAAK,KACH,OAAOD,EAAUO,OAEnB,IAAK,MACL,IAAK,MACL,IAAK,OACL,IAAK,MACL,IAAK,OACL,IAAK,MACL,IAAK,MACH,OAAOP,EAAUQ,MAEnB,IAAK,MACL,IAAK,MACL,IAAK,OACL,IAAK,QACH,OAAOR,EAAUS,KAEnB,QACE,OAAO,KAEb"}
1
+ {"version":3,"file":"ssr-manifest.js","sources":["../../src/services/ssr-manifest.ts"],"sourcesContent":[null],"names":["SsrManifest","RouteAssets","static","config","pathNormalize","root","buildDir","manifestName","viteAliases","basename","renderBuiltUrl","constructor","super","path","resolve","getParams","isModulePreload","this","getVite","alias","PathNormalize","get","params","instance","isDev","Boolean","getOutDir","getAssetsManifestFile","loadClientManifest","clientManifestDir","clientSsrManifest","fs","existsSync","result","JSON","parse","readFileSync","encoding","rmSync","readdirSync","length","recursive","getRoutesTreeIds","routes","index","forEach","route","position","String","filter","join","routeId","id","import","getAppPath","children","Object","assign","getRouteAssets","manifest","module","isNested","assets","css","file","reduce","res","asset","type","getAssetType","isEntry","filename","posix","normalize","modifiedFilename","ssr","hostId","hostType","split","at","toLowerCase","url","weight","getAssetWeight","isPreload","imports","nestedAsset","nestedModule","buildRoutesManifest","routesService","ParseRoutes","routesPaths","postfixes","getImportPostfix","entries","routePath","routePostfix","find","postfix","undefined","routeMeta","sortAssets","values","writeFileSync","stringify","getAssets","isSpa","getAssetsDev","getDevRouteIds","map","pathId","getDevModules","routeIds","pluginConfig","getPluginConfig","rootIds","clientFile","serverFile","modules","moduleId","ext","moduleGraph","getModuleById","push","prepareDevAssets","vite","Promise","all","async","findAppFile","transformRequest","visited","Set","visit","has","add","test","importedModules","getModuleAssets","scripts","flatMap","AssetType","script","skipModules","clientImportedModules","size","subModule","transformResult","includes","code","match","groups","style","content","console","warn","chalk","yellowBright","image","font"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ interface IBrowserTimelineEvent {
2
+ stage: 'shell' | 'router.ready' | 'init' | 'resolve' | 'reject' | 'response.end';
3
+ at: number;
4
+ id?: number;
5
+ }
6
+ interface IBrowserObservation {
7
+ events: IBrowserTimelineEvent[];
8
+ errors: string[];
9
+ roots: Record<string, string>;
10
+ seen: WeakMap<Element, number>;
11
+ shellAt?: number;
12
+ }
13
+ declare global {
14
+ interface Window {
15
+ __ssrBoostTest?: IBrowserObservation;
16
+ }
17
+ }
18
+ /** Serialized by addInitScript: keep every runtime dependency inside this function. */
19
+ declare const installBrowserObserver: () => void;
20
+ interface IHydrationInspection {
21
+ ready: boolean;
22
+ consumed: boolean;
23
+ pending: number;
24
+ duplicates: string[];
25
+ errors: string[];
26
+ }
27
+ /** Compare server text multiplicities to the hydrated root, allowing existing repeats. */
28
+ declare const inspectHydration: (selector: string) => IHydrationInspection;
29
+ export { installBrowserObserver, inspectHydration };
30
+ export type { IBrowserTimelineEvent, IHydrationInspection };
@@ -0,0 +1,2 @@
1
+ const e=()=>{if(window.__ssrBoostTest)return;const e={events:[],errors:[],roots:{},seen:new WeakMap};window.__ssrBoostTest=e;const t=(t,o)=>{e.events.push({stage:t,at:performance.now(),...void 0===o?{}:{id:o}})},o=()=>{const o=performance.now();for(const r of document.querySelectorAll("body *")){const n=r.getBoundingClientRect();!r.closest("script, style, template, [hidden]")&&n.width>0&&n.height>0&&"hidden"!==getComputedStyle(r).visibility&&(void 0===e.shellAt&&(e.shellAt=o,t("shell")),e.seen.has(r)||e.seen.set(r,o))}};new MutationObserver(o).observe(document,{childList:!0,subtree:!0,attributes:!0});const r=console.error;console.error=(...t)=>{e.errors.push(t.map(String).join(" ")),r(...t)},window.addEventListener("error",t=>e.errors.push(t.message)),window.addEventListener("unhandledrejection",t=>e.errors.push(String(t.reason))),window.addEventListener("ssr-boost:router-ready",r=>{const{rootId:n}=r.detail,s=document.getElementById(n);s&&(e.roots[n]=s.innerHTML),o(),t("router.ready")}),window.addEventListener("load",()=>t("response.end"),{once:!0});const n=[];let s=Array.prototype.push;const d=new WeakSet;Object.defineProperty(n,"push",{configurable:!0,get:()=>(...e)=>{for(const o of e){if(d.has(o))continue;d.add(o);const[e,r]=o;"init"!==e&&"resolve"!==e&&"reject"!==e||t(e,"number"==typeof r?r:void 0)}return s.apply(n,e)},set:e=>{s=e}}),Reflect.set(window,"__ssrBoostStream",n)},t=e=>{const t=window.__ssrBoostTest,o=document.querySelector(e),r=o?t?.roots[o.id]:void 0,n=document.createElement("div");n.innerHTML=r??"";const s=e=>{const t=new Map;for(const o of[e,...e.querySelectorAll("*")]){if(o.closest("script, style, template, [hidden]"))continue;const e=[...o.childNodes].filter(e=>e.nodeType===Node.TEXT_NODE).map(e=>e.textContent).join("").replace(/\s+/g," ").trim();e&&t.set(e,(t.get(e)??0)+1)}return t},d=s(n),i=o?s(o):new Map,c=(e,t)=>{let o=0;for(const[r,n]of e){const e=r.length/t.length;Number.isInteger(e)&&t.repeat(e)===r&&(o+=e*n)}return o},l=[...d].filter(([e])=>c(i,e)>c(d,e)).map(([e])=>e),a=o?document.createTreeWalker(o,NodeFilter.SHOW_COMMENT):void 0;let u=0;for(;a?.nextNode();)"$?"===a.currentNode.textContent&&u++;return{ready:void 0!==r,consumed:void 0===Reflect.get(window,"__staticRouterHydrationData"),pending:u,duplicates:l,errors:t?.errors.filter(e=>/(?:#|errors\/)(418|423|425)\b|hydrat(?:ion|ing|e|ed)|server rendered HTML|did not match/i.test(e))??[]}};export{t as inspectHydration,e as installBrowserObserver};
2
+ //# sourceMappingURL=browser-observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-observer.js","sources":["../../src/testing/browser-observer.ts"],"sourcesContent":[null],"names":["installBrowserObserver","window","__ssrBoostTest","state","events","errors","roots","seen","WeakMap","record","stage","id","push","at","performance","now","undefined","scan","element","document","querySelectorAll","rect","getBoundingClientRect","closest","width","height","getComputedStyle","visibility","shellAt","has","set","MutationObserver","observe","childList","subtree","attributes","originalError","console","error","args","map","String","join","addEventListener","event","message","reason","rootId","detail","root","getElementById","innerHTML","once","queue","downstream","Array","prototype","observed","WeakSet","Object","defineProperty","configurable","get","frames","frame","add","apply","replacement","Reflect","inspectHydration","selector","querySelector","html","server","createElement","texts","counts","Map","child","text","childNodes","filter","node","nodeType","Node","TEXT_NODE","textContent","replace","trim","before","after","multiplicity","total","candidate","count","copies","length","Number","isInteger","repeat","duplicates","walker","createTreeWalker","NodeFilter","SHOW_COMMENT","pending","nextNode","currentNode","ready","consumed","test"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { FC, PropsWithChildren } from 'react';
2
+ import type { RouteObject } from 'react-router';
3
+ import { createStaticHandler } from 'react-router';
4
+ import type { ICreateHandlerOptions, IHtmlShell } from '../core/handler.js';
5
+ import type { TRenderToStream } from '../core/render.js';
6
+ import type { TRouteObject } from '../interfaces/route-object.js';
7
+ import type { ILoadHtmlShellOptions } from '../node/production.js';
8
+ import TestResponse from './response.js';
9
+ interface ITestRequestInit extends RequestInit {
10
+ isStream?: boolean;
11
+ /** Whole-request deadline, including loaders and body consumption. */
12
+ timeout?: number;
13
+ }
14
+ interface ITestHandlerOptions<TAppProps> extends Omit<ICreateHandlerOptions<TAppProps>, 'getHtml'> {
15
+ routes: TRouteObject[] | RouteObject[];
16
+ App?: FC<PropsWithChildren<{
17
+ server: TAppProps;
18
+ }>>;
19
+ shell?: IHtmlShell | ILoadHtmlShellOptions;
20
+ routerOptions?: Parameters<typeof createStaticHandler>[1];
21
+ renderToStream?: TRenderToStream;
22
+ signal?: AbortSignal;
23
+ timeout?: number;
24
+ }
25
+ interface ITestHandler {
26
+ fetch: (input: string | Request, init?: ITestRequestInit) => Promise<TestResponse>;
27
+ }
28
+ type TLoadShell = (options: ILoadHtmlShellOptions) => Promise<() => IHtmlShell>;
29
+ /** Share the Fetch-only implementation between Node and conditional edge exports. */
30
+ declare const testHandlerFactory: (renderer: TRenderToStream, loadShell: TLoadShell) => <TAppProps = Record<string, any>>({ routes, App, shell, routerOptions, renderToStream, signal: defaultSignal, timeout: defaultTimeout, onContext, onRouterReady, ...options }: ITestHandlerOptions<TAppProps>) => ITestHandler;
31
+ export type { ITestHandler, ITestHandlerOptions, ITestRequestInit };
32
+ export default testHandlerFactory;
@@ -0,0 +1,2 @@
1
+ import e from"react";import{createStaticHandler as t}from"react-router";import r from"../core/handler.js";import{TEST_ORIGIN as o}from"./requests.js";import n from"./response.js";const i={header:'<!doctype html><html><head></head><body><div id="root">',footer:'</div><script type="module">/* test browser entry */<\/script></body></html>'},a=(a,s)=>({routes:m,App:c,shell:l=i,routerOptions:d,renderToStream:u=a,signal:p,timeout:f,onContext:h,onRouterReady:b,...w})=>{const y=t(m,d);let g;const v=async()=>"indexFile"in l?(g??=s(l),(await g)()):{...l};return{fetch:async(t,{isStream:i,timeout:a=f,signal:s,...m}={})=>{const l=performance.now(),d=new AbortController,g=[d.signal,p,s,t instanceof Request?t.signal:void 0].filter(e=>Boolean(e)),R=AbortSignal.any(g),S=new Request("string"==typeof t?new URL(t,o):t,{...m,signal:R});let x,E,A;const T=new Promise((e,t)=>{A=t}),C=()=>A(R.reason),j=()=>{clearTimeout(x),R.removeEventListener("abort",C)};if(R.addEventListener("abort",C,{once:!0}),void 0!==a){if(!Number.isFinite(a)||a<0)throw j(),new RangeError("timeout must be a finite, non-negative number of milliseconds.");x=setTimeout(()=>d.abort(new DOMException(`SSR test timed out after ${a}ms`,"TimeoutError")),a)}try{R.throwIfAborted();const t=r({handler:y,renderToStream:u,createApp:(t,r)=>c?e.createElement(c,{server:r.appProps},t):t},{...w,getHtml:v,onContext:e=>{({timeline:E}=e.context),h?.(e)},onRouterReady:async e=>{const t=await(b?.(e));return void 0===i?t??{}:{...t,isStream:i}}})(S);t.then(e=>{if(R.aborted)return e.body?.cancel(R.reason)}).catch(()=>{});const o=await Promise.race([t,T]);return new n(o,{started:l,timeline:E,signal:R,onComplete:j})}catch(e){throw j(),E?.abort(e),E?.end(),e}}}};export{a as default};
2
+ //# sourceMappingURL=create-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-handler.js","sources":["../../src/testing/create-handler.tsx"],"sourcesContent":[null],"names":["DEFAULT_SHELL","header","footer","testHandlerFactory","renderer","loadShell","routes","App","shell","routerOptions","renderToStream","signal","defaultSignal","timeout","defaultTimeout","onContext","onRouterReady","options","handler","createStaticHandler","fileShell","getHtml","async","fetch","input","isStream","init","started","performance","now","controller","AbortController","signals","Request","undefined","filter","item","Boolean","combined","AbortSignal","any","request","URL","TEST_ORIGIN","timer","timeline","rejectAbort","aborted","Promise","_","reject","onAbort","reason","cleanup","clearTimeout","removeEventListener","addEventListener","once","Number","isFinite","RangeError","setTimeout","abort","DOMException","throwIfAborted","pending","createHandler","createApp","children","context","React","createElement","server","appProps","params","result","then","response","body","cancel","catch","race","TestResponse","onComplete","error","end"],"mappings":"mLAmCA,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,EACJ,MAAMC,EAAUC,SACV,cAAed,GACjBY,IAAcf,EAAUG,UAEVY,MAGT,IAAKZ,GAGd,MAAO,CACLe,MAAOD,MAAOE,GAASC,WAAUZ,UAAUC,EAAgBH,YAAWe,GAAS,MAC7E,MAAMC,EAAUC,YAAYC,MACtBC,EAAa,IAAIC,gBACjBC,EAAU,CACdF,EAAWnB,OACXC,EACAD,EACAa,aAAiBS,QAAUT,EAAMb,YAASuB,GAC1CC,OAAQC,GAA8BC,QAAQD,IAC1CE,EAAWC,YAAYC,IAAIR,GAC3BS,EAAU,IAAIR,QACD,iBAAVT,EAAqB,IAAIkB,IAAIlB,EAAOmB,GAAenB,EAC1D,IACKE,EACHf,OAAQ2B,IAGZ,IAAIM,EACAC,EACAC,EACJ,MAAMC,EAAU,IAAIC,QAAe,CAACC,EAAGC,KACrCJ,EAAcI,IAEVC,EAAU,IAAYL,EAAYR,EAASc,QAC3CC,EAAU,KACdC,aAAaV,GACbN,EAASiB,oBAAoB,QAASJ,IAKxC,GAFAb,EAASkB,iBAAiB,QAASL,EAAS,CAAEM,MAAM,SAEpCvB,IAAZrB,EAAuB,CACzB,IAAK6C,OAAOC,SAAS9C,IAAYA,EAAU,EAEzC,MADAwC,IACM,IAAIO,WAAW,kEAGvBhB,EAAQiB,WACN,IACE/B,EAAWgC,MACT,IAAIC,aAAa,4BAA4BlD,MAAa,iBAE9DA,EAEJ,CAEA,IACEyB,EAAS0B,iBACT,MAqBMC,EArBQC,EACZ,CACEhD,UACAR,iBACAyD,UAAW,CAACC,EAAUC,IACpB9D,EAAM+D,EAAAC,cAAChE,EAAG,CAACiE,OAAQH,EAAQI,UAAWL,GAAkBA,GAE5D,IACKnD,EACHI,UACAN,UAAY2D,MACP7B,YAAa6B,EAAOL,SACvBtD,IAAY2D,IAEd1D,cAAeM,MAAOoD,IACpB,MAAMC,QAAe3D,IAAgB0D,IAErC,YAAoBxC,IAAbT,EAA0BkD,GAAU,CAAA,EAAM,IAAKA,EAAQlD,cAIpDF,CAAMkB,GAGjBwB,EACFW,KAAMC,IACL,GAAIvC,EAASS,QACX,OAAO8B,EAASC,MAAMC,OAAOzC,EAASc,UAKzC4B,MAAM,QAET,MAAMH,QAAiB7B,QAAQiC,KAAK,CAAChB,EAASlB,IAE9C,OAAO,IAAImC,EAAaL,EAAU,CAChClD,UACAkB,WACAlC,OAAQ2B,EACR6C,WAAY9B,GAEhB,CAAE,MAAO+B,GAIP,MAHA/B,IACAR,GAAUiB,MAAMsB,GAChBvC,GAAUwC,MACJD,CACR"}