@symbo.ls/brender 3.14.681 → 3.14.682
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 +13 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/render.js +37 -37
- package/index.js +7 -1
- package/package.json +4 -4
- package/render.js +72 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @symbo.ls/brender
|
|
2
2
|
|
|
3
|
+
## 3.14.682
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6b34e4a: A built page writes its atomic rules in the app's cascade-tier order (XMA #1283). In the app each rule sits in a tier sheet (`@symbo.ls/css` atomic.js "Cascade tiers": max-width rules narrowest last, min-width widest last, a longhand class after its shorthand). brender's `renderPage` kept the rules of every page of a build in one set and wrote them in that set's order, each where the FIRST page that used it put it: `/` minted `@media (max-width: 560px){…{grid-template-columns:1fr}}`, `/b` minted the 768 px rule after it, and the built `/b` wrote 560 before 768, so at 390 px it showed 2 columns where the app shows 1 (and a longhand class an earlier page minted lost to the shorthand a later page needs). `@symbo.ls/css` exports `tierOfStyle(style)` (the tier of a `<style>` the engine made, read off its `data-tier`; null for any other `<style>`) and `sortByTier(items, tierOf)` (a stable sort in cascade order, on the one tier comparison the sheets' own placement uses). brender's render names the tier of each captured class rule (`classRuleTiers`, also on `renderRoute`'s result: the tier of the engine sheet it was read from, never re-derived from the rule's text), and `renderPage` (both `cssClasses` modes) and `getAccumulatedEmotionCSS` write the rules by tier, in first-written order inside a tier; one page's own rules keep their order, and the `@font-face` rules keep theirs. brender also exports `sortByTier` for a caller that merges several renders: `smbls publish`'s pre-render (`buildSsrCache`) now stores the routes' shared rules (`__ssr.__styles.css`) in tier order, so the platform serves `/b` with 768 before 560 too; with an older brender it keeps the first-seen order. `smbls` re-exports the two helpers (`export *` of `@symbo.ls/css`) and inlines the engine in its bundles.
|
|
8
|
+
- Updated dependencies [6b34e4a]
|
|
9
|
+
- Updated dependencies [0db50ef]
|
|
10
|
+
- Updated dependencies [b4c02a8]
|
|
11
|
+
- Updated dependencies [a4fdcb8]
|
|
12
|
+
- @symbo.ls/css@3.14.783
|
|
13
|
+
- smbls@3.14.877
|
|
14
|
+
- @symbo.ls/element@3.14.829
|
|
15
|
+
|
|
3
16
|
## 3.14.681
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createEnv as e}from"./env.js";import{resetKeys as r,assignKeys as t,mapKeysToElements as o}from"./keys.js";import{loadProject as a,loadAndRenderAll as m}from"./load.js";import{render as s,renderElement as
|
|
1
|
+
import{createEnv as e}from"./env.js";import{resetKeys as r,assignKeys as t,mapKeysToElements as o}from"./keys.js";import{loadProject as a,loadAndRenderAll as m}from"./load.js";import{render as s,renderElement as i,renderRoute as p,renderPage as l,resetGlobalCSSCache as d,getAccumulatedEmotionCSS as n,replaceEmotionCSS as c,adoptionScripts as f,prerenderParts as S,buildStamp as g,sortByTier as h}from"./render.js";import{extractMetadata as u,generateHeadHtml as P}from"./metadata.js";import{collectBrNodes as y,hydrate as C}from"./hydrate.js";import{generateSitemap as E}from"./sitemap.js";import{prefetchPageData as R,injectPrefetchedState as T}from"./prefetch.js";import{composeIntoShell as b}from"./shell.js";import{trimSpriteToPage as k,classRulesForPage as x,markupClasses as A,trimVariablesToPage as F,stylesheetRules as K}from"./pageWeight.js";import{markFacesSheet as j,facesSheetMarks as B}from"./faces.js";import{drawnFaces as H}from"./drawnFaces.js";var O={createEnv:e,resetKeys:r,assignKeys:t,mapKeysToElements:o,loadProject:a,loadAndRenderAll:m,render:s,renderElement:i,renderRoute:p,renderPage:l,resetGlobalCSSCache:d,getAccumulatedEmotionCSS:n,replaceEmotionCSS:c,extractMetadata:u,generateHeadHtml:P,collectBrNodes:y,hydrate:C,generateSitemap:E,prefetchPageData:R,injectPrefetchedState:T,composeIntoShell:b,adoptionScripts:f,prerenderParts:S,buildStamp:g,trimSpriteToPage:k,classRulesForPage:x,markupClasses:A,trimVariablesToPage:F,stylesheetRules:K,sortByTier:h,markFacesSheet:j,facesSheetMarks:B,drawnFaces:H};export{f as adoptionScripts,t as assignKeys,g as buildStamp,x as classRulesForPage,y as collectBrNodes,b as composeIntoShell,e as createEnv,O as default,H as drawnFaces,u as extractMetadata,B as facesSheetMarks,P as generateHeadHtml,E as generateSitemap,n as getAccumulatedEmotionCSS,C as hydrate,T as injectPrefetchedState,m as loadAndRenderAll,a as loadProject,o as mapKeysToElements,j as markFacesSheet,A as markupClasses,R as prefetchPageData,S as prerenderParts,s as render,i as renderElement,l as renderPage,p as renderRoute,c as replaceEmotionCSS,d as resetGlobalCSSCache,r as resetKeys,h as sortByTier,K as stylesheetRules,k as trimSpriteToPage,F as trimVariablesToPage};
|
package/dist/esm/render.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import{resolve as g,join as rt,dirname as j}from"path";import{existsSync as b,unlinkSync as ct,readFileSync as Y,realpathSync as it}from"fs";import{resolvePackageEntry as at}from"./packageEntry.js";import{tmpdir as lt}from"os";import{randomBytes as ft}from"crypto";import{createRequire as ye}from"module";import{pathToFileURL as pt}from"url";import{createEnv as je}from"./env.js";import{resetKeys as ve,assignKeys as Le,mapKeysToElements as Ae}from"./keys.js";import{extractMetadata as be,generateHeadHtml as ut}from"./metadata.js";import"./hydrate.js";import{composeIntoShell as dt}from"./shell.js";import{trimSpriteToPage as mt,classRulesForPage as gt,markupClasses as ht,trimVariablesToPage as yt}from"./pageWeight.js";import{facesSheetTag as bt}from"./faces.js";import{fetchSSRTranslations as St}from"./prefetch.js";import{createEarlySeedScript as Rt}from"@symbo.ls/fetch";import{headerEntries as wt}from"@symbo.ls/fetch/rest";import{brenderStampMeta as kt,brenderLazyMeta as $e,escapeRegExp as xt,jsonForScript as _t,libraryPackageSpecs as Et,polyglotFallbackLang as Se,polyglotLangStorageKey as Tt,polyglotAddressLang as jt,polyglotStartupScript as vt}from"@symbo.ls/utils";import{brenderRegistryBlock as Lt,brenderRegistryTreeBlock as At}from"@symbo.ls/utils/server";import*as $t from"@symbo.ls/utils/server";import*as Dt from"@symbo.ls/utils";let le=null;const Ct=async()=>{if(le)return le;try{return le=(await import("@symbo.ls/funcql")).funcqlPlugin,le}catch{return null}};import"linkedom";import{createEarlySeedBlock as Ot,fetchRunsOf as Mt}from"@symbo.ls/fetch";import{reset as qt}from"@symbo.ls/css";const fe=(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},pe=(e,t)=>Se(e?.lang,t),Pt=e=>{const t=$t.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=>{const t=Dt.withPolyglotTranslations;return typeof t=="function"?t(e):e},Ce=(e,t,o,n)=>{if(o?.translations){const r=o.translations[t];if(r){const a=fe(r,e);if(a!==void 0)return a}}if(n?.translations){const r=n.translations[t];if(r){const a=fe(r,e);if(a!==void 0)return a}}const s=Se(void 0,o);if(s!==t&&o?.translations){const r=o.translations[s];if(r){const a=fe(r,e);if(a!==void 0)return a}}},It=function(e,t){if(!e)return"";const o=this?.context,n=o?.polyglot,s=this?.state?.root||o?.state?.root,r=Ce(e,t||pe(s,n),n,s);if(r!==void 0)return r;const a=xe(ke);return n&&a&&a.labelKeys.add(e),e},Oe=function(){return pe(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=ye(import.meta.url))}catch{}const Ft=()=>{if(!import.meta.url||!O)return{isMonorepo:!1,monorepoRoot:null,resolvePackage:p=>p};const e=it(new URL(".",import.meta.url).pathname),t=g(e,"../..");if(b(g(t,"packages","smbls","src","createDomql.js")))return{isMonorepo:!0,monorepoRoot:t};let n;try{const p=O.resolve("smbls/package.json");n=j(p)}catch{let p=e;for(;p!==j(p);){const m=g(p,"node_modules","smbls");if(b(g(m,"package.json"))){n=m;break}p=j(p)}}let s=O;if(n)try{s=ye(g(n,"package.json"))}catch{}let r,a=process.cwd();for(;a!==j(a);){if(b(g(a,"package.json"))){r=a;break}a=j(a)}let f=s;if(r)try{f=ye(g(r,"package.json"))}catch{}return{isMonorepo:!1,smblsRoot:n,brenderDir:e,projectRoot:r,_smblsRequire:s,_projectRequire:f}},z=(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},an=(e,t,...o)=>{if(e.isMonorepo)return g(e.monorepoRoot,"packages",t,...o);const n=z(e,`${t}/package.json`);return n?g(j(n),...o):null},ln=(e,t,...o)=>{if(e.isMonorepo)return g(e.monorepoRoot,"plugins",t,...o);const n=z(e,`@symbo.ls/${t}/package.json`);return n?g(j(n),...o):null},Re=(e,t,...o)=>{if(e.isMonorepo){for(const s of["packages","plugins"]){const r=g(e.monorepoRoot,s,t,...o);if(b(r))return r}return null}const n=z(e,`@symbo.ls/${t}/package.json`);return n?g(j(n),...o):null},Me=(e,t,...o)=>{if(e.isMonorepo)return g(e.monorepoRoot,"packages","domql","packages",t,...o);const n=z(e,`@symbo.ls/${t}/package.json`);return n?g(j(n),...o):null};let ue=null;const qe="smbls/ssr",Gt=async()=>{const e=await import("smbls/ssr");if(typeof e?.createDomqlElement!="function")throw new Error("smbls/ssr does not export createDomqlElement");return e},Pe=()=>(ue||(ue=Bt().catch(e=>{throw ue=null,e})),ue),Bt=async()=>{const e=Ft();let t;if(O&&e.isMonorepo)t=g(e.monorepoRoot,"packages","smbls","src","createDomql.js");else{let l;try{return await Gt()}catch(c){l=c}if(!O)throw new Error(`brender: ${qe} is not available in this bundled runtime (${l.message}). Bundle smbls \u2265 the release that adds the smbls/ssr export alongside @symbo.ls/brender.`);const i=e.smblsRoot&&g(e.smblsRoot,"src","createDomql.js");if(i&&b(i))t=i;else throw new Error(`brender: cannot load ${qe} (${l.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=rt(lt(),`br_createDomql_${ft(6).toString("hex")}.mjs`),s=at,r=e.isMonorepo?await import(pt(g(e.monorepoRoot,"scripts","vite-workspace-source.mjs")).href):null,a=r?new Set(r.workspacePackageRoots().map(l=>r.workspacePackageAt(l).name)):null,f=/^(?:smbls(?:\/.*)?|domql|css-in-props(?:\/.*)?|@symbo\.ls\/[^/]+)$/,p={name:"workspace-resolve",setup(l){r&&(l.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(!a.has(u))return;const y=r.resolveWorkspaceSource(i.path,i.importer||t);return y?{path:y}:{errors:[{text:`"${i.path}" names no source file in the workspace`}]}}),l.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)),l.onResolve({filter:/^smbls/},i=>{const c=i.path.replace(/^smbls\/?/,""),u=e.isMonorepo?g(e.monorepoRoot,"packages","smbls"):e.smblsRoot;if(!u)return;if(!c){const _=s(u);return _?{path:_}:void 0}const y=g(u,c);if(b(y))return{path:y};if(b(y+".js"))return{path:y+".js"};const S=g(y,"index.js");if(b(S))return{path:S}}),l.onResolve({filter:/^domql$/},i=>{if(e.isMonorepo){const c=g(e.monorepoRoot,"packages","domql","src","index.js");if(b(c))return{path:c};const u=g(e.monorepoRoot,"packages","domql","index.js");if(b(u))return{path:u}}else try{const c=_require.resolve("domql/package.json"),u=s(j(c));if(u)return{path:u}}catch{}}),l.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 y of["packages","plugins"]){const S=g(e.monorepoRoot,y,c,"src","index.js");if(b(S))return{path:S};const _=g(e.monorepoRoot,y,c,"index.js");if(b(_))return{path:_}}const u=g(e.monorepoRoot,"packages","default-config","blank","index.js");if(c==="default-config"&&b(u))return{path:u}}else{const u=Re(e,c,"src","index.js");if(u&&b(u))return{path:u};const y=Re(e,c,"index.js");if(y&&b(y))return{path:y};if(c==="default-config"){const S=Re(e,"default-config","blank","index.js");if(S&&b(S))return{path:S}}}}),l.onResolve({filter:/^@domql\//},i=>{const c=i.path.replace("@symbo.ls/","");if(e.isMonorepo){const u=g(e.monorepoRoot,"packages","domql","packages",c,"src","index.js");if(b(u))return{path:u};const y=g(e.monorepoRoot,"packages","domql","packages",c,"index.js");if(b(y))return{path:y}}else{const u=Me(e,c,"src","index.js");if(u&&b(u))return{path:u};const y=Me(e,c,"index.js");if(y&&b(y))return{path:y}}}),l.onResolve({filter:/^css-in-props/},i=>{let c;if(e.isMonorepo)c=g(e.monorepoRoot,"packages","css-in-props");else{const S=z(e,"css-in-props/package.json");S&&(c=j(S))}if(!c)return;const u=i.path.replace(/^css-in-props\/?/,"");if(u){const S=g(c,u),_=g(S,"index.js");if(b(_))return{path:_};if(b(S+".js"))return{path:S+".js"};if(b(S))return{path:S}}const y=s(c);if(y)return{path:y}}),l.onResolve({filter:/^@emotion\//},i=>{let c;if(e.isMonorepo)c=g(e.monorepoRoot,"node_modules",i.path);else{const u=z(e,`${i.path}/package.json`);if(!u)return;c=j(u)}if(b(c)){const u=g(c,"package.json");if(b(u))try{const y=JSON.parse(Y(u,"utf8")),S=y.module||y.main||"dist/emotion-css.esm.js";return{path:g(c,S)}}catch{}return{path:c}}}),l.onResolve({filter:/\.json$/},i=>{if(i.resolveDir){const c=g(i.resolveDir,i.path);if(b(c))return{path:c}}}),l.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"}}),l.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"}}),l.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"})),l.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"}}),l.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?[g(e.monorepoRoot,"node_modules")]:[...e.smblsRoot?[g(e.smblsRoot,"node_modules")]:[],...e.projectRoot?[g(e.projectRoot,"node_modules")]:[],...e.smblsRoot?[g(e.smblsRoot,"..","..","node_modules")]:[]].filter(l=>b(l)),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 m=await import(`file://${n}`);if(process.env.BRENDER_DEBUG)console.log("[brender] Bundle saved:",n);else try{ct(n)}catch{}return m},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"}},Nt=(e,t)=>{const o={};return Ie(e,(n,s)=>{if(!s.__brKey)return;const r=t(n);o[r===""?"__root":r]=s.__brKey}),o},Ie=(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)},Ht=new Set(["app","config","pages","components","state","snippets","designSystem","dependencies","functions","methods","files","sharedLibraries"]);let W=0;const Fe=Symbol.for("brender.fetchTracked"),we=()=>W,zt=256*1024,Wt=1024*1024,Ut=new Set(["accept-language","accept"]),Ge={renders:0,record:null},Vt=50,ke={renders:0,record:null},Be=(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)}}},xe=e=>e.record&&!e.record.tainted?e.record:null,Jt=e=>{try{const t=new URL(e);return t.origin+t.pathname}catch{return String(e).split("?")[0]}},_e=(e,t,o)=>{!e||e.tainted||e.failures.length>=Vt||e.failures.push({url:Jt(t),reason:o})},Ke=e=>e&&typeof e=="object"&&typeof e.url=="string"?e.url:String(e),Yt=e=>{const[t,o]=e,n=t&&typeof t=="object"&&typeof t.url=="string",s=Ke(t),r=String(o&&o.method||n&&t.method||"GET").toUpperCase(),a={},f=p=>{if(!p)return;const m=!Array.isArray(p)&&typeof p.entries!="function";for(const[l,i]of wt(p))m&&i==null||(a[String(l).toLowerCase()]=String(i))};return n&&f(t.headers),o&&f(o.headers),{url:s,method:r,headers:a}},Xt=(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>zt||e.bytes+a.length>Wt||(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[Fe])return;const t=function(...o){W++;let n=!1;const s=()=>{n||(n=!0,W--)},r=i=>{W++,i.then(()=>{W--},()=>{W--})},a=xe(Ge),f=xe(ke);let p=null;if(a)try{p=Yt(o),(p.method!=="GET"||!/^https?:/i.test(p.url)||Object.keys(p.headers).some(i=>!Ut.has(i)))&&(p=null)}catch{p=null}const m=()=>Ke(o[0]);let l;try{l=e.apply(this,o)}catch(i){throw _e(f,m(),i&&i.message||"failed"),s(),i}return l&&typeof l.then=="function"?l.then(i=>{p&&Xt(a,p,i,r),f&&i&&i.ok===!1&&_e(f,m(),"HTTP "+i.status),s()},i=>{_e(f,m(),i&&i.message||"network error"),s()}):s(),l};t[Fe]=!0,globalThis.fetch=t},fn=({brRegistry:e,fetchSeed:t,hydrateFlag:o=!0}={})=>{if(!e||!Object.keys(e).length)return"";const n=_t(e);return o?`<script>window.__BR_REGISTRY__=${n};window.__BRENDER_HYDRATE__=true<\/script>`+(t&&t.length?`
|
|
2
|
-
`+
|
|
1
|
+
import{resolve as h,join as at,dirname as j}from"path";import{existsSync as S,unlinkSync as lt,readFileSync as Q,realpathSync as ft}from"fs";import{resolvePackageEntry as pt}from"./packageEntry.js";import{tmpdir as ut}from"os";import{randomBytes as mt}from"crypto";import{createRequire as Re}from"module";import{pathToFileURL as dt}from"url";import{createEnv as Ae}from"./env.js";import{resetKeys as $e,assignKeys as De,mapKeysToElements as Oe}from"./keys.js";import{extractMetadata as we,generateHeadHtml as gt}from"./metadata.js";import"./hydrate.js";import{composeIntoShell as ht}from"./shell.js";import{trimSpriteToPage as yt,classRulesForPage as bt,markupClasses as St,trimVariablesToPage as Rt}from"./pageWeight.js";import{facesSheetTag as wt}from"./faces.js";import{fetchSSRTranslations as kt}from"./prefetch.js";import{createEarlySeedScript as xt}from"@symbo.ls/fetch";import{headerEntries as Tt}from"@symbo.ls/fetch/rest";import{brenderStampMeta as _t,brenderLazyMeta as Ce,escapeRegExp as Et,jsonForScript as jt,libraryPackageSpecs as vt,polyglotFallbackLang as ke,polyglotLangStorageKey as Lt,polyglotAddressLang as At,polyglotStartupScript as $t}from"@symbo.ls/utils";import{brenderRegistryBlock as Dt,brenderRegistryTreeBlock as Ot}from"@symbo.ls/utils/server";import*as Ct from"@symbo.ls/utils/server";import*as Mt from"@symbo.ls/utils";let pe=null;const qt=async()=>{if(pe)return pe;try{return pe=(await import("@symbo.ls/funcql")).funcqlPlugin,pe}catch{return null}};import"linkedom";import{createEarlySeedBlock as Pt,fetchRunsOf as It}from"@symbo.ls/fetch";import{reset as Ft}from"@symbo.ls/css";import*as ue from"@symbo.ls/css";const Bt=e=>typeof ue.tierOfStyle=="function"?ue.tierOfStyle(e):null,Gt=(e,t)=>typeof ue.sortByTier=="function"?ue.sortByTier(e,t):Array.from(e||[]),me=(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},de=(e,t)=>ke(e?.lang,t),Kt=e=>{const t=Ct.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},Me=e=>{const t=Mt.withPolyglotTranslations;return typeof t=="function"?t(e):e},qe=(e,t,o,n)=>{if(o?.translations){const r=o.translations[t];if(r){const a=me(r,e);if(a!==void 0)return a}}if(n?.translations){const r=n.translations[t];if(r){const a=me(r,e);if(a!==void 0)return a}}const s=ke(void 0,o);if(s!==t&&o?.translations){const r=o.translations[s];if(r){const a=me(r,e);if(a!==void 0)return a}}},Nt=function(e,t){if(!e)return"";const o=this?.context,n=o?.polyglot,s=this?.state?.root||o?.state?.root,r=qe(e,t||de(s,n),n,s);if(r!==void 0)return r;const a=Ee(_e);return n&&a&&a.labelKeys.add(e),e},Pe=function(){return de(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 C=null;try{import.meta.url&&(C=Re(import.meta.url))}catch{}const Ht=()=>{if(!import.meta.url||!C)return{isMonorepo:!1,monorepoRoot:null,resolvePackage:u=>u};const e=ft(new URL(".",import.meta.url).pathname),t=h(e,"../..");if(S(h(t,"packages","smbls","src","createDomql.js")))return{isMonorepo:!0,monorepoRoot:t};let n;try{const u=C.resolve("smbls/package.json");n=j(u)}catch{let u=e;for(;u!==j(u);){const g=h(u,"node_modules","smbls");if(S(h(g,"package.json"))){n=g;break}u=j(u)}}let s=C;if(n)try{s=Re(h(n,"package.json"))}catch{}let r,a=process.cwd();for(;a!==j(a);){if(S(h(a,"package.json"))){r=a;break}a=j(a)}let l=s;if(r)try{l=Re(h(r,"package.json"))}catch{}return{isMonorepo:!1,smblsRoot:n,brenderDir:e,projectRoot:r,_smblsRequire:s,_projectRequire:l}},H=(e,t)=>{const o=e.isMonorepo?[C]:[e._smblsRequire,e._projectRequire,C].filter(Boolean);for(const n of o)try{return n.resolve(t)}catch{}return null},mn=(e,t,...o)=>{if(e.isMonorepo)return h(e.monorepoRoot,"packages",t,...o);const n=H(e,`${t}/package.json`);return n?h(j(n),...o):null},dn=(e,t,...o)=>{if(e.isMonorepo)return h(e.monorepoRoot,"plugins",t,...o);const n=H(e,`@symbo.ls/${t}/package.json`);return n?h(j(n),...o):null},xe=(e,t,...o)=>{if(e.isMonorepo){for(const s of["packages","plugins"]){const r=h(e.monorepoRoot,s,t,...o);if(S(r))return r}return null}const n=H(e,`@symbo.ls/${t}/package.json`);return n?h(j(n),...o):null},Ie=(e,t,...o)=>{if(e.isMonorepo)return h(e.monorepoRoot,"packages","domql","packages",t,...o);const n=H(e,`@symbo.ls/${t}/package.json`);return n?h(j(n),...o):null};let ge=null;const Fe="smbls/ssr",zt=async()=>{const e=await import("smbls/ssr");if(typeof e?.createDomqlElement!="function")throw new Error("smbls/ssr does not export createDomqlElement");return e},Be=()=>(ge||(ge=Wt().catch(e=>{throw ge=null,e})),ge),Wt=async()=>{const e=Ht();let t;if(C&&e.isMonorepo)t=h(e.monorepoRoot,"packages","smbls","src","createDomql.js");else{let f;try{return await zt()}catch(c){f=c}if(!C)throw new Error(`brender: ${Fe} 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 i=e.smblsRoot&&h(e.smblsRoot,"src","createDomql.js");if(i&&S(i))t=i;else throw new Error(`brender: cannot load ${Fe} (${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=at(ut(),`br_createDomql_${mt(6).toString("hex")}.mjs`),s=pt,r=e.isMonorepo?await import(dt(h(e.monorepoRoot,"scripts","vite-workspace-source.mjs")).href):null,a=r?new Set(r.workspacePackageRoots().map(f=>r.workspacePackageAt(f).name)):null,l=/^(?:smbls(?:\/.*)?|domql|css-in-props(?:\/.*)?|@symbo\.ls\/[^/]+)$/,u={name:"workspace-resolve",setup(f){r&&(f.onResolve({filter:/^[^./]/},i=>{if(l.test(i.path))return;const c=i.path.split("/"),m=i.path.startsWith("@")?c.slice(0,2).join("/"):c[0];if(!a.has(m))return;const y=r.resolveWorkspaceSource(i.path,i.importer||t);return y?{path:y}:{errors:[{text:`"${i.path}" names no source file in the workspace`}]}}),f.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)),f.onResolve({filter:/^smbls/},i=>{const c=i.path.replace(/^smbls\/?/,""),m=e.isMonorepo?h(e.monorepoRoot,"packages","smbls"):e.smblsRoot;if(!m)return;if(!c){const T=s(m);return T?{path:T}:void 0}const y=h(m,c);if(S(y))return{path:y};if(S(y+".js"))return{path:y+".js"};const R=h(y,"index.js");if(S(R))return{path:R}}),f.onResolve({filter:/^domql$/},i=>{if(e.isMonorepo){const c=h(e.monorepoRoot,"packages","domql","src","index.js");if(S(c))return{path:c};const m=h(e.monorepoRoot,"packages","domql","index.js");if(S(m))return{path:m}}else try{const c=_require.resolve("domql/package.json"),m=s(j(c));if(m)return{path:m}}catch{}}),f.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 y of["packages","plugins"]){const R=h(e.monorepoRoot,y,c,"src","index.js");if(S(R))return{path:R};const T=h(e.monorepoRoot,y,c,"index.js");if(S(T))return{path:T}}const m=h(e.monorepoRoot,"packages","default-config","blank","index.js");if(c==="default-config"&&S(m))return{path:m}}else{const m=xe(e,c,"src","index.js");if(m&&S(m))return{path:m};const y=xe(e,c,"index.js");if(y&&S(y))return{path:y};if(c==="default-config"){const R=xe(e,"default-config","blank","index.js");if(R&&S(R))return{path:R}}}}),f.onResolve({filter:/^@domql\//},i=>{const c=i.path.replace("@symbo.ls/","");if(e.isMonorepo){const m=h(e.monorepoRoot,"packages","domql","packages",c,"src","index.js");if(S(m))return{path:m};const y=h(e.monorepoRoot,"packages","domql","packages",c,"index.js");if(S(y))return{path:y}}else{const m=Ie(e,c,"src","index.js");if(m&&S(m))return{path:m};const y=Ie(e,c,"index.js");if(y&&S(y))return{path:y}}}),f.onResolve({filter:/^css-in-props/},i=>{let c;if(e.isMonorepo)c=h(e.monorepoRoot,"packages","css-in-props");else{const R=H(e,"css-in-props/package.json");R&&(c=j(R))}if(!c)return;const m=i.path.replace(/^css-in-props\/?/,"");if(m){const R=h(c,m),T=h(R,"index.js");if(S(T))return{path:T};if(S(R+".js"))return{path:R+".js"};if(S(R))return{path:R}}const y=s(c);if(y)return{path:y}}),f.onResolve({filter:/^@emotion\//},i=>{let c;if(e.isMonorepo)c=h(e.monorepoRoot,"node_modules",i.path);else{const m=H(e,`${i.path}/package.json`);if(!m)return;c=j(m)}if(S(c)){const m=h(c,"package.json");if(S(m))try{const y=JSON.parse(Q(m,"utf8")),R=y.module||y.main||"dist/emotion-css.esm.js";return{path:h(c,R)}}catch{}return{path:c}}}),f.onResolve({filter:/\.json$/},i=>{if(i.resolveDir){const c=h(i.resolveDir,i.path);if(S(c))return{path:c}}}),f.onLoad({filter:/smbls\/.*options\.js$/},async i=>{if(!i.path.includes("smbls/")||!i.path.endsWith("options.js"))return;let c=Q(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"}}),f.onLoad({filter:/smbls\/.*init\.js$/},async i=>{if(!i.path.includes("smbls/")||!i.path.endsWith("init.js"))return;let c=Q(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"}}),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 i=>{let c=Q(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"}}),f.onLoad({filter:/fetchOnCreate\.js$/},async i=>{if(!i.path.includes("smbls/"))return;let c=Q(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:[u],nodePaths:e.isMonorepo?[h(e.monorepoRoot,"node_modules")]:[...e.smblsRoot?[h(e.smblsRoot,"node_modules")]:[],...e.projectRoot?[h(e.projectRoot,"node_modules")]:[],...e.smblsRoot?[h(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{lt(n)}catch{}return g},Ut={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"}},Vt=(e,t)=>{const o={};return Ge(e,(n,s)=>{if(!s.__brKey)return;const r=t(n);o[r===""?"__root":r]=s.__brKey}),o},Ge=(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)},Jt=new Set(["app","config","pages","components","state","snippets","designSystem","dependencies","functions","methods","files","sharedLibraries"]);let z=0;const Ke=Symbol.for("brender.fetchTracked"),Te=()=>z,Yt=256*1024,Xt=1024*1024,Qt=new Set(["accept-language","accept"]),Ne={renders:0,record:null},Zt=50,_e={renders:0,record:null},He=(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)}}},Ee=e=>e.record&&!e.record.tainted?e.record:null,eo=e=>{try{const t=new URL(e);return t.origin+t.pathname}catch{return String(e).split("?")[0]}},je=(e,t,o)=>{!e||e.tainted||e.failures.length>=Zt||e.failures.push({url:eo(t),reason:o})},ze=e=>e&&typeof e=="object"&&typeof e.url=="string"?e.url:String(e),to=e=>{const[t,o]=e,n=t&&typeof t=="object"&&typeof t.url=="string",s=ze(t),r=String(o&&o.method||n&&t.method||"GET").toUpperCase(),a={},l=u=>{if(!u)return;const g=!Array.isArray(u)&&typeof u.entries!="function";for(const[f,i]of Tt(u))g&&i==null||(a[String(f).toLowerCase()]=String(i))};return n&&l(t.headers),o&&l(o.headers),{url:s,method:r,headers:a}},oo=(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>Yt||e.bytes+a.length>Xt||(e.bytes+=a.length,e.entries.push({url:t.url,lang:t.headers["accept-language"]||"",status:o.status,type:s,body:a}))},()=>{}))},no=()=>{const e=globalThis.fetch;if(typeof e!="function"||e[Ke])return;const t=function(...o){z++;let n=!1;const s=()=>{n||(n=!0,z--)},r=i=>{z++,i.then(()=>{z--},()=>{z--})},a=Ee(Ne),l=Ee(_e);let u=null;if(a)try{u=to(o),(u.method!=="GET"||!/^https?:/i.test(u.url)||Object.keys(u.headers).some(i=>!Qt.has(i)))&&(u=null)}catch{u=null}const g=()=>ze(o[0]);let f;try{f=e.apply(this,o)}catch(i){throw je(l,g(),i&&i.message||"failed"),s(),i}return f&&typeof f.then=="function"?f.then(i=>{u&&oo(a,u,i,r),l&&i&&i.ok===!1&&je(l,g(),"HTTP "+i.status),s()},i=>{je(l,g(),i&&i.message||"network error"),s()}):s(),f};t[Ke]=!0,globalThis.fetch=t},gn=({brRegistry:e,fetchSeed:t,hydrateFlag:o=!0}={})=>{if(!e||!Object.keys(e).length)return"";const n=jt(e);return o?`<script>window.__BR_REGISTRY__=${n};window.__BRENDER_HYDRATE__=true<\/script>`+(t&&t.length?`
|
|
2
|
+
`+xt(t):""):`<script>window.__BR_REGISTRY__=${n}<\/script>`},so=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=vt(e())}catch{return}for(const[r]of s)!o.has(r)&&Object.prototype.hasOwnProperty.call(n,r)&&Reflect.deleteProperty(n,r)}},ro=3e4,co=2147483647;let We=Promise.resolve();const Ue=()=>{},io=e=>{const t=We.then(e);return We=t.then(Ue,Ue),t},ao=e=>{if(e===void 0)return ro;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,co)},Ve=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},lo=(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},fo=e=>{e.closed=!0;for(const t of e.undo.splice(0))t()},po=e=>{let t=!1;return()=>{t||(t=!0,e())}},Je=(e,t={})=>{let o;try{o=ao(t.timeout),Ve(t.search)}catch(n){return Promise.reject(n)}return io(()=>uo(Me(e),t,o))},uo=async(e,t,o)=>{await Be();const n={closed:!1,undo:[]},s=mo(e,t,n);if(!o)return s;let r;const a=new Promise((l,u)=>{r=setTimeout(()=>{fo(n),u(lo(t,o))},o)});try{return await Promise.race([s,a])}finally{clearTimeout(r)}},mo=async(e,t,o)=>{const{route:n="/",pathname:s,state:r,context:a,prefetch:l=!1,lazyGroups:u}=t,g=s||n,f=Ve(t.search);no();const i=He(_e,()=>({failures:[],labelKeys:new Set,tainted:!1}));try{return await go(Kt(e),{route:n,locationPath:g,locationSearch:f,stateOverrides:r,contextOverrides:a,prefetch:l,lazyGroups:u},i.record,o)}finally{i.close()}},go=async(e,{route:t,locationPath:o,locationSearch:n,stateOverrides:s,contextOverrides:r,prefetch:a,lazyGroups:l},u,g)=>{const f=()=>{if(g.closed)throw new Error("brender: this render was abandoned at its timeout")};let i;if(a){try{i=await kt(e)}catch(M){g.closed||console.warn("[brender] SSR translation fetch failed:",M.message)}f()}const{window:c,document:m}=Ae(),y=m.body;c.location.pathname=o,n&&(c.location.search=n,c.location.href=c.location.origin+o+n);let R=null;const T=[he("document",m),he("location",c.location),he("localStorage",c.localStorage),he("sessionStorage",c.sessionStorage),so(()=>R&&R.sharedLibraries)].map(po);g.undo.push(...T);try{const{createDomqlElement:M,PRERENDER_REGISTRY_FORMATS:Z}=await Be();f();const be=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 p of ko)e[p]!=null&&x[p]==null&&(x[p]=e[p]);const _=x.polyglot?{...x.polyglot,prefetch:!1}:void 0,U=At(o,_);U&&c.localStorage.setItem(Lt(_),U),i&&_&&(_.translations={..._.translations||{},...i});const ee=L(e.state||{});Ft();const te={};for(const p in e){if(Jt.has(p))continue;const b=e[p];te[p]=b&&typeof b=="object"?L(b):b}const k={...te,state:ee,...s?{state:{...ee,...s}}:{},dependencies:L(e.dependencies||{}),components:L(e.components||{}),snippets:L(e.snippets||{}),pages:L(e.pages||{}),functions:{...e.functions||{},polyglot:Nt,getActiveLang:Pe,getLang:Pe},methods:e.methods||{},designSystem:L(e.designSystem||{}),files:e.files||{},sharedLibraries:e.sharedLibraries||[],...x,..._?{polyglot:_}:{},document:m,window:c,parent:{node:y},initOptions:{},domqlOptions:{sourcemap:!1},firstRender:!1,sync:!1,inspect:!1,notifications:!1,afterFirstView:null,isolateDesignSystem:!0,isolateFetchCache:!0,captureDesignSystem:!0,...ho(l),...r||{},ssr:!0};R=k;const q=await qt();f(),q&&(k.plugins=k.plugins||[],k.plugins.some(p=>p.name==="funcql")||k.plugins.push(q)),$e();const oe=He(Ne,()=>({entries:[],bytes:0,tainted:!1})),P=oe.record;let d;try{if(d=await M(be,k),f(),k.lazyFirstView){const D=(d&&d.context||k).__firstNavigation;if(D&&typeof D.then=="function"){try{await D}catch{}f()}}const p=Date.now(),b=a?2e3:50,w=D=>new Promise(fe=>setTimeout(fe,D));for(await w(Math.min(50,b));a&&!g.closed&&Te()>0&&Date.now()-p<b;)await w(10),Te()===0&&await w(Math.max(0,Math.min(50,b-(Date.now()-p))));if(f(),a&&await yo(d,_)){f();const D=Date.now();for(await w(Math.min(50,b));!g.closed&&Te()>0&&Date.now()-D<b;)await w(10);f()}}finally{oe.close()}const I=P&&!P.tainted&&!(x.fetch&&x.fetch.seed===!1)?P.entries.slice():[];De(y);const ne=Oe(d),{elementPath:se}=await import("@symbo.ls/element");f();const A=Vt(d,se),V=I.length?It(d&&d.context||k,se):{},re=d?.context?.routerOptions?.contentElementKey||"content",F=d&&d[re],J=F&&typeof F=="object"&&F.__ref?F:void 0,ce=we(e,t,d,d?.state,J),E=[],K=new Map,Y=m.head||m.querySelector("head");if(Y){let p=null;for(const b of Y.querySelectorAll("style")){if(p=Bt(b)||p,b.sheet&&b.sheet.cssRules)for(const w of b.sheet.cssRules)w.cssText&&(E.push(w),p&&!K.has(w.cssText)&&K.set(w.cssText,p));if(!E.length){const w=b.textContent||"";w&&(E.push({cssText:w}),p&&!K.has(w)&&K.set(w,p))}}}const ie=E.map(p=>p.cssText),{globalCSS:ae,classRules:X}=vo(E),Se=X.map(p=>K.get(p)||null);let v=Qe(y.innerHTML);const B=d?.state?.root,G=de(B,_),O=bo(i,B);O&&(v=Xe(v,Ye(O,G,_)));const N=u&&!u.tainted?{failedRequests:u.failures.slice(),rawLabelKeys:wo(u.labelKeys,v,G,_,B)}:null,$=(d&&d.context||k).__lazyFirstViews,le=$&&typeof $.forEach=="function"?[...$]:[];return{html:v,metadata:ce,registry:ne,brRegistry:A,element:d,emotionCSS:ie,lazyGroups:le,globalCSS:ae,classRules:X,classRuleTiers:Se,fetchSeed:I,fetchRuns:V,document:m,window:c,ssrTranslations:O||void 0,activeLang:G,diagnostics:N,preparedDesignSystem:k.preparedDesignSystem||null,registryFormats:Array.isArray(Z)?Z.slice():["paths"]}}finally{for(const M of T)M()}},ho=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{}},he=(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]})},yo=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=de(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},ve=/\{\{\s*([^|{}]+?)\s*\|\s*polyglot\s*\}\}/g,Le=e=>e&&typeof e.parse=="function"?e.parse():e,bo=(e,t)=>{const o=Le(t?.translations),n={};for(const s of[e,o])if(!(!s||typeof s!="object"))for(const r in s){const a=Le(s[r]);a&&typeof a=="object"&&(n[r]={...n[r]||{},...a})}return Object.keys(n).length?n:null},Ye=(e,t,o)=>e[t]||e[ke(void 0,o)]||Object.values(e)[0]||{},Xe=(e,t)=>e.replace(ve,(o,n)=>me(t,n.trim())??o),So=/<script\b[^>]*\btype\s*=\s*["']?application\/json["']?[^>]*>[\s\S]*?<\/script\s*>/gi,Ro=(e,t)=>new RegExp(`(?:^|[^\\w.-])${Et(t)}(?![\\w-]|\\.\\w)`).test(e),wo=(e,t,o,n,s)=>{const r=new Set,a=t.replace(So,"");for(const l of e)/\s/.test(l)||qe(l,o,n,s)===void 0&&Ro(a,l)&&r.add(l);for(const l of a.matchAll(ve))r.add(l[1].trim());return[...r]},hn=async(e,t={})=>{const{context:o={}}=t,{window:n,document:s}=Ae(),r=s.body,{create:a}=await import("@symbo.ls/element"),l=await import("@symbo.ls/utils"),u={...Ut,...o.components||{}},g={...l,...o.utils||{},...o.functions||{}};$e();let f;try{f=a(e,{node:r},"root",{context:{document:s,window:n,...o,components:u,utils:g,ssr:!0}})}catch{}De(r);const i=f?Oe(f):{};return{html:Qe(r.innerHTML),registry:i,element:f}},Qe=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}),ko=["globalTheme","themeStorageKey","themeRoot","useReset","useVariable","useFontImport","useIconSprite","useSvgSprite","useDocumentTheme","useDefaultConfig","useDefaultIcons","useThemeSuffixedVars","verbose","semanticIcons"],xo=new Set(["auto","system"]),Ze=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||xo.has(s)?null:s},To=e=>String(e).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<"),_o=/\.[A-Za-z_\\-]/,Eo=e=>{if(typeof e!="string"||!e)return!1;const t=e.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,'""').replace(/\[[^\]]*\]/g,"[]");return!_o.test(t)},jo=/^\s*(:root|\[data-theme|\[data-skin)/,et=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)?jo.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(et));return n.has(null)||n.size!==1?n.has(null)?null:"reset":[...n][0]}return null},tt=e=>typeof e=="string"&&/^\s*@font-face\b/i.test(e),vo=e=>{const t={root:[],reset:[],keyframes:[]},o=[];for(const n of e||[]){const s=et(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 W=new Map;const ot=e=>Gt(e,t=>W.get(t)),yn=()=>{W=new Map},bn=()=>ot(W.keys()).join(`
|
|
6
|
+
`),Sn=(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
|
-
</style>`,
|
|
16
|
-
${
|
|
17
|
-
</style>`:"",
|
|
18
|
-
`:"",
|
|
19
|
-
`:"";
|
|
8
|
+
</style>`:""),Rn=async(e,t={})=>{const{route:o="/",pathname:n,search:s,prefetch:r=!0,timeout:a}=t,l=await Je(e,{route:o,pathname:n,search:s,prefetch:r,timeout:a});if(!l)return null;const u=e.designSystem||{},g=l.globalCSS;let f=null;try{const c=Lo(l.element);Object.keys(c).length&&(f=c)}catch{}const i=l.activeLang;return{html:l.html,css:l.classRules.join(`
|
|
9
|
+
`),classRules:l.classRules.slice(),classRuleTiers:l.classRuleTiers.slice(),globalCSS:g,resetCss:g.resetRules,fontLinks:it(u),metadata:l.metadata||we(e,o),brKeyCount:l.registry?Object.keys(l.registry).length:0,brRegistry:l.brRegistry||{},fetchSeed:l.fetchSeed||[],fetchRuns:l.fetchRuns||{},ssrTranslations:l.ssrTranslations,prefetchedState:f,activeLang:i,theme:Ze(e),diagnostics:l.diagnostics,preparedDesignSystem:l.preparedDesignSystem||null}},Lo=e=>{const t={};return Ge(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("~/"),l=a?r.slice(2):r,u=a?o.state.root:o.state,g=Le(u&&u[l]);l&&g!=null&&typeof g!="function"&&(t[l]=g)}}),t},wn=async(e,t="/",o={})=>{const n=Me(e),{lang:s,themeColor:r,isr:a,hydrate:l=!0,prefetch:u=!0,shell:g,adoptDom:f=!1,pathname:i,search:c,eagerImages:m=ct,preloadScripts:y=!0,nonce:R,timeout:T,stamp:M,time:Z,spriteIcons:be="all",cssClasses:x="all",cssVariables:_="all",registryFormat:U="paths",lazyGroups:ee,paint:te}=o,k=Ao(te),q=Io(R),oe=s||n.state?.lang||n.app?.metadata?.lang||"en",P=Ze(n),d=await Je(n,{route:t,pathname:i,search:c,prefetch:u,timeout:T,lazyGroups:ee});if(!d)return null;const I={...d.metadata};if(r&&(I["theme-color"]=r),typeof g=="string"&&!n.name){const p="\0brender-undeclared-title\0";if(we({...n,name:p},t,d.element,d.element?.state).title===p)for(const w of["title","og:title","twitter:title"])I[w]===d.metadata.title&&delete I[w]}const ne=gt(I),se=d.classRuleTiers||[];d.classRules.forEach((p,b)=>{p&&!W.has(p)&&W.set(p,se[b]||null)});let A=Mo(d.html,m);be==="page"&&(A=yt(A,typeof g=="string"?g:"").html);const V=Array.from(W.keys()),re=V.filter(tt),F=ot(re.length?V.filter(p=>!tt(p)):V),J=x==="page"?bt(F,St(A,typeof g=="string"?g:"")).join(`
|
|
10
|
+
`):F.join(`
|
|
11
|
+
`),ce=wt(re),E=d.globalCSS,Y=`<style data-brender>
|
|
12
|
+
${(_==="page"?Rt(E.rootRule||"",E.resetRules,E.keyframeRules,J,A,typeof g=="string"?g:"").css:E.rootRule)||""}
|
|
13
|
+
${E.resetRules||""}
|
|
14
|
+
${E.keyframeRules||""}
|
|
15
|
+
</style>`,ie=J?`<style data-emotion="smbls">
|
|
16
|
+
${J}
|
|
17
|
+
</style>`:"",ae=it(n.designSystem||{}),X=Object.keys(d.registry).length,Se=U==="tree"||U==="auto"&&(d.registryFormats||[]).includes("tree"),v=qo({brRegistry:d.brRegistry,fetchSeed:d.fetchSeed,fetchRuns:d.fetchRuns,adoptDom:f,stamp:M,time:Z,registryFormat:Se?"tree":"paths",lazyGroups:d.lazyGroups});let B="";if(a&&a.clientScript){const p=Number.isInteger(o.depth)?o.depth:t==="/"?0:t.replace(/^\/|\/$/g,"").split("/").length,b=p>0?"../".repeat(p):"./";if(l){const w=$t({polyglot:n.polyglot||n.config?.polyglot,translations:d.ssrTranslations,lang:d.activeLang,pathname:i||t,attrs:q}),D=w?w+`
|
|
18
|
+
`:"",fe=v.blocks?v.blocks+`
|
|
19
|
+
`:"";B=`${D}${fe}<script type="module" src="${b}${a.clientScript}"${q}><\/script>`}else B=`<script type="module"${q}>
|
|
20
20
|
{
|
|
21
21
|
const brEls = document.querySelectorAll('body > :not(script):not(style)')
|
|
22
22
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -33,29 +33,29 @@ ${$}
|
|
|
33
33
|
observer.observe(document.body, { childList: true })
|
|
34
34
|
}
|
|
35
35
|
<\/script>
|
|
36
|
-
<script type="module" src="${
|
|
37
|
-
${
|
|
38
|
-
`),body:
|
|
39
|
-
`+
|
|
40
|
-
<html lang="${
|
|
36
|
+
<script type="module" src="${b}${a.clientScript}"${q}><\/script>`}const G={...n.config||{}};n.polyglot&&!G.polyglot&&(G.polyglot=n.polyglot);const O=G.polyglot;let N=ne;if(O){const p={...O.translations||{}};for(const b in d.ssrTranslations||{})p[b]={...p[b]||{},...d.ssrTranslations[b]};N=Xe(ne,Ye(p,d.activeLang,O))}const $=d.diagnostics;if($)for(const p of N.matchAll(ve)){const b=p[1].trim();$.rawLabelKeys.includes(b)||$.rawLabelKeys.push(b)}if(typeof g=="string"){const p=ht(g,{headTags:`${N}
|
|
37
|
+
${v.meta}`,headEnd:[ae,ce,Y,ie].filter(Boolean).join(`
|
|
38
|
+
`),body:k?A+`
|
|
39
|
+
`+st:A,depth:Number.isInteger(o.depth)?o.depth:0,bootScripts:v.blocks,lang:s||(O?d.activeLang:void 0),theme:P,preloadScripts:y});return{html:k?rt(p):p,route:t,brKeyCount:X,shell:!0,diagnostics:$,preparedDesignSystem:d.preparedDesignSystem||null,lazyGroups:d.lazyGroups||[]}}const le=`<!DOCTYPE html>
|
|
40
|
+
<html lang="${oe}"${P?` data-theme="${To(P)}"`:""}>
|
|
41
41
|
<head>
|
|
42
|
-
${
|
|
43
|
-
${
|
|
42
|
+
${N}${a&&a.clientScript&&l?`
|
|
43
|
+
${v.meta}`:""}
|
|
44
|
+
${ae}
|
|
44
45
|
${ce}
|
|
45
|
-
${
|
|
46
|
-
${
|
|
47
|
-
${re}
|
|
46
|
+
${Y}
|
|
47
|
+
${ie}
|
|
48
48
|
</head>
|
|
49
49
|
<body>
|
|
50
|
-
${
|
|
51
|
-
${
|
|
52
|
-
${
|
|
50
|
+
${A}${k?`
|
|
51
|
+
${st}`:""}
|
|
52
|
+
${B}
|
|
53
53
|
</body>
|
|
54
|
-
</html>`;return{html:
|
|
55
|
-
`+
|
|
56
|
-
`+
|
|
57
|
-
`+e},
|
|
58
|
-
`):""}
|
|
59
|
-
`+
|
|
60
|
-
|
|
61
|
-
`)}},
|
|
54
|
+
</html>`;return{html:k?rt(le):le,route:t,brKeyCount:X,diagnostics:$,preparedDesignSystem:d.preparedDesignSystem||null,lazyGroups:d.lazyGroups||[]}},nt="smbls-whole",st=`<template id="${nt}"></template>`,ye=`<link rel="expect" href="#${nt}" blocking="render">`,Ao=e=>!!(e&&typeof e=="object"&&e.whole===!0),$o=/<meta\b[^>]*\bcharset\s*=[^>]*>/i,Do=[/<head\b[^>]*>/i,/<html\b[^>]*>/i,/^\s*<!doctype\b[^>]*>/i],rt=e=>{if(typeof e!="string"||e.includes(ye))return e;const t=$o.exec(e.slice(0,1024));if(t){const o=t.index+t[0].length;return e.slice(0,o)+`
|
|
55
|
+
`+ye+e.slice(o)}for(const o of Do){const n=o.exec(e);if(n)return e.slice(0,n.index+n[0].length)+`
|
|
56
|
+
`+ye+e.slice(n.index+n[0].length)}return ye+`
|
|
57
|
+
`+e},ct=2,Oo=/<img\b(?:[^>"']|"[^"]*"|'[^']*')*>/gi,Co=/\sloading\s*=/i,Mo=(e,t=ct)=>{if(t===!1||t==null||typeof e!="string")return e;const o=Math.max(0,Number(t)||0);let n=0;return e.replace(Oo,s=>n++<o||Co.test(s)?s:s.replace(/^<img\b/i,'<img loading="lazy"'))},it=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
|
+
`):""},qo=({brRegistry:e,fetchSeed:t,fetchRuns:o,adoptDom:n=!1,stamp:s,time:r,registryFormat:a="paths",lazyGroups:l}={})=>{const g=n&&e&&Object.keys(e).length?a==="tree"&&Ot(e)||Dt(e):"",f=Pt(t,o);return{meta:`<meta name="brender" content="${g?"hydrate":"replace"}">
|
|
59
|
+
`+_t(Po(s,r))+(Ce(l)?`
|
|
60
|
+
`+Ce(l):""),blocks:[g,f].filter(Boolean).join(`
|
|
61
|
+
`)}},Po=(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}},Io=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{ct as EAGER_IMAGES_DEFAULT,Fe as SMBLS_SSR_SPECIFIER,nt as WHOLE_MARKER_ID,gn as adoptionScripts,Po as buildStamp,Ze as fixedThemeOf,bn as getAccumulatedEmotionCSS,Mo as markLazyImages,Ao as paintsWhole,qo as prerenderParts,Je as render,hn as renderElement,wn as renderPage,Rn as renderRoute,Sn as replaceEmotionCSS,yn as resetGlobalCSSCache,Gt as sortByTier,vo as splitCapturedCSS,rt as withWholePaint};
|
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createEnv } from './env.js'
|
|
2
2
|
import { resetKeys, assignKeys, mapKeysToElements } from './keys.js'
|
|
3
3
|
import { loadProject, loadAndRenderAll } from './load.js'
|
|
4
|
-
import { render, renderElement, renderRoute, renderPage, resetGlobalCSSCache, getAccumulatedEmotionCSS, replaceEmotionCSS, adoptionScripts, prerenderParts, buildStamp } from './render.js'
|
|
4
|
+
import { render, renderElement, renderRoute, renderPage, resetGlobalCSSCache, getAccumulatedEmotionCSS, replaceEmotionCSS, adoptionScripts, prerenderParts, buildStamp, sortByTier } from './render.js'
|
|
5
5
|
import { extractMetadata, generateHeadHtml } from './metadata.js'
|
|
6
6
|
import { collectBrNodes, hydrate } from './hydrate.js'
|
|
7
7
|
import { generateSitemap } from './sitemap.js'
|
|
@@ -50,6 +50,9 @@ export {
|
|
|
50
50
|
markupClasses,
|
|
51
51
|
trimVariablesToPage,
|
|
52
52
|
stylesheetRules,
|
|
53
|
+
// The atomic engine's cascade-tier order (XMA #1283), for a caller that
|
|
54
|
+
// unions the class rules of several renders (renderRoute's classRuleTiers)
|
|
55
|
+
sortByTier,
|
|
53
56
|
markFacesSheet,
|
|
54
57
|
facesSheetMarks,
|
|
55
58
|
drawnFaces
|
|
@@ -85,6 +88,9 @@ export default {
|
|
|
85
88
|
markupClasses,
|
|
86
89
|
trimVariablesToPage,
|
|
87
90
|
stylesheetRules,
|
|
91
|
+
// The atomic engine's cascade-tier order (XMA #1283), for a caller that
|
|
92
|
+
// unions the class rules of several renders (renderRoute's classRuleTiers)
|
|
93
|
+
sortByTier,
|
|
88
94
|
markFacesSheet,
|
|
89
95
|
facesSheetMarks,
|
|
90
96
|
drawnFaces
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/brender",
|
|
3
|
-
"version": "3.14.
|
|
3
|
+
"version": "3.14.682",
|
|
4
4
|
"license": "CC-BY-NC-4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
"prepublishOnly": "npm run build"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@symbo.ls/css": "^3.14.
|
|
59
|
+
"@symbo.ls/css": "^3.14.783",
|
|
60
60
|
"@symbo.ls/default-config": "^3.14.794",
|
|
61
|
-
"@symbo.ls/element": "^3.14.
|
|
61
|
+
"@symbo.ls/element": "^3.14.829",
|
|
62
62
|
"@symbo.ls/fetch": "^3.14.679",
|
|
63
63
|
"@symbo.ls/helmet": "^3.14.674",
|
|
64
64
|
"@symbo.ls/scratch": "^3.14.799",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"linkedom": "^0.16.8"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"smbls": "^3.14.
|
|
70
|
+
"smbls": "^3.14.877"
|
|
71
71
|
},
|
|
72
72
|
"optionalDependencies": {
|
|
73
73
|
"@symbo.ls/funcql": "^3.14.0"
|
package/render.js
CHANGED
|
@@ -40,6 +40,25 @@ const getFuncqlPlugin = async () => {
|
|
|
40
40
|
import { parseHTML } from 'linkedom'
|
|
41
41
|
import { createEarlySeedBlock, fetchRunsOf } from '@symbo.ls/fetch'
|
|
42
42
|
import { css, injectGlobal, reset as resetCss } from '@symbo.ls/css'
|
|
43
|
+
// The atomic engine's cascade tiers (@symbo.ls/css atomic.js "The tiers for a
|
|
44
|
+
// reader of the sheets", XMA #1283), through the namespace, read at call time:
|
|
45
|
+
// tierOfStyle / sortByTier are newer than this package's css floor (a named
|
|
46
|
+
// import of a missing export fails the module at link time). Without them the
|
|
47
|
+
// rules keep the order they were captured in, as before.
|
|
48
|
+
import * as atomicCss from '@symbo.ls/css'
|
|
49
|
+
|
|
50
|
+
const tierOfStyle = (style) => (typeof atomicCss.tierOfStyle === 'function' ? atomicCss.tierOfStyle(style) : null)
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Items in the atomic engine's cascade-tier order (@symbo.ls/css sortByTier):
|
|
54
|
+
* by the tier `tierOf(item)` names, the order they came in inside a tier. For
|
|
55
|
+
* a caller that merges the class rules of several renders (renderPage below,
|
|
56
|
+
* @symbo.ls/cli's publish-time pre-render with renderRoute's `classRuleTiers`).
|
|
57
|
+
* @param {Iterable<*>} items
|
|
58
|
+
* @param {(item: *) => (string|null|undefined)} tierOf
|
|
59
|
+
* @returns {Array<*>}
|
|
60
|
+
*/
|
|
61
|
+
export const sortByTier = (items, tierOf) => (typeof atomicCss.sortByTier === 'function' ? atomicCss.sortByTier(items, tierOf) : Array.from(items || []))
|
|
43
62
|
|
|
44
63
|
// Lightweight SSR polyglot functions — resolve translations from context
|
|
45
64
|
// without needing the full polyglot plugin runtime
|
|
@@ -1517,24 +1536,41 @@ const renderWithDiagnostics = async (data, { route, locationPath, locationSearch
|
|
|
1517
1536
|
|
|
1518
1537
|
// Extract CSS from style tags in virtual head (atomic CSS engine writes here)
|
|
1519
1538
|
const capturedRules = []
|
|
1539
|
+
// The cascade tier each captured rule was filed in (XMA #1283), by its
|
|
1540
|
+
// text: the tier of the engine sheet it was read from (tierOfStyle). A
|
|
1541
|
+
// <style> the engine did not make (the element's data-smbls-scoped sheet, a
|
|
1542
|
+
// helmet style) takes the tier of the engine sheet before it, whose rules
|
|
1543
|
+
// its own follow in the head. The head holds the tier sheets in cascade
|
|
1544
|
+
// order, so this capture is in the app's order and its tiers never go down;
|
|
1545
|
+
// renderPage merges the rules of a build's pages and writes them by tier.
|
|
1546
|
+
const capturedTiers = new Map()
|
|
1520
1547
|
const head = document.head || document.querySelector('head')
|
|
1521
1548
|
if (head) {
|
|
1549
|
+
let tier = null
|
|
1522
1550
|
for (const style of head.querySelectorAll('style')) {
|
|
1551
|
+
tier = tierOfStyle(style) || tier
|
|
1523
1552
|
if (style.sheet && style.sheet.cssRules) {
|
|
1524
1553
|
for (const rule of style.sheet.cssRules) {
|
|
1525
|
-
if (rule.cssText)
|
|
1554
|
+
if (!rule.cssText) continue
|
|
1555
|
+
capturedRules.push(rule)
|
|
1556
|
+
if (tier && !capturedTiers.has(rule.cssText)) capturedTiers.set(rule.cssText, tier)
|
|
1526
1557
|
}
|
|
1527
1558
|
}
|
|
1528
1559
|
if (!capturedRules.length) {
|
|
1529
1560
|
const content = style.textContent || ''
|
|
1530
|
-
if (content)
|
|
1561
|
+
if (content) {
|
|
1562
|
+
capturedRules.push({ cssText: content })
|
|
1563
|
+
if (tier && !capturedTiers.has(content)) capturedTiers.set(content, tier)
|
|
1564
|
+
}
|
|
1531
1565
|
}
|
|
1532
1566
|
}
|
|
1533
1567
|
}
|
|
1534
1568
|
const emotionCSS = capturedRules.map((rule) => rule.cssText)
|
|
1535
1569
|
// globalCSS: the init-injected globals; classRules: everything else, in
|
|
1536
|
-
// capture order (see splitCapturedCSS)
|
|
1570
|
+
// capture order (see splitCapturedCSS); classRuleTiers: the tier of each
|
|
1571
|
+
// class rule, beside it (null where no engine sheet came before it).
|
|
1537
1572
|
const { globalCSS, classRules } = splitCapturedCSS(capturedRules)
|
|
1573
|
+
const classRuleTiers = classRules.map((rule) => capturedTiers.get(rule) || null)
|
|
1538
1574
|
|
|
1539
1575
|
let html = fixSvgContent(body.innerHTML)
|
|
1540
1576
|
|
|
@@ -1565,7 +1601,7 @@ const renderWithDiagnostics = async (data, { route, locationPath, locationSearch
|
|
|
1565
1601
|
const firstViews = ((element && element.context) || ctx).__lazyFirstViews
|
|
1566
1602
|
const lazyGroupsShown = firstViews && typeof firstViews.forEach === 'function' ? [...firstViews] : []
|
|
1567
1603
|
|
|
1568
|
-
return { html, metadata, registry, brRegistry, element, emotionCSS, lazyGroups: lazyGroupsShown, globalCSS, classRules, fetchSeed, fetchRuns, document, window, ssrTranslations: labels || undefined, activeLang, diagnostics, preparedDesignSystem: ctx.preparedDesignSystem || null,
|
|
1604
|
+
return { html, metadata, registry, brRegistry, element, emotionCSS, lazyGroups: lazyGroupsShown, globalCSS, classRules, classRuleTiers, fetchSeed, fetchRuns, document, window, ssrTranslations: labels || undefined, activeLang, diagnostics, preparedDesignSystem: ctx.preparedDesignSystem || null,
|
|
1569
1605
|
// the registry encodings the client of this smbls reads (smbls
|
|
1570
1606
|
// prerender.js PRERENDER_REGISTRY_FORMATS); an older smbls reads paths
|
|
1571
1607
|
registryFormats: Array.isArray(PRERENDER_REGISTRY_FORMATS) ? PRERENDER_REGISTRY_FORMATS.slice() : ['paths'] }
|
|
@@ -1901,18 +1937,28 @@ export const splitCapturedCSS = (rules) => {
|
|
|
1901
1937
|
// Emotion's singleton cache marks classes as "inserted" after the first render,
|
|
1902
1938
|
// so subsequent renders only produce NEW classes not seen before.
|
|
1903
1939
|
// We merge all CSS rules across renders to ensure every page has complete styles.
|
|
1904
|
-
|
|
1940
|
+
// Rule text → the cascade tier its first render read it in (render's
|
|
1941
|
+
// classRuleTiers). The map keeps the order rules were first captured in — a
|
|
1942
|
+
// rule an earlier page minted stays ahead of every rule a later page mints, so
|
|
1943
|
+
// it is written by tier (inTierOrder), never in this order (XMA #1283: `/`
|
|
1944
|
+
// minted the ≤560 px rule, `/b` the ≤768 px one, and `/b` wrote 560 first).
|
|
1945
|
+
let _accumulatedEmotionCSS = new Map()
|
|
1946
|
+
|
|
1947
|
+
// The accumulated rules given, in the app's cascade-tier order: the tier
|
|
1948
|
+
// sheets' order in the app's <head>, the first-written order inside a tier.
|
|
1949
|
+
const inTierOrder = (rules) => sortByTier(rules, (rule) => _accumulatedEmotionCSS.get(rule))
|
|
1905
1950
|
|
|
1906
1951
|
/**
|
|
1907
1952
|
* Reset the cached global CSS and emotion CSS (useful when rendering multiple projects).
|
|
1908
1953
|
*/
|
|
1909
|
-
export const resetGlobalCSSCache = () => { _accumulatedEmotionCSS = new
|
|
1954
|
+
export const resetGlobalCSSCache = () => { _accumulatedEmotionCSS = new Map() }
|
|
1910
1955
|
|
|
1911
1956
|
/**
|
|
1912
|
-
* Returns the complete accumulated emotion CSS from all renders so far
|
|
1957
|
+
* Returns the complete accumulated emotion CSS from all renders so far, in
|
|
1958
|
+
* the app's cascade-tier order.
|
|
1913
1959
|
* Call this after rendering ALL pages to get the full CSS needed by every page.
|
|
1914
1960
|
*/
|
|
1915
|
-
export const getAccumulatedEmotionCSS = () =>
|
|
1961
|
+
export const getAccumulatedEmotionCSS = () => inTierOrder(_accumulatedEmotionCSS.keys()).join('\n')
|
|
1916
1962
|
|
|
1917
1963
|
/**
|
|
1918
1964
|
* Replace the emotion CSS in a rendered HTML page with updated CSS.
|
|
@@ -1970,6 +2016,10 @@ export const renderRoute = async (data, options = {}) => {
|
|
|
1970
2016
|
// the same rules as a list — a caller that unions several routes' CSS
|
|
1971
2017
|
// (the publish-time ssrCache) dedupes by rule
|
|
1972
2018
|
classRules: result.classRules.slice(),
|
|
2019
|
+
// the cascade tier of each of them (render's capture, XMA #1283): a
|
|
2020
|
+
// caller that unions several routes' rules writes the union in the app's
|
|
2021
|
+
// order with sortByTier — one route's own rules already are in it
|
|
2022
|
+
classRuleTiers: result.classRuleTiers.slice(),
|
|
1973
2023
|
globalCSS,
|
|
1974
2024
|
resetCss: globalCSS.resetRules,
|
|
1975
2025
|
fontLinks: generateFontLinks(ds),
|
|
@@ -2128,9 +2178,11 @@ export const renderPage = async (payload, route = '/', options = {}) => {
|
|
|
2128
2178
|
// collect all rules across renders to build the complete stylesheet.
|
|
2129
2179
|
// Only the classes accumulate: the globals are this page's own (one :root,
|
|
2130
2180
|
// one copy of each @keyframes — they used to pile up across pages).
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2181
|
+
// Each with the tier its render read it in.
|
|
2182
|
+
const tiers = result.classRuleTiers || []
|
|
2183
|
+
result.classRules.forEach((rule, i) => {
|
|
2184
|
+
if (rule && !_accumulatedEmotionCSS.has(rule)) _accumulatedEmotionCSS.set(rule, tiers[i] || null)
|
|
2185
|
+
})
|
|
2134
2186
|
|
|
2135
2187
|
// Images past the first `eagerImages` load lazily unless they say how to
|
|
2136
2188
|
// load (see markLazyImages).
|
|
@@ -2155,9 +2207,16 @@ export const renderPage = async (payload, route = '/', options = {}) => {
|
|
|
2155
2207
|
// sheet the takeover never touches keeps them loaded; smbls applyFontFaces
|
|
2156
2208
|
// finds them declared and adds none of its own (smbls prerender.js
|
|
2157
2209
|
// serverStyles does not select it, so it stays for the page's life).
|
|
2158
|
-
|
|
2210
|
+
//
|
|
2211
|
+
// The class rules go in the app's cascade-tier order (XMA #1283): in the
|
|
2212
|
+
// order they were first captured, the ≤560 px rule `/` minted stayed ahead
|
|
2213
|
+
// of the ≤768 px rule `/b` minted after it, and `/b` showed 2 columns at
|
|
2214
|
+
// 390 px where the app shows 1 (and a longhand class an earlier page minted
|
|
2215
|
+
// lost to its shorthand). One page's own rules are already in this order;
|
|
2216
|
+
// a stable sort leaves them so. The faces keep their first-captured order.
|
|
2217
|
+
const accumulated = Array.from(_accumulatedEmotionCSS.keys())
|
|
2159
2218
|
const faceRules = accumulated.filter(isFontFaceText)
|
|
2160
|
-
const classRules = faceRules.length ? accumulated.filter((rule) => !isFontFaceText(rule)) : accumulated
|
|
2219
|
+
const classRules = inTierOrder(faceRules.length ? accumulated.filter((rule) => !isFontFaceText(rule)) : accumulated)
|
|
2161
2220
|
const emotionCSS = cssClasses === 'page'
|
|
2162
2221
|
? classRulesForPage(classRules, markupClasses(bodyHtml, typeof shell === 'string' ? shell : '')).join('\n')
|
|
2163
2222
|
: classRules.join('\n')
|