@symbo.ls/brender 3.14.679 → 3.14.680
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/CHANGELOG.md +24 -0
- package/README.md +1 -0
- package/dist/esm/render.js +35 -35
- package/package.json +7 -7
- package/render.js +34 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @symbo.ls/brender
|
|
2
2
|
|
|
3
|
+
## 3.14.680
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 74ce537: A page's agent view is rendered ahead for AI crawlers (S1). AI crawlers read only the served HTML, and a page's agent view (the landing's `?view=agent`, which its app shows at init) existed in the browser only: every publish-time render was made at the route's address with no query, so `/pricing` and `/pricing?view=agent` served the same bytes.
|
|
8
|
+
|
|
9
|
+
- brender: `render()`, `renderRoute()` and `renderPage()` take `search`, the query of the address the page is rendered at. The render's `location.search` and `location.href` carry it, so a page that reads its query renders that view; the head stays the page's own. `''`, `'?'`, `null` or none render as before, byte for byte; each render owns its location, so the next render never inherits a query. A value that is not a string, or that holds a `#`, throws a TypeError that names the option.
|
|
10
|
+
- utils (`@symbo.ls/utils/server`): `agentViewOf(data)` reads config.js `agentView: { param: 'view', on: 'agent', off: 'human' }` (`true`, `{}` or a missing field take these defaults) under the platform render worker's rules (`param` a letter, then up to 31 letters, digits, `_` or `-`, not `__smbls…`; `on` / `off` 1–32 of those, and different), and throws a TypeError that names the shape for a declaration outside them; null without one. It reads a project payload where the renderer reads `polyglot`: under `data.config` (else `data.settings`) when the payload keeps config nested, else at its top level, where frank spreads config.js — a served `/get` payload has no `config`, and its `settings` is the platform's own. `renderVariantsOf(data)` gives the renders a publish makes beside each page: `[{ name: 'agent', search: '?view=agent' }]`, or `[]`. `AGENT_VIEW_DEFAULTS` is exported.
|
|
11
|
+
- mermaid: `renderProjectHtml` takes `search` (a live render at that query; never the visitor's own query). `@symbo.ls/mermaid/render` exports `renderVariants(data)` — the variant list, read with that lookup — which the platform's publish feature-checks: it then renders each page once more per variant and stores it under `<route><search>`.
|
|
12
|
+
- cli: `smbls publish --ssr` renders each stored route once more per variant, after every page (in page order, `/` first) and within the same time budget, and stores it in the same `PUT /core/projects/:projectId/prerender` under `<route>?<param>=<on>` (`/pricing?view=agent`, `/?view=agent`), the key the platform serves crawlers from. The variants have size budgets of their own, so a site whose pages fill the pages' 16 MB still gets its agent views and a page never loses its place to one: 8 MB for all of them (`--ssr-variant-budget <MB>`, or `symbols.json` `brender.variantBudgetMB`) and 1 MB for one (`--ssr-variant-route-cap <KB>`, or `brender.variantRouteKB`; 1024 is also the most, the platform's cap per stored row — a page keeps its own 512 KB). A flag wins over symbols.json; a value that is not a number above 0, or that passes the platform's cap, stops the publish with a message that names it. A publish keeps within the platform's caps per version, which refuse a larger write as a whole: at most 500 routes, variants included (`maxRoutes`), and 20 MB with the styles, which the variants stop short of. A variant never takes a page's place; a route whose own render was not stored gets none. The publish report lists them apart (`N of M static routes stored and K of L variant renders (?view=agent; X KB)`), and a variant render that was not stored gives one warning with the count, the first route it missed and the reasons (`⚠ 12 of 57 variant renders not stored, from /pricing?view=agent: 12 variant budget spent (8 MB)`). A declaration it cannot use is printed (`agent view not pre-rendered: …`) and the publish stores the pages alone. Without `agentView` a publish renders and stores what it did before.
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [8eb4239]
|
|
15
|
+
- Updated dependencies [b6a3cd6]
|
|
16
|
+
- Updated dependencies [74ce537]
|
|
17
|
+
- Updated dependencies [a271b1b]
|
|
18
|
+
- Updated dependencies [4537877]
|
|
19
|
+
- Updated dependencies [6da9c79]
|
|
20
|
+
- @symbo.ls/default-config@3.14.794
|
|
21
|
+
- @symbo.ls/scratch@3.14.799
|
|
22
|
+
- @symbo.ls/element@3.14.823
|
|
23
|
+
- smbls@3.14.869
|
|
24
|
+
- @symbo.ls/utils@3.14.859
|
|
25
|
+
- @symbo.ls/fetch@3.14.678
|
|
26
|
+
|
|
3
27
|
## 3.14.679
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -147,6 +147,7 @@ Options:
|
|
|
147
147
|
| Option | Default | What it does |
|
|
148
148
|
|--------|---------|--------------|
|
|
149
149
|
| `pathname` | the route | The address the page is rendered at. The router matches it, and `location` (canonical, og:url) reads it. A route with parameters needs one (`renderPage(data, '/:lang/about', { pathname: '/en/about' })`); the not-found page `/*` is rendered at `/404` by `smbls build`. |
|
|
150
|
+
| `search` | — | The query of the address the page is rendered at (`'?view=agent'`; the `?` is added when missing). The render's `location.search` and `location.href` carry it, as a browser's do at that address, so a page that reads its query (an agent view its app shows at init) renders that view; the head is the page's own. `render()` and `renderRoute()` take it too. `''`, `'?'`, `null` or none: no query, and the render is the same as before, byte for byte. A value that is not a string, or that holds a `#`, throws a TypeError that names the option. |
|
|
150
151
|
| `shell` | — | A built app document (e.g. `dist/index.html`) to render INTO. |
|
|
151
152
|
| `preloadScripts` | `true` | With `shell`: a high-priority `modulepreload` (`preload as=script` for a classic script) in `<head>` for each script the shell boots from, so the pre-rendered images do not take its bandwidth. `async` and `nomodule` scripts are left alone. |
|
|
152
153
|
| `eagerImages` | `2` | Images past the first `eagerImages` in the markup get `loading="lazy"`, unless they name their own `loading`. `false` turns it off. |
|
package/dist/esm/render.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import{resolve as d,join as tt,dirname as j}from"path";import{existsSync as S,unlinkSync as ot,readFileSync as J,realpathSync as nt}from"fs";import{resolvePackageEntry as st}from"./packageEntry.js";import{tmpdir as rt}from"os";import{randomBytes as ct}from"crypto";import{createRequire as ge}from"module";import{pathToFileURL as it}from"url";import{createEnv as je}from"./env.js";import{resetKeys as Te,assignKeys as ve,mapKeysToElements as Le}from"./keys.js";import{extractMetadata as he,generateHeadHtml as lt}from"./metadata.js";import"./hydrate.js";import{composeIntoShell as at}from"./shell.js";import{trimSpriteToPage as ft,classRulesForPage as pt,markupClasses as ut,trimVariablesToPage as mt}from"./pageWeight.js";import{facesSheetTag as dt}from"./faces.js";import{fetchSSRTranslations as gt}from"./prefetch.js";import{createEarlySeedScript as ht}from"@symbo.ls/fetch";import{headerEntries as yt}from"@symbo.ls/fetch/rest";import{brenderStampMeta as bt,brenderLazyMeta as Ae,escapeRegExp as St,jsonForScript as Rt,libraryPackageSpecs as wt,polyglotFallbackLang as ye,polyglotLangStorageKey as kt,polyglotAddressLang as xt,polyglotStartupScript as _t}from"@symbo.ls/utils";import{brenderRegistryBlock as Et,brenderRegistryTreeBlock as jt}from"@symbo.ls/utils/server";import*as Tt from"@symbo.ls/utils/server";let ce=null;const vt=async()=>{if(ce)return ce;try{return ce=(await import("@symbo.ls/funcql")).funcqlPlugin,ce}catch{return null}};import"linkedom";import{createEarlySeedBlock as Lt,fetchRunsOf as At}from"@symbo.ls/fetch";import{reset as $t}from"@symbo.ls/css";const ie=(e,t)=>{if(!e||!t)return;if(e[t]!==void 0)return e[t];const o=t.split(".");let n=e;for(const s of o){if(n==null||typeof n!="object")return;n=n[s]}return n},le=(e,t)=>ye(e?.lang,t),Dt=e=>{const t=Tt.revivePolyglotDefaultLang;if(typeof t!="function"||!e||typeof e!="object")return e;const o=e.polyglot?t(e.polyglot):e.polyglot,n=e.config&&e.config.polyglot,s=n&&t(n);if(o===e.polyglot&&s===n)return e;const r={...e};return o!==e.polyglot&&(r.polyglot=o),s!==n&&(r.config={...e.config,polyglot:s}),r},$e=(e,t,o,n)=>{if(o?.translations){const r=o.translations[t];if(r){const i=ie(r,e);if(i!==void 0)return i}}if(n?.translations){const r=n.translations[t];if(r){const i=ie(r,e);if(i!==void 0)return i}}const s=ye(void 0,o);if(s!==t&&o?.translations){const r=o.translations[s];if(r){const i=ie(r,e);if(i!==void 0)return i}}},Ct=function(e,t){if(!e)return"";const o=this?.context,n=o?.polyglot,s=this?.state?.root||o?.state?.root,r=$e(e,t||le(s,n),n,s);if(r!==void 0)return r;const i=we(Re);return n&&i&&i.labelKeys.add(e),e},De=function(){return le(this?.state?.root,this?.context?.polyglot)},L=(e,t=new WeakMap)=>{if(e===null||typeof e!="object")return e;if(t.has(e))return t.get(e);if(Array.isArray(e)){const n=[];t.set(e,n);for(const s of e)n.push(typeof s=="object"&&s!==null?L(s,t):s);return n}const o={};t.set(e,o);for(const n of Object.keys(e)){const s=e[n];o[n]=typeof s=="object"&&s!==null?L(s,t):s}return o};let q=null;try{import.meta.url&&(q=ge(import.meta.url))}catch{}const Mt=()=>{if(!import.meta.url||!q)return{isMonorepo:!1,monorepoRoot:null,resolvePackage:a=>a};const e=nt(new URL(".",import.meta.url).pathname),t=d(e,"../..");if(S(d(t,"packages","smbls","src","createDomql.js")))return{isMonorepo:!0,monorepoRoot:t};let n;try{const a=q.resolve("smbls/package.json");n=j(a)}catch{let a=e;for(;a!==j(a);){const g=d(a,"node_modules","smbls");if(S(d(g,"package.json"))){n=g;break}a=j(a)}}let s=q;if(n)try{s=ge(d(n,"package.json"))}catch{}let r,i=process.cwd();for(;i!==j(i);){if(S(d(i,"package.json"))){r=i;break}i=j(i)}let u=s;if(r)try{u=ge(d(r,"package.json"))}catch{}return{isMonorepo:!1,smblsRoot:n,brenderDir:e,projectRoot:r,_smblsRequire:s,_projectRequire:u}},H=(e,t)=>{const o=e.isMonorepo?[q]:[e._smblsRequire,e._projectRequire,q].filter(Boolean);for(const n of o)try{return n.resolve(t)}catch{}return null},on=(e,t,...o)=>{if(e.isMonorepo)return d(e.monorepoRoot,"packages",t,...o);const n=H(e,`${t}/package.json`);return n?d(j(n),...o):null},nn=(e,t,...o)=>{if(e.isMonorepo)return d(e.monorepoRoot,"plugins",t,...o);const n=H(e,`@symbo.ls/${t}/package.json`);return n?d(j(n),...o):null},be=(e,t,...o)=>{if(e.isMonorepo){for(const s of["packages","plugins"]){const r=d(e.monorepoRoot,s,t,...o);if(S(r))return r}return null}const n=H(e,`@symbo.ls/${t}/package.json`);return n?d(j(n),...o):null},Ce=(e,t,...o)=>{if(e.isMonorepo)return d(e.monorepoRoot,"packages","domql","packages",t,...o);const n=H(e,`@symbo.ls/${t}/package.json`);return n?d(j(n),...o):null};let ae=null;const Me="smbls/ssr",Ot=async()=>{const e=await import("smbls/ssr");if(typeof e?.createDomqlElement!="function")throw new Error("smbls/ssr does not export createDomqlElement");return e},Oe=()=>(ae||(ae=qt().catch(e=>{throw ae=null,e})),ae),qt=async()=>{const e=Mt();let t;if(q&&e.isMonorepo)t=d(e.monorepoRoot,"packages","smbls","src","createDomql.js");else{let f;try{return await Ot()}catch(l){f=l}if(!q)throw new Error(`brender: ${Me} is not available in this bundled runtime (${f.message}). Bundle smbls \u2265 the release that adds the smbls/ssr export alongside @symbo.ls/brender.`);const c=e.smblsRoot&&d(e.smblsRoot,"src","createDomql.js");if(c&&S(c))t=c;else throw new Error(`brender: cannot load ${Me} (${f.message}). Server rendering needs smbls installed in this project, at a release that exports smbls/ssr`+(e.smblsRoot?` (found smbls at ${e.smblsRoot}).`:" (no smbls package found)."))}const o=await import("esbuild"),n=tt(rt(),`br_createDomql_${ct(6).toString("hex")}.mjs`),s=st,r=e.isMonorepo?await import(it(d(e.monorepoRoot,"scripts","vite-workspace-source.mjs")).href):null,i=r?new Set(r.workspacePackageRoots().map(f=>r.workspacePackageAt(f).name)):null,u=/^(?:smbls(?:\/.*)?|domql|css-in-props(?:\/.*)?|@symbo\.ls\/[^/]+)$/,a={name:"workspace-resolve",setup(f){r&&(f.onResolve({filter:/^[^./]/},c=>{if(u.test(c.path))return;const l=c.path.split("/"),p=c.path.startsWith("@")?l.slice(0,2).join("/"):l[0];if(!i.has(p))return;const h=r.resolveWorkspaceSource(c.path,c.importer||t);return h?{path:h}:{errors:[{text:`"${c.path}" names no source file in the workspace`}]}}),f.onLoad({filter:/[\\/]dist[\\/]/},c=>r.isWorkspaceDist(c.path)?{errors:[{text:`${c.path} is a BUILD of a workspace package \u2014 the render bundles source`}]}:void 0)),f.onResolve({filter:/^smbls/},c=>{const l=c.path.replace(/^smbls\/?/,""),p=e.isMonorepo?d(e.monorepoRoot,"packages","smbls"):e.smblsRoot;if(!p)return;if(!l){const k=s(p);return k?{path:k}:void 0}const h=d(p,l);if(S(h))return{path:h};if(S(h+".js"))return{path:h+".js"};const R=d(h,"index.js");if(S(R))return{path:R}}),f.onResolve({filter:/^domql$/},c=>{if(e.isMonorepo){const l=d(e.monorepoRoot,"packages","domql","src","index.js");if(S(l))return{path:l};const p=d(e.monorepoRoot,"packages","domql","index.js");if(S(p))return{path:p}}else try{const l=_require.resolve("domql/package.json"),p=s(j(l));if(p)return{path:p}}catch{}}),f.onResolve({filter:/^@symbo\.ls\//},c=>{const l=c.path.replace("@symbo.ls/","");if(l==="sync")return{path:"sync-stub",namespace:"brender-stub"};if(e.isMonorepo){for(const h of["packages","plugins"]){const R=d(e.monorepoRoot,h,l,"src","index.js");if(S(R))return{path:R};const k=d(e.monorepoRoot,h,l,"index.js");if(S(k))return{path:k}}const p=d(e.monorepoRoot,"packages","default-config","blank","index.js");if(l==="default-config"&&S(p))return{path:p}}else{const p=be(e,l,"src","index.js");if(p&&S(p))return{path:p};const h=be(e,l,"index.js");if(h&&S(h))return{path:h};if(l==="default-config"){const R=be(e,"default-config","blank","index.js");if(R&&S(R))return{path:R}}}}),f.onResolve({filter:/^@domql\//},c=>{const l=c.path.replace("@symbo.ls/","");if(e.isMonorepo){const p=d(e.monorepoRoot,"packages","domql","packages",l,"src","index.js");if(S(p))return{path:p};const h=d(e.monorepoRoot,"packages","domql","packages",l,"index.js");if(S(h))return{path:h}}else{const p=Ce(e,l,"src","index.js");if(p&&S(p))return{path:p};const h=Ce(e,l,"index.js");if(h&&S(h))return{path:h}}}),f.onResolve({filter:/^css-in-props/},c=>{let l;if(e.isMonorepo)l=d(e.monorepoRoot,"packages","css-in-props");else{const R=H(e,"css-in-props/package.json");R&&(l=j(R))}if(!l)return;const p=c.path.replace(/^css-in-props\/?/,"");if(p){const R=d(l,p),k=d(R,"index.js");if(S(k))return{path:k};if(S(R+".js"))return{path:R+".js"};if(S(R))return{path:R}}const h=s(l);if(h)return{path:h}}),f.onResolve({filter:/^@emotion\//},c=>{let l;if(e.isMonorepo)l=d(e.monorepoRoot,"node_modules",c.path);else{const p=H(e,`${c.path}/package.json`);if(!p)return;l=j(p)}if(S(l)){const p=d(l,"package.json");if(S(p))try{const h=JSON.parse(J(p,"utf8")),R=h.module||h.main||"dist/emotion-css.esm.js";return{path:d(l,R)}}catch{}return{path:l}}}),f.onResolve({filter:/\.json$/},c=>{if(c.resolveDir){const l=d(c.resolveDir,c.path);if(S(l))return{path:l}}}),f.onLoad({filter:/smbls\/.*options\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("options.js"))return;let l=J(c.path,"utf8");return l=l.replace(/import\s*\{[^}]*version[^}]*\}\s*from\s*['"][^'"]*package\.json['"][^;\n]*/,"const version = '0.0.0'"),l=l.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:l,loader:"js"}}),f.onLoad({filter:/smbls\/.*init\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("init.js"))return;let l=J(c.path,"utf8");return l=l.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:l,loader:"js"}}),f.onLoad({filter:/.*/,namespace:"brender-stub"},()=>({contents:"export const SyncComponent = {}; export const Inspect = {}; export const Notifications = {}; export const syncPlugin = () => ({}); export const notificationsPlugin = () => ({}); export const seedRawDesignSystem = () => {}; export const inspectPlugin = () => ({}); export default {}",loader:"js"})),f.onLoad({filter:/smbls\/src\/router\.js$/},async c=>{let l=J(c.path,"utf8");return l=l.replace(/import\s*\{\s*Link\s*\}\s*from\s*['"]smbls['"]/,"const Link = { tag: 'a', attr: { href: (el) => el.href } }"),{contents:l,loader:"js"}}),f.onLoad({filter:/fetchOnCreate\.js$/},async c=>{if(!c.path.includes("smbls/"))return;let l=J(c.path,"utf8");return l=l.replace(/window\s*&&\s*window\.location\s*\?\s*window\.location\.host\.includes/g,"window && window.location && window.location.host ? window.location.host.includes"),{contents:l,loader:"js"}})}};await o.build({entryPoints:[t],bundle:!0,format:"esm",platform:"node",outfile:n,write:!0,logLevel:"warning",plugins:[a],nodePaths:e.isMonorepo?[d(e.monorepoRoot,"node_modules")]:[...e.smblsRoot?[d(e.smblsRoot,"node_modules")]:[],...e.projectRoot?[d(e.projectRoot,"node_modules")]:[],...e.smblsRoot?[d(e.smblsRoot,"..","..","node_modules")]:[]].filter(f=>S(f)),supported:{"import-attributes":!1},external:["fs","path","os","crypto","url","http","https","stream","util","events","buffer","child_process","worker_threads","net","tls","dns","dgram","zlib","assert","querystring","string_decoder","readline","perf_hooks","async_hooks","v8","vm","cluster","inspector","module","process","tty","color-contrast-checker","linkedom"]});const g=await import(`file://${n}`);if(process.env.BRENDER_DEBUG)console.log("[brender] Bundle saved:",n);else try{ot(n)}catch{}return g},Pt={Box:{},Focusable:{},Block:{display:"block"},Inline:{display:"inline"},Flex:{display:"flex"},InlineFlex:{display:"inline-flex"},Grid:{display:"grid"},InlineGrid:{display:"inline-grid"},Link:{tag:"a",attr:{href:e=>e.href,target:e=>e.target,rel:e=>e.rel}},A:{extends:"Link"},RouteLink:{extends:"Link"},Img:{tag:"img",attr:{src:e=>{let t=e.src;return typeof t=="string"&&t.includes("{{")&&(t=e.call("replaceLiteralsWithObjectFields",t,e.state)),t},alt:e=>e.alt,loading:e=>e.loading}},Image:{extends:"Img"},Button:{tag:"button"},FocusableComponent:{tag:"button"},Form:{tag:"form"},Input:{tag:"input"},TextArea:{tag:"textarea"},Textarea:{tag:"textarea"},Select:{tag:"select"},Label:{tag:"label"},Iframe:{tag:"iframe"},Video:{tag:"video"},Audio:{tag:"audio"},Canvas:{tag:"canvas"},Span:{tag:"span"},P:{tag:"p"},H1:{tag:"h1"},H2:{tag:"h2"},H3:{tag:"h3"},H4:{tag:"h4"},H5:{tag:"h5"},H6:{tag:"h6"},Svg:{tag:"svg",attr:{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}},Text:{tag:"span"}},It=(e,t)=>{const o={};return qe(e,(n,s)=>{if(!s.__brKey)return;const r=t(n);o[r===""?"__root":r]=s.__brKey}),o},qe=(e,t)=>{const o=n=>{const s=n&&n.__ref;if(s&&(t(n,s),s.__children))for(const r of s.__children)o(n[r])};o(e)},Ft=new Set(["app","config","pages","components","state","snippets","designSystem","dependencies","functions","methods","files","sharedLibraries"]);let z=0;const Pe=Symbol.for("brender.fetchTracked"),Se=()=>z,Gt=256*1024,Bt=1024*1024,Kt=new Set(["accept-language","accept"]),Ie={renders:0,record:null},Nt=50,Re={renders:0,record:null},Fe=(e,t)=>{e.renders++,e.renders===1?e.record=t():e.record&&(e.record.tainted=!0);const o=e.record;return{record:o,close:()=>{e.renders--,e.record===o&&(e.record=null)}}},we=e=>e.record&&!e.record.tainted?e.record:null,Ht=e=>{try{const t=new URL(e);return t.origin+t.pathname}catch{return String(e).split("?")[0]}},ke=(e,t,o)=>{!e||e.tainted||e.failures.length>=Nt||e.failures.push({url:Ht(t),reason:o})},Ge=e=>e&&typeof e=="object"&&typeof e.url=="string"?e.url:String(e),zt=e=>{const[t,o]=e,n=t&&typeof t=="object"&&typeof t.url=="string",s=Ge(t),r=String(o&&o.method||n&&t.method||"GET").toUpperCase(),i={},u=a=>{if(!a)return;const g=!Array.isArray(a)&&typeof a.entries!="function";for(const[f,c]of yt(a))g&&c==null||(i[String(f).toLowerCase()]=String(c))};return n&&u(t.headers),o&&u(o.headers),{url:s,method:r,headers:i}},Wt=(e,t,o,n)=>{if(!o||!o.ok||typeof o.clone!="function")return;const s=o.headers&&o.headers.get&&o.headers.get("content-type")||"";if(!/json|^text\//i.test(s))return;let r;try{r=o.clone()}catch{return}n(r.text().then(i=>{e.tainted||i.length>Gt||e.bytes+i.length>Bt||(e.bytes+=i.length,e.entries.push({url:t.url,lang:t.headers["accept-language"]||"",status:o.status,type:s,body:i}))},()=>{}))},Ut=()=>{const e=globalThis.fetch;if(typeof e!="function"||e[Pe])return;const t=function(...o){z++;let n=!1;const s=()=>{n||(n=!0,z--)},r=c=>{z++,c.then(()=>{z--},()=>{z--})},i=we(Ie),u=we(Re);let a=null;if(i)try{a=zt(o),(a.method!=="GET"||!/^https?:/i.test(a.url)||Object.keys(a.headers).some(c=>!Kt.has(c)))&&(a=null)}catch{a=null}const g=()=>Ge(o[0]);let f;try{f=e.apply(this,o)}catch(c){throw ke(u,g(),c&&c.message||"failed"),s(),c}return f&&typeof f.then=="function"?f.then(c=>{a&&Wt(i,a,c,r),u&&c&&c.ok===!1&&ke(u,g(),"HTTP "+c.status),s()},c=>{ke(u,g(),c&&c.message||"network error"),s()}):s(),f};t[Pe]=!0,globalThis.fetch=t},sn=({brRegistry:e,fetchSeed:t,hydrateFlag:o=!0}={})=>{if(!e||!Object.keys(e).length)return"";const n=Rt(e);return o?`<script>window.__BR_REGISTRY__=${n};window.__BRENDER_HYDRATE__=true<\/script>`+(t&&t.length?`
|
|
2
|
-
`+
|
|
1
|
+
import{resolve as d,join as nt,dirname as j}from"path";import{existsSync as S,unlinkSync as st,readFileSync as Y,realpathSync as rt}from"fs";import{resolvePackageEntry as ct}from"./packageEntry.js";import{tmpdir as it}from"os";import{randomBytes as lt}from"crypto";import{createRequire as he}from"module";import{pathToFileURL as at}from"url";import{createEnv as Te}from"./env.js";import{resetKeys as ve,assignKeys as Le,mapKeysToElements as Ae}from"./keys.js";import{extractMetadata as ye,generateHeadHtml as ft}from"./metadata.js";import"./hydrate.js";import{composeIntoShell as pt}from"./shell.js";import{trimSpriteToPage as ut,classRulesForPage as mt,markupClasses as dt,trimVariablesToPage as gt}from"./pageWeight.js";import{facesSheetTag as ht}from"./faces.js";import{fetchSSRTranslations as yt}from"./prefetch.js";import{createEarlySeedScript as bt}from"@symbo.ls/fetch";import{headerEntries as St}from"@symbo.ls/fetch/rest";import{brenderStampMeta as Rt,brenderLazyMeta as $e,escapeRegExp as wt,jsonForScript as kt,libraryPackageSpecs as xt,polyglotFallbackLang as be,polyglotLangStorageKey as _t,polyglotAddressLang as Et,polyglotStartupScript as jt}from"@symbo.ls/utils";import{brenderRegistryBlock as Tt,brenderRegistryTreeBlock as vt}from"@symbo.ls/utils/server";import*as Lt from"@symbo.ls/utils/server";let ie=null;const At=async()=>{if(ie)return ie;try{return ie=(await import("@symbo.ls/funcql")).funcqlPlugin,ie}catch{return null}};import"linkedom";import{createEarlySeedBlock as $t,fetchRunsOf as Dt}from"@symbo.ls/fetch";import{reset as Ct}from"@symbo.ls/css";const le=(e,t)=>{if(!e||!t)return;if(e[t]!==void 0)return e[t];const o=t.split(".");let n=e;for(const s of o){if(n==null||typeof n!="object")return;n=n[s]}return n},ae=(e,t)=>be(e?.lang,t),Ot=e=>{const t=Lt.revivePolyglotDefaultLang;if(typeof t!="function"||!e||typeof e!="object")return e;const o=e.polyglot?t(e.polyglot):e.polyglot,n=e.config&&e.config.polyglot,s=n&&t(n);if(o===e.polyglot&&s===n)return e;const r={...e};return o!==e.polyglot&&(r.polyglot=o),s!==n&&(r.config={...e.config,polyglot:s}),r},De=(e,t,o,n)=>{if(o?.translations){const r=o.translations[t];if(r){const l=le(r,e);if(l!==void 0)return l}}if(n?.translations){const r=n.translations[t];if(r){const l=le(r,e);if(l!==void 0)return l}}const s=be(void 0,o);if(s!==t&&o?.translations){const r=o.translations[s];if(r){const l=le(r,e);if(l!==void 0)return l}}},Mt=function(e,t){if(!e)return"";const o=this?.context,n=o?.polyglot,s=this?.state?.root||o?.state?.root,r=De(e,t||ae(s,n),n,s);if(r!==void 0)return r;const l=ke(we);return n&&l&&l.labelKeys.add(e),e},Ce=function(){return ae(this?.state?.root,this?.context?.polyglot)},L=(e,t=new WeakMap)=>{if(e===null||typeof e!="object")return e;if(t.has(e))return t.get(e);if(Array.isArray(e)){const n=[];t.set(e,n);for(const s of e)n.push(typeof s=="object"&&s!==null?L(s,t):s);return n}const o={};t.set(e,o);for(const n of Object.keys(e)){const s=e[n];o[n]=typeof s=="object"&&s!==null?L(s,t):s}return o};let q=null;try{import.meta.url&&(q=he(import.meta.url))}catch{}const qt=()=>{if(!import.meta.url||!q)return{isMonorepo:!1,monorepoRoot:null,resolvePackage:p=>p};const e=rt(new URL(".",import.meta.url).pathname),t=d(e,"../..");if(S(d(t,"packages","smbls","src","createDomql.js")))return{isMonorepo:!0,monorepoRoot:t};let n;try{const p=q.resolve("smbls/package.json");n=j(p)}catch{let p=e;for(;p!==j(p);){const h=d(p,"node_modules","smbls");if(S(d(h,"package.json"))){n=h;break}p=j(p)}}let s=q;if(n)try{s=he(d(n,"package.json"))}catch{}let r,l=process.cwd();for(;l!==j(l);){if(S(d(l,"package.json"))){r=l;break}l=j(l)}let f=s;if(r)try{f=he(d(r,"package.json"))}catch{}return{isMonorepo:!1,smblsRoot:n,brenderDir:e,projectRoot:r,_smblsRequire:s,_projectRequire:f}},z=(e,t)=>{const o=e.isMonorepo?[q]:[e._smblsRequire,e._projectRequire,q].filter(Boolean);for(const n of o)try{return n.resolve(t)}catch{}return null},sn=(e,t,...o)=>{if(e.isMonorepo)return d(e.monorepoRoot,"packages",t,...o);const n=z(e,`${t}/package.json`);return n?d(j(n),...o):null},rn=(e,t,...o)=>{if(e.isMonorepo)return d(e.monorepoRoot,"plugins",t,...o);const n=z(e,`@symbo.ls/${t}/package.json`);return n?d(j(n),...o):null},Se=(e,t,...o)=>{if(e.isMonorepo){for(const s of["packages","plugins"]){const r=d(e.monorepoRoot,s,t,...o);if(S(r))return r}return null}const n=z(e,`@symbo.ls/${t}/package.json`);return n?d(j(n),...o):null},Oe=(e,t,...o)=>{if(e.isMonorepo)return d(e.monorepoRoot,"packages","domql","packages",t,...o);const n=z(e,`@symbo.ls/${t}/package.json`);return n?d(j(n),...o):null};let fe=null;const Me="smbls/ssr",Pt=async()=>{const e=await import("smbls/ssr");if(typeof e?.createDomqlElement!="function")throw new Error("smbls/ssr does not export createDomqlElement");return e},qe=()=>(fe||(fe=It().catch(e=>{throw fe=null,e})),fe),It=async()=>{const e=qt();let t;if(q&&e.isMonorepo)t=d(e.monorepoRoot,"packages","smbls","src","createDomql.js");else{let a;try{return await Pt()}catch(c){a=c}if(!q)throw new Error(`brender: ${Me} is not available in this bundled runtime (${a.message}). Bundle smbls \u2265 the release that adds the smbls/ssr export alongside @symbo.ls/brender.`);const i=e.smblsRoot&&d(e.smblsRoot,"src","createDomql.js");if(i&&S(i))t=i;else throw new Error(`brender: cannot load ${Me} (${a.message}). Server rendering needs smbls installed in this project, at a release that exports smbls/ssr`+(e.smblsRoot?` (found smbls at ${e.smblsRoot}).`:" (no smbls package found)."))}const o=await import("esbuild"),n=nt(it(),`br_createDomql_${lt(6).toString("hex")}.mjs`),s=ct,r=e.isMonorepo?await import(at(d(e.monorepoRoot,"scripts","vite-workspace-source.mjs")).href):null,l=r?new Set(r.workspacePackageRoots().map(a=>r.workspacePackageAt(a).name)):null,f=/^(?:smbls(?:\/.*)?|domql|css-in-props(?:\/.*)?|@symbo\.ls\/[^/]+)$/,p={name:"workspace-resolve",setup(a){r&&(a.onResolve({filter:/^[^./]/},i=>{if(f.test(i.path))return;const c=i.path.split("/"),u=i.path.startsWith("@")?c.slice(0,2).join("/"):c[0];if(!l.has(u))return;const g=r.resolveWorkspaceSource(i.path,i.importer||t);return g?{path:g}:{errors:[{text:`"${i.path}" names no source file in the workspace`}]}}),a.onLoad({filter:/[\\/]dist[\\/]/},i=>r.isWorkspaceDist(i.path)?{errors:[{text:`${i.path} is a BUILD of a workspace package \u2014 the render bundles source`}]}:void 0)),a.onResolve({filter:/^smbls/},i=>{const c=i.path.replace(/^smbls\/?/,""),u=e.isMonorepo?d(e.monorepoRoot,"packages","smbls"):e.smblsRoot;if(!u)return;if(!c){const E=s(u);return E?{path:E}:void 0}const g=d(u,c);if(S(g))return{path:g};if(S(g+".js"))return{path:g+".js"};const R=d(g,"index.js");if(S(R))return{path:R}}),a.onResolve({filter:/^domql$/},i=>{if(e.isMonorepo){const c=d(e.monorepoRoot,"packages","domql","src","index.js");if(S(c))return{path:c};const u=d(e.monorepoRoot,"packages","domql","index.js");if(S(u))return{path:u}}else try{const c=_require.resolve("domql/package.json"),u=s(j(c));if(u)return{path:u}}catch{}}),a.onResolve({filter:/^@symbo\.ls\//},i=>{const c=i.path.replace("@symbo.ls/","");if(c==="sync")return{path:"sync-stub",namespace:"brender-stub"};if(e.isMonorepo){for(const g of["packages","plugins"]){const R=d(e.monorepoRoot,g,c,"src","index.js");if(S(R))return{path:R};const E=d(e.monorepoRoot,g,c,"index.js");if(S(E))return{path:E}}const u=d(e.monorepoRoot,"packages","default-config","blank","index.js");if(c==="default-config"&&S(u))return{path:u}}else{const u=Se(e,c,"src","index.js");if(u&&S(u))return{path:u};const g=Se(e,c,"index.js");if(g&&S(g))return{path:g};if(c==="default-config"){const R=Se(e,"default-config","blank","index.js");if(R&&S(R))return{path:R}}}}),a.onResolve({filter:/^@domql\//},i=>{const c=i.path.replace("@symbo.ls/","");if(e.isMonorepo){const u=d(e.monorepoRoot,"packages","domql","packages",c,"src","index.js");if(S(u))return{path:u};const g=d(e.monorepoRoot,"packages","domql","packages",c,"index.js");if(S(g))return{path:g}}else{const u=Oe(e,c,"src","index.js");if(u&&S(u))return{path:u};const g=Oe(e,c,"index.js");if(g&&S(g))return{path:g}}}),a.onResolve({filter:/^css-in-props/},i=>{let c;if(e.isMonorepo)c=d(e.monorepoRoot,"packages","css-in-props");else{const R=z(e,"css-in-props/package.json");R&&(c=j(R))}if(!c)return;const u=i.path.replace(/^css-in-props\/?/,"");if(u){const R=d(c,u),E=d(R,"index.js");if(S(E))return{path:E};if(S(R+".js"))return{path:R+".js"};if(S(R))return{path:R}}const g=s(c);if(g)return{path:g}}),a.onResolve({filter:/^@emotion\//},i=>{let c;if(e.isMonorepo)c=d(e.monorepoRoot,"node_modules",i.path);else{const u=z(e,`${i.path}/package.json`);if(!u)return;c=j(u)}if(S(c)){const u=d(c,"package.json");if(S(u))try{const g=JSON.parse(Y(u,"utf8")),R=g.module||g.main||"dist/emotion-css.esm.js";return{path:d(c,R)}}catch{}return{path:c}}}),a.onResolve({filter:/\.json$/},i=>{if(i.resolveDir){const c=d(i.resolveDir,i.path);if(S(c))return{path:c}}}),a.onLoad({filter:/smbls\/.*options\.js$/},async i=>{if(!i.path.includes("smbls/")||!i.path.endsWith("options.js"))return;let c=Y(i.path,"utf8");return c=c.replace(/import\s*\{[^}]*version[^}]*\}\s*from\s*['"][^'"]*package\.json['"][^;\n]*/,"const version = '0.0.0'"),c=c.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:c,loader:"js"}}),a.onLoad({filter:/smbls\/.*init\.js$/},async i=>{if(!i.path.includes("smbls/")||!i.path.endsWith("init.js"))return;let c=Y(i.path,"utf8");return c=c.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:c,loader:"js"}}),a.onLoad({filter:/.*/,namespace:"brender-stub"},()=>({contents:"export const SyncComponent = {}; export const Inspect = {}; export const Notifications = {}; export const syncPlugin = () => ({}); export const notificationsPlugin = () => ({}); export const seedRawDesignSystem = () => {}; export const inspectPlugin = () => ({}); export default {}",loader:"js"})),a.onLoad({filter:/smbls\/src\/router\.js$/},async i=>{let c=Y(i.path,"utf8");return c=c.replace(/import\s*\{\s*Link\s*\}\s*from\s*['"]smbls['"]/,"const Link = { tag: 'a', attr: { href: (el) => el.href } }"),{contents:c,loader:"js"}}),a.onLoad({filter:/fetchOnCreate\.js$/},async i=>{if(!i.path.includes("smbls/"))return;let c=Y(i.path,"utf8");return c=c.replace(/window\s*&&\s*window\.location\s*\?\s*window\.location\.host\.includes/g,"window && window.location && window.location.host ? window.location.host.includes"),{contents:c,loader:"js"}})}};await o.build({entryPoints:[t],bundle:!0,format:"esm",platform:"node",outfile:n,write:!0,logLevel:"warning",plugins:[p],nodePaths:e.isMonorepo?[d(e.monorepoRoot,"node_modules")]:[...e.smblsRoot?[d(e.smblsRoot,"node_modules")]:[],...e.projectRoot?[d(e.projectRoot,"node_modules")]:[],...e.smblsRoot?[d(e.smblsRoot,"..","..","node_modules")]:[]].filter(a=>S(a)),supported:{"import-attributes":!1},external:["fs","path","os","crypto","url","http","https","stream","util","events","buffer","child_process","worker_threads","net","tls","dns","dgram","zlib","assert","querystring","string_decoder","readline","perf_hooks","async_hooks","v8","vm","cluster","inspector","module","process","tty","color-contrast-checker","linkedom"]});const h=await import(`file://${n}`);if(process.env.BRENDER_DEBUG)console.log("[brender] Bundle saved:",n);else try{st(n)}catch{}return h},Ft={Box:{},Focusable:{},Block:{display:"block"},Inline:{display:"inline"},Flex:{display:"flex"},InlineFlex:{display:"inline-flex"},Grid:{display:"grid"},InlineGrid:{display:"inline-grid"},Link:{tag:"a",attr:{href:e=>e.href,target:e=>e.target,rel:e=>e.rel}},A:{extends:"Link"},RouteLink:{extends:"Link"},Img:{tag:"img",attr:{src:e=>{let t=e.src;return typeof t=="string"&&t.includes("{{")&&(t=e.call("replaceLiteralsWithObjectFields",t,e.state)),t},alt:e=>e.alt,loading:e=>e.loading}},Image:{extends:"Img"},Button:{tag:"button"},FocusableComponent:{tag:"button"},Form:{tag:"form"},Input:{tag:"input"},TextArea:{tag:"textarea"},Textarea:{tag:"textarea"},Select:{tag:"select"},Label:{tag:"label"},Iframe:{tag:"iframe"},Video:{tag:"video"},Audio:{tag:"audio"},Canvas:{tag:"canvas"},Span:{tag:"span"},P:{tag:"p"},H1:{tag:"h1"},H2:{tag:"h2"},H3:{tag:"h3"},H4:{tag:"h4"},H5:{tag:"h5"},H6:{tag:"h6"},Svg:{tag:"svg",attr:{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}},Text:{tag:"span"}},Gt=(e,t)=>{const o={};return Pe(e,(n,s)=>{if(!s.__brKey)return;const r=t(n);o[r===""?"__root":r]=s.__brKey}),o},Pe=(e,t)=>{const o=n=>{const s=n&&n.__ref;if(s&&(t(n,s),s.__children))for(const r of s.__children)o(n[r])};o(e)},Bt=new Set(["app","config","pages","components","state","snippets","designSystem","dependencies","functions","methods","files","sharedLibraries"]);let W=0;const Ie=Symbol.for("brender.fetchTracked"),Re=()=>W,Kt=256*1024,Nt=1024*1024,Ht=new Set(["accept-language","accept"]),Fe={renders:0,record:null},zt=50,we={renders:0,record:null},Ge=(e,t)=>{e.renders++,e.renders===1?e.record=t():e.record&&(e.record.tainted=!0);const o=e.record;return{record:o,close:()=>{e.renders--,e.record===o&&(e.record=null)}}},ke=e=>e.record&&!e.record.tainted?e.record:null,Wt=e=>{try{const t=new URL(e);return t.origin+t.pathname}catch{return String(e).split("?")[0]}},xe=(e,t,o)=>{!e||e.tainted||e.failures.length>=zt||e.failures.push({url:Wt(t),reason:o})},Be=e=>e&&typeof e=="object"&&typeof e.url=="string"?e.url:String(e),Ut=e=>{const[t,o]=e,n=t&&typeof t=="object"&&typeof t.url=="string",s=Be(t),r=String(o&&o.method||n&&t.method||"GET").toUpperCase(),l={},f=p=>{if(!p)return;const h=!Array.isArray(p)&&typeof p.entries!="function";for(const[a,i]of St(p))h&&i==null||(l[String(a).toLowerCase()]=String(i))};return n&&f(t.headers),o&&f(o.headers),{url:s,method:r,headers:l}},Vt=(e,t,o,n)=>{if(!o||!o.ok||typeof o.clone!="function")return;const s=o.headers&&o.headers.get&&o.headers.get("content-type")||"";if(!/json|^text\//i.test(s))return;let r;try{r=o.clone()}catch{return}n(r.text().then(l=>{e.tainted||l.length>Kt||e.bytes+l.length>Nt||(e.bytes+=l.length,e.entries.push({url:t.url,lang:t.headers["accept-language"]||"",status:o.status,type:s,body:l}))},()=>{}))},Jt=()=>{const e=globalThis.fetch;if(typeof e!="function"||e[Ie])return;const t=function(...o){W++;let n=!1;const s=()=>{n||(n=!0,W--)},r=i=>{W++,i.then(()=>{W--},()=>{W--})},l=ke(Fe),f=ke(we);let p=null;if(l)try{p=Ut(o),(p.method!=="GET"||!/^https?:/i.test(p.url)||Object.keys(p.headers).some(i=>!Ht.has(i)))&&(p=null)}catch{p=null}const h=()=>Be(o[0]);let a;try{a=e.apply(this,o)}catch(i){throw xe(f,h(),i&&i.message||"failed"),s(),i}return a&&typeof a.then=="function"?a.then(i=>{p&&Vt(l,p,i,r),f&&i&&i.ok===!1&&xe(f,h(),"HTTP "+i.status),s()},i=>{xe(f,h(),i&&i.message||"network error"),s()}):s(),a};t[Ie]=!0,globalThis.fetch=t},cn=({brRegistry:e,fetchSeed:t,hydrateFlag:o=!0}={})=>{if(!e||!Object.keys(e).length)return"";const n=kt(e);return o?`<script>window.__BR_REGISTRY__=${n};window.__BRENDER_HYDRATE__=true<\/script>`+(t&&t.length?`
|
|
2
|
+
`+bt(t):""):`<script>window.__BR_REGISTRY__=${n}<\/script>`},Yt=e=>{const t=globalThis.__SMBLS_PKGS__,o=new Set(t&&typeof t=="object"?Object.getOwnPropertyNames(t):[]);return()=>{const n=globalThis.__SMBLS_PKGS__;if(!n||typeof n!="object")return;let s;try{s=xt(e())}catch{return}for(const[r]of s)!o.has(r)&&Object.prototype.hasOwnProperty.call(n,r)&&Reflect.deleteProperty(n,r)}},Xt=3e4,Qt=2147483647;let Ke=Promise.resolve();const Ne=()=>{},Zt=e=>{const t=Ke.then(e);return Ke=t.then(Ne,Ne),t},eo=e=>{if(e===void 0)return Xt;if(e===0||e===!1||e===1/0)return 0;if(typeof e!="number"||!(e>0))throw new TypeError(`brender: options.timeout is a number of milliseconds, or 0 / false for no limit \u2014 not ${JSON.stringify(e)}`);return Math.min(e,Qt)},He=e=>{if(e==null||e===""||e==="?")return"";if(typeof e!="string"||e.includes("#"))throw new TypeError(`brender: options.search is a query string ('?view=agent'), without a hash \u2014 not ${JSON.stringify(e)}`);return e.charAt(0)==="?"?e:"?"+e},to=(e,t)=>{const o=e.route||"/",n=e.pathname||o,s=n===o?o:`${n} (route ${o})`,r=new Error(`brender: the render of ${s} did not finish within ${t} ms and was abandoned, so the renders after it can run (options.timeout)`);return r.code="BRENDER_RENDER_TIMEOUT",r.route=o,r.pathname=n,r.timeout=t,r},oo=e=>{e.closed=!0;for(const t of e.undo.splice(0))t()},no=e=>{let t=!1;return()=>{t||(t=!0,e())}},ze=(e,t={})=>{let o;try{o=eo(t.timeout),He(t.search)}catch(n){return Promise.reject(n)}return Zt(()=>so(e,t,o))},so=async(e,t,o)=>{await qe();const n={closed:!1,undo:[]},s=ro(e,t,n);if(!o)return s;let r;const l=new Promise((f,p)=>{r=setTimeout(()=>{oo(n),p(to(t,o))},o)});try{return await Promise.race([s,l])}finally{clearTimeout(r)}},ro=async(e,t,o)=>{const{route:n="/",pathname:s,state:r,context:l,prefetch:f=!1,lazyGroups:p}=t,h=s||n,a=He(t.search);Jt();const i=Ge(we,()=>({failures:[],labelKeys:new Set,tainted:!1}));try{return await co(Ot(e),{route:n,locationPath:h,locationSearch:a,stateOverrides:r,contextOverrides:l,prefetch:f,lazyGroups:p},i.record,o)}finally{i.close()}},co=async(e,{route:t,locationPath:o,locationSearch:n,stateOverrides:s,contextOverrides:r,prefetch:l,lazyGroups:f},p,h)=>{const a=()=>{if(h.closed)throw new Error("brender: this render was abandoned at its timeout")};let i;if(l){try{i=await yt(e)}catch(P){h.closed||console.warn("[brender] SSR translation fetch failed:",P.message)}a()}const{window:c,document:u}=Te(),g=u.body;c.location.pathname=o,n&&(c.location.search=n,c.location.href=c.location.origin+o+n);let R=null;const E=[pe("document",u),pe("location",c.location),pe("localStorage",c.localStorage),pe("sessionStorage",c.sessionStorage),Yt(()=>R&&R.sharedLibraries)].map(no);h.undo.push(...E);try{const{createDomqlElement:P,PRERENDER_REGISTRY_FORMATS:X}=await qe();a();const de=L(e.app||{}),x={...e.config||{}};e.polyglot&&!x.polyglot&&(x.polyglot=e.polyglot),e.fetch&&!x.fetch&&(x.fetch=e.fetch),e.router&&!x.router&&(x.router=e.router);for(const m of mo)e[m]!=null&&x[m]==null&&(x[m]=e[m]);const _=x.polyglot?{...x.polyglot,prefetch:!1}:void 0,Q=Et(o,_);Q&&c.localStorage.setItem(_t(_),Q),i&&_&&(_.translations={..._.translations||{},...i});const Z=L(e.state||{});Ct();const I={};for(const m in e){if(Bt.has(m))continue;const b=e[m];I[m]=b&&typeof b=="object"?L(b):b}const k={...I,state:Z,...s?{state:{...Z,...s}}:{},dependencies:L(e.dependencies||{}),components:L(e.components||{}),snippets:L(e.snippets||{}),pages:L(e.pages||{}),functions:{...e.functions||{},polyglot:Mt,getActiveLang:Ce,getLang:Ce},methods:e.methods||{},designSystem:L(e.designSystem||{}),files:e.files||{},sharedLibraries:e.sharedLibraries||[],...x,..._?{polyglot:_}:{},document:u,window:c,parent:{node:g},initOptions:{},domqlOptions:{sourcemap:!1},firstRender:!1,sync:!1,inspect:!1,notifications:!1,afterFirstView:null,isolateDesignSystem:!0,isolateFetchCache:!0,captureDesignSystem:!0,...io(f),...r||{},ssr:!0};R=k;const ee=await At();a(),ee&&(k.plugins=k.plugins||[],k.plugins.some(m=>m.name==="funcql")||k.plugins.push(ee)),ve();const K=Ge(Fe,()=>({entries:[],bytes:0,tainted:!1})),y=K.record;let w;try{if(w=await P(de,k),a(),k.lazyFirstView){const D=(w&&w.context||k).__firstNavigation;if(D&&typeof D.then=="function"){try{await D}catch{}a()}}const m=Date.now(),b=l?2e3:50,T=D=>new Promise(ce=>setTimeout(ce,D));for(await T(Math.min(50,b));l&&!h.closed&&Re()>0&&Date.now()-m<b;)await T(10),Re()===0&&await T(Math.max(0,Math.min(50,b-(Date.now()-m))));if(a(),l&&await lo(w,_)){a();const D=Date.now();for(await T(Math.min(50,b));!h.closed&&Re()>0&&Date.now()-D<b;)await T(10);a()}}finally{K.close()}const U=y&&!y.tainted&&!(x.fetch&&x.fetch.seed===!1)?y.entries.slice():[];Le(g);const A=Ae(w),{elementPath:N}=await import("@symbo.ls/element");a();const te=Gt(w,N),oe=U.length?Dt(w&&w.context||k,N):{},V=w?.context?.routerOptions?.contentElementKey||"content",F=w&&w[V],C=F&&typeof F=="object"&&F.__ref?F:void 0,je=ye(e,t,w,w?.state,C),O=[],J=u.head||u.querySelector("head");if(J)for(const m of J.querySelectorAll("style")){if(m.sheet&&m.sheet.cssRules)for(const b of m.sheet.cssRules)b.cssText&&O.push(b);if(!O.length){const b=m.textContent||"";b&&O.push({cssText:b})}}const ne=O.map(m=>m.cssText),{globalCSS:se,classRules:ge}=Ro(O);let v=Ve(g.innerHTML);const G=w?.state?.root,B=ae(G,_),M=ao(i,G);M&&(v=Ue(v,We(M,B,_)));const H=p&&!p.tainted?{failedRequests:p.failures.slice(),rawLabelKeys:uo(p.labelKeys,v,B,_,G)}:null,$=(w&&w.context||k).__lazyFirstViews,re=$&&typeof $.forEach=="function"?[...$]:[];return{html:v,metadata:je,registry:A,brRegistry:te,element:w,emotionCSS:ne,lazyGroups:re,globalCSS:se,classRules:ge,fetchSeed:U,fetchRuns:oe,document:u,window:c,ssrTranslations:M||void 0,activeLang:B,diagnostics:H,preparedDesignSystem:k.preparedDesignSystem||null,registryFormats:Array.isArray(X)?X.slice():["paths"]}}finally{for(const P of E)P()}},io=e=>{if(e==="load"||e===!0)return{lazyFirstView:!0};if(Array.isArray(e)){const t=e.filter(o=>typeof o=="string"&&o);return t.length?{lazyFirstView:t}:{}}return{}},pe=(e,t)=>{const o=Object.getOwnPropertyDescriptor(globalThis,e);return o&&!o.configurable?!o.writable&&!o.set?()=>{}:(globalThis[e]=t,()=>{}):(Object.defineProperty(globalThis,e,{value:t,writable:!0,configurable:!0,enumerable:!0}),()=>{o?Object.defineProperty(globalThis,e,o):delete globalThis[e]})},lo=async(e,t)=>{if(!t||!t.fetch||!e||typeof e.call!="function")return!1;const o=e.state&&e.state.root;if(!o)return!1;const n=ae(o,t),s=o.translations&&o.translations[n];if(s&&typeof s=="object"&&Object.keys(s).length||t.translations&&t.translations[n])return!1;try{await e.call("loadTranslations",n,{inFlight:!0})}catch{}return!0},_e=/\{\{\s*([^|{}]+?)\s*\|\s*polyglot\s*\}\}/g,Ee=e=>e&&typeof e.parse=="function"?e.parse():e,ao=(e,t)=>{const o=Ee(t?.translations),n={};for(const s of[e,o])if(!(!s||typeof s!="object"))for(const r in s){const l=Ee(s[r]);l&&typeof l=="object"&&(n[r]={...n[r]||{},...l})}return Object.keys(n).length?n:null},We=(e,t,o)=>e[t]||e[be(void 0,o)]||Object.values(e)[0]||{},Ue=(e,t)=>e.replace(_e,(o,n)=>le(t,n.trim())??o),fo=/<script\b[^>]*\btype\s*=\s*["']?application\/json["']?[^>]*>[\s\S]*?<\/script\s*>/gi,po=(e,t)=>new RegExp(`(?:^|[^\\w.-])${wt(t)}(?![\\w-]|\\.\\w)`).test(e),uo=(e,t,o,n,s)=>{const r=new Set,l=t.replace(fo,"");for(const f of e)/\s/.test(f)||De(f,o,n,s)===void 0&&po(l,f)&&r.add(f);for(const f of l.matchAll(_e))r.add(f[1].trim());return[...r]},ln=async(e,t={})=>{const{context:o={}}=t,{window:n,document:s}=Te(),r=s.body,{create:l}=await import("@symbo.ls/element"),f=await import("@symbo.ls/utils"),p={...Ft,...o.components||{}},h={...f,...o.utils||{},...o.functions||{}};ve();let a;try{a=l(e,{node:r},"root",{context:{document:s,window:n,...o,components:p,utils:h,ssr:!0}})}catch{}Le(r);const i=a?Ae(a):{};return{html:Ve(r.innerHTML),registry:i,element:a}},Ve=e=>e.replace(/(<svg\b[^>]*>)([\s\S]*?)(<\/svg>)/gi,(t,o,n,s)=>{if(n.includes("<")){const r=n.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&").replace(/"/g,'"').replace(/'/g,"'");return o+r+s}return t}),mo=["globalTheme","themeStorageKey","themeRoot","useReset","useVariable","useFontImport","useIconSprite","useSvgSprite","useDocumentTheme","useDefaultConfig","useDefaultIcons","useThemeSuffixedVars","verbose","semanticIcons"],go=new Set(["auto","system"]),Je=e=>{if(!e||typeof e!="object")return null;const t=e.config&&typeof e.config=="object"?e.config:{};if((t.themeRoot!=null?t.themeRoot:e.themeRoot)!=null)return null;const n=t.globalTheme!=null?t.globalTheme:e.globalTheme;if(typeof n!="string")return null;const s=n.trim();return!s||go.has(s)?null:s},ho=e=>String(e).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<"),yo=/\.[A-Za-z_\\-]/,bo=e=>{if(typeof e!="string"||!e)return!1;const t=e.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,'""').replace(/\[[^\]]*\]/g,"[]");return!yo.test(t)},So=/^\s*(:root|\[data-theme|\[data-skin)/,Ye=e=>{const t=e&&e.cssText;if(typeof t!="string")return null;if(/^@(-webkit-)?keyframes\b/.test(t))return"keyframes";if(t.startsWith("@font-face"))return null;if(typeof e.selectorText=="string")return bo(e.selectorText)?So.test(e.selectorText)?"root":"reset":null;const o=e.cssRules&&Array.from(e.cssRules);if(o&&o.length&&/^@(media|supports|container)\b/.test(t)){const n=new Set(o.map(Ye));return n.has(null)||n.size!==1?n.has(null)?null:"reset":[...n][0]}return null},Xe=e=>typeof e=="string"&&/^\s*@font-face\b/i.test(e),Ro=e=>{const t={root:[],reset:[],keyframes:[]},o=[];for(const n of e||[]){const s=Ye(n);s?t[s].push(n.cssText):n&&n.cssText&&o.push(n.cssText)}return{globalCSS:{rootRule:t.root.join(`
|
|
3
3
|
`),resetRules:t.reset.join(`
|
|
4
4
|
`),keyframeRules:t.keyframes.join(`
|
|
5
|
-
`),fontFaceCSS:""},classRules:o}};let
|
|
6
|
-
`),
|
|
5
|
+
`),fontFaceCSS:""},classRules:o}};let ue=new Set;const an=()=>{ue=new Set},fn=()=>Array.from(ue).join(`
|
|
6
|
+
`),pn=(e,t)=>e.replace(/<style data-emotion="smbls">[\s\S]*?<\/style>/,t?`<style data-emotion="smbls">
|
|
7
7
|
${t}
|
|
8
|
-
</style>`:""),
|
|
9
|
-
`),classRules:
|
|
10
|
-
`):
|
|
11
|
-
`),
|
|
12
|
-
${(
|
|
8
|
+
</style>`:""),un=async(e,t={})=>{const{route:o="/",pathname:n,search:s,prefetch:r=!0,timeout:l}=t,f=await ze(e,{route:o,pathname:n,search:s,prefetch:r,timeout:l});if(!f)return null;const p=e.designSystem||{},h=f.globalCSS;let a=null;try{const c=wo(f.element);Object.keys(c).length&&(a=c)}catch{}const i=f.activeLang;return{html:f.html,css:f.classRules.join(`
|
|
9
|
+
`),classRules:f.classRules.slice(),globalCSS:h,resetCss:h.resetRules,fontLinks:ot(p),metadata:f.metadata||ye(e,o),brKeyCount:f.registry?Object.keys(f.registry).length:0,brRegistry:f.brRegistry||{},fetchSeed:f.fetchSeed||[],fetchRuns:f.fetchRuns||{},ssrTranslations:f.ssrTranslations,prefetchedState:a,activeLang:i,theme:Je(e),diagnostics:f.diagnostics,preparedDesignSystem:f.preparedDesignSystem||null}},wo=e=>{const t={};return Pe(e,o=>{const n=o.fetch;if(!(!n||typeof n!="object"||!o.state))for(const s of Array.isArray(n)?n:[n]){const r=s&&typeof s=="object"&&typeof s.as=="string"?s.as:null;if(!r)continue;const l=r.startsWith("~/"),f=l?r.slice(2):r,p=l?o.state.root:o.state,h=Ee(p&&p[f]);f&&h!=null&&typeof h!="function"&&(t[f]=h)}}),t},mn=async(e,t="/",o={})=>{const{lang:n,themeColor:s,isr:r,hydrate:l=!0,prefetch:f=!0,shell:p,adoptDom:h=!1,pathname:a,search:i,eagerImages:c=tt,preloadScripts:u=!0,nonce:g,timeout:R,stamp:E,time:P,spriteIcons:X="all",cssClasses:de="all",cssVariables:x="all",registryFormat:_="paths",lazyGroups:Q,paint:Z}=o,I=ko(Z),k=Ao(g),ee=n||e.state?.lang||e.app?.metadata?.lang||"en",K=Je(e),y=await ze(e,{route:t,pathname:a,search:i,prefetch:f,timeout:R,lazyGroups:Q});if(!y)return null;const w={...y.metadata};if(s&&(w["theme-color"]=s),typeof p=="string"&&!e.name){const m="\0brender-undeclared-title\0";if(ye({...e,name:m},t,y.element,y.element?.state).title===m)for(const T of["title","og:title","twitter:title"])w[T]===y.metadata.title&&delete w[T]}const U=ft(w);for(const m of y.classRules)m&&ue.add(m);let A=To(y.html,c);X==="page"&&(A=ut(A,typeof p=="string"?p:"").html);const N=Array.from(ue),te=N.filter(Xe),oe=te.length?N.filter(m=>!Xe(m)):N,V=de==="page"?mt(oe,dt(A,typeof p=="string"?p:"")).join(`
|
|
10
|
+
`):oe.join(`
|
|
11
|
+
`),F=ht(te),C=y.globalCSS,O=`<style data-brender>
|
|
12
|
+
${(x==="page"?gt(C.rootRule||"",C.resetRules,C.keyframeRules,V,A,typeof p=="string"?p:"").css:C.rootRule)||""}
|
|
13
13
|
${C.resetRules||""}
|
|
14
14
|
${C.keyframeRules||""}
|
|
15
|
-
</style>`,V
|
|
16
|
-
${
|
|
17
|
-
</style>`:"",
|
|
18
|
-
`:"",
|
|
19
|
-
`:"";
|
|
15
|
+
</style>`,J=V?`<style data-emotion="smbls">
|
|
16
|
+
${V}
|
|
17
|
+
</style>`:"",ne=ot(e.designSystem||{}),se=Object.keys(y.registry).length,ge=_==="tree"||_==="auto"&&(y.registryFormats||[]).includes("tree"),v=vo({brRegistry:y.brRegistry,fetchSeed:y.fetchSeed,fetchRuns:y.fetchRuns,adoptDom:h,stamp:E,time:P,registryFormat:ge?"tree":"paths",lazyGroups:y.lazyGroups});let G="";if(r&&r.clientScript){const m=Number.isInteger(o.depth)?o.depth:t==="/"?0:t.replace(/^\/|\/$/g,"").split("/").length,b=m>0?"../".repeat(m):"./";if(l){const T=jt({polyglot:e.polyglot||e.config?.polyglot,translations:y.ssrTranslations,lang:y.activeLang,pathname:a||t,attrs:k}),D=T?T+`
|
|
18
|
+
`:"",ce=v.blocks?v.blocks+`
|
|
19
|
+
`:"";G=`${D}${ce}<script type="module" src="${b}${r.clientScript}"${k}><\/script>`}else G=`<script type="module"${k}>
|
|
20
20
|
{
|
|
21
21
|
const brEls = document.querySelectorAll('body > :not(script):not(style)')
|
|
22
22
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -33,29 +33,29 @@ ${U}
|
|
|
33
33
|
observer.observe(document.body, { childList: true })
|
|
34
34
|
}
|
|
35
35
|
<\/script>
|
|
36
|
-
<script type="module" src="${b}${r.clientScript}"${
|
|
37
|
-
${v.meta}`,headEnd:[
|
|
38
|
-
`),body:
|
|
39
|
-
`+
|
|
40
|
-
<html lang="${
|
|
36
|
+
<script type="module" src="${b}${r.clientScript}"${k}><\/script>`}const B={...e.config||{}};e.polyglot&&!B.polyglot&&(B.polyglot=e.polyglot);const M=B.polyglot;let H=U;if(M){const m={...M.translations||{}};for(const b in y.ssrTranslations||{})m[b]={...m[b]||{},...y.ssrTranslations[b]};H=Ue(U,We(m,y.activeLang,M))}const $=y.diagnostics;if($)for(const m of H.matchAll(_e)){const b=m[1].trim();$.rawLabelKeys.includes(b)||$.rawLabelKeys.push(b)}if(typeof p=="string"){const m=pt(p,{headTags:`${H}
|
|
37
|
+
${v.meta}`,headEnd:[ne,F,O,J].filter(Boolean).join(`
|
|
38
|
+
`),body:I?A+`
|
|
39
|
+
`+Ze:A,depth:Number.isInteger(o.depth)?o.depth:0,bootScripts:v.blocks,lang:n||(M?y.activeLang:void 0),theme:K,preloadScripts:u});return{html:I?et(m):m,route:t,brKeyCount:se,shell:!0,diagnostics:$,preparedDesignSystem:y.preparedDesignSystem||null,lazyGroups:y.lazyGroups||[]}}const re=`<!DOCTYPE html>
|
|
40
|
+
<html lang="${ee}"${K?` data-theme="${ho(K)}"`:""}>
|
|
41
41
|
<head>
|
|
42
|
-
${
|
|
42
|
+
${H}${r&&r.clientScript&&l?`
|
|
43
43
|
${v.meta}`:""}
|
|
44
|
-
${
|
|
45
|
-
${
|
|
46
|
-
${
|
|
47
|
-
${
|
|
44
|
+
${ne}
|
|
45
|
+
${F}
|
|
46
|
+
${O}
|
|
47
|
+
${J}
|
|
48
48
|
</head>
|
|
49
49
|
<body>
|
|
50
|
-
${A}${
|
|
51
|
-
${
|
|
52
|
-
${
|
|
50
|
+
${A}${I?`
|
|
51
|
+
${Ze}`:""}
|
|
52
|
+
${G}
|
|
53
53
|
</body>
|
|
54
|
-
</html>`;return{html:
|
|
55
|
-
`+
|
|
56
|
-
`+
|
|
57
|
-
`+e},
|
|
58
|
-
`):""},
|
|
59
|
-
`+
|
|
60
|
-
|
|
61
|
-
`)}},
|
|
54
|
+
</html>`;return{html:I?et(re):re,route:t,brKeyCount:se,diagnostics:$,preparedDesignSystem:y.preparedDesignSystem||null,lazyGroups:y.lazyGroups||[]}},Qe="smbls-whole",Ze=`<template id="${Qe}"></template>`,me=`<link rel="expect" href="#${Qe}" blocking="render">`,ko=e=>!!(e&&typeof e=="object"&&e.whole===!0),xo=/<meta\b[^>]*\bcharset\s*=[^>]*>/i,_o=[/<head\b[^>]*>/i,/<html\b[^>]*>/i,/^\s*<!doctype\b[^>]*>/i],et=e=>{if(typeof e!="string"||e.includes(me))return e;const t=xo.exec(e.slice(0,1024));if(t){const o=t.index+t[0].length;return e.slice(0,o)+`
|
|
55
|
+
`+me+e.slice(o)}for(const o of _o){const n=o.exec(e);if(n)return e.slice(0,n.index+n[0].length)+`
|
|
56
|
+
`+me+e.slice(n.index+n[0].length)}return me+`
|
|
57
|
+
`+e},tt=2,Eo=/<img\b(?:[^>"']|"[^"]*"|'[^']*')*>/gi,jo=/\sloading\s*=/i,To=(e,t=tt)=>{if(t===!1||t==null||typeof e!="string")return e;const o=Math.max(0,Number(t)||0);let n=0;return e.replace(Eo,s=>n++<o||jo.test(s)?s:s.replace(/^<img\b/i,'<img loading="lazy"'))},ot=e=>{if(!e)return"";const t=e.font_family||e.fontFamily||{},o=new Set;for(const s of Object.values(t)){if(typeof s!="string")continue;const r=s.match(/'([^']+)'/);r&&o.add(r[1])}return o.size?['<link rel="preconnect" href="https://fonts.googleapis.com">','<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>',`<link href="https://fonts.googleapis.com/css2?${[...o].map(s=>`family=${s.replace(/\s+/g,"+")}:wght@300;400;500;600;700`).join("&")}&display=swap" rel="stylesheet">`].join(`
|
|
58
|
+
`):""},vo=({brRegistry:e,fetchSeed:t,fetchRuns:o,adoptDom:n=!1,stamp:s,time:r,registryFormat:l="paths",lazyGroups:f}={})=>{const h=n&&e&&Object.keys(e).length?l==="tree"&&vt(e)||Tt(e):"",a=$t(t,o);return{meta:`<meta name="brender" content="${h?"hydrate":"replace"}">
|
|
59
|
+
`+Rt(Lo(s,r))+($e(f)?`
|
|
60
|
+
`+$e(f):""),blocks:[h,a].filter(Boolean).join(`
|
|
61
|
+
`)}},Lo=(e,t)=>{const o=typeof t=="number"&&isFinite(t)?Math.round(t):Date.now();return{stamp:e!=null&&e!==""?String(e):new Date(o).toISOString(),time:o}},Ao=e=>{if(e==null||e==="")return"";const t=String(e);if(!/^[A-Za-z0-9+/=_-]+$/.test(t))throw new Error("brender: a nonce is base64 or base64url text");return` nonce="${t}"`};export{tt as EAGER_IMAGES_DEFAULT,Me as SMBLS_SSR_SPECIFIER,Qe as WHOLE_MARKER_ID,cn as adoptionScripts,Lo as buildStamp,Je as fixedThemeOf,fn as getAccumulatedEmotionCSS,To as markLazyImages,ko as paintsWhole,vo as prerenderParts,ze as render,ln as renderElement,mn as renderPage,un as renderRoute,pn as replaceEmotionCSS,an as resetGlobalCSSCache,Ro as splitCapturedCSS,et as withWholePaint};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/brender",
|
|
3
|
-
"version": "3.14.
|
|
3
|
+
"version": "3.14.680",
|
|
4
4
|
"license": "CC-BY-NC-4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -57,17 +57,17 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@symbo.ls/css": "^3.14.782",
|
|
60
|
-
"@symbo.ls/default-config": "^3.14.
|
|
61
|
-
"@symbo.ls/element": "^3.14.
|
|
62
|
-
"@symbo.ls/fetch": "^3.14.
|
|
60
|
+
"@symbo.ls/default-config": "^3.14.794",
|
|
61
|
+
"@symbo.ls/element": "^3.14.823",
|
|
62
|
+
"@symbo.ls/fetch": "^3.14.678",
|
|
63
63
|
"@symbo.ls/helmet": "^3.14.674",
|
|
64
|
-
"@symbo.ls/scratch": "^3.14.
|
|
65
|
-
"@symbo.ls/utils": "^3.14.
|
|
64
|
+
"@symbo.ls/scratch": "^3.14.799",
|
|
65
|
+
"@symbo.ls/utils": "^3.14.859",
|
|
66
66
|
"esbuild": "^0.28.1",
|
|
67
67
|
"linkedom": "^0.16.8"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"smbls": "^3.14.
|
|
70
|
+
"smbls": "^3.14.869"
|
|
71
71
|
},
|
|
72
72
|
"optionalDependencies": {
|
|
73
73
|
"@symbo.ls/funcql": "^3.14.0"
|
package/render.js
CHANGED
|
@@ -1063,6 +1063,19 @@ const renderTimeoutOf = (value) => {
|
|
|
1063
1063
|
return Math.min(value, TIMER_MAX)
|
|
1064
1064
|
}
|
|
1065
1065
|
|
|
1066
|
+
// `options.search`: the query of the address the page is rendered at (S1,
|
|
1067
|
+
// final-landing 2026-10-28: the landing's agent view, `?view=agent`, read by
|
|
1068
|
+
// its app at init). '?a=b', or 'a=b'; undefined, null, '' or '?' for none —
|
|
1069
|
+
// then the location is as it was before the option, byte for byte. A hash
|
|
1070
|
+
// is no part of it.
|
|
1071
|
+
const renderSearchOf = (value) => {
|
|
1072
|
+
if (value === undefined || value === null || value === '' || value === '?') return ''
|
|
1073
|
+
if (typeof value !== 'string' || value.includes('#')) {
|
|
1074
|
+
throw new TypeError(`brender: options.search is a query string ('?view=agent'), without a hash — not ${JSON.stringify(value)}`)
|
|
1075
|
+
}
|
|
1076
|
+
return value.charAt(0) === '?' ? value : '?' + value
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1066
1079
|
const renderTimeoutError = (options, timeout) => {
|
|
1067
1080
|
const route = options.route || '/'
|
|
1068
1081
|
const pathname = options.pathname || route
|
|
@@ -1105,6 +1118,8 @@ const once = (fn) => {
|
|
|
1105
1118
|
* @param {object} [options]
|
|
1106
1119
|
* @param {string} [options.route='/'] - The route/page to render
|
|
1107
1120
|
* @param {string} [options.pathname] - The address the page is rendered at (default: the route)
|
|
1121
|
+
* @param {string} [options.search] - That address's query ('?view=agent'): the
|
|
1122
|
+
* render's location.search (and href); none by default
|
|
1108
1123
|
* @param {object} [options.state] - State overrides
|
|
1109
1124
|
* @param {object} [options.context] - Additional context overrides
|
|
1110
1125
|
* @param {boolean} [options.prefetch=false] - Fetch table/RPC labels first and wait for the page's requests
|
|
@@ -1116,6 +1131,7 @@ export const render = (data, options = {}) => {
|
|
|
1116
1131
|
let timeout
|
|
1117
1132
|
try {
|
|
1118
1133
|
timeout = renderTimeoutOf(options.timeout)
|
|
1134
|
+
renderSearchOf(options.search)
|
|
1119
1135
|
} catch (err) {
|
|
1120
1136
|
return Promise.reject(err)
|
|
1121
1137
|
}
|
|
@@ -1148,18 +1164,20 @@ const renderOnce = async (data, options, turn) => {
|
|
|
1148
1164
|
const { route = '/', pathname, state: stateOverrides, context: contextOverrides, prefetch = false, lazyGroups } = options
|
|
1149
1165
|
// pathname is the actual URL path (e.g. /podcast/abc-123), route is the page pattern (e.g. /podcast/:id)
|
|
1150
1166
|
const locationPath = pathname || route
|
|
1167
|
+
// its query ('' for none; checked in render())
|
|
1168
|
+
const locationSearch = renderSearchOf(options.search)
|
|
1151
1169
|
|
|
1152
1170
|
// This render's diagnostics (see `DIAG`), open before its first request.
|
|
1153
1171
|
trackFetches()
|
|
1154
1172
|
const diag = openRenderRecord(DIAG, () => ({ failures: [], labelKeys: new Set(), tainted: false }))
|
|
1155
1173
|
try {
|
|
1156
|
-
return await renderWithDiagnostics(withRevivedDefaultLang(data), { route, locationPath, stateOverrides, contextOverrides, prefetch, lazyGroups }, diag.record, turn)
|
|
1174
|
+
return await renderWithDiagnostics(withRevivedDefaultLang(data), { route, locationPath, locationSearch, stateOverrides, contextOverrides, prefetch, lazyGroups }, diag.record, turn)
|
|
1157
1175
|
} finally {
|
|
1158
1176
|
diag.close()
|
|
1159
1177
|
}
|
|
1160
1178
|
}
|
|
1161
1179
|
|
|
1162
|
-
const renderWithDiagnostics = async (data, { route, locationPath, stateOverrides, contextOverrides, prefetch, lazyGroups }, diag, turn) => {
|
|
1180
|
+
const renderWithDiagnostics = async (data, { route, locationPath, locationSearch, stateOverrides, contextOverrides, prefetch, lazyGroups }, diag, turn) => {
|
|
1163
1181
|
// After every wait: a render abandoned at its timeout stops here (see
|
|
1164
1182
|
// "One render at a time").
|
|
1165
1183
|
const live = () => {
|
|
@@ -1199,6 +1217,13 @@ const renderWithDiagnostics = async (data, { route, locationPath, stateOverrides
|
|
|
1199
1217
|
|
|
1200
1218
|
// Set route on location so the router picks it up
|
|
1201
1219
|
window.location.pathname = locationPath
|
|
1220
|
+
// The address's query (`options.search`): page code reads it as in a
|
|
1221
|
+
// browser at that address — location.search, and href with it. None: the
|
|
1222
|
+
// location as before (href stays the origin's).
|
|
1223
|
+
if (locationSearch) {
|
|
1224
|
+
window.location.search = locationSearch
|
|
1225
|
+
window.location.href = window.location.origin + locationPath + locationSearch
|
|
1226
|
+
}
|
|
1202
1227
|
|
|
1203
1228
|
// globalThis.document/location for the bundled smbls code (which uses
|
|
1204
1229
|
// `window = globalThis`) during SSR, and the render's own storage behind
|
|
@@ -1894,6 +1919,7 @@ export const replaceEmotionCSS = (html, newCSS) => {
|
|
|
1894
1919
|
* @param {object} data - Full project data
|
|
1895
1920
|
* @param {object} [options]
|
|
1896
1921
|
* @param {string} [options.route='/'] - Route to render
|
|
1922
|
+
* @param {string} [options.search] - The query of the address (see render())
|
|
1897
1923
|
* @param {number|false} [options.timeout] - render()'s time limit (30 s by default)
|
|
1898
1924
|
* @returns {Promise<{ html: string, css: string, resetCss: string, fontLinks: string, metadata: object, brKeyCount: number }>}
|
|
1899
1925
|
*/
|
|
@@ -1901,11 +1927,11 @@ export const renderRoute = async (data, options = {}) => {
|
|
|
1901
1927
|
// `prefetch: false` fetches no table/RPC labels first and does not wait for
|
|
1902
1928
|
// the page's requests — the publish-time pre-render (smbls publish →
|
|
1903
1929
|
// ssrCache) renders data-free.
|
|
1904
|
-
const { route = '/', pathname, prefetch = true, timeout } = options
|
|
1930
|
+
const { route = '/', pathname, search, prefetch = true, timeout } = options
|
|
1905
1931
|
|
|
1906
1932
|
// Use the full render pipeline which handles polyglot, prefetch, emotion, etc.
|
|
1907
1933
|
// Pass pathname so the virtual DOM location reflects the actual URL (for dynamic routes)
|
|
1908
|
-
const result = await render(data, { route, pathname, prefetch, timeout })
|
|
1934
|
+
const result = await render(data, { route, pathname, search, prefetch, timeout })
|
|
1909
1935
|
if (!result) return null
|
|
1910
1936
|
|
|
1911
1937
|
const ds = data.designSystem || {}
|
|
@@ -2011,6 +2037,8 @@ const collectFetchedState = (element) => {
|
|
|
2011
2037
|
* The result then carries `shell: true`.
|
|
2012
2038
|
* @param {number|false} [options.timeout] - render()'s time limit (30 s by
|
|
2013
2039
|
* default; 0 or false: none) — see render()
|
|
2040
|
+
* @param {string} [options.search] - The query of the address the page is
|
|
2041
|
+
* rendered at ('?view=agent'; see render()); none by default
|
|
2014
2042
|
* @param {string|number} [options.stamp] - The build's data stamp, written into
|
|
2015
2043
|
* the page (see buildStamp); default: the render time as an ISO string
|
|
2016
2044
|
* @param {number} [options.time] - The build time in ms (see buildStamp);
|
|
@@ -2039,7 +2067,7 @@ const collectFetchedState = (element) => {
|
|
|
2039
2067
|
* @returns {Promise<{ html: string, route: string, brKeyCount: number, shell?: true }>}
|
|
2040
2068
|
*/
|
|
2041
2069
|
export const renderPage = async (data, route = '/', options = {}) => {
|
|
2042
|
-
const { lang, themeColor, isr, hydrate = true, prefetch = true, shell, adoptDom = false, pathname, eagerImages = EAGER_IMAGES_DEFAULT, preloadScripts = true, nonce, timeout, stamp, time, spriteIcons = 'all', cssClasses = 'all', cssVariables = 'all', registryFormat = 'paths', lazyGroups, paint } = options
|
|
2070
|
+
const { lang, themeColor, isr, hydrate = true, prefetch = true, shell, adoptDom = false, pathname, search, eagerImages = EAGER_IMAGES_DEFAULT, preloadScripts = true, nonce, timeout, stamp, time, spriteIcons = 'all', cssClasses = 'all', cssVariables = 'all', registryFormat = 'paths', lazyGroups, paint } = options
|
|
2043
2071
|
const whole = paintsWhole(paint)
|
|
2044
2072
|
const nonceAttr = nonceAttribute(nonce)
|
|
2045
2073
|
|
|
@@ -2054,7 +2082,7 @@ export const renderPage = async (data, route = '/', options = {}) => {
|
|
|
2054
2082
|
// canonical/og:url built from it read it. Without it a route was rendered
|
|
2055
2083
|
// at its own pattern: the `/*` page wrote a `/*` canonical into 404.html
|
|
2056
2084
|
// (xma.info report, brender build item 7).
|
|
2057
|
-
const result = await render(data, { route, pathname, prefetch, timeout, lazyGroups })
|
|
2085
|
+
const result = await render(data, { route, pathname, search, prefetch, timeout, lazyGroups })
|
|
2058
2086
|
if (!result) return null
|
|
2059
2087
|
|
|
2060
2088
|
const metadata = { ...result.metadata }
|