@symbo.ls/brender 3.14.671 → 3.14.672
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 +28 -0
- package/dist/esm/render.js +34 -31
- package/package.json +2 -2
- package/render.js +25 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @symbo.ls/brender
|
|
2
2
|
|
|
3
|
+
## 3.14.672
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 77f0e31: Release note (XMA, round 8 E13): the element-path registry of a built page has a new tag. A step after `smbls build` that looks for the old tag does not find it.
|
|
8
|
+
|
|
9
|
+
- Old tag: `<script type="application/json" data-brender="registry">`. Its content is an object, element path → `br-<n>`.
|
|
10
|
+
- New tag, written by `smbls build` (`renderPage({ registryFormat: 'auto' })`) when the page's own smbls reads it (smbls 3.14.848 or later, cli 3.14.814 or later): `<script type="application/json" data-brender="registry-tree">`. Its content is the same registry as a tree, `{ "f": "tree", "e": [...] }` (`@symbo.ls/utils` `encodeBrenderRegistry` / `decodeBrenderRegistry`). It is about a third of the bytes.
|
|
11
|
+
- A registry that cannot be a tree (a value that is not `br-<n>`) still ships in the old tag. `renderPage` called directly still writes the old tag by default (`registryFormat: 'paths'`).
|
|
12
|
+
- To keep the old tag in `smbls build`, set `"brender": { "registryFormat": "paths" }` in `symbols.json`.
|
|
13
|
+
|
|
14
|
+
How a post-build step finds the end of the page markup:
|
|
15
|
+
|
|
16
|
+
- The markup is inserted right after `<body>`. The page's data blocks come directly after it, then the shell's own body content.
|
|
17
|
+
- The first data block after the markup is one of these: `<script type="application/json" data-brender="registry">`, `<script type="application/json" data-brender="registry-tree">`, or `<script type="application/json" data-fetch-seed>` (the recorded answers). A page with `brender.hydrate: false` has no registry block. A page that made no anonymous request has no fetch-seed block.
|
|
18
|
+
- Match all three, not one full tag. For example: `/<script type="application\/json" data-(?:brender="registry(?:-tree)?"|fetch-seed\b)/`. Do not match the full old tag text.
|
|
19
|
+
- When none of them is there, the markup ends where the shell's own body content starts (its first `<script`). Another way: read the elements that carry `data-br`. Every element of the markup carries one.
|
|
20
|
+
|
|
21
|
+
- 75fc737: Round 8, XMA ("on a slow desktop, data holds still"): the text of a page built ahead no longer falls back to the system font while the app takes the page over.
|
|
22
|
+
|
|
23
|
+
- Cause: Chrome makes new, unloaded `FontFace` objects when the style sheet that holds a page's `@font-face` rules changes. The takeover changed it twice. First, smbls inserted the framework's default `SourceSans` face, a face with no file (`src: ;`). Second, it removed the server's styles and copied their faces into a new `<style data-smbls-faces>`. Each time the text drew in the fallback font for one to three frames, and every text block changed size. Measured on a fixture page of 40 data blocks, desktop 1440 px, CPU 6x slower: 45,828 px of layout change in 2 frames with `build.prepareDesignSystem` on, 68,742 px in 3 frames with `{ shell: false, pages: false }`. Now 0 px in both, 4 of 4 runs.
|
|
24
|
+
- `@symbo.ls/brender` `renderPage` writes the page's `@font-face` rules in a `<style data-smbls-faces>` of their own, ahead of `<style data-brender>`. They are no longer in `<style data-emotion="smbls">`. The takeover does not select that sheet, so it stays for the page's life and keeps its faces loaded. `splitCapturedCSS` does not change.
|
|
25
|
+
- `smbls` `applyFontFaces` does not insert a face that names no file.
|
|
26
|
+
- A post-build step that moves the `@font-face` rules out of the server's styles finds none there now. It can leave `<style data-smbls-faces>` where it is.
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [75fc737]
|
|
29
|
+
- smbls@3.14.850
|
|
30
|
+
|
|
3
31
|
## 3.14.671
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
package/dist/esm/render.js
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
import{resolve as m,join as He,dirname as _}from"path";import{existsSync as h,unlinkSync as Ue,readFileSync as z,realpathSync as We}from"fs";import{resolvePackageEntry as Je}from"./packageEntry.js";import{tmpdir as Ye}from"os";import{randomBytes as ze}from"crypto";import{createRequire as le}from"module";import{pathToFileURL as Ve}from"url";import{createEnv as Se}from"./env.js";import{resetKeys as Re,assignKeys as ke,mapKeysToElements as we}from"./keys.js";import{extractMetadata as pe,generateHeadHtml as Xe}from"./metadata.js";import"./hydrate.js";import{composeIntoShell as Qe}from"./shell.js";import{trimSpriteToPage as Ze,classRulesForPage as et,markupClasses as tt,trimVariablesToPage as ot}from"./pageWeight.js";import{fetchSSRTranslations as nt}from"./prefetch.js";import{createEarlySeedScript as st}from"@symbo.ls/fetch";import{headerEntries as rt}from"@symbo.ls/fetch/rest";import{brenderRegistryBlock as ct,brenderRegistryTreeBlock as it,brenderStampMeta as at,escapeRegExp as lt,jsonForScript as pt,polyglotFallbackLang as oe,polyglotLangStorageKey as ft,polyglotAddressLang as ut,polyglotStartupScript as mt}from"@symbo.ls/utils";let ne=null;const dt=async()=>{if(ne)return ne;try{return ne=(await import("@symbo.ls/funcql")).funcqlPlugin,ne}catch{return null}};import"linkedom";import{createEarlySeedBlock as gt}from"@symbo.ls/fetch";import{reset as ht}from"@symbo.ls/css";const se=(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},re=(e,t)=>oe(e?.lang,t),xe=(e,t,o,n)=>{if(o?.translations){const r=o.translations[t];if(r){const i=se(r,e);if(i!==void 0)return i}}if(n?.translations){const r=n.translations[t];if(r){const i=se(r,e);if(i!==void 0)return i}}const s=oe(void 0,o);if(s!==t&&o?.translations){const r=o.translations[s];if(r){const i=se(r,e);if(i!==void 0)return i}}},yt=function(e,t){if(!e)return"";const o=this?.context,n=o?.polyglot,s=this?.state?.root||o?.state?.root,r=xe(e,t||re(s,n),n,s);if(r!==void 0)return r;const i=de(me);return n&&i&&i.labelKeys.add(e),e},je=function(){return re(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 O=null;try{import.meta.url&&(O=le(import.meta.url))}catch{}const bt=()=>{if(!import.meta.url||!O)return{isMonorepo:!1,monorepoRoot:null,resolvePackage:l=>l};const e=We(new URL(".",import.meta.url).pathname),t=m(e,"../..");if(h(m(t,"packages","smbls","src","createDomql.js")))return{isMonorepo:!0,monorepoRoot:t};let n;try{const l=O.resolve("smbls/package.json");n=_(l)}catch{let l=e;for(;l!==_(l);){const g=m(l,"node_modules","smbls");if(h(m(g,"package.json"))){n=g;break}l=_(l)}}let s=O;if(n)try{s=le(m(n,"package.json"))}catch{}let r,i=process.cwd();for(;i!==_(i);){if(h(m(i,"package.json"))){r=i;break}i=_(i)}let f=s;if(r)try{f=le(m(r,"package.json"))}catch{}return{isMonorepo:!1,smblsRoot:n,brenderDir:e,projectRoot:r,_smblsRequire:s,_projectRequire:f}},H=(e,t)=>{const o=e.isMonorepo?[O]:[e._smblsRequire,e._projectRequire,O].filter(Boolean);for(const n of o)try{return n.resolve(t)}catch{}return null},Co=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"packages",t,...o);const n=H(e,`${t}/package.json`);return n?m(_(n),...o):null},qo=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"plugins",t,...o);const n=H(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null},fe=(e,t,...o)=>{if(e.isMonorepo){for(const s of["packages","plugins"]){const r=m(e.monorepoRoot,s,t,...o);if(h(r))return r}return null}const n=H(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null},Ee=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"packages","domql","packages",t,...o);const n=H(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null};let ce=null;const Te="smbls/ssr",St=async()=>{const e=await import("smbls/ssr");if(typeof e?.createDomqlElement!="function")throw new Error("smbls/ssr does not export createDomqlElement");return e},_e=()=>(ce||(ce=Rt().catch(e=>{throw ce=null,e})),ce),Rt=async()=>{const e=bt();let t;if(O&&e.isMonorepo)t=m(e.monorepoRoot,"packages","smbls","src","createDomql.js");else{let p;try{return await St()}catch(a){p=a}if(!O)throw new Error(`brender: ${Te} is not available in this bundled runtime (${p.message}). Bundle smbls \u2265 the release that adds the smbls/ssr export alongside @symbo.ls/brender.`);const c=e.smblsRoot&&m(e.smblsRoot,"src","createDomql.js");if(c&&h(c))t=c;else throw new Error(`brender: cannot load ${Te} (${p.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=He(Ye(),`br_createDomql_${ze(6).toString("hex")}.mjs`),s=Je,r=e.isMonorepo?await import(Ve(m(e.monorepoRoot,"scripts","vite-workspace-source.mjs")).href):null,i=r?new Set(r.workspacePackageRoots().map(p=>r.workspacePackageAt(p).name)):null,f=/^(?:smbls(?:\/.*)?|domql|css-in-props(?:\/.*)?|@symbo\.ls\/[^/]+)$/,l={name:"workspace-resolve",setup(p){r&&(p.onResolve({filter:/^[^./]/},c=>{if(f.test(c.path))return;const a=c.path.split("/"),u=c.path.startsWith("@")?a.slice(0,2).join("/"):a[0];if(!i.has(u))return;const d=r.resolveWorkspaceSource(c.path,c.importer||t);return d?{path:d}:{errors:[{text:`"${c.path}" names no source file in the workspace`}]}}),p.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)),p.onResolve({filter:/^smbls/},c=>{const a=c.path.replace(/^smbls\/?/,""),u=e.isMonorepo?m(e.monorepoRoot,"packages","smbls"):e.smblsRoot;if(!u)return;if(!a){const E=s(u);return E?{path:E}:void 0}const d=m(u,a);if(h(d))return{path:d};if(h(d+".js"))return{path:d+".js"};const b=m(d,"index.js");if(h(b))return{path:b}}),p.onResolve({filter:/^domql$/},c=>{if(e.isMonorepo){const a=m(e.monorepoRoot,"packages","domql","src","index.js");if(h(a))return{path:a};const u=m(e.monorepoRoot,"packages","domql","index.js");if(h(u))return{path:u}}else try{const a=_require.resolve("domql/package.json"),u=s(_(a));if(u)return{path:u}}catch{}}),p.onResolve({filter:/^@symbo\.ls\//},c=>{const a=c.path.replace("@symbo.ls/","");if(a==="sync")return{path:"sync-stub",namespace:"brender-stub"};if(e.isMonorepo){for(const d of["packages","plugins"]){const b=m(e.monorepoRoot,d,a,"src","index.js");if(h(b))return{path:b};const E=m(e.monorepoRoot,d,a,"index.js");if(h(E))return{path:E}}const u=m(e.monorepoRoot,"packages","default-config","blank","index.js");if(a==="default-config"&&h(u))return{path:u}}else{const u=fe(e,a,"src","index.js");if(u&&h(u))return{path:u};const d=fe(e,a,"index.js");if(d&&h(d))return{path:d};if(a==="default-config"){const b=fe(e,"default-config","blank","index.js");if(b&&h(b))return{path:b}}}}),p.onResolve({filter:/^@domql\//},c=>{const a=c.path.replace("@symbo.ls/","");if(e.isMonorepo){const u=m(e.monorepoRoot,"packages","domql","packages",a,"src","index.js");if(h(u))return{path:u};const d=m(e.monorepoRoot,"packages","domql","packages",a,"index.js");if(h(d))return{path:d}}else{const u=Ee(e,a,"src","index.js");if(u&&h(u))return{path:u};const d=Ee(e,a,"index.js");if(d&&h(d))return{path:d}}}),p.onResolve({filter:/^css-in-props/},c=>{let a;if(e.isMonorepo)a=m(e.monorepoRoot,"packages","css-in-props");else{const b=H(e,"css-in-props/package.json");b&&(a=_(b))}if(!a)return;const u=c.path.replace(/^css-in-props\/?/,"");if(u){const b=m(a,u),E=m(b,"index.js");if(h(E))return{path:E};if(h(b+".js"))return{path:b+".js"};if(h(b))return{path:b}}const d=s(a);if(d)return{path:d}}),p.onResolve({filter:/^@emotion\//},c=>{let a;if(e.isMonorepo)a=m(e.monorepoRoot,"node_modules",c.path);else{const u=H(e,`${c.path}/package.json`);if(!u)return;a=_(u)}if(h(a)){const u=m(a,"package.json");if(h(u))try{const d=JSON.parse(z(u,"utf8")),b=d.module||d.main||"dist/emotion-css.esm.js";return{path:m(a,b)}}catch{}return{path:a}}}),p.onResolve({filter:/\.json$/},c=>{if(c.resolveDir){const a=m(c.resolveDir,c.path);if(h(a))return{path:a}}}),p.onLoad({filter:/smbls\/.*options\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("options.js"))return;let a=z(c.path,"utf8");return a=a.replace(/import\s*\{[^}]*version[^}]*\}\s*from\s*['"][^'"]*package\.json['"][^;\n]*/,"const version = '0.0.0'"),a=a.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:a,loader:"js"}}),p.onLoad({filter:/smbls\/.*init\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("init.js"))return;let a=z(c.path,"utf8");return a=a.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:a,loader:"js"}}),p.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"})),p.onLoad({filter:/smbls\/src\/router\.js$/},async c=>{let a=z(c.path,"utf8");return a=a.replace(/import\s*\{\s*Link\s*\}\s*from\s*['"]smbls['"]/,"const Link = { tag: 'a', attr: { href: (el) => el.href } }"),{contents:a,loader:"js"}}),p.onLoad({filter:/fetchOnCreate\.js$/},async c=>{if(!c.path.includes("smbls/"))return;let a=z(c.path,"utf8");return a=a.replace(/window\s*&&\s*window\.location\s*\?\s*window\.location\.host\.includes/g,"window && window.location && window.location.host ? window.location.host.includes"),{contents:a,loader:"js"}})}};await o.build({entryPoints:[t],bundle:!0,format:"esm",platform:"node",outfile:n,write:!0,logLevel:"warning",plugins:[l],nodePaths:e.isMonorepo?[m(e.monorepoRoot,"node_modules")]:[...e.smblsRoot?[m(e.smblsRoot,"node_modules")]:[],...e.projectRoot?[m(e.projectRoot,"node_modules")]:[],...e.smblsRoot?[m(e.smblsRoot,"..","..","node_modules")]:[]].filter(p=>h(p)),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{Ue(n)}catch{}return g},kt={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"}},wt=(e,t)=>{const o={};return ve(e,(n,s)=>{if(!s.__brKey)return;const r=t(n);o[r===""?"__root":r]=s.__brKey}),o},ve=(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)},xt=new Set(["app","config","pages","components","state","snippets","designSystem","dependencies","functions","methods","files","sharedLibraries"]);let U=0;const Le=Symbol.for("brender.fetchTracked"),ue=()=>U,jt=256*1024,Et=1024*1024,Tt=new Set(["accept-language","accept"]),De={renders:0,record:null},_t=50,me={renders:0,record:null},$e=(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)}}},de=e=>e.record&&!e.record.tainted?e.record:null,vt=e=>{try{const t=new URL(e);return t.origin+t.pathname}catch{return String(e).split("?")[0]}},ge=(e,t,o)=>{!e||e.tainted||e.failures.length>=_t||e.failures.push({url:vt(t),reason:o})},Ae=e=>e&&typeof e=="object"&&typeof e.url=="string"?e.url:String(e),Lt=e=>{const[t,o]=e,n=t&&typeof t=="object"&&typeof t.url=="string",s=Ae(t),r=String(o&&o.method||n&&t.method||"GET").toUpperCase(),i={},f=l=>{if(!l)return;const g=!Array.isArray(l)&&typeof l.entries!="function";for(const[p,c]of rt(l))g&&c==null||(i[String(p).toLowerCase()]=String(c))};return n&&f(t.headers),o&&f(o.headers),{url:s,method:r,headers:i}},Dt=(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>jt||e.bytes+i.length>Et||(e.bytes+=i.length,e.entries.push({url:t.url,lang:t.headers["accept-language"]||"",status:o.status,type:s,body:i}))},()=>{}))},$t=()=>{const e=globalThis.fetch;if(typeof e!="function"||e[Le])return;const t=function(...o){U++;let n=!1;const s=()=>{n||(n=!0,U--)},r=c=>{U++,c.then(()=>{U--},()=>{U--})},i=de(De),f=de(me);let l=null;if(i)try{l=Lt(o),(l.method!=="GET"||!/^https?:/i.test(l.url)||Object.keys(l.headers).some(c=>!Tt.has(c)))&&(l=null)}catch{l=null}const g=()=>Ae(o[0]);let p;try{p=e.apply(this,o)}catch(c){throw ge(f,g(),c&&c.message||"failed"),s(),c}return p&&typeof p.then=="function"?p.then(c=>{l&&Dt(i,l,c,r),f&&c&&c.ok===!1&&ge(f,g(),"HTTP "+c.status),s()},c=>{ge(f,g(),c&&c.message||"network error"),s()}):s(),p};t[Le]=!0,globalThis.fetch=t},Mo=({brRegistry:e,fetchSeed:t,hydrateFlag:o=!0}={})=>{if(!e||!Object.keys(e).length)return"";const n=pt(e);return o?`<script>window.__BR_REGISTRY__=${n};window.__BRENDER_HYDRATE__=true<\/script>`+(t&&t.length?`
|
|
2
|
-
`+
|
|
1
|
+
import{resolve as m,join as Je,dirname as _}from"path";import{existsSync as h,unlinkSync as Ye,readFileSync as X,realpathSync as ze}from"fs";import{resolvePackageEntry as Ve}from"./packageEntry.js";import{tmpdir as Xe}from"os";import{randomBytes as Qe}from"crypto";import{createRequire as fe}from"module";import{pathToFileURL as Ze}from"url";import{createEnv as Re}from"./env.js";import{resetKeys as ke,assignKeys as we,mapKeysToElements as xe}from"./keys.js";import{extractMetadata as pe,generateHeadHtml as et}from"./metadata.js";import"./hydrate.js";import{composeIntoShell as tt}from"./shell.js";import{trimSpriteToPage as ot,classRulesForPage as nt,markupClasses as st,trimVariablesToPage as rt}from"./pageWeight.js";import{fetchSSRTranslations as ct}from"./prefetch.js";import{createEarlySeedScript as at}from"@symbo.ls/fetch";import{headerEntries as it}from"@symbo.ls/fetch/rest";import{brenderRegistryBlock as lt,brenderRegistryTreeBlock as ft,brenderStampMeta as pt,escapeRegExp as ut,jsonForScript as mt,polyglotFallbackLang as oe,polyglotLangStorageKey as dt,polyglotAddressLang as gt,polyglotStartupScript as ht}from"@symbo.ls/utils";let ne=null;const yt=async()=>{if(ne)return ne;try{return ne=(await import("@symbo.ls/funcql")).funcqlPlugin,ne}catch{return null}};import"linkedom";import{createEarlySeedBlock as bt}from"@symbo.ls/fetch";import{reset as St}from"@symbo.ls/css";const se=(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},re=(e,t)=>oe(e?.lang,t),je=(e,t,o,n)=>{if(o?.translations){const r=o.translations[t];if(r){const a=se(r,e);if(a!==void 0)return a}}if(n?.translations){const r=n.translations[t];if(r){const a=se(r,e);if(a!==void 0)return a}}const s=oe(void 0,o);if(s!==t&&o?.translations){const r=o.translations[s];if(r){const a=se(r,e);if(a!==void 0)return a}}},Rt=function(e,t){if(!e)return"";const o=this?.context,n=o?.polyglot,s=this?.state?.root||o?.state?.root,r=je(e,t||re(s,n),n,s);if(r!==void 0)return r;const a=ge(de);return n&&a&&a.labelKeys.add(e),e},Te=function(){return re(this?.state?.root,this?.context?.polyglot)},$=(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?$(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?$(s,t):s}return o};let O=null;try{import.meta.url&&(O=fe(import.meta.url))}catch{}const kt=()=>{if(!import.meta.url||!O)return{isMonorepo:!1,monorepoRoot:null,resolvePackage:l=>l};const e=ze(new URL(".",import.meta.url).pathname),t=m(e,"../..");if(h(m(t,"packages","smbls","src","createDomql.js")))return{isMonorepo:!0,monorepoRoot:t};let n;try{const l=O.resolve("smbls/package.json");n=_(l)}catch{let l=e;for(;l!==_(l);){const g=m(l,"node_modules","smbls");if(h(m(g,"package.json"))){n=g;break}l=_(l)}}let s=O;if(n)try{s=fe(m(n,"package.json"))}catch{}let r,a=process.cwd();for(;a!==_(a);){if(h(m(a,"package.json"))){r=a;break}a=_(a)}let p=s;if(r)try{p=fe(m(r,"package.json"))}catch{}return{isMonorepo:!1,smblsRoot:n,brenderDir:e,projectRoot:r,_smblsRequire:s,_projectRequire:p}},U=(e,t)=>{const o=e.isMonorepo?[O]:[e._smblsRequire,e._projectRequire,O].filter(Boolean);for(const n of o)try{return n.resolve(t)}catch{}return null},Io=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"packages",t,...o);const n=U(e,`${t}/package.json`);return n?m(_(n),...o):null},Oo=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"plugins",t,...o);const n=U(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null},ue=(e,t,...o)=>{if(e.isMonorepo){for(const s of["packages","plugins"]){const r=m(e.monorepoRoot,s,t,...o);if(h(r))return r}return null}const n=U(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null},Ee=(e,t,...o)=>{if(e.isMonorepo)return m(e.monorepoRoot,"packages","domql","packages",t,...o);const n=U(e,`@symbo.ls/${t}/package.json`);return n?m(_(n),...o):null};let ce=null;const _e="smbls/ssr",wt=async()=>{const e=await import("smbls/ssr");if(typeof e?.createDomqlElement!="function")throw new Error("smbls/ssr does not export createDomqlElement");return e},ve=()=>(ce||(ce=xt().catch(e=>{throw ce=null,e})),ce),xt=async()=>{const e=kt();let t;if(O&&e.isMonorepo)t=m(e.monorepoRoot,"packages","smbls","src","createDomql.js");else{let f;try{return await wt()}catch(i){f=i}if(!O)throw new Error(`brender: ${_e} 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&&m(e.smblsRoot,"src","createDomql.js");if(c&&h(c))t=c;else throw new Error(`brender: cannot load ${_e} (${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=Je(Xe(),`br_createDomql_${Qe(6).toString("hex")}.mjs`),s=Ve,r=e.isMonorepo?await import(Ze(m(e.monorepoRoot,"scripts","vite-workspace-source.mjs")).href):null,a=r?new Set(r.workspacePackageRoots().map(f=>r.workspacePackageAt(f).name)):null,p=/^(?:smbls(?:\/.*)?|domql|css-in-props(?:\/.*)?|@symbo\.ls\/[^/]+)$/,l={name:"workspace-resolve",setup(f){r&&(f.onResolve({filter:/^[^./]/},c=>{if(p.test(c.path))return;const i=c.path.split("/"),u=c.path.startsWith("@")?i.slice(0,2).join("/"):i[0];if(!a.has(u))return;const d=r.resolveWorkspaceSource(c.path,c.importer||t);return d?{path:d}:{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 i=c.path.replace(/^smbls\/?/,""),u=e.isMonorepo?m(e.monorepoRoot,"packages","smbls"):e.smblsRoot;if(!u)return;if(!i){const E=s(u);return E?{path:E}:void 0}const d=m(u,i);if(h(d))return{path:d};if(h(d+".js"))return{path:d+".js"};const b=m(d,"index.js");if(h(b))return{path:b}}),f.onResolve({filter:/^domql$/},c=>{if(e.isMonorepo){const i=m(e.monorepoRoot,"packages","domql","src","index.js");if(h(i))return{path:i};const u=m(e.monorepoRoot,"packages","domql","index.js");if(h(u))return{path:u}}else try{const i=_require.resolve("domql/package.json"),u=s(_(i));if(u)return{path:u}}catch{}}),f.onResolve({filter:/^@symbo\.ls\//},c=>{const i=c.path.replace("@symbo.ls/","");if(i==="sync")return{path:"sync-stub",namespace:"brender-stub"};if(e.isMonorepo){for(const d of["packages","plugins"]){const b=m(e.monorepoRoot,d,i,"src","index.js");if(h(b))return{path:b};const E=m(e.monorepoRoot,d,i,"index.js");if(h(E))return{path:E}}const u=m(e.monorepoRoot,"packages","default-config","blank","index.js");if(i==="default-config"&&h(u))return{path:u}}else{const u=ue(e,i,"src","index.js");if(u&&h(u))return{path:u};const d=ue(e,i,"index.js");if(d&&h(d))return{path:d};if(i==="default-config"){const b=ue(e,"default-config","blank","index.js");if(b&&h(b))return{path:b}}}}),f.onResolve({filter:/^@domql\//},c=>{const i=c.path.replace("@symbo.ls/","");if(e.isMonorepo){const u=m(e.monorepoRoot,"packages","domql","packages",i,"src","index.js");if(h(u))return{path:u};const d=m(e.monorepoRoot,"packages","domql","packages",i,"index.js");if(h(d))return{path:d}}else{const u=Ee(e,i,"src","index.js");if(u&&h(u))return{path:u};const d=Ee(e,i,"index.js");if(d&&h(d))return{path:d}}}),f.onResolve({filter:/^css-in-props/},c=>{let i;if(e.isMonorepo)i=m(e.monorepoRoot,"packages","css-in-props");else{const b=U(e,"css-in-props/package.json");b&&(i=_(b))}if(!i)return;const u=c.path.replace(/^css-in-props\/?/,"");if(u){const b=m(i,u),E=m(b,"index.js");if(h(E))return{path:E};if(h(b+".js"))return{path:b+".js"};if(h(b))return{path:b}}const d=s(i);if(d)return{path:d}}),f.onResolve({filter:/^@emotion\//},c=>{let i;if(e.isMonorepo)i=m(e.monorepoRoot,"node_modules",c.path);else{const u=U(e,`${c.path}/package.json`);if(!u)return;i=_(u)}if(h(i)){const u=m(i,"package.json");if(h(u))try{const d=JSON.parse(X(u,"utf8")),b=d.module||d.main||"dist/emotion-css.esm.js";return{path:m(i,b)}}catch{}return{path:i}}}),f.onResolve({filter:/\.json$/},c=>{if(c.resolveDir){const i=m(c.resolveDir,c.path);if(h(i))return{path:i}}}),f.onLoad({filter:/smbls\/.*options\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("options.js"))return;let i=X(c.path,"utf8");return i=i.replace(/import\s*\{[^}]*version[^}]*\}\s*from\s*['"][^'"]*package\.json['"][^;\n]*/,"const version = '0.0.0'"),i=i.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:i,loader:"js"}}),f.onLoad({filter:/smbls\/.*init\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("init.js"))return;let i=X(c.path,"utf8");return i=i.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:i,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 i=X(c.path,"utf8");return i=i.replace(/import\s*\{\s*Link\s*\}\s*from\s*['"]smbls['"]/,"const Link = { tag: 'a', attr: { href: (el) => el.href } }"),{contents:i,loader:"js"}}),f.onLoad({filter:/fetchOnCreate\.js$/},async c=>{if(!c.path.includes("smbls/"))return;let i=X(c.path,"utf8");return i=i.replace(/window\s*&&\s*window\.location\s*\?\s*window\.location\.host\.includes/g,"window && window.location && window.location.host ? window.location.host.includes"),{contents:i,loader:"js"}})}};await o.build({entryPoints:[t],bundle:!0,format:"esm",platform:"node",outfile:n,write:!0,logLevel:"warning",plugins:[l],nodePaths:e.isMonorepo?[m(e.monorepoRoot,"node_modules")]:[...e.smblsRoot?[m(e.smblsRoot,"node_modules")]:[],...e.projectRoot?[m(e.projectRoot,"node_modules")]:[],...e.smblsRoot?[m(e.smblsRoot,"..","..","node_modules")]:[]].filter(f=>h(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{Ye(n)}catch{}return g},jt={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"}},Tt=(e,t)=>{const o={};return Le(e,(n,s)=>{if(!s.__brKey)return;const r=t(n);o[r===""?"__root":r]=s.__brKey}),o},Le=(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)},Et=new Set(["app","config","pages","components","state","snippets","designSystem","dependencies","functions","methods","files","sharedLibraries"]);let W=0;const $e=Symbol.for("brender.fetchTracked"),me=()=>W,_t=256*1024,vt=1024*1024,Lt=new Set(["accept-language","accept"]),De={renders:0,record:null},$t=50,de={renders:0,record:null},Ae=(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)}}},ge=e=>e.record&&!e.record.tainted?e.record:null,Dt=e=>{try{const t=new URL(e);return t.origin+t.pathname}catch{return String(e).split("?")[0]}},he=(e,t,o)=>{!e||e.tainted||e.failures.length>=$t||e.failures.push({url:Dt(t),reason:o})},Ce=e=>e&&typeof e=="object"&&typeof e.url=="string"?e.url:String(e),At=e=>{const[t,o]=e,n=t&&typeof t=="object"&&typeof t.url=="string",s=Ce(t),r=String(o&&o.method||n&&t.method||"GET").toUpperCase(),a={},p=l=>{if(!l)return;const g=!Array.isArray(l)&&typeof l.entries!="function";for(const[f,c]of it(l))g&&c==null||(a[String(f).toLowerCase()]=String(c))};return n&&p(t.headers),o&&p(o.headers),{url:s,method:r,headers:a}},Ct=(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(a=>{e.tainted||a.length>_t||e.bytes+a.length>vt||(e.bytes+=a.length,e.entries.push({url:t.url,lang:t.headers["accept-language"]||"",status:o.status,type:s,body:a}))},()=>{}))},qt=()=>{const e=globalThis.fetch;if(typeof e!="function"||e[$e])return;const t=function(...o){W++;let n=!1;const s=()=>{n||(n=!0,W--)},r=c=>{W++,c.then(()=>{W--},()=>{W--})},a=ge(De),p=ge(de);let l=null;if(a)try{l=At(o),(l.method!=="GET"||!/^https?:/i.test(l.url)||Object.keys(l.headers).some(c=>!Lt.has(c)))&&(l=null)}catch{l=null}const g=()=>Ce(o[0]);let f;try{f=e.apply(this,o)}catch(c){throw he(p,g(),c&&c.message||"failed"),s(),c}return f&&typeof f.then=="function"?f.then(c=>{l&&Ct(a,l,c,r),p&&c&&c.ok===!1&&he(p,g(),"HTTP "+c.status),s()},c=>{he(p,g(),c&&c.message||"network error"),s()}):s(),f};t[$e]=!0,globalThis.fetch=t},Po=({brRegistry:e,fetchSeed:t,hydrateFlag:o=!0}={})=>{if(!e||!Object.keys(e).length)return"";const n=mt(e);return o?`<script>window.__BR_REGISTRY__=${n};window.__BRENDER_HYDRATE__=true<\/script>`+(t&&t.length?`
|
|
2
|
+
`+at(t):""):`<script>window.__BR_REGISTRY__=${n}<\/script>`},Mt=3e4,It=2147483647;let qe=Promise.resolve();const Me=()=>{},Ot=e=>{const t=qe.then(e);return qe=t.then(Me,Me),t},Pt=e=>{if(e===void 0)return Mt;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,It)},Ft=(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},Bt=e=>{e.closed=!0;for(const t of e.undo.splice(0))t()},Kt=e=>{let t=!1;return()=>{t||(t=!0,e())}},Ie=(e,t={})=>{let o;try{o=Pt(t.timeout)}catch(n){return Promise.reject(n)}return Ot(()=>Gt(e,t,o))},Gt=async(e,t,o)=>{await ve();const n={closed:!1,undo:[]},s=Nt(e,t,n);if(!o)return s;let r;const a=new Promise((p,l)=>{r=setTimeout(()=>{Bt(n),l(Ft(t,o))},o)});try{return await Promise.race([s,a])}finally{clearTimeout(r)}},Nt=async(e,t,o)=>{const{route:n="/",pathname:s,state:r,context:a,prefetch:p=!1}=t,l=s||n;qt();const g=Ae(de,()=>({failures:[],labelKeys:new Set,tainted:!1}));try{return await Ht(e,{route:n,locationPath:l,stateOverrides:r,contextOverrides:a,prefetch:p},g.record,o)}finally{g.close()}},Ht=async(e,{route:t,locationPath:o,stateOverrides:n,contextOverrides:s,prefetch:r},a,p)=>{const l=()=>{if(p.closed)throw new Error("brender: this render was abandoned at its timeout")};let g;if(r){try{g=await ct(e)}catch(d){p.closed||console.warn("[brender] SSR translation fetch failed:",d.message)}l()}const{window:f,document:c}=Re(),i=c.body;f.location.pathname=o;const u=[ae("document",c),ae("location",f.location),ae("localStorage",f.localStorage),ae("sessionStorage",f.sessionStorage)].map(Kt);p.undo.push(...u);try{const{createDomqlElement:d,PRERENDER_REGISTRY_FORMATS:b}=await ve();l();const E=$(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 y of Vt)e[y]!=null&&x[y]==null&&(x[y]=e[y]);const w=x.polyglot?{...x.polyglot}:void 0,Q=gt(o,w);Q&&f.localStorage.setItem(dt(w),Q),g&&w&&(w.translations={...w.translations||{},...g});const v=$(e.state||{});(g||w)&&(v.root||(v.root={}),w&&(v.root.lang=oe(v.root.lang,w)),g&&(v.root.translations={...v.root.translations||{},...g})),St();const P={};for(const y in e){if(Et.has(y))continue;const k=e[y];P[y]=k&&typeof k=="object"?$(k):k}const D={...P,state:v,...n?{state:{...v,...n}}:{},dependencies:$(e.dependencies||{}),components:$(e.components||{}),snippets:$(e.snippets||{}),pages:$(e.pages||{}),functions:{...e.functions||{},polyglot:Rt,getActiveLang:Te,getLang:Te},methods:e.methods||{},designSystem:$(e.designSystem||{}),files:e.files||{},sharedLibraries:e.sharedLibraries||[],...x,...w?{polyglot:w}:{},document:c,window:f,parent:{node:i},initOptions:{},domqlOptions:{sourcemap:!1},firstRender:!1,sync:!1,inspect:!1,notifications:!1,isolateDesignSystem:!0,isolateFetchCache:!0,captureDesignSystem:!0,...s||{}},N=await yt();l(),N&&(D.plugins=D.plugins||[],D.plugins.some(y=>y.name==="funcql")||D.plugins.push(N)),ke();const S=Ae(De,()=>({entries:[],bytes:0,tainted:!1})),A=S.record;let j;try{j=await d(E,D),l();const y=Date.now(),k=r?2e3:50,R=T=>new Promise(G=>setTimeout(G,T));for(await R(Math.min(50,k));r&&!p.closed&&me()>0&&Date.now()-y<k;)await R(10),me()===0&&await R(Math.max(0,Math.min(50,k-(Date.now()-y))));if(l(),r&&await Ut(j,w)){l();const T=Date.now();for(await R(Math.min(50,k));!p.closed&&me()>0&&Date.now()-T<k;)await R(10);l()}}finally{S.close()}const C=A&&!A.tainted&&!(x.fetch&&x.fetch.seed===!1)?A.entries.slice():[];we(i);const J=xe(j),{elementPath:Y}=await import("@symbo.ls/element");l();const Z=Tt(j,Y),z=j?.context?.routerOptions?.contentElementKey||"content",F=j&&j[z],q=F&&typeof F=="object"&&F.__ref?F:void 0,Se=pe(e,t,j,j?.state,q),M=[],V=c.head||c.querySelector("head");if(V)for(const y of V.querySelectorAll("style")){if(y.sheet&&y.sheet.cssRules)for(const k of y.sheet.cssRules)k.cssText&&M.push(k);if(!M.length){const k=y.textContent||"";k&&M.push({cssText:k})}}const ee=M.map(y=>y.cssText),{globalCSS:te,classRules:le}=oo(M);let L=Fe(i.innerHTML);const B=j?.state?.root,K=re(B,w),I=Wt(g,B);I&&(L=Pe(L,Oe(I,K,w)));const H=a&&!a.tainted?{failedRequests:a.failures.slice(),rawLabelKeys:zt(a.labelKeys,L,K,w,B)}:null;return{html:L,metadata:Se,registry:J,brRegistry:Z,element:j,emotionCSS:ee,globalCSS:te,classRules:le,fetchSeed:C,document:c,window:f,ssrTranslations:I||void 0,activeLang:K,diagnostics:H,preparedDesignSystem:D.preparedDesignSystem||null,registryFormats:Array.isArray(b)?b.slice():["paths"]}}finally{for(const d of u)d()}},ae=(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]})},Ut=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=re(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},ye=/\{\{\s*([^|{}]+?)\s*\|\s*polyglot\s*\}\}/g,be=e=>e&&typeof e.parse=="function"?e.parse():e,Wt=(e,t)=>{const o=be(t?.translations),n={};for(const s of[e,o])if(!(!s||typeof s!="object"))for(const r in s){const a=be(s[r]);a&&typeof a=="object"&&(n[r]={...n[r]||{},...a})}return Object.keys(n).length?n:null},Oe=(e,t,o)=>e[t]||e[oe(void 0,o)]||Object.values(e)[0]||{},Pe=(e,t)=>e.replace(ye,(o,n)=>se(t,n.trim())??o),Jt=/<script\b[^>]*\btype\s*=\s*["']?application\/json["']?[^>]*>[\s\S]*?<\/script\s*>/gi,Yt=(e,t)=>new RegExp(`(?:^|[^\\w.-])${ut(t)}(?![\\w-]|\\.\\w)`).test(e),zt=(e,t,o,n,s)=>{const r=new Set,a=t.replace(Jt,"");for(const p of e)/\s/.test(p)||je(p,o,n,s)===void 0&&Yt(a,p)&&r.add(p);for(const p of a.matchAll(ye))r.add(p[1].trim());return[...r]},Fo=async(e,t={})=>{const{context:o={}}=t,{window:n,document:s}=Re(),r=s.body,{create:a}=await import("@symbo.ls/element"),p=await import("@symbo.ls/utils"),l={...jt,...o.components||{}},g={...p,...o.utils||{},...o.functions||{}};ke();let f;try{f=a(e,{node:r},"root",{context:{document:s,window:n,...o,components:l,utils:g}})}catch{}we(r);const c=f?xe(f):{};return{html:Fe(r.innerHTML),registry:c,element:f}},Fe=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}),Vt=["globalTheme","themeStorageKey","themeRoot","useReset","useVariable","useFontImport","useIconSprite","useSvgSprite","useDocumentTheme","useDefaultConfig","useDefaultIcons","useThemeSuffixedVars","verbose","semanticIcons"],Xt=new Set(["auto","system"]),Be=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||Xt.has(s)?null:s},Qt=e=>String(e).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<"),Zt=/\.[A-Za-z_\\-]/,eo=e=>{if(typeof e!="string"||!e)return!1;const t=e.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,'""').replace(/\[[^\]]*\]/g,"[]");return!Zt.test(t)},to=/^\s*(:root|\[data-theme|\[data-skin)/,Ke=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 eo(e.selectorText)?to.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(Ke));return n.has(null)||n.size!==1?n.has(null)?null:"reset":[...n][0]}return null},Ge=e=>typeof e=="string"&&/^\s*@font-face\b/i.test(e),oo=e=>{const t={root:[],reset:[],keyframes:[]},o=[];for(const n of e||[]){const s=Ke(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 ie=new Set;const Bo=()=>{ie=new Set},Ko=()=>Array.from(ie).join(`
|
|
6
|
+
`),Go=(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
|
-
${(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
${
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
8
|
+
</style>`:""),No=async(e,t={})=>{const{route:o="/",pathname:n,prefetch:s=!0,timeout:r}=t,a=await Ie(e,{route:o,pathname:n,prefetch:s,timeout:r});if(!a)return null;const p=e.designSystem||{},l=a.globalCSS;let g=null;try{const c=no(a.element);Object.keys(c).length&&(g=c)}catch{}const f=a.activeLang;return{html:a.html,css:a.classRules.join(`
|
|
9
|
+
`),classRules:a.classRules.slice(),globalCSS:l,resetCss:l.resetRules,fontLinks:He(p),metadata:a.metadata||pe(e,o),brKeyCount:a.registry?Object.keys(a.registry).length:0,brRegistry:a.brRegistry||{},fetchSeed:a.fetchSeed||[],ssrTranslations:a.ssrTranslations,prefetchedState:g,activeLang:f,theme:Be(e),diagnostics:a.diagnostics,preparedDesignSystem:a.preparedDesignSystem||null}},no=e=>{const t={};return Le(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 a=r.startsWith("~/"),p=a?r.slice(2):r,l=a?o.state.root:o.state,g=be(l&&l[p]);p&&g!=null&&typeof g!="function"&&(t[p]=g)}}),t},Ho=async(e,t="/",o={})=>{const{lang:n,themeColor:s,isr:r,hydrate:a=!0,prefetch:p=!0,shell:l,adoptDom:g=!1,pathname:f,eagerImages:c=Ne,preloadScripts:i=!0,nonce:u,timeout:d,stamp:b,time:E,spriteIcons:x="all",cssClasses:w="all",cssVariables:Q="all",registryFormat:v="paths"}=o,P=lo(u),D=n||e.state?.lang||e.app?.metadata?.lang||"en",N=Be(e),S=await Ie(e,{route:t,pathname:f,prefetch:p,timeout:d});if(!S)return null;const A={...S.metadata};if(s&&(A["theme-color"]=s),typeof l=="string"&&!e.name){const R="\0brender-undeclared-title\0";if(pe({...e,name:R},t,S.element,S.element?.state).title===R)for(const G of["title","og:title","twitter:title"])A[G]===S.metadata.title&&delete A[G]}const j=et(A);for(const R of S.classRules)R&&ie.add(R);let C=co(S.html,c);x==="page"&&(C=ot(C,typeof l=="string"?l:"").html);const J=Array.from(ie),Y=J.filter(Ge),Z=Y.length?J.filter(R=>!Ge(R)):J,z=w==="page"?nt(Z,st(C,typeof l=="string"?l:"")).join(`
|
|
10
|
+
`):Z.join(`
|
|
11
|
+
`),F=Y.length?`<style data-smbls-faces>
|
|
12
|
+
${Y.join(`
|
|
13
|
+
`)}
|
|
14
|
+
</style>`:"",q=S.globalCSS,M=`<style data-brender>
|
|
15
|
+
${(Q==="page"?rt(q.rootRule||"",q.resetRules,q.keyframeRules,z,C,typeof l=="string"?l:"").css:q.rootRule)||""}
|
|
16
|
+
${q.resetRules||""}
|
|
17
|
+
${q.keyframeRules||""}
|
|
18
|
+
</style>`,V=z?`<style data-emotion="smbls">
|
|
19
|
+
${z}
|
|
20
|
+
</style>`:"",ee=He(e.designSystem||{}),te=Object.keys(S.registry).length,le=v==="tree"||v==="auto"&&(S.registryFormats||[]).includes("tree"),L=ao({brRegistry:S.brRegistry,fetchSeed:S.fetchSeed,adoptDom:g,stamp:b,time:E,registryFormat:le?"tree":"paths"});let B="";if(r&&r.clientScript){const R=Number.isInteger(o.depth)?o.depth:t==="/"?0:t.replace(/^\/|\/$/g,"").split("/").length,T=R>0?"../".repeat(R):"./";if(a){const G=ht({polyglot:e.polyglot||e.config?.polyglot,translations:S.ssrTranslations,lang:S.activeLang,pathname:f||t,attrs:P}),Ue=G?G+`
|
|
21
|
+
`:"",We=L.blocks?L.blocks+`
|
|
22
|
+
`:"";B=`${Ue}${We}<script type="module" src="${T}${r.clientScript}"${P}><\/script>`}else B=`<script type="module"${P}>
|
|
20
23
|
{
|
|
21
24
|
const brEls = document.querySelectorAll('body > :not(script):not(style)')
|
|
22
25
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -33,23 +36,23 @@ ${W}
|
|
|
33
36
|
observer.observe(document.body, { childList: true })
|
|
34
37
|
}
|
|
35
38
|
<\/script>
|
|
36
|
-
<script type="module" src="${T}${r.clientScript}"${P}><\/script>`}const
|
|
37
|
-
${
|
|
38
|
-
`),body:
|
|
39
|
-
<html lang="${
|
|
39
|
+
<script type="module" src="${T}${r.clientScript}"${P}><\/script>`}const K={...e.config||{}};e.polyglot&&!K.polyglot&&(K.polyglot=e.polyglot);const I=K.polyglot;let H=j;if(I){const R={...I.translations||{}};for(const T in S.ssrTranslations||{})R[T]={...R[T]||{},...S.ssrTranslations[T]};H=Pe(j,Oe(R,S.activeLang,I))}const y=S.diagnostics;if(y)for(const R of H.matchAll(ye)){const T=R[1].trim();y.rawLabelKeys.includes(T)||y.rawLabelKeys.push(T)}return typeof l=="string"?{html:tt(l,{headTags:`${H}
|
|
40
|
+
${L.meta}`,headEnd:[ee,F,M,V].filter(Boolean).join(`
|
|
41
|
+
`),body:C,depth:Number.isInteger(o.depth)?o.depth:0,bootScripts:L.blocks,lang:n||(I?S.activeLang:void 0),theme:N,preloadScripts:i}),route:t,brKeyCount:te,shell:!0,diagnostics:y,preparedDesignSystem:S.preparedDesignSystem||null}:{html:`<!DOCTYPE html>
|
|
42
|
+
<html lang="${D}"${N?` data-theme="${Qt(N)}"`:""}>
|
|
40
43
|
<head>
|
|
41
|
-
${
|
|
42
|
-
${
|
|
43
|
-
${
|
|
44
|
-
|
|
45
|
-
${Q}
|
|
44
|
+
${H}${r&&r.clientScript&&a?`
|
|
45
|
+
${L.meta}`:""}
|
|
46
|
+
${ee}
|
|
46
47
|
${F}
|
|
48
|
+
${M}
|
|
49
|
+
${V}
|
|
47
50
|
</head>
|
|
48
51
|
<body>
|
|
49
|
-
${
|
|
50
|
-
${
|
|
52
|
+
${C}
|
|
53
|
+
${B}
|
|
51
54
|
</body>
|
|
52
|
-
</html>`,route:t,brKeyCount:
|
|
53
|
-
`):""},
|
|
54
|
-
`+
|
|
55
|
-
`)}},
|
|
55
|
+
</html>`,route:t,brKeyCount:te,diagnostics:y,preparedDesignSystem:S.preparedDesignSystem||null}},Ne=2,so=/<img\b(?:[^>"']|"[^"]*"|'[^']*')*>/gi,ro=/\sloading\s*=/i,co=(e,t=Ne)=>{if(t===!1||t==null||typeof e!="string")return e;const o=Math.max(0,Number(t)||0);let n=0;return e.replace(so,s=>n++<o||ro.test(s)?s:s.replace(/^<img\b/i,'<img loading="lazy"'))},He=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(`
|
|
56
|
+
`):""},ao=({brRegistry:e,fetchSeed:t,adoptDom:o=!1,stamp:n,time:s,registryFormat:r="paths"}={})=>{const p=o&&e&&Object.keys(e).length?r==="tree"&&ft(e)||lt(e):"",l=bt(t);return{meta:`<meta name="brender" content="${p?"hydrate":"replace"}">
|
|
57
|
+
`+pt(io(n,s)),blocks:[p,l].filter(Boolean).join(`
|
|
58
|
+
`)}},io=(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}},lo=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{Ne as EAGER_IMAGES_DEFAULT,_e as SMBLS_SSR_SPECIFIER,Po as adoptionScripts,io as buildStamp,Be as fixedThemeOf,Ko as getAccumulatedEmotionCSS,co as markLazyImages,ao as prerenderParts,Ie as render,Fo as renderElement,Ho as renderPage,No as renderRoute,Go as replaceEmotionCSS,Bo as resetGlobalCSSCache,oo as splitCapturedCSS};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/brender",
|
|
3
|
-
"version": "3.14.
|
|
3
|
+
"version": "3.14.672",
|
|
4
4
|
"license": "CC-BY-NC-4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"linkedom": "^0.16.8"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"smbls": "^3.14.
|
|
60
|
+
"smbls": "^3.14.850"
|
|
61
61
|
},
|
|
62
62
|
"optionalDependencies": {
|
|
63
63
|
"@symbo.ls/funcql": "^3.14.0"
|
package/render.js
CHANGED
|
@@ -1693,6 +1693,9 @@ const classifyRule = (rule) => {
|
|
|
1693
1693
|
return null
|
|
1694
1694
|
}
|
|
1695
1695
|
|
|
1696
|
+
// An @font-face rule's text (renderPage keeps them apart, see facesStyle).
|
|
1697
|
+
const isFontFaceText = (text) => typeof text === 'string' && /^\s*@font-face\b/i.test(text)
|
|
1698
|
+
|
|
1696
1699
|
export const splitCapturedCSS = (rules) => {
|
|
1697
1700
|
const groups = { root: [], reset: [], keyframes: [] }
|
|
1698
1701
|
const rest = []
|
|
@@ -1949,9 +1952,25 @@ export const renderPage = async (data, route = '/', options = {}) => {
|
|
|
1949
1952
|
// `cssClasses: 'page'` — of the rules every page so far needed, the ones
|
|
1950
1953
|
// this page's markup can match (pageWeight.js classRulesForPage, XMA round
|
|
1951
1954
|
// 8, E12): the client writes the rules of each element it creates itself.
|
|
1955
|
+
//
|
|
1956
|
+
// The @font-face rules go in a <style data-smbls-faces> of their own, ahead
|
|
1957
|
+
// of the server's styles (XMA round 8, "data holds still" on a slow
|
|
1958
|
+
// desktop). The app removes the server's styles once its own are in, and
|
|
1959
|
+
// smbls kept the faces by moving them into a new <style data-smbls-faces> —
|
|
1960
|
+
// a new style sheet, so Chrome made new, unloaded FontFace objects for them:
|
|
1961
|
+
// the text fell back to the system font for a frame or more while the files
|
|
1962
|
+
// were read again, and every block of text changed size during the takeover.
|
|
1963
|
+
// Deleting the other rules from the server's sheet re-creates them too. A
|
|
1964
|
+
// sheet the takeover never touches keeps them loaded; smbls applyFontFaces
|
|
1965
|
+
// finds them declared and adds none of its own (smbls prerender.js
|
|
1966
|
+
// serverStyles does not select it, so it stays for the page's life).
|
|
1967
|
+
const accumulated = Array.from(_accumulatedEmotionCSS)
|
|
1968
|
+
const faceRules = accumulated.filter(isFontFaceText)
|
|
1969
|
+
const classRules = faceRules.length ? accumulated.filter((rule) => !isFontFaceText(rule)) : accumulated
|
|
1952
1970
|
const emotionCSS = cssClasses === 'page'
|
|
1953
|
-
? classRulesForPage(
|
|
1954
|
-
:
|
|
1971
|
+
? classRulesForPage(classRules, markupClasses(bodyHtml, typeof shell === 'string' ? shell : '')).join('\n')
|
|
1972
|
+
: classRules.join('\n')
|
|
1973
|
+
const facesStyle = faceRules.length ? `<style data-smbls-faces>\n${faceRules.join('\n')}\n</style>` : ''
|
|
1955
1974
|
|
|
1956
1975
|
// Global CSS (variables, reset, keyframes): this render's own init output.
|
|
1957
1976
|
// The style tags, built once for both documents below.
|
|
@@ -2072,7 +2091,7 @@ export const renderPage = async (data, route = '/', options = {}) => {
|
|
|
2072
2091
|
if (typeof shell === 'string') {
|
|
2073
2092
|
const html = composeIntoShell(shell, {
|
|
2074
2093
|
headTags: `${resolvedHeadTags}\n${prerender.meta}`,
|
|
2075
|
-
headEnd: [fontLinks, brenderStyle, emotionStyle].filter(Boolean).join('\n'),
|
|
2094
|
+
headEnd: [fontLinks, facesStyle, brenderStyle, emotionStyle].filter(Boolean).join('\n'),
|
|
2076
2095
|
body: bodyHtml,
|
|
2077
2096
|
depth: Number.isInteger(options.depth) ? options.depth : 0,
|
|
2078
2097
|
bootScripts: prerender.blocks,
|
|
@@ -2086,14 +2105,14 @@ export const renderPage = async (data, route = '/', options = {}) => {
|
|
|
2086
2105
|
return { html, route, brKeyCount, shell: true, diagnostics, preparedDesignSystem: result.preparedDesignSystem || null }
|
|
2087
2106
|
}
|
|
2088
2107
|
|
|
2089
|
-
//
|
|
2090
|
-
//
|
|
2108
|
+
// The line after the font links holds the page's @font-face rules in a
|
|
2109
|
+
// <style data-smbls-faces> of their own (see facesStyle above).
|
|
2091
2110
|
const html = `<!DOCTYPE html>
|
|
2092
2111
|
<html lang="${htmlLang}"${htmlTheme ? ` data-theme="${escapeAttr(htmlTheme)}"` : ''}>
|
|
2093
2112
|
<head>
|
|
2094
2113
|
${resolvedHeadTags}${isr && isr.clientScript && hydrate ? `\n${prerender.meta}` : ''}
|
|
2095
2114
|
${fontLinks}
|
|
2096
|
-
|
|
2115
|
+
${facesStyle}
|
|
2097
2116
|
${brenderStyle}
|
|
2098
2117
|
${emotionStyle}
|
|
2099
2118
|
</head>
|