@symbo.ls/brender 3.14.662 → 3.14.664
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 +53 -0
- package/dist/esm/env.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/render.js +30 -113
- package/dist/esm/shell.js +6 -5
- package/env.js +59 -1
- package/index.js +5 -3
- package/package.json +8 -8
- package/render.js +333 -758
- package/shell.js +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @symbo.ls/brender
|
|
2
2
|
|
|
3
|
+
## 3.14.664
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Performance pass on the 3.14.827–3.14.832 batch, and opt-in View Transitions.
|
|
8
|
+
|
|
9
|
+
- Element create is faster than 3.14.826 again (kekela-like 4,068-element tree: create CPU min 1,265–1,355 ms vs 1,361–1,532 ms on 3.14.826). Per-definition caching of the extends merge layers (46,330 → 13,600 entries), no per-element source-text reads, one attribute writer.
|
|
10
|
+
- `css()` 3x faster (21 → 7 µs per call), byte-identical CSS output.
|
|
11
|
+
- Helmet renders a head layer only when its values change (20 `root.update({})` → 0 head renders, was 40). One runtime head writer: `applyElementMetadata`.
|
|
12
|
+
- brender/mermaid: registry script is escaped on the ISR and non-adopt paths; head/SSR output byte-identical otherwise.
|
|
13
|
+
- View Transitions for page switches (opt-in), `viewTransitionName` / `viewTransitionClass` flat props, `designSystem.viewTransition` animations.
|
|
14
|
+
- utils exports shared helpers used by helmet, frank, fetch and polyglot (escapeHtml, jsonForScript, alternateLinkKey, faviconLinkKey, bareLibraryKey, librarySpecsFor, polyglotLangStorageKey, ...).
|
|
15
|
+
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- smbls@3.14.833
|
|
18
|
+
- @symbo.ls/element@3.14.803
|
|
19
|
+
- @symbo.ls/css@3.14.777
|
|
20
|
+
- @symbo.ls/scratch@3.14.788
|
|
21
|
+
- @symbo.ls/utils@3.14.786
|
|
22
|
+
- @symbo.ls/fetch@3.14.664
|
|
23
|
+
- @symbo.ls/helmet@3.14.670
|
|
24
|
+
|
|
25
|
+
## 3.14.663
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- Server rendering is correct and fast, opt-in hydration, and Cloudflare deploys run the full build (FW-BRENDER-HYDRATION-AND-CF-DEPLOY-PROVIDER-1, FW-PUBLISH-TIME-PRERENDER-SSRCACHE-1).
|
|
30
|
+
|
|
31
|
+
Behaviour changes (check these first):
|
|
32
|
+
|
|
33
|
+
- `smbls build` copies `public/` into the output root (never replacing a file the bundler wrote), so `_redirects`, `_headers` and `404.html` ship with every bundler.
|
|
34
|
+
- Booting over a pre-rendered page removes only `style[data-emotion="smbls"]` and `style[data-brender]`; the host page's own `<style>` tags stay.
|
|
35
|
+
- The Cloudflare worker (`renderProjectHtml` without eval) keeps the client render instead of painting a wrong pre-render; a stored pre-render (`ssrCache` / `__ssr`) is still served. `ssrWithoutEval: true` opts back in.
|
|
36
|
+
|
|
37
|
+
Fixes:
|
|
38
|
+
|
|
39
|
+
- Every server render after the first one paints its theme colours again (linkedom made `deepClone` copy nothing nested).
|
|
40
|
+
- Server pages ship their own reset, keyframes and `:root` once, also in the Cloudflare worker (`generateGlobalCSS` read the wrong keys, wrote files and cached across projects).
|
|
41
|
+
- A pre-render waits for its own requests instead of a flat 2 s; server renders stop rescanning the head for every inserted rule.
|
|
42
|
+
- The server render gets the project's `globalScope` and context keys, as the client does; a `<select>` with a value no longer drops its parent.
|
|
43
|
+
|
|
44
|
+
New, opt-in:
|
|
45
|
+
|
|
46
|
+
- Hydration: `hydrate: true` (or `window.__BRENDER_HYDRATE__` from the server, with `__BR_REGISTRY__`) adopts the server DOM instead of replacing it; a mismatch falls back to a fresh node, a throw to the fresh render. brender `renderPage({ adoptDom })` ships the registry and the recorded GET answers; `@symbo.ls/fetch` exports `createEarlySeedScript`, `earlyKey`, `EARLY_KEY`.
|
|
47
|
+
- `smbls deploy --provider cloudflare [--target pages|workers] [--dry-run] [--no-brender]` runs the full `smbls build` pipeline; `--target workers` writes Workers Static Assets config.
|
|
48
|
+
- `smbls publish --ssr` (or `"prerender": true` in `symbols.json`) pre-renders every static route and stores it as `__ssr`, which the platform renderer serves; off by default.
|
|
49
|
+
|
|
50
|
+
- Updated dependencies
|
|
51
|
+
- smbls@3.14.828
|
|
52
|
+
- @symbo.ls/element@3.14.800
|
|
53
|
+
- @symbo.ls/css@3.14.775
|
|
54
|
+
- @symbo.ls/fetch@3.14.663
|
|
55
|
+
|
|
3
56
|
## 3.14.662
|
|
4
57
|
|
|
5
58
|
### Patch Changes
|
package/dist/esm/env.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseHTML as
|
|
1
|
+
import{parseHTML as c}from"linkedom";const a=new WeakSet;class h{static[Symbol.hasInstance](e){return a.has(e)}}const u=n=>{let e=Object.getPrototypeOf(n.createElement("select")),l;for(;e&&!(l=Object.getOwnPropertyDescriptor(e,"value"));)e=Object.getPrototypeOf(e);!e||!l||!l.get||l.set||Object.defineProperty(e,"value",{configurable:!0,enumerable:l.enumerable,get:l.get,set(r){const o=r==null?"":String(r);let t=!1;for(const s of this.querySelectorAll("option")){const i=s.hasAttribute("value")?s.getAttribute("value"):s.textContent;!t&&i===o?(s.setAttribute("selected",""),t=!0):s.removeAttribute("selected")}}})},b=(n="<!DOCTYPE html><html><head></head><body></body></html>")=>{const{window:e,document:l}=c(n);e.requestAnimationFrame||(e.requestAnimationFrame=o=>{const t=setTimeout(o,0);return t?.unref&&t.unref(),t}),e.cancelAnimationFrame||(e.cancelAnimationFrame=o=>clearTimeout(o)),e.history||(e.history={pushState:()=>{},replaceState:()=>{},state:null}),e.location||(e.location={pathname:"/",search:"",hash:"",origin:"http://localhost",protocol:"http:",host:"localhost",hostname:"localhost",port:"",href:"http://localhost/"}),e.URL||(e.URL=URL),e.scrollTo||(e.scrollTo=()=>{});const r=()=>{const o={};return{getItem:t=>o[t]??null,setItem:(t,s)=>{o[t]=String(s)},removeItem:t=>{delete o[t]},clear:()=>{for(const t in o)delete o[t]},get length(){return Object.keys(o).length},key:t=>Object.keys(o)[t]??null}};return e.localStorage||(e.localStorage=r()),e.sessionStorage||(e.sessionStorage=r()),globalThis.localStorage||(globalThis.localStorage=e.localStorage),globalThis.sessionStorage||(globalThis.sessionStorage=e.sessionStorage),u(l),e.MutationObserver||(e.MutationObserver=class{constructor(){}observe(){}disconnect(){}takeRecords(){return[]}}),globalThis.window=e,globalThis.document=l,globalThis.Node=e.Node||globalThis.Node,globalThis.Element=e.Element||globalThis.Element,globalThis.HTMLElement=e.HTMLElement||globalThis.HTMLElement,globalThis.MutationObserver=e.MutationObserver,a.add(e),e.constructor&&e.constructor!==Object?globalThis.Window=e.constructor:(typeof globalThis.Window!="function"||globalThis.Window===Object)&&(globalThis.Window=h),{window:e,document:l}};export{b as createEnv};
|
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 m,loadAndRenderAll as a}from"./load.js";import{render 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 m,loadAndRenderAll as a}from"./load.js";import{render as p,renderElement as n,renderRoute as d,renderPage as i,resetGlobalCSSCache as l,getAccumulatedEmotionCSS as c,replaceEmotionCSS as f,adoptionScripts as s}from"./render.js";import{extractMetadata as S,generateHeadHtml as g}from"./metadata.js";import{collectBrNodes as h,hydrate as E}from"./hydrate.js";import{generateSitemap as u}from"./sitemap.js";import{prefetchPageData as y,injectPrefetchedState as C}from"./prefetch.js";import{composeIntoShell as P}from"./shell.js";var D={createEnv:e,resetKeys:r,assignKeys:t,mapKeysToElements:o,loadProject:m,loadAndRenderAll:a,render:p,renderElement:n,renderRoute:d,renderPage:i,resetGlobalCSSCache:l,getAccumulatedEmotionCSS:c,replaceEmotionCSS:f,extractMetadata:S,generateHeadHtml:g,collectBrNodes:h,hydrate:E,generateSitemap:u,prefetchPageData:y,injectPrefetchedState:C,composeIntoShell:P,adoptionScripts:s};export{s as adoptionScripts,t as assignKeys,h as collectBrNodes,P as composeIntoShell,e as createEnv,D as default,S as extractMetadata,g as generateHeadHtml,u as generateSitemap,c as getAccumulatedEmotionCSS,E as hydrate,C as injectPrefetchedState,a as loadAndRenderAll,m as loadProject,o as mapKeysToElements,y as prefetchPageData,p as render,n as renderElement,i as renderPage,d as renderRoute,f as replaceEmotionCSS,l as resetGlobalCSSCache,r as resetKeys};
|
package/dist/esm/render.js
CHANGED
|
@@ -1,87 +1,22 @@
|
|
|
1
|
-
import{resolve as m,join as Q,dirname as P}from"path";import{existsSync as y,unlinkSync as Ct,readFileSync as K,realpathSync as Tt}from"fs";import{resolvePackageEntry as Ot}from"./packageEntry.js";import{tmpdir as Lt}from"os";import{randomBytes as It}from"crypto";import{createRequire as tt}from"module";import{createEnv as st}from"./env.js";import{resetKeys as rt,assignKeys as it,mapKeysToElements as ct}from"./keys.js";import{extractMetadata as et,generateHeadHtml as At}from"./metadata.js";import"./hydrate.js";import{composeIntoShell as Et}from"./shell.js";import{prefetchPageData as Pt,injectPrefetchedState as qt,fetchSSRTranslations as vt}from"./prefetch.js";let z=null;const Dt=async()=>{if(z)return z;try{return z=(await import("@symbo.ls/funcql")).funcqlPlugin,z}catch{return null}};import"linkedom";import{reset as Mt}from"@symbo.ls/css";const ot=(t,e)=>{if(!t||!e)return;if(t[e]!==void 0)return t[e];const o=e.split(".");let n=t;for(const r of o){if(n==null||typeof n!="object")return;n=n[r]}return n},Ft=function(t,e){if(!t)return"";const o=this?.context,n=o?.polyglot,r=e||n?.defaultLang||"en";if(n?.translations){const l=n.translations[r];if(l){const c=ot(l,t);if(c!==void 0)return c}}const u=this?.state?.root||o?.state?.root;if(u?.translations){const l=u.translations[r];if(l){const c=ot(l,t);if(c!==void 0)return c}}const p=n?.defaultLang||"en";if(p!==r&&n?.translations){const l=n.translations[p];if(l){const c=ot(l,t);if(c!==void 0)return c}}return t},lt=function(){const t=this?.context;return this?.state?.root?.lang||t?.polyglot?.defaultLang||"en"},F=(t,e=new WeakMap)=>{if(t===null||typeof t!="object")return t;if(e.has(t))return e.get(t);if(Array.isArray(t)){const n=[];e.set(t,n);for(const r of t)n.push(typeof r=="object"&&r!==null?F(r,e):r);return n}const o={};e.set(t,o);for(const n of Object.keys(t)){const r=t[n];o[n]=typeof r=="object"&&r!==null?F(r,e):r}return o},at=()=>{const t=new WeakSet;return(e,o)=>{if(typeof o!="function"){if(typeof o=="object"&&o!==null){if(t.has(o))return;t.add(o)}return o}}};let B=null;try{import.meta.url&&(B=tt(import.meta.url))}catch{}const ft=()=>{if(!import.meta.url||!B)return{isMonorepo:!1,monorepoRoot:null,resolvePackage:c=>c};const t=Tt(new URL(".",import.meta.url).pathname),e=m(t,"../..");if(y(m(e,"packages","smbls","src","createDomql.js")))return{isMonorepo:!0,monorepoRoot:e};let n;try{const c=B.resolve("smbls/package.json");n=P(c)}catch{let c=t;for(;c!==P(c);){const s=m(c,"node_modules","smbls");if(y(m(s,"package.json"))){n=s;break}c=P(c)}}let r=B;if(n)try{r=tt(m(n,"package.json"))}catch{}let u,p=process.cwd();for(;p!==P(p);){if(y(m(p,"package.json"))){u=p;break}p=P(p)}let l=r;if(u)try{l=tt(m(u,"package.json"))}catch{}return{isMonorepo:!1,smblsRoot:n,brenderDir:t,projectRoot:u,_smblsRequire:r,_projectRequire:l}},H=(t,e)=>{const o=t.isMonorepo?[B]:[t._smblsRequire,t._projectRequire,B].filter(Boolean);for(const n of o)try{return n.resolve(e)}catch{}return null},he=(t,e,...o)=>{if(t.isMonorepo)return m(t.monorepoRoot,"packages",e,...o);const n=H(t,`${e}/package.json`);return n?m(P(n),...o):null},be=(t,e,...o)=>{if(t.isMonorepo)return m(t.monorepoRoot,"plugins",e,...o);const n=H(t,`@symbo.ls/${e}/package.json`);return n?m(P(n),...o):null},nt=(t,e,...o)=>{if(t.isMonorepo){for(const r of["packages","plugins"]){const u=m(t.monorepoRoot,r,e,...o);if(y(u))return u}return null}const n=H(t,`@symbo.ls/${e}/package.json`);return n?m(P(n),...o):null},Y=(t,e,...o)=>{if(t.isMonorepo)return m(t.monorepoRoot,"packages","domql","packages",e,...o);const n=H(t,`@symbo.ls/${e}/package.json`);return n?m(P(n),...o):null};let W=null;const ut="smbls/ssr",pt=async()=>{const t=await import("smbls/ssr");if(typeof t?.createDomqlElement!="function")throw new Error("smbls/ssr does not export createDomqlElement");return t},Nt=async()=>{if(W)return W;const t=ft();if(!B)try{return W=await pt(),W}catch(l){throw new Error(`brender: ${ut} is not available in this bundled runtime (${l.message}). Bundle smbls \u2265 the release that adds the smbls/ssr export alongside @symbo.ls/brender.`)}let e;if(t.isMonorepo)e=m(t.monorepoRoot,"packages","smbls","src","createDomql.js");else{let l;try{return W=await pt(),W}catch(s){l=s}const c=t.smblsRoot&&m(t.smblsRoot,"src","createDomql.js");if(c&&y(c))e=c;else throw new Error(`brender: cannot load ${ut} (${l.message}). Server rendering needs smbls installed in this project, at a release that exports smbls/ssr`+(t.smblsRoot?` (found smbls at ${t.smblsRoot}).`:" (no smbls package found)."))}const o=await import("esbuild"),n=Q(Lt(),`br_createDomql_${It(6).toString("hex")}.mjs`),r=Ot,u={name:"workspace-resolve",setup(l){l.onResolve({filter:/^smbls/},c=>{const s=c.path.replace(/^smbls\/?/,""),i=t.isMonorepo?m(t.monorepoRoot,"packages","smbls"):t.smblsRoot;if(!i)return;if(!s){const g=r(i);return g?{path:g}:void 0}const a=m(i,s);if(y(a))return{path:a};if(y(a+".js"))return{path:a+".js"};const f=m(a,"index.js");if(y(f))return{path:f}}),l.onResolve({filter:/^domql$/},c=>{if(t.isMonorepo){const s=m(t.monorepoRoot,"packages","domql","src","index.js");if(y(s))return{path:s};const i=m(t.monorepoRoot,"packages","domql","index.js");if(y(i))return{path:i}}else try{const s=_require.resolve("domql/package.json"),i=r(P(s));if(i)return{path:i}}catch{}}),l.onResolve({filter:/^@symbo\.ls\//},c=>{const s=c.path.replace("@symbo.ls/","");if(s==="sync")return{path:"sync-stub",namespace:"brender-stub"};if(t.isMonorepo){for(const a of["packages","plugins"]){const f=m(t.monorepoRoot,a,s,"src","index.js");if(y(f))return{path:f};const g=m(t.monorepoRoot,a,s,"index.js");if(y(g))return{path:g}}const i=m(t.monorepoRoot,"packages","default-config","blank","index.js");if(s==="default-config"&&y(i))return{path:i}}else{const i=nt(t,s,"src","index.js");if(i&&y(i))return{path:i};const a=nt(t,s,"index.js");if(a&&y(a))return{path:a};if(s==="default-config"){const f=nt(t,"default-config","blank","index.js");if(f&&y(f))return{path:f}}}}),l.onResolve({filter:/^@domql\//},c=>{const s=c.path.replace("@symbo.ls/","");if(t.isMonorepo){const i=m(t.monorepoRoot,"packages","domql","packages",s,"src","index.js");if(y(i))return{path:i};const a=m(t.monorepoRoot,"packages","domql","packages",s,"index.js");if(y(a))return{path:a}}else{const i=Y(t,s,"src","index.js");if(i&&y(i))return{path:i};const a=Y(t,s,"index.js");if(a&&y(a))return{path:a}}}),l.onResolve({filter:/^css-in-props/},c=>{let s;if(t.isMonorepo)s=m(t.monorepoRoot,"packages","css-in-props");else{const f=H(t,"css-in-props/package.json");f&&(s=P(f))}if(!s)return;const i=c.path.replace(/^css-in-props\/?/,"");if(i){const f=m(s,i),g=m(f,"index.js");if(y(g))return{path:g};if(y(f+".js"))return{path:f+".js"};if(y(f))return{path:f}}const a=r(s);if(a)return{path:a}}),l.onResolve({filter:/^@emotion\//},c=>{let s;if(t.isMonorepo)s=m(t.monorepoRoot,"node_modules",c.path);else{const i=H(t,`${c.path}/package.json`);if(!i)return;s=P(i)}if(y(s)){const i=m(s,"package.json");if(y(i))try{const a=JSON.parse(K(i,"utf8")),f=a.module||a.main||"dist/emotion-css.esm.js";return{path:m(s,f)}}catch{}return{path:s}}}),l.onResolve({filter:/\.json$/},c=>{if(c.resolveDir){const s=m(c.resolveDir,c.path);if(y(s))return{path:s}}}),l.onLoad({filter:/smbls\/.*options\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("options.js"))return;let s=K(c.path,"utf8");return s=s.replace(/import\s*\{[^}]*version[^}]*\}\s*from\s*['"][^'"]*package\.json['"][^;\n]*/,"const version = '0.0.0'"),s=s.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:s,loader:"js"}}),l.onLoad({filter:/smbls\/.*init\.js$/},async c=>{if(!c.path.includes("smbls/")||!c.path.endsWith("init.js"))return;let s=K(c.path,"utf8");return s=s.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:s,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 c=>{let s=K(c.path,"utf8");return s=s.replace(/import\s*\{\s*Link\s*\}\s*from\s*['"]smbls['"]/,"const Link = { tag: 'a', attr: { href: (el) => el.href } }"),{contents:s,loader:"js"}}),l.onLoad({filter:/fetchOnCreate\.js$/},async c=>{if(!c.path.includes("smbls/"))return;let s=K(c.path,"utf8");return s=s.replace(/window\s*&&\s*window\.location\s*\?\s*window\.location\.host\.includes/g,"window && window.location && window.location.host ? window.location.host.includes"),{contents:s,loader:"js"}})}};await o.build({entryPoints:[e],bundle:!0,format:"esm",platform:"node",outfile:n,write:!0,logLevel:"warning",plugins:[u],nodePaths:t.isMonorepo?[m(t.monorepoRoot,"node_modules")]:[...t.smblsRoot?[m(t.smblsRoot,"node_modules")]:[],...t.projectRoot?[m(t.projectRoot,"node_modules")]:[],...t.smblsRoot?[m(t.smblsRoot,"..","..","node_modules")]:[]].filter(l=>y(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 p=await import(`file://${n}`);if(process.env.BRENDER_DEBUG)console.log("[brender] Bundle saved:",n);else try{Ct(n)}catch{}return W=p,p},Bt={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:t=>t.href,target:t=>t.target,rel:t=>t.rel}},A:{extends:"Link"},RouteLink:{extends:"Link"},Img:{tag:"img",attr:{src:t=>{let e=t.src;return typeof e=="string"&&e.includes("{{")&&(e=t.call("replaceLiteralsWithObjectFields",e,t.state)),e},alt:t=>t.alt,loading:t=>t.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"}},mt=(t,e="")=>{if(!t||!t.__ref)return{};const o={},n=t.__ref.__brKey;if(n&&(o[e===""?"__root":e]=n),t.__ref.__children)for(const r of t.__ref.__children){const u=t[r];if(u&&u.__ref){const p=e===""?r:`${e}.${r}`;Object.assign(o,mt(u,p))}}return o},dt=async(t,e={})=>{const{route:o="/",pathname:n,state:r,context:u,prefetch:p=!1}=e,l=n||o,c=globalThis.location,s=globalThis.window;(!globalThis.location||globalThis.location.pathname!==l)&&(globalThis.location={pathname:l,href:l,search:"",hash:"",origin:""}),globalThis.window||(globalThis.window={location:globalThis.location});let i;if(p)try{const h=t.pages||{};i={...h};const O=await Pt(t,o);if(O.size){const V=JSON.parse(JSON.stringify(h[o],(v,N)=>{if(typeof N!="function")return N})),U=(v,N)=>{if(!(!v||!N))for(const D in v)typeof v[D]=="function"?N[D]=v[D]:typeof v[D]=="object"&&v[D]!==null&&!Array.isArray(v[D])&&typeof N[D]=="object"&&N[D]!==null&&U(v[D],N[D])};U(h[o],V),qt(V,O),i[o]=V}}catch(h){console.error("[brender] Prefetch error:",h),i=t.pages}let a;if(p)try{a=await vt(t)}catch(h){console.warn("[brender] SSR translation fetch failed:",h.message)}c!==void 0?globalThis.location=c:delete globalThis.location,s!==void 0?globalThis.window=s:delete globalThis.window;const{window:f,document:g}=st(),T=g.body;f.location.pathname=l;const d=globalThis.document,b=globalThis.location;globalThis.document=g,globalThis.location=f.location;const{createDomqlElement:q}=await Nt(),L=F(t.app||{}),S={...t.config||{}};t.polyglot&&!S.polyglot&&(S.polyglot=t.polyglot),t.fetch&&!S.fetch&&(S.fetch=t.fetch),t.router&&!S.router&&(S.router=t.router);for(const h of["useReset","useVariable","useFontImport","useIconSprite","useSvgSprite","useDefaultConfig","useDocumentTheme"])t[h]!=null&&S[h]==null&&(S[h]=t[h]);const _=S.polyglot?{...S.polyglot}:void 0;a&&_&&(_.translations={..._.translations||{},...a});const j=F(t.state||{});(a||_)&&(j.root||(j.root={}),_&&(j.root.lang=j.root.lang||_.defaultLang||"en"),a&&(j.root.translations={...j.root.translations||{},...a})),Mt();const M={state:j,...r?{state:{...j,...r}}:{},dependencies:F(t.dependencies||{}),components:F(t.components||{}),snippets:F(t.snippets||{}),pages:F(i||t.pages||{}),functions:{...t.functions||{},polyglot:Ft,getActiveLang:lt,getLang:lt},methods:t.methods||{},designSystem:F(t.designSystem||{}),files:t.files||{},sharedLibraries:t.sharedLibraries||[],...S,..._?{polyglot:_}:{},document:g,window:f,parent:{node:T},initOptions:{},domqlOptions:{sourcemap:!1},sync:!1,inspect:!1,notifications:!1,...u||{}},k=await Dt();k&&(M.plugins=M.plugins||[],M.plugins.some(h=>h.name==="funcql")||M.plugins.push(k)),rt();const I=await q(L,M),E=p?2e3:50;await new Promise(h=>setTimeout(h,E)),it(T);const w=ct(I),C=mt(I),R=et(t,o,I,I?.state),x=[],$=g.head||g.querySelector("head");if($)for(const h of $.querySelectorAll("style")){if(h.sheet&&h.sheet.cssRules)for(const O of h.sheet.cssRules)O.cssText&&x.push(O.cssText);if(!x.length){const O=h.textContent||"";O&&x.push(O)}}let A=gt(T.innerHTML);if(a){const h=_?.defaultLang||"en",O=a[h]||Object.values(a)[0]||{};A=A.replace(/\{\{\s*([^|{}]+?)\s*\|\s*polyglot\s*\}\}/g,(V,U)=>{const v=U.trim();return O[v]??V})}return d!==void 0?globalThis.document=d:delete globalThis.document,b!==void 0?globalThis.location=b:delete globalThis.location,{html:A,metadata:R,registry:w,brRegistry:C,element:I,emotionCSS:x,document:g,window:f,ssrTranslations:a,prefetchedPages:i}},ye=async(t,e={})=>{const{context:o={}}=e,{window:n,document:r}=st(),u=r.body,{create:p}=await import("@symbo.ls/element"),l=await import("@symbo.ls/utils"),c={...Bt,...o.components||{}},s={...l,...o.utils||{},...o.functions||{}};rt();let i;try{i=p(t,{node:u},"root",{context:{document:r,window:n,...o,components:c,utils:s}})}catch{}it(u);const a=i?ct(i):{};return{html:gt(u.innerHTML),registry:a,element:i}},gt=t=>t.replace(/(<svg\b[^>]*>)([\s\S]*?)(<\/svg>)/gi,(e,o,n,r)=>{if(n.includes("<")){const u=n.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&").replace(/"/g,'"').replace(/'/g,"'");return o+u+r}return e});let J=null;const Wt=["globalTheme","themeStorageKey","themeRoot","useReset","useVariable","useFontImport","useIconSprite","useSvgSprite","useDocumentTheme","useDefaultConfig","useDefaultIcons","useThemeSuffixedVars","verbose","semanticIcons"],ht=t=>{if(!t||typeof t!="object")return null;if(t.config&&typeof t.config=="object")return t.config;const e={};let o=!1;for(const n of Wt)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n],o=!0);return o?e:t.settings||null},bt=(t,e,o)=>{const n=Object.entries(e||{}).map(([r,u])=>`${o} ${r}: ${u}`).join(`;
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
`);
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
`),
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// Merge with defaults (same as initEmotion)
|
|
21
|
-
const merged = {}
|
|
22
|
-
for (const k in DEFAULT_CONFIG) merged[k] = DEFAULT_CONFIG[k]
|
|
23
|
-
for (const k in ds) {
|
|
24
|
-
if (typeof ds[k] === 'object' && !Array.isArray(ds[k]) && typeof merged[k] === 'object' && !Array.isArray(merged[k])) {
|
|
25
|
-
merged[k] = { ...merged[k], ...ds[k] }
|
|
26
|
-
} else {
|
|
27
|
-
merged[k] = ds[k]
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const conf = set({
|
|
32
|
-
useReset: true,
|
|
33
|
-
useVariable: true,
|
|
34
|
-
useFontImport: true,
|
|
35
|
-
useDocumentTheme: true,
|
|
36
|
-
useDefaultConfig: true,
|
|
37
|
-
globalTheme: 'auto',
|
|
38
|
-
...merged,
|
|
39
|
-
...cfg
|
|
40
|
-
}, { newConfig: {} })
|
|
41
|
-
|
|
42
|
-
const result = {
|
|
43
|
-
CSS_VARS: conf.CSS_VARS || {},
|
|
44
|
-
CSS_MEDIA_VARS: conf.CSS_MEDIA_VARS || {},
|
|
45
|
-
// Skin rules \u2014 the same builder smbls init() injects on the client
|
|
46
|
-
// (FW-SCRATCH-SKINS-DIMENSION-1).
|
|
47
|
-
CSS_SKIN_RULES: typeof scratchNs.buildSkinVarStyles === 'function'
|
|
48
|
-
? scratchNs.buildSkinVarStyles(conf.cssSkinVars, conf.cssSkinFallback, ':root')
|
|
49
|
-
: {},
|
|
50
|
-
reset: conf.reset || {},
|
|
51
|
-
animation: conf.animation || {}
|
|
52
|
-
}
|
|
53
|
-
// Export as globalThis so we can read it
|
|
54
|
-
globalThis.__BR_GLOBAL_CSS__ = result
|
|
55
|
-
export default result
|
|
56
|
-
`);const f=ft(),g={name:"workspace-resolve",setup(w){w.onResolve({filter:/^@symbo\.ls\//},C=>{const R=C.path.replace("@symbo.ls/","");if(f.isMonorepo){for(const $ of["packages","plugins"]){const A=m(f.monorepoRoot,$,R,"src","index.js");if(o(A))return{path:A};const h=m(f.monorepoRoot,$,R,"index.js");if(o(h))return{path:h}}const x=m(f.monorepoRoot,"packages","default-config","blank","index.js");if(R==="default-config"&&o(x))return{path:x}}}),w.onResolve({filter:/^@domql\//},C=>{const R=C.path.replace("@symbo.ls/","");if(f.isMonorepo){const x=m(f.monorepoRoot,"packages","domql","packages",R,"src","index.js");if(o(x))return{path:x}}else{const x=Y(f,R,"src","index.js");if(x&&o(x))return{path:x};const $=Y(f,R,"index.js");if($&&o($))return{path:$}}})}};await l.build({entryPoints:[i],bundle:!0,format:"esm",platform:"node",outfile:a,write:!0,logLevel:"silent",plugins:[g],nodePaths:f.isMonorepo?[m(f.monorepoRoot,"node_modules")]:[...f.smblsRoot?[m(f.smblsRoot,"node_modules")]:[],...f.projectRoot?[m(f.projectRoot,"node_modules")]:[],...f.smblsRoot?[m(f.smblsRoot,"..","..","node_modules")]:[]].filter(w=>o(w)),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"]});const d=(await import(`file://${a}`)).default||{};try{r(i)}catch{}try{r(a)}catch{}const b=d.CSS_VARS||{},q=d.CSS_MEDIA_VARS||{},L=d.RESET||{},S=d.ANIMATION||{},_=Object.entries(b).map(([w,C])=>` ${w}: ${C}`).join(`;
|
|
57
|
-
`);let j=_?`:root {
|
|
58
|
-
${_};
|
|
59
|
-
}`:"";const M=Object.entries(q).map(([w,C])=>{const R=Object.entries(C).map(([x,$])=>` ${x}: ${$}`).join(`;
|
|
60
|
-
`);return R?w.startsWith("@media")?`${w} {
|
|
61
|
-
:root:not([data-theme]) {
|
|
62
|
-
${R};
|
|
63
|
-
}
|
|
64
|
-
}`:`${w} {
|
|
65
|
-
${R};
|
|
66
|
-
}`:""}).filter(Boolean).join(`
|
|
67
|
-
|
|
68
|
-
`);M&&(j+=`
|
|
69
|
-
|
|
70
|
-
`+M);const k=Jt(d.CSS_SKIN_RULES);k&&(j+=(j?`
|
|
71
|
-
|
|
72
|
-
`:"")+k);const I=kt(L),E=[];for(const w in S){const C=S[w];if(!C||typeof C!="object")continue;const R=Object.entries(C).map(([x,$])=>{if(typeof $!="object")return"";const A=Object.entries($).map(([h,O])=>`${G(h)}: ${O}`).join("; ");return` ${x} { ${A}; }`}).join(`
|
|
73
|
-
`);E.push(`@keyframes ${w} {
|
|
74
|
-
${R}
|
|
75
|
-
}`)}return J={rootRule:j,resetRules:I,fontFaceCSS:"",keyframeRules:E.join(`
|
|
76
|
-
`)},J}catch(o){return console.warn("generateGlobalCSS failed:",o.message,o.stack),J={rootRule:"",resetRules:"",fontFaceCSS:"",keyframeRules:""},J}};let Z=new Set;const Se=()=>{J=null,Z=new Set},Re=()=>Array.from(Z).join(`
|
|
77
|
-
`),je=(t,e)=>t.replace(/<style data-emotion="smbls">[\s\S]*?<\/style>/,e?`<style data-emotion="smbls">
|
|
78
|
-
${e}
|
|
79
|
-
</style>`:""),we=async(t,e={})=>{const{route:o="/",pathname:n}=e,r=await dt(t,{route:o,pathname:n,prefetch:!0});if(!r)return null;const u=t.designSystem||{},p=await yt(u,ht(t));let l=null,c=null;try{const s=r.element,i=s?.context?.polyglot||t.polyglot||t.config?.polyglot;if(c=s?.state?.root?.lang||i?.defaultLang||"en",r.prefetchedPages&&r.prefetchedPages[o]){const a=r.prefetchedPages[o],f=(g,T={})=>{if(!g||typeof g!="object")return T;if(g.state&&typeof g.state=="object")for(const[d,b]of Object.entries(g.state))b!=null&&typeof b!="function"&&(T[d]=b);for(const[d,b]of Object.entries(g))d==="state"||d==="props"||d==="attr"||d==="on"||d==="define"||d==="__ref"||d.startsWith("__")||b&&typeof b=="object"&&!Array.isArray(b)&&f(b,T);return T};l=f(a)}}catch{}return{html:r.html,css:r.emotionCSS?r.emotionCSS.join(`
|
|
80
|
-
`):"",globalCSS:p,resetCss:p.resetRules||kt(u.reset),fontLinks:$t(u),metadata:r.metadata||et(t,o),brKeyCount:r.registry?Object.keys(r.registry).length:0,brRegistry:r.brRegistry||{},ssrTranslations:r.ssrTranslations,prefetchedState:l,activeLang:c}},xe=async(t,e="/",o={})=>{const{lang:n,themeColor:r,isr:u,hydrate:p=!0,prefetch:l=!0,shell:c}=o,s=n||t.state?.lang||t.app?.metadata?.lang||"en",i=await dt(t,{route:e,prefetch:l});if(!i)return null;const a={...i.metadata};if(r&&(a["theme-color"]=r),typeof c=="string"&&!t.name){const k="\0brender-undeclared-title\0";if(et({...t,name:k},e,i.element,i.element?.state).title===k)for(const E of["title","og:title","twitter:title"])a[E]===i.metadata.title&&delete a[E]}const f=At(a);if(i.emotionCSS&&i.emotionCSS.length)for(const k of i.emotionCSS)k&&Z.add(k);const g=Array.from(Z).join(`
|
|
81
|
-
`),T=t.designSystem||{},d=await yt(T,ht(t)),b=$t(T),q=Object.keys(i.registry).length;let L="";if(u&&u.clientScript){const k=Number.isInteger(o.depth)?o.depth:e==="/"?0:e.replace(/^\/|\/$/g,"").split("/").length,I=k>0?"../".repeat(k):"./";if(p){let E="";if(i.ssrTranslations){const R=t.polyglot||t.config?.polyglot,x=R?.storagePrefix||"",$=R?.storageLangKey||"",A=[];for(const h in i.ssrTranslations){const O=i.ssrTranslations[h];O&&typeof O=="object"&&A.push(`localStorage.setItem(${JSON.stringify(x+h)},${JSON.stringify(JSON.stringify(O))})`)}if($){const h=R?.defaultLang||"en";A.push(`if(!localStorage.getItem(${JSON.stringify($)}))localStorage.setItem(${JSON.stringify($)},${JSON.stringify(h)})`)}A.length&&(E=`<script>try{${A.join(";")}}catch(e){}<\/script>
|
|
82
|
-
`)}const w=i.brRegistry&&Object.keys(i.brRegistry).length?JSON.stringify(i.brRegistry):null,C=w?`<script>window.__BR_REGISTRY__=${w}<\/script>
|
|
83
|
-
`:"";L=`${E}${C}<script>window.__BRENDER__=true<\/script>
|
|
84
|
-
<script type="module" src="${I}${u.clientScript}"><\/script>`}else L=`<script type="module">
|
|
1
|
+
import{resolve as u,join as ke,dirname as v}from"path";import{existsSync as d,unlinkSync as we,readFileSync as V,realpathSync as xe}from"fs";import{resolvePackageEntry as _e}from"./packageEntry.js";import{tmpdir as je}from"os";import{randomBytes as ve}from"crypto";import{createRequire as oe}from"module";import{createEnv as ie}from"./env.js";import{resetKeys as ae,assignKeys as ce,mapKeysToElements as fe}from"./keys.js";import{extractMetadata as ne,generateHeadHtml as Te}from"./metadata.js";import"./hydrate.js";import{composeIntoShell as Ee}from"./shell.js";import{prefetchPageData as Le,injectPrefetchedState as Ce,fetchSSRTranslations as qe}from"./prefetch.js";import{createEarlySeedScript as $e}from"@symbo.ls/fetch";import{headerEntries as Pe}from"@symbo.ls/fetch/rest";import{jsonForScript as De}from"@symbo.ls/utils";let Q=null;const Ae=async()=>{if(Q)return Q;try{return Q=(await import("@symbo.ls/funcql")).funcqlPlugin,Q}catch{return null}};import"linkedom";import{reset as Me}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 l of o){if(n==null||typeof n!="object")return;n=n[l]}return n},Oe=function(e,t){if(!e)return"";const o=this?.context,n=o?.polyglot,l=t||n?.defaultLang||"en";if(n?.translations){const c=n.translations[l];if(c){const r=se(c,e);if(r!==void 0)return r}}const a=this?.state?.root||o?.state?.root;if(a?.translations){const c=a.translations[l];if(c){const r=se(c,e);if(r!==void 0)return r}}const p=n?.defaultLang||"en";if(p!==l&&n?.translations){const c=n.translations[p];if(c){const r=se(c,e);if(r!==void 0)return r}}return e},pe=function(){const e=this?.context;return this?.state?.root?.lang||e?.polyglot?.defaultLang||"en"},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 l of e)n.push(typeof l=="object"&&l!==null?L(l,t):l);return n}const o={};t.set(e,o);for(const n of Object.keys(e)){const l=e[n];o[n]=typeof l=="object"&&l!==null?L(l,t):l}return o};let M=null;try{import.meta.url&&(M=oe(import.meta.url))}catch{}const Ie=()=>{if(!import.meta.url||!M)return{isMonorepo:!1,monorepoRoot:null,resolvePackage:r=>r};const e=xe(new URL(".",import.meta.url).pathname),t=u(e,"../..");if(d(u(t,"packages","smbls","src","createDomql.js")))return{isMonorepo:!0,monorepoRoot:t};let n;try{const r=M.resolve("smbls/package.json");n=v(r)}catch{let r=e;for(;r!==v(r);){const s=u(r,"node_modules","smbls");if(d(u(s,"package.json"))){n=s;break}r=v(r)}}let l=M;if(n)try{l=oe(u(n,"package.json"))}catch{}let a,p=process.cwd();for(;p!==v(p);){if(d(u(p,"package.json"))){a=p;break}p=v(p)}let c=l;if(a)try{c=oe(u(a,"package.json"))}catch{}return{isMonorepo:!1,smblsRoot:n,brenderDir:e,projectRoot:a,_smblsRequire:l,_projectRequire:c}},K=(e,t)=>{const o=e.isMonorepo?[M]:[e._smblsRequire,e._projectRequire,M].filter(Boolean);for(const n of o)try{return n.resolve(t)}catch{}return null},_t=(e,t,...o)=>{if(e.isMonorepo)return u(e.monorepoRoot,"packages",t,...o);const n=K(e,`${t}/package.json`);return n?u(v(n),...o):null},jt=(e,t,...o)=>{if(e.isMonorepo)return u(e.monorepoRoot,"plugins",t,...o);const n=K(e,`@symbo.ls/${t}/package.json`);return n?u(v(n),...o):null},re=(e,t,...o)=>{if(e.isMonorepo){for(const l of["packages","plugins"]){const a=u(e.monorepoRoot,l,t,...o);if(d(a))return a}return null}const n=K(e,`@symbo.ls/${t}/package.json`);return n?u(v(n),...o):null},ue=(e,t,...o)=>{if(e.isMonorepo)return u(e.monorepoRoot,"packages","domql","packages",t,...o);const n=K(e,`@symbo.ls/${t}/package.json`);return n?u(v(n),...o):null};let X=null;const me="smbls/ssr",Fe=async()=>{const e=await import("smbls/ssr");if(typeof e?.createDomqlElement!="function")throw new Error("smbls/ssr does not export createDomqlElement");return e},Ne=async()=>{if(X)return X;const e=Ie();let t;if(M&&e.isMonorepo)t=u(e.monorepoRoot,"packages","smbls","src","createDomql.js");else{let c;try{return X=await Fe(),X}catch(s){c=s}if(!M)throw new Error(`brender: ${me} is not available in this bundled runtime (${c.message}). Bundle smbls \u2265 the release that adds the smbls/ssr export alongside @symbo.ls/brender.`);const r=e.smblsRoot&&u(e.smblsRoot,"src","createDomql.js");if(r&&d(r))t=r;else throw new Error(`brender: cannot load ${me} (${c.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=ke(je(),`br_createDomql_${ve(6).toString("hex")}.mjs`),l=_e,a={name:"workspace-resolve",setup(c){c.onResolve({filter:/^smbls/},r=>{const s=r.path.replace(/^smbls\/?/,""),f=e.isMonorepo?u(e.monorepoRoot,"packages","smbls"):e.smblsRoot;if(!f)return;if(!s){const h=l(f);return h?{path:h}:void 0}const i=u(f,s);if(d(i))return{path:i};if(d(i+".js"))return{path:i+".js"};const m=u(i,"index.js");if(d(m))return{path:m}}),c.onResolve({filter:/^domql$/},r=>{if(e.isMonorepo){const s=u(e.monorepoRoot,"packages","domql","src","index.js");if(d(s))return{path:s};const f=u(e.monorepoRoot,"packages","domql","index.js");if(d(f))return{path:f}}else try{const s=_require.resolve("domql/package.json"),f=l(v(s));if(f)return{path:f}}catch{}}),c.onResolve({filter:/^@symbo\.ls\//},r=>{const s=r.path.replace("@symbo.ls/","");if(s==="sync")return{path:"sync-stub",namespace:"brender-stub"};if(e.isMonorepo){for(const i of["packages","plugins"]){const m=u(e.monorepoRoot,i,s,"src","index.js");if(d(m))return{path:m};const h=u(e.monorepoRoot,i,s,"index.js");if(d(h))return{path:h}}const f=u(e.monorepoRoot,"packages","default-config","blank","index.js");if(s==="default-config"&&d(f))return{path:f}}else{const f=re(e,s,"src","index.js");if(f&&d(f))return{path:f};const i=re(e,s,"index.js");if(i&&d(i))return{path:i};if(s==="default-config"){const m=re(e,"default-config","blank","index.js");if(m&&d(m))return{path:m}}}}),c.onResolve({filter:/^@domql\//},r=>{const s=r.path.replace("@symbo.ls/","");if(e.isMonorepo){const f=u(e.monorepoRoot,"packages","domql","packages",s,"src","index.js");if(d(f))return{path:f};const i=u(e.monorepoRoot,"packages","domql","packages",s,"index.js");if(d(i))return{path:i}}else{const f=ue(e,s,"src","index.js");if(f&&d(f))return{path:f};const i=ue(e,s,"index.js");if(i&&d(i))return{path:i}}}),c.onResolve({filter:/^css-in-props/},r=>{let s;if(e.isMonorepo)s=u(e.monorepoRoot,"packages","css-in-props");else{const m=K(e,"css-in-props/package.json");m&&(s=v(m))}if(!s)return;const f=r.path.replace(/^css-in-props\/?/,"");if(f){const m=u(s,f),h=u(m,"index.js");if(d(h))return{path:h};if(d(m+".js"))return{path:m+".js"};if(d(m))return{path:m}}const i=l(s);if(i)return{path:i}}),c.onResolve({filter:/^@emotion\//},r=>{let s;if(e.isMonorepo)s=u(e.monorepoRoot,"node_modules",r.path);else{const f=K(e,`${r.path}/package.json`);if(!f)return;s=v(f)}if(d(s)){const f=u(s,"package.json");if(d(f))try{const i=JSON.parse(V(f,"utf8")),m=i.module||i.main||"dist/emotion-css.esm.js";return{path:u(s,m)}}catch{}return{path:s}}}),c.onResolve({filter:/\.json$/},r=>{if(r.resolveDir){const s=u(r.resolveDir,r.path);if(d(s))return{path:s}}}),c.onLoad({filter:/smbls\/.*options\.js$/},async r=>{if(!r.path.includes("smbls/")||!r.path.endsWith("options.js"))return;let s=V(r.path,"utf8");return s=s.replace(/import\s*\{[^}]*version[^}]*\}\s*from\s*['"][^'"]*package\.json['"][^;\n]*/,"const version = '0.0.0'"),s=s.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:s,loader:"js"}}),c.onLoad({filter:/smbls\/.*init\.js$/},async r=>{if(!r.path.includes("smbls/")||!r.path.endsWith("init.js"))return;let s=V(r.path,"utf8");return s=s.replace(/import\s*\{[^}]*createRequire[^}]*\}\s*from\s*['"]module['"][^;\n]*/g,"// createRequire removed for brender build"),{contents:s,loader:"js"}}),c.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"})),c.onLoad({filter:/smbls\/src\/router\.js$/},async r=>{let s=V(r.path,"utf8");return s=s.replace(/import\s*\{\s*Link\s*\}\s*from\s*['"]smbls['"]/,"const Link = { tag: 'a', attr: { href: (el) => el.href } }"),{contents:s,loader:"js"}}),c.onLoad({filter:/fetchOnCreate\.js$/},async r=>{if(!r.path.includes("smbls/"))return;let s=V(r.path,"utf8");return s=s.replace(/window\s*&&\s*window\.location\s*\?\s*window\.location\.host\.includes/g,"window && window.location && window.location.host ? window.location.host.includes"),{contents:s,loader:"js"}})}};await o.build({entryPoints:[t],bundle:!0,format:"esm",platform:"node",outfile:n,write:!0,logLevel:"warning",plugins:[a],nodePaths:e.isMonorepo?[u(e.monorepoRoot,"node_modules")]:[...e.smblsRoot?[u(e.smblsRoot,"node_modules")]:[],...e.projectRoot?[u(e.projectRoot,"node_modules")]:[],...e.smblsRoot?[u(e.smblsRoot,"..","..","node_modules")]:[]].filter(c=>d(c)),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 p=await import(`file://${n}`);if(process.env.BRENDER_DEBUG)console.log("[brender] Bundle saved:",n);else try{we(n)}catch{}return X=p,p},Be={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"}},He=(e,t)=>{const o={},n=l=>{const a=l&&l.__ref;if(a){if(a.__brKey){const p=t(l);o[p===""?"__root":p]=a.__brKey}if(a.__children)for(const p of a.__children)n(l[p])}};return n(e),o},Je=new Set(["app","config","pages","components","state","snippets","designSystem","dependencies","functions","methods","files","sharedLibraries"]);let G=0;const ge=Symbol.for("brender.fetchTracked"),de=()=>G,Ke=256*1024,Ge=1024*1024,We=new Set(["accept-language","accept"]);let le=0,D=null;const Ue=e=>{const[t,o]=e,n=t&&typeof t=="object"&&typeof t.url=="string",l=n?t.url:String(t),a=String(o&&o.method||n&&t.method||"GET").toUpperCase(),p={},c=r=>{if(!r)return;const s=!Array.isArray(r)&&typeof r.entries!="function";for(const[f,i]of Pe(r))s&&i==null||(p[String(f).toLowerCase()]=String(i))};return n&&c(t.headers),o&&c(o.headers),{url:l,method:a,headers:p}},Ye=(e,t,o,n)=>{if(!o||!o.ok||typeof o.clone!="function")return;const l=o.headers&&o.headers.get&&o.headers.get("content-type")||"";if(!/json|^text\//i.test(l))return;let a;try{a=o.clone()}catch{return}n(a.text().then(p=>{e.tainted||p.length>Ke||e.bytes+p.length>Ge||(e.bytes+=p.length,e.entries.push({url:t.url,lang:t.headers["accept-language"]||"",status:o.status,type:l,body:p}))},()=>{}))},ze=()=>{const e=globalThis.fetch;if(typeof e!="function"||e[ge])return;const t=function(...o){G++;let n=!1;const l=()=>{n||(n=!0,G--)},a=s=>{G++,s.then(()=>{G--},()=>{G--})},p=D&&!D.tainted?D:null;let c=null;if(p)try{c=Ue(o),(c.method!=="GET"||!/^https?:/i.test(c.url)||Object.keys(c.headers).some(s=>!We.has(s)))&&(c=null)}catch{c=null}let r;try{r=e.apply(this,o)}catch(s){throw l(),s}return r&&typeof r.then=="function"?r.then(s=>{c&&Ye(p,c,s,a),l()},l):l(),r};t[ge]=!0,globalThis.fetch=t},Ve=({brRegistry:e,fetchSeed:t,hydrateFlag:o=!0}={})=>{if(!e||!Object.keys(e).length)return"";const n=De(e);return o?`<script>window.__BR_REGISTRY__=${n};window.__BRENDER_HYDRATE__=true<\/script>`+(t&&t.length?`
|
|
2
|
+
`+$e(t):""):`<script>window.__BR_REGISTRY__=${n}<\/script>`},he=async(e,t={})=>{const{route:o="/",pathname:n,state:l,context:a,prefetch:p=!1}=t,c=n||o,r=globalThis.location,s=globalThis.window;(!globalThis.location||globalThis.location.pathname!==c)&&(globalThis.location={pathname:c,href:c,search:"",hash:"",origin:""}),globalThis.window||(globalThis.window={location:globalThis.location});let f;if(p)try{const g=e.pages||{};f={...g};const y=await Le(e,o);if(y.size){const P=JSON.parse(JSON.stringify(g[o],(_,A)=>{if(typeof A!="function")return A})),J=(_,A)=>{if(!(!_||!A))for(const E in _)typeof _[E]=="function"?A[E]=_[E]:typeof _[E]=="object"&&_[E]!==null&&!Array.isArray(_[E])&&typeof A[E]=="object"&&A[E]!==null&&J(_[E],A[E])};J(g[o],P),Ce(P,y),f[o]=P}}catch(g){console.error("[brender] Prefetch error:",g),f=e.pages}let i;if(p)try{i=await qe(e)}catch(g){console.warn("[brender] SSR translation fetch failed:",g.message)}r!==void 0?globalThis.location=r:delete globalThis.location,s!==void 0?globalThis.window=s:delete globalThis.window;const{window:m,document:h}=ie(),w=h.body;m.location.pathname=c;const T=globalThis.document,S=globalThis.location;globalThis.document=h,globalThis.location=m.location;const{createDomqlElement:R}=await Ne(),Z=L(e.app||{}),k={...e.config||{}};e.polyglot&&!k.polyglot&&(k.polyglot=e.polyglot),e.fetch&&!k.fetch&&(k.fetch=e.fetch),e.router&&!k.router&&(k.router=e.router);for(const g of Xe)e[g]!=null&&k[g]==null&&(k[g]=e[g]);const x=k.polyglot?{...k.polyglot}:void 0;i&&x&&(x.translations={...x.translations||{},...i});const j=L(e.state||{});(i||x)&&(j.root||(j.root={}),x&&(j.root.lang=j.root.lang||x.defaultLang||"en"),i&&(j.root.translations={...j.root.translations||{},...i})),Me();const F={};for(const g in e){if(Je.has(g))continue;const y=e[g];F[g]=y&&typeof y=="object"?L(y):y}const C={...F,state:j,...l?{state:{...j,...l}}:{},dependencies:L(e.dependencies||{}),components:L(e.components||{}),snippets:L(e.snippets||{}),pages:L(f||e.pages||{}),functions:{...e.functions||{},polyglot:Oe,getActiveLang:pe,getLang:pe},methods:e.methods||{},designSystem:L(e.designSystem||{}),files:e.files||{},sharedLibraries:e.sharedLibraries||[],...k,...x?{polyglot:x}:{},document:h,window:m,parent:{node:w},initOptions:{},domqlOptions:{sourcemap:!1},sync:!1,inspect:!1,notifications:!1,...a||{}},N=await Ae();N&&(C.plugins=C.plugins||[],C.plugins.some(g=>g.name==="funcql")||C.plugins.push(N)),ae(),ze(),le++,le===1?D={entries:[],bytes:0,tainted:!1}:D&&(D.tainted=!0);const W=D;let b;try{b=await R(Z,C);const g=Date.now(),y=p?2e3:50,P=J=>new Promise(_=>setTimeout(_,J));for(await P(Math.min(50,y));p&&de()>0&&Date.now()-g<y;)await P(10),de()===0&&await P(Math.max(0,Math.min(50,y-(Date.now()-g))))}finally{le--,D===W&&(D=null)}const B=W&&!W.tainted?W.entries.slice():[];ce(w);const q=fe(b),{elementPath:U}=await import("@symbo.ls/element"),O=He(b,U),Y=ne(e,o,b,b?.state),$=[],I=h.head||h.querySelector("head");if(I)for(const g of I.querySelectorAll("style")){if(g.sheet&&g.sheet.cssRules)for(const y of g.sheet.cssRules)y.cssText&&$.push(y);if(!$.length){const y=g.textContent||"";y&&$.push({cssText:y})}}const H=$.map(g=>g.cssText),{globalCSS:z,classRules:Re}=tt($);let te=ye(w.innerHTML);if(i){const g=x?.defaultLang||"en",y=i[g]||Object.values(i)[0]||{};te=te.replace(/\{\{\s*([^|{}]+?)\s*\|\s*polyglot\s*\}\}/g,(P,J)=>{const _=J.trim();return y[_]??P})}return T!==void 0?globalThis.document=T:delete globalThis.document,S!==void 0?globalThis.location=S:delete globalThis.location,{html:te,metadata:Y,registry:q,brRegistry:O,element:b,emotionCSS:H,globalCSS:z,classRules:Re,fetchSeed:B,document:h,window:m,ssrTranslations:i,prefetchedPages:f}},vt=async(e,t={})=>{const{context:o={}}=t,{window:n,document:l}=ie(),a=l.body,{create:p}=await import("@symbo.ls/element"),c=await import("@symbo.ls/utils"),r={...Be,...o.components||{}},s={...c,...o.utils||{},...o.functions||{}};ae();let f;try{f=p(e,{node:a},"root",{context:{document:l,window:n,...o,components:r,utils:s}})}catch{}ce(a);const i=f?fe(f):{};return{html:ye(a.innerHTML),registry:i,element:f}},ye=e=>e.replace(/(<svg\b[^>]*>)([\s\S]*?)(<\/svg>)/gi,(t,o,n,l)=>{if(n.includes("<")){const a=n.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&").replace(/"/g,'"').replace(/'/g,"'");return o+a+l}return t}),Xe=["globalTheme","themeStorageKey","themeRoot","useReset","useVariable","useFontImport","useIconSprite","useSvgSprite","useDocumentTheme","useDefaultConfig","useDefaultIcons","useThemeSuffixedVars","verbose","semanticIcons"],Ze=/\.[A-Za-z_\\-]/,Qe=e=>{if(typeof e!="string"||!e)return!1;const t=e.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,'""').replace(/\[[^\]]*\]/g,"[]");return!Ze.test(t)},et=/^\s*(:root|\[data-theme|\[data-skin)/,be=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 Qe(e.selectorText)?et.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(be));return n.has(null)||n.size!==1?n.has(null)?null:"reset":[...n][0]}return null},tt=e=>{const t={root:[],reset:[],keyframes:[]},o=[];for(const n of e||[]){const l=be(n);l?t[l].push(n.cssText):n&&n.cssText&&o.push(n.cssText)}return{globalCSS:{rootRule:t.root.join(`
|
|
3
|
+
`),resetRules:t.reset.join(`
|
|
4
|
+
`),keyframeRules:t.keyframes.join(`
|
|
5
|
+
`),fontFaceCSS:""},classRules:o}};let ee=new Set;const Tt=()=>{ee=new Set},Et=()=>Array.from(ee).join(`
|
|
6
|
+
`),Lt=(e,t)=>e.replace(/<style data-emotion="smbls">[\s\S]*?<\/style>/,t?`<style data-emotion="smbls">
|
|
7
|
+
${t}
|
|
8
|
+
</style>`:""),Ct=async(e,t={})=>{const{route:o="/",pathname:n,prefetch:l=!0}=t,a=await he(e,{route:o,pathname:n,prefetch:l});if(!a)return null;const p=e.designSystem||{},c=a.globalCSS;let r=null,s=null;try{const f=a.element,i=f?.context?.polyglot||e.polyglot||e.config?.polyglot;if(s=f?.state?.root?.lang||i?.defaultLang||"en",a.prefetchedPages&&a.prefetchedPages[o]){const m=a.prefetchedPages[o],h=(w,T={})=>{if(!w||typeof w!="object")return T;if(w.state&&typeof w.state=="object")for(const[S,R]of Object.entries(w.state))R!=null&&typeof R!="function"&&(T[S]=R);for(const[S,R]of Object.entries(w))S==="state"||S==="props"||S==="attr"||S==="on"||S==="define"||S==="__ref"||S.startsWith("__")||R&&typeof R=="object"&&!Array.isArray(R)&&h(R,T);return T};r=h(m)}}catch{}return{html:a.html,css:a.classRules.join(`
|
|
9
|
+
`),classRules:a.classRules.slice(),globalCSS:c,resetCss:c.resetRules,fontLinks:Se(p),metadata:a.metadata||ne(e,o),brKeyCount:a.registry?Object.keys(a.registry).length:0,brRegistry:a.brRegistry||{},fetchSeed:a.fetchSeed||[],ssrTranslations:a.ssrTranslations,prefetchedState:r,activeLang:s}},qt=async(e,t="/",o={})=>{const{lang:n,themeColor:l,isr:a,hydrate:p=!0,prefetch:c=!0,shell:r,adoptDom:s=!1}=o,f=n||e.state?.lang||e.app?.metadata?.lang||"en",i=await he(e,{route:t,prefetch:c});if(!i)return null;const m={...i.metadata};if(l&&(m["theme-color"]=l),typeof r=="string"&&!e.name){const b="\0brender-undeclared-title\0";if(ne({...e,name:b},t,i.element,i.element?.state).title===b)for(const q of["title","og:title","twitter:title"])m[q]===i.metadata.title&&delete m[q]}const h=Te(m);for(const b of i.classRules)b&&ee.add(b);const w=Array.from(ee).join(`
|
|
10
|
+
`),T=i.globalCSS,S=`<style data-brender>
|
|
11
|
+
${T.rootRule||""}
|
|
12
|
+
${T.resetRules||""}
|
|
13
|
+
${T.keyframeRules||""}
|
|
14
|
+
</style>`,R=w?`<style data-emotion="smbls">
|
|
15
|
+
${w}
|
|
16
|
+
</style>`:"",Z=Se(e.designSystem||{}),k=Object.keys(i.registry).length,x=Ve({brRegistry:i.brRegistry,fetchSeed:i.fetchSeed,hydrateFlag:s});let j="";if(a&&a.clientScript){const b=Number.isInteger(o.depth)?o.depth:t==="/"?0:t.replace(/^\/|\/$/g,"").split("/").length,B=b>0?"../".repeat(b):"./";if(p){let q="";if(i.ssrTranslations){const O=e.polyglot||e.config?.polyglot,Y=O?.storagePrefix||"",$=O?.storageLangKey||"",I=[];for(const H in i.ssrTranslations){const z=i.ssrTranslations[H];z&&typeof z=="object"&&I.push(`localStorage.setItem(${JSON.stringify(Y+H)},${JSON.stringify(JSON.stringify(z))})`)}if($){const H=O?.defaultLang||"en";I.push(`if(!localStorage.getItem(${JSON.stringify($)}))localStorage.setItem(${JSON.stringify($)},${JSON.stringify(H)})`)}I.length&&(q=`<script>try{${I.join(";")}}catch(e){}<\/script>
|
|
17
|
+
`)}const U=x?x+`
|
|
18
|
+
`:"";j=`${q}${U}<script>window.__BRENDER__=true<\/script>
|
|
19
|
+
<script type="module" src="${B}${a.clientScript}"><\/script>`}else j=`<script type="module">
|
|
85
20
|
{
|
|
86
21
|
const brEls = document.querySelectorAll('body > :not(script):not(style)')
|
|
87
22
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -98,37 +33,19 @@ ${e}
|
|
|
98
33
|
observer.observe(document.body, { childList: true })
|
|
99
34
|
}
|
|
100
35
|
<\/script>
|
|
101
|
-
<script type="module" src="${
|
|
102
|
-
|
|
103
|
-
${
|
|
104
|
-
${d.keyframeRules||""}
|
|
105
|
-
</style>`,g?`<style data-emotion="smbls">
|
|
106
|
-
${g}
|
|
107
|
-
</style>`:""];return{html:Et(c,{headTags:j,headEnd:[b,...k].filter(Boolean).join(`
|
|
108
|
-
`),body:i.html,depth:Number.isInteger(o.depth)?o.depth:0}),route:e,brKeyCount:q,shell:!0}}return{html:`<!DOCTYPE html>
|
|
109
|
-
<html lang="${s}">
|
|
36
|
+
<script type="module" src="${B}${a.clientScript}"><\/script>`}const F={...e.config||{}};e.polyglot&&!F.polyglot&&(F.polyglot=e.polyglot);const C=F.polyglot;let N=h;if(C){const b=C.defaultLang||"en",q={...C.translations||{},...i.ssrTranslations||{}}[b]||{};N=h.replace(/\{\{\s*([^|{}]+?)\s*\|\s*polyglot\s*\}\}/g,(U,O)=>{const Y=O.trim();return q[Y]??U})}return typeof r=="string"?{html:Ee(r,{headTags:N,headEnd:[Z,S,R].filter(Boolean).join(`
|
|
37
|
+
`),body:i.html,depth:Number.isInteger(o.depth)?o.depth:0,bootScripts:s?x:""}),route:t,brKeyCount:k,shell:!0}:{html:`<!DOCTYPE html>
|
|
38
|
+
<html lang="${f}">
|
|
110
39
|
<head>
|
|
111
|
-
${
|
|
112
|
-
${
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
${
|
|
116
|
-
${d.resetRules||""}
|
|
117
|
-
${d.keyframeRules||""}
|
|
118
|
-
</style>
|
|
119
|
-
${g?`<style data-emotion="smbls">
|
|
120
|
-
${g}
|
|
121
|
-
</style>`:""}
|
|
40
|
+
${N}
|
|
41
|
+
${Z}
|
|
42
|
+
|
|
43
|
+
${S}
|
|
44
|
+
${R}
|
|
122
45
|
</head>
|
|
123
46
|
<body>
|
|
124
47
|
${i.html}
|
|
125
|
-
${
|
|
48
|
+
${j}
|
|
126
49
|
</body>
|
|
127
|
-
</html>`,route:
|
|
128
|
-
`)
|
|
129
|
-
`);c.push(`@keyframes ${s} {
|
|
130
|
-
${a}
|
|
131
|
-
}`)}return[...c,...r].join(`
|
|
132
|
-
`)},kt=t=>{if(!t)return"";const e=[];for(const[o,n]of Object.entries(t)){if(!n||typeof n!="object")continue;const r=[],u=[];for(const[p,l]of Object.entries(n)){if(typeof l=="object"&&l!==null){if(p.startsWith("@media")||p.startsWith("@")){const c=Object.entries(l).filter(([,s])=>typeof s!="object").map(([s,i])=>`${G(s)}: ${i}`).join("; ");c&&u.push(`${p} { ${o} { ${c}; } }`)}continue}r.push(`${G(p)}: ${l}`)}r.length&&e.push(`${o} { ${r.join("; ")}; }`),e.push(...u)}return e.join(`
|
|
133
|
-
`)},$t=t=>{if(!t)return"";const e=t.font_family||t.fontFamily||{},o=new Set;for(const r of Object.values(e)){if(typeof r!="string")continue;const u=r.match(/'([^']+)'/);u&&o.add(u[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(r=>`family=${r.replace(/\s+/g,"+")}:wght@300;400;500;600;700`).join("&")}&display=swap" rel="stylesheet">`].join(`
|
|
134
|
-
`):""};export{ut as SMBLS_SSR_SPECIFIER,Re as getAccumulatedEmotionCSS,dt as render,ye as renderElement,xe as renderPage,we as renderRoute,je as replaceEmotionCSS,Se as resetGlobalCSSCache,Jt as skinRulesToCSS};
|
|
50
|
+
</html>`,route:t,brKeyCount:k}},Se=e=>{if(!e)return"";const t=e.font_family||e.fontFamily||{},o=new Set;for(const l of Object.values(t)){if(typeof l!="string")continue;const a=l.match(/'([^']+)'/);a&&o.add(a[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(l=>`family=${l.replace(/\s+/g,"+")}:wght@300;400;500;600;700`).join("&")}&display=swap" rel="stylesheet">`].join(`
|
|
51
|
+
`):""};export{me as SMBLS_SSR_SPECIFIER,Ve as adoptionScripts,Et as getAccumulatedEmotionCSS,he as render,vt as renderElement,qt as renderPage,Ct as renderRoute,Lt as replaceEmotionCSS,Tt as resetGlobalCSSCache,tt as splitCapturedCSS};
|
package/dist/esm/shell.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
const
|
|
2
|
-
${
|
|
1
|
+
const A=/<head(\s[^>]*)?>/i,C=/<body(\s[^>]*)?>/i,d=(e,t)=>{const s=new RegExp(`\\s${t}\\s*=\\s*("([^"]*)"|'([^']*)'|([^\\s>]+))`,"i").exec(e);return s?s[2]??s[3]??s[4]??"":null},y=e=>{const t=e.slice(0,12).toLowerCase();if(t.startsWith("<title"))return"title";if(t.startsWith("<meta")){if(d(e,"charset")!==null)return"charset";for(const s of["name","property","http-equiv","itemprop"]){const r=d(e,s);if(r!==null)return`${s}:${r.toLowerCase()}`}return null}if(t.startsWith("<link")){const s=(d(e,"rel")||"").toLowerCase();return s==="canonical"?"link:canonical":s==="icon"||s==="shortcut icon"?`link:${s}:${d(e,"href")||""}`:s==="alternate"&&d(e,"hreflang")!==null?`link:alternate:${(d(e,"hreflang")||"").toLowerCase()}`:null}return null},k=/<title[^>]*>[\s\S]*?<\/title\s*>|<meta\b[^>]*>|<link\b[^>]*>/gi,L=/<(script|style|noscript|template|textarea)\b[\s\S]*?<\/\1\s*>/gi,E=e=>[...e.matchAll(L)].map(t=>[t.index,t.index+t[0].length,t[0]]),R=(e,t,s=r=>r)=>{let r="",i=0;for(const[c,n,l]of E(e))r+=t(e.slice(i,c))+s(l),i=n;return r+t(e.slice(i))},f=(e,t,s=0)=>{const r=E(e),i=new RegExp(t.source,t.flags.includes("g")?t.flags:t.flags+"g");i.lastIndex=s;let c;for(;c=i.exec(e);){const n=c.index,l=r.find(([u,h])=>n>u&&n<h);if(!l)return c;i.lastIndex=l[1]}return null},B=e=>!!e&&!/^(?:[a-z][a-z0-9+.-]*:|\/|#|\?)/i.test(e),_=(e,t)=>e.replace(/(\s(?:src|href)\s*=\s*)(?:(["'])([^"']*)\2|([^\s"'>]+))/gi,(s,r,i,c,n)=>{const l=i?c:n;if(!B(l))return s;const u=i||"";return`${r}${u}${t}${l.replace(/^\.\//,"")}${u}`}),D=(e,t)=>{if(!t)return e;const s="../".repeat(t);return R(e,r=>r.replace(/<link\b[^>]*>/gi,i=>_(i,s)),r=>/^<script\b/i.test(r)?r.replace(/^<script\b[^>]*>/i,i=>_(i,s)):r)},I=(e,{headTags:t="",headEnd:s="",body:r="",depth:i=0,bootScripts:c=""}={})=>{if(typeof e!="string"||!e.trim())throw new Error("brender: the shell document is empty");let n=D(e,i);const l=new Set;for(const o of t.matchAll(k)){const a=y(o[0]);a&&l.add(a)}const u=o=>R(o,a=>a.replace(k,O=>l.has(y(O))?"":O)),h=t?`
|
|
2
|
+
${t}`:"",g=s?`
|
|
3
3
|
${s}
|
|
4
|
-
`:"",p=f(
|
|
4
|
+
`:"",p=f(n,A),w=p&&f(n,/<\/head\s*>/i,p.index);if(p&&w){const o=p.index+p[0].length,a=w.index;n=n.slice(0,o)+h+u(n.slice(o,a))+g+n.slice(a)}else{n=u(n);const o=f(n,/<html(\s[^>]*)?>/i)||f(n,/<!doctype[^>]*>/i),a=o?o.index+o[0].length:0;n=n.slice(0,a)+h+g+n.slice(a)}const $=`
|
|
5
5
|
<script>window.__BRENDER__=true<\/script>
|
|
6
|
-
${
|
|
7
|
-
|
|
6
|
+
${c?c+`
|
|
7
|
+
`:""}${r}
|
|
8
|
+
`,x=f(n,C);if(x){const o=x.index+x[0].length;return n.slice(0,o)+$+n.slice(o)}const m=f(n,/<\/(?:body|html)\s*>/i),b=m?m.index:n.length;return n.slice(0,b)+$+n.slice(b)};export{I as composeIntoShell,y as headTagKey};
|
package/env.js
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
import { parseHTML } from 'linkedom'
|
|
2
2
|
|
|
3
|
+
// The virtual windows createEnv() made — see the `globalThis.Window` note below.
|
|
4
|
+
const ssrWindows = new WeakSet()
|
|
5
|
+
class SSRWindow {
|
|
6
|
+
static [Symbol.hasInstance] (obj) { return ssrWindows.has(obj) }
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Give a getter-only HTMLSelectElement#value its setter (see createEnv). The
|
|
10
|
+
// prototype is linkedom's, shared by every document it parses: patched once.
|
|
11
|
+
const patchSelectValue = (document) => {
|
|
12
|
+
let proto = Object.getPrototypeOf(document.createElement('select'))
|
|
13
|
+
let desc
|
|
14
|
+
while (proto && !(desc = Object.getOwnPropertyDescriptor(proto, 'value'))) proto = Object.getPrototypeOf(proto)
|
|
15
|
+
if (!proto || !desc || !desc.get || desc.set) return
|
|
16
|
+
Object.defineProperty(proto, 'value', {
|
|
17
|
+
configurable: true,
|
|
18
|
+
enumerable: desc.enumerable,
|
|
19
|
+
get: desc.get,
|
|
20
|
+
set (value) {
|
|
21
|
+
const wanted = value == null ? '' : String(value)
|
|
22
|
+
let matched = false
|
|
23
|
+
for (const option of this.querySelectorAll('option')) {
|
|
24
|
+
const optionValue = option.hasAttribute('value') ? option.getAttribute('value') : option.textContent
|
|
25
|
+
if (!matched && optionValue === wanted) {
|
|
26
|
+
option.setAttribute('selected', '')
|
|
27
|
+
matched = true
|
|
28
|
+
} else {
|
|
29
|
+
option.removeAttribute('selected')
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
3
36
|
/**
|
|
4
37
|
* Creates a virtual DOM environment for server-side rendering.
|
|
5
38
|
* Returns window and document that DOMQL can use as context.
|
|
@@ -54,6 +87,14 @@ export const createEnv = (html = '<!DOCTYPE html><html><head></head><body></body
|
|
|
54
87
|
if (!globalThis.localStorage) globalThis.localStorage = window.localStorage
|
|
55
88
|
if (!globalThis.sessionStorage) globalThis.sessionStorage = window.sessionStorage
|
|
56
89
|
|
|
90
|
+
// linkedom's HTMLSelectElement has a `value` getter and NO setter: a
|
|
91
|
+
// `value` prop on a <select> threw "Cannot set property value … which has
|
|
92
|
+
// only a getter" and dropped the parent's children from the markup
|
|
93
|
+
// (docs.symbols.app lost DocsNavbar and DocSidebar through its language
|
|
94
|
+
// select — FW-BRENDER-HYDRATION-AND-CF-DEPLOY-PROVIDER-1). The browser's
|
|
95
|
+
// setter: the option with that value becomes the selected one.
|
|
96
|
+
patchSelectValue(document)
|
|
97
|
+
|
|
57
98
|
// Stub MutationObserver for SSR (not provided by linkedom)
|
|
58
99
|
if (!window.MutationObserver) {
|
|
59
100
|
window.MutationObserver = class MutationObserver {
|
|
@@ -72,7 +113,24 @@ export const createEnv = (html = '<!DOCTYPE html><html><head></head><body></body
|
|
|
72
113
|
globalThis.Element = window.Element || globalThis.Element
|
|
73
114
|
globalThis.HTMLElement = window.HTMLElement || globalThis.HTMLElement
|
|
74
115
|
globalThis.MutationObserver = window.MutationObserver
|
|
75
|
-
|
|
116
|
+
// NEVER `window.constructor`: linkedom's window is a Proxy whose
|
|
117
|
+
// constructor is `Object`, and it reads unknown properties through to
|
|
118
|
+
// globalThis — so `window.Window` became `Object`, @symbo.ls/utils
|
|
119
|
+
// `isDOMNode(obj)` (`obj instanceof window.Window`) answered true for EVERY
|
|
120
|
+
// object, and `deepClone` (which keeps DOM nodes by reference) stopped
|
|
121
|
+
// cloning anything nested. Every later render in the same process then
|
|
122
|
+
// built on the first render's in-place-processed design system: 18–42
|
|
123
|
+
// self-referential theme variables per page on the platform worker
|
|
124
|
+
// (FW-BRENDER-HYDRATION-AND-CF-DEPLOY-PROVIDER-1). A real Window class (a
|
|
125
|
+
// jsdom host) is kept; otherwise a class whose only instances are the
|
|
126
|
+
// virtual windows this module created, so the window itself stays a host
|
|
127
|
+
// object (kept by reference, as before) and nothing else does.
|
|
128
|
+
ssrWindows.add(window)
|
|
129
|
+
if (window.constructor && window.constructor !== Object) {
|
|
130
|
+
globalThis.Window = window.constructor
|
|
131
|
+
} else if (typeof globalThis.Window !== 'function' || globalThis.Window === Object) {
|
|
132
|
+
globalThis.Window = SSRWindow
|
|
133
|
+
}
|
|
76
134
|
|
|
77
135
|
return { window, document }
|
|
78
136
|
}
|
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 } from './render.js'
|
|
4
|
+
import { render, renderElement, renderRoute, renderPage, resetGlobalCSSCache, getAccumulatedEmotionCSS, replaceEmotionCSS, adoptionScripts } 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'
|
|
@@ -29,7 +29,8 @@ export {
|
|
|
29
29
|
generateSitemap,
|
|
30
30
|
prefetchPageData,
|
|
31
31
|
injectPrefetchedState,
|
|
32
|
-
composeIntoShell
|
|
32
|
+
composeIntoShell,
|
|
33
|
+
adoptionScripts
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
export default {
|
|
@@ -53,5 +54,6 @@ export default {
|
|
|
53
54
|
generateSitemap,
|
|
54
55
|
prefetchPageData,
|
|
55
56
|
injectPrefetchedState,
|
|
56
|
-
composeIntoShell
|
|
57
|
+
composeIntoShell,
|
|
58
|
+
adoptionScripts
|
|
57
59
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/brender",
|
|
3
|
-
"version": "3.14.
|
|
3
|
+
"version": "3.14.664",
|
|
4
4
|
"license": "CC-BY-NC-4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -46,18 +46,18 @@
|
|
|
46
46
|
"prepublishOnly": "npm run build"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@symbo.ls/css": "^3.14.
|
|
49
|
+
"@symbo.ls/css": "^3.14.777",
|
|
50
50
|
"@symbo.ls/default-config": "^3.14.785",
|
|
51
|
-
"@symbo.ls/element": "^3.14.
|
|
52
|
-
"@symbo.ls/fetch": "^3.14.
|
|
53
|
-
"@symbo.ls/helmet": "^3.14.
|
|
54
|
-
"@symbo.ls/scratch": "^3.14.
|
|
55
|
-
"@symbo.ls/utils": "^3.14.
|
|
51
|
+
"@symbo.ls/element": "^3.14.803",
|
|
52
|
+
"@symbo.ls/fetch": "^3.14.664",
|
|
53
|
+
"@symbo.ls/helmet": "^3.14.670",
|
|
54
|
+
"@symbo.ls/scratch": "^3.14.788",
|
|
55
|
+
"@symbo.ls/utils": "^3.14.786",
|
|
56
56
|
"esbuild": "^0.28.1",
|
|
57
57
|
"linkedom": "^0.16.8"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"smbls": "^3.14.
|
|
60
|
+
"smbls": "^3.14.833"
|
|
61
61
|
},
|
|
62
62
|
"optionalDependencies": {
|
|
63
63
|
"@symbo.ls/funcql": "^3.14.0"
|